Ignore:
Timestamp:
Jan 30, 2018, 3:54:32 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
633a642
Parents:
f792cb8 (diff), 42be3c3 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ConversionCost.cc

    rf792cb8 r7416d46a  
    4444                        EqvClass eqvClass;
    4545                        NamedTypeDecl *namedType;
    46                         PRINT( std::cerr << "type inst " << destAsTypeInst->get_name(); )
    47                         if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
     46                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
     47                        if ( env.lookup( destAsTypeInst->name, eqvClass ) ) {
    4848                                if ( eqvClass.type ) {
    4949                                        return conversionCost( src, eqvClass.type, indexer, env );
     
    5151                                        return Cost::infinity;
    5252                                }
    53                         } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
     53                        } else if ( ( namedType = indexer.lookupType( destAsTypeInst->name ) ) ) {
    5454                                PRINT( std::cerr << " found" << std::endl; )
    5555                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    5656                                // all typedefs should be gone by this point
    5757                                assert( type );
    58                                 if ( type->get_base() ) {
    59                                         return conversionCost( src, type->get_base(), indexer, env ) + Cost::safe;
     58                                if ( type->base ) {
     59                                        return conversionCost( src, type->base, indexer, env ) + Cost::safe;
    6060                                } // if
    6161                        } // if
     
    7777                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    7878                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    79                         return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer &){
     79                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    8080                                return ptrsAssignable( t1, t2, env );
    8181                        });
    8282                } else {
    83                         ConversionCost converter( dest, indexer, env );
     83                        PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
    8484                        src->accept( converter );
    85                         if ( converter.get_cost() == Cost::infinity ) {
     85                        if ( converter.pass.get_cost() == Cost::infinity ) {
    8686                                return Cost::infinity;
    8787                        } else {
    88                                 return converter.get_cost() + Cost::zero;
     88                                return converter.pass.get_cost() + Cost::zero;
    8989                        } // if
    9090                } // if
     
    9595                if ( diff > 0 ) {
    9696                        // TODO: document this
    97                         Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->get_base(), dest, diff-1, indexer, env, func );
     97                        Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
    9898                        cost.incReference();
    9999                        return cost;
    100100                } else if ( diff < -1 ) {
    101101                        // TODO: document this
    102                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->get_base(), diff+1, indexer, env, func );
     102                        Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
    103103                        cost.incReference();
    104104                        return cost;
     
    108108                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    109109                                PRINT( std::cerr << "converting between references" << std::endl; )
    110                                 Type::Qualifiers tq1 = srcAsRef->get_base()->get_qualifiers();
    111                                 Type::Qualifiers tq2 = destAsRef->get_base()->get_qualifiers();
    112                                 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) {
     110                                Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
     111                                Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
     112                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
    113113                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    114114                                        if ( tq1 == tq2 ) {
     
    120120                                        }
    121121                                } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    122                                         int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
     122                                        int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
    123123                                        PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
    124124                                        if ( assignResult > 0 ) {
     
    130130                        } else {
    131131                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    132                                 ConversionCost converter( dest, indexer, env );
     132                                PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
    133133                                src->accept( converter );
    134                                 return converter.get_cost();
     134                                return converter.pass.get_cost();
    135135                        } // if
    136136                } else {
     
    138138                        assert( diff == -1 && destAsRef );
    139139                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
    140                         if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) {
     140                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
    141141                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    142142                                if ( src->get_lvalue() ) {
     
    146146                                        )
    147147                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    148                                         if ( src->get_qualifiers() == destAsRef->get_base()->get_qualifiers() ) {
     148                                        if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
    149149                                                return Cost::reference; // cost needs to be non-zero to add cast
    150                                         } if ( src->get_qualifiers() < destAsRef->get_base()->get_qualifiers() ) {
     150                                        } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
    151151                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    152152                                        } else {
    153153                                                return Cost::unsafe;
    154154                                        } // if
    155                                 } else if ( destAsRef->get_base()->get_const() ) {
     155                                } else if ( destAsRef->base->get_const() ) {
    156156                                        PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
    157157                                        // rvalue-to-const-reference conversion: T => const T &
     
    173173        }
    174174
    175         ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    176                 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ) {
     175        ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     176                : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
    177177        }
    178178
     
    257257        };
    258258
    259         void ConversionCost::visit( VoidType * ) {
     259        void ConversionCost::postvisit( VoidType * ) {
    260260                cost = Cost::infinity;
    261261        }
    262262
    263         void ConversionCost::visit(BasicType *basicType) {
     263        void ConversionCost::postvisit(BasicType *basicType) {
    264264                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    265265                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
     
    278278        }
    279279
    280         void ConversionCost::visit( PointerType * pointerType ) {
     280        void ConversionCost::postvisit( PointerType * pointerType ) {
    281281                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    282282                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
    283                         Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers();
    284                         Type::Qualifiers tq2 = destAsPtr->get_base()->get_qualifiers();
    285                         if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
     283                        Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
     284                        Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
     285                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    286286                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    287287                                if ( tq1 == tq2 ) {
     
    312312        }
    313313
    314         void ConversionCost::visit( ArrayType * ) {}
    315 
    316         void ConversionCost::visit( ReferenceType * refType ) {
     314        void ConversionCost::postvisit( ArrayType * ) {}
     315
     316        void ConversionCost::postvisit( ReferenceType * refType ) {
    317317                // Note: dest can never be a reference, since it would have been caught in an earlier check
    318318                assert( ! dynamic_cast< ReferenceType * >( dest ) );
     
    320320                // recursively compute conversion cost from T1 to T2.
    321321                // cv can be safely dropped because of 'implicit dereference' behavior.
    322                 refType->base->accept( *this );
     322                cost = costFunc( refType->base, dest, indexer, env );
    323323                if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
    324324                        cost.incReference();  // prefer exact qualifiers
     
    331331        }
    332332
    333         void ConversionCost::visit( FunctionType * ) {}
    334 
    335         void ConversionCost::visit( StructInstType * inst ) {
     333        void ConversionCost::postvisit( FunctionType * ) {}
     334
     335        void ConversionCost::postvisit( StructInstType * inst ) {
    336336                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    337337                        if ( inst->name == destAsInst->name ) {
     
    341341        }
    342342
    343         void ConversionCost::visit( UnionInstType * inst ) {
     343        void ConversionCost::postvisit( UnionInstType * inst ) {
    344344                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
    345345                        if ( inst->name == destAsInst->name ) {
     
    349349        }
    350350
    351         void ConversionCost::visit( EnumInstType * ) {
     351        void ConversionCost::postvisit( EnumInstType * ) {
    352352                static Type::Qualifiers q;
    353353                static BasicType integer( q, BasicType::SignedInt );
    354                 integer.accept( *this );  // safe if dest >= int
     354                cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
    355355                if ( cost < Cost::unsafe ) {
    356356                        cost.incSafe();
     
    358358        }
    359359
    360         void ConversionCost::visit( TraitInstType * ) {}
    361 
    362         void ConversionCost::visit( TypeInstType *inst ) {
     360        void ConversionCost::postvisit( TraitInstType * ) {}
     361
     362        void ConversionCost::postvisit( TypeInstType *inst ) {
    363363                EqvClass eqvClass;
    364364                NamedTypeDecl *namedType;
    365                 if ( env.lookup( inst->get_name(), eqvClass ) ) {
    366                         cost = conversionCost( eqvClass.type, dest, indexer, env );
     365                if ( env.lookup( inst->name, eqvClass ) ) {
     366                        cost = costFunc( eqvClass.type, dest, indexer, env );
    367367                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
    368                         if ( inst->get_name() == destAsInst->get_name() ) {
     368                        if ( inst->name == destAsInst->name ) {
    369369                                cost = Cost::zero;
    370370                        }
    371                 } else if ( ( namedType = indexer.lookupType( inst->get_name() ) ) ) {
     371                } else if ( ( namedType = indexer.lookupType( inst->name ) ) ) {
    372372                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    373373                        // all typedefs should be gone by this point
    374374                        assert( type );
    375                         if ( type->get_base() ) {
    376                                 cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost::safe;
    377                         } // if
    378                 } // if
    379         }
    380 
    381         void ConversionCost::visit( TupleType * tupleType ) {
     375                        if ( type->base ) {
     376                                cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
     377                        } // if
     378                } // if
     379        }
     380
     381        void ConversionCost::postvisit( TupleType * tupleType ) {
    382382                Cost c = Cost::zero;
    383383                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
    384                         std::list< Type * >::const_iterator srcIt = tupleType->get_types().begin();
    385                         std::list< Type * >::const_iterator destIt = destAsTuple->get_types().begin();
    386                         while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
    387                                 Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
     384                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
     385                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
     386                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
     387                                Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
    388388                                if ( newCost == Cost::infinity ) {
    389389                                        return;
     
    391391                                c += newCost;
    392392                        } // while
    393                         if ( destIt != destAsTuple->get_types().end() ) {
     393                        if ( destIt != destAsTuple->types.end() ) {
    394394                                cost = Cost::infinity;
    395395                        } else {
     
    399399        }
    400400
    401         void ConversionCost::visit( VarArgsType * ) {
     401        void ConversionCost::postvisit( VarArgsType * ) {
    402402                if ( dynamic_cast< VarArgsType* >( dest ) ) {
    403403                        cost = Cost::zero;
     
    405405        }
    406406
    407         void ConversionCost::visit( ZeroType * ) {
     407        void ConversionCost::postvisit( ZeroType * ) {
    408408                if ( dynamic_cast< ZeroType * >( dest ) ) {
    409409                        cost = Cost::zero;
     
    422422        }
    423423
    424         void ConversionCost::visit( OneType * ) {
     424        void ConversionCost::postvisit( OneType * ) {
    425425                if ( dynamic_cast< OneType * >( dest ) ) {
    426426                        cost = Cost::zero;
Note: See TracChangeset for help on using the changeset viewer.