Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ConversionCost.cc

    rb0837e4 r00ac42e  
    4242        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    4343                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    44                         EqvClass eqvClass;
    45                         NamedTypeDecl *namedType;
    46                         PRINT( std::cerr << "type inst " << destAsTypeInst->get_name(); )
    47                         if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
    48                                 if ( eqvClass.type ) {
    49                                         return conversionCost( src, eqvClass.type, indexer, env );
     44                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
     45                        if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
     46                                if ( eqvClass->type ) {
     47                                        return conversionCost( src, eqvClass->type, indexer, env );
    5048                                } else {
    5149                                        return Cost::infinity;
    5250                                }
    53                         } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
     51                        } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
    5452                                PRINT( std::cerr << " found" << std::endl; )
    5553                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    5654                                // all typedefs should be gone by this point
    5755                                assert( type );
    58                                 if ( type->get_base() ) {
    59                                         return conversionCost( src, type->get_base(), indexer, env ) + Cost::safe;
     56                                if ( type->base ) {
     57                                        return conversionCost( src, type->base, indexer, env ) + Cost::safe;
    6058                                } // if
    6159                        } // if
     
    7775                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    7876                        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 &){
     77                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    8078                                return ptrsAssignable( t1, t2, env );
    8179                        });
    8280                } else {
    83                         ConversionCost converter( dest, indexer, env );
     81                        PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
    8482                        src->accept( converter );
    85                         if ( converter.get_cost() == Cost::infinity ) {
     83                        if ( converter.pass.get_cost() == Cost::infinity ) {
    8684                                return Cost::infinity;
    8785                        } else {
    88                                 return converter.get_cost() + Cost::zero;
     86                                return converter.pass.get_cost() + Cost::zero;
    8987                        } // if
    9088                } // if
     
    9290
    9391        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    94                 PRINT( std::cerr << "convert to reference cost... diff " << diff << std::endl; )
     92                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    9593                if ( diff > 0 ) {
    9694                        // TODO: document this
    97                         Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->get_base(), dest, diff-1, indexer, env, func );
     95                        Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
    9896                        cost.incReference();
    9997                        return cost;
    10098                } else if ( diff < -1 ) {
    10199                        // TODO: document this
    102                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->get_base(), diff+1, indexer, env, func );
     100                        Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
    103101                        cost.incReference();
    104102                        return cost;
     
    108106                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    109107                                PRINT( std::cerr << "converting between references" << std::endl; )
    110                                 if ( srcAsRef->get_base()->get_qualifiers() <= destAsRef->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( srcAsRef->get_base(), destAsRef->get_base(), indexer, env ) ) {
    111                                         return Cost::safe;
     108                                Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
     109                                Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
     110                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
     111                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     112                                        if ( tq1 == tq2 ) {
     113                                                // types are the same
     114                                                return Cost::zero;
     115                                        } else {
     116                                                // types are the same, except otherPointer has more qualifiers
     117                                                return Cost::safe;
     118                                        }
    112119                                } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    113                                         int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
     120                                        int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
    114121                                        PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
    115122                                        if ( assignResult > 0 ) {
     
    121128                        } else {
    122129                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    123                                 ConversionCost converter( dest, indexer, env );
     130                                PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
    124131                                src->accept( converter );
    125                                 return converter.get_cost();
     132                                return converter.pass.get_cost();
    126133                        } // if
    127134                } else {
     
    129136                        assert( diff == -1 && destAsRef );
    130137                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
    131                         if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) {
     138                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
    132139                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    133140                                if ( src->get_lvalue() ) {
     
    137144                                        )
    138145                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    139                                         if ( src->get_qualifiers() == destAsRef->get_base()->get_qualifiers() ) {
     146                                        if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
    140147                                                return Cost::reference; // cost needs to be non-zero to add cast
    141                                         } if ( src->get_qualifiers() < destAsRef->get_base()->get_qualifiers() ) {
     148                                        } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
    142149                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    143150                                        } else {
    144151                                                return Cost::unsafe;
    145152                                        } // if
    146                                 } else if ( destAsRef->get_base()->get_const() ) {
     153                                } else if ( destAsRef->base->get_const() ) {
    147154                                        PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
    148155                                        // rvalue-to-const-reference conversion: T => const T &
     
    161168        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    162169                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    163                 return convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
    164         }
    165 
    166         ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env )
    167                 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ) {
     170                Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
     171                PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
     172                return cost;
     173        }
     174
     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 ) {
    168177        }
    169178
     
    219228*/
    220229
    221         static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
    222         /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag  I128,   U128 */
    223                 /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              12,             13,             14,             12,             13,             14,             -1,             -1,             -1,             10,             11,     },
    224                 /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,     },
    225                 /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,     },
    226                 /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              10,             11,             12,             10,             11,             12,             -1,             -1,             -1,             8,              9,      },
    227                 /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              9,              10,             11,             9,              10,             11,             -1,             -1,             -1,             7,              8,      },
    228                 /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              8,              9,              10,             8,              9,              10,             -1,             -1,             -1,             6,              7,      },
    229                 /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              7,              8,              9,              7,              8,              9,              -1,             -1,             -1,             5,              6,      },
    230                 /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,      },
    231                 /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,      },
    232                 /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              5,              6,              7,              5,              6,              7,              -1,             -1,             -1,             3,              4,      },
    233                 /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              4,              5,              6,              4,              5,              6,              -1,             -1,             -1,             2,              3,      },
    234                 /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              3,              4,              5,              3,              4,              5,              -1,             -1,             -1,             1,              2,      },
    235 
    236                 /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1,             -1,             -1,     },
    237                 /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1,             -1,             -1,     },
    238                 /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,     },
    239                 /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1,             -1,             -1,     },
    240                 /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1,             -1,             -1,     },
    241                 /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1,             -1,             -1,     },
    242                 /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2,              -1,             -1,     },
    243                 /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1,              -1,             -1,     },
    244                 /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0,              -1,             -1,     },
    245 
    246                 /* I128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             2,              3,              4,              3,              4,              5,              -1,             -1,             -1,             0,              1,      },
    247                 /* U128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              2,              3,              4,              -1,             -1,             -1,             -1,             0,      },
     230        static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
     231        /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag  I128,   U128, F80, F128 */
     232                /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              12,             13,             14,             12,             13,             14,             -1,             -1,             -1,             10,             11,       14,   15},
     233                /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,       13,   14},
     234                /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,       13,   14},
     235                /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              10,             11,             12,             10,             11,             12,             -1,             -1,             -1,             8,              9,        12,   13},
     236                /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              9,              10,             11,             9,              10,             11,             -1,             -1,             -1,             7,              8,        11,   12},
     237                /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              8,              9,              10,             8,              9,              10,             -1,             -1,             -1,             6,              7,        10,   11},
     238                /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              7,              8,              9,              7,              8,              9,              -1,             -1,             -1,             5,              6,        9,    10},
     239                /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,        8,    9},
     240                /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,        8,    9},
     241                /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              5,              6,              7,              5,              6,              7,              -1,             -1,             -1,             3,              4,        7,    8},
     242                /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              4,              5,              6,              4,              5,              6,              -1,             -1,             -1,             2,              3,        6,    7},
     243                /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              3,              4,              5,              3,              4,              5,              -1,             -1,             -1,             1,              2,        5,    6},
     244
     245                /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1,             -1,             -1,       2,    3},
     246                /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1,             -1,             -1,       1,    2},
     247                /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       -1,   1},
     248                /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
     249                /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
     250                /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
     251                /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2,              -1,             -1,       -1,   -1},
     252                /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1,              -1,             -1,       -1,   -1},
     253                /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0,              -1,             -1,       -1,   -1},
     254
     255                /* I128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             2,              3,              4,              3,              4,              5,              -1,             -1,             -1,             0,              1,        4,    4},
     256                /* U128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              2,              3,              4,              -1,             -1,             -1,             -1,             0,        3,    3},
     257
     258                /* F80 */       { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       0,    1},
     259                /* F128 */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       -1,   0},
    248260        };
    249 
    250         void ConversionCost::visit( __attribute((unused)) VoidType *voidType ) {
     261        static_assert(
     262                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     263                "Each basic type kind should have a corresponding row in the cost matrix"
     264        );
     265
     266
     267        void ConversionCost::postvisit( VoidType * ) {
    251268                cost = Cost::infinity;
    252269        }
    253270
    254         void ConversionCost::visit(BasicType *basicType) {
     271        void ConversionCost::postvisit(BasicType *basicType) {
    255272                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    256273                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
     
    264281                        // xxx - not positive this is correct, but appears to allow casting int => enum
    265282                        cost = Cost::unsafe;
    266                 } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
    267                         cost = Cost::unsafe;
    268                 } // if
    269         }
    270 
    271         void ConversionCost::visit( PointerType * pointerType ) {
     283                } // if
     284                // no cases for zero_t/one_t because it should not be possible to convert int, etc. to zero_t/one_t.
     285        }
     286
     287        void ConversionCost::postvisit( PointerType * pointerType ) {
    272288                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    273                         PRINT( std::cerr << pointerType << " ===> " << destAsPtr; )
    274                         Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers();
    275                         Type::Qualifiers tq2 = destAsPtr->get_base()->get_qualifiers();
    276                         if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {
     289                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
     290                        Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
     291                        Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
     292                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
     293                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    277294                                if ( tq1 == tq2 ) {
    278295                                        // types are the same
     
    280297                                } else {
    281298                                        // types are the same, except otherPointer has more qualifiers
    282                                         PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    283299                                        cost = Cost::safe;
    284300                                }
    285                         } else {  // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
     301                        } else {
    286302                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
    287303                                PRINT( std::cerr << " :: " << assignResult << std::endl; )
    288                                 if ( assignResult > 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
    289                                         cost = Cost::safe;
     304                                if ( assignResult > 0 && tq1 <= tq2 ) {
     305                                        // xxx - want the case where qualifiers are added to be more expensive than the case where qualifiers are the same. Is 1 safe vs. 2 safe correct?
     306                                        if ( tq1 == tq2 ) {
     307                                                cost = Cost::safe;
     308                                        } else if ( tq1 < tq2 ) {
     309                                                cost = Cost::safe+Cost::safe;
     310                                        }
    290311                                } else if ( assignResult < 0 ) {
    291312                                        cost = Cost::unsafe;
     
    293314                                // assignResult == 0 means Cost::Infinity
    294315                        } // if
    295                 } else if ( dynamic_cast< ZeroType * >( dest ) ) {
    296                         cost = Cost::unsafe;
    297                 } // if
    298         }
    299 
    300         void ConversionCost::visit( ArrayType * ) {}
    301 
    302         void ConversionCost::visit( ReferenceType * refType ) {
     316                        // case case for zero_t because it should not be possible to convert pointers to zero_t.
     317                } // if
     318        }
     319
     320        void ConversionCost::postvisit( ArrayType * ) {}
     321
     322        void ConversionCost::postvisit( ReferenceType * refType ) {
    303323                // Note: dest can never be a reference, since it would have been caught in an earlier check
    304324                assert( ! dynamic_cast< ReferenceType * >( dest ) );
     
    306326                // recursively compute conversion cost from T1 to T2.
    307327                // cv can be safely dropped because of 'implicit dereference' behavior.
    308                 refType->base->accept( *this );
     328                cost = costFunc( refType->base, dest, indexer, env );
    309329                if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
    310330                        cost.incReference();  // prefer exact qualifiers
     
    317337        }
    318338
    319         void ConversionCost::visit( FunctionType * ) {}
    320 
    321         void ConversionCost::visit( StructInstType * inst ) {
     339        void ConversionCost::postvisit( FunctionType * ) {}
     340
     341        void ConversionCost::postvisit( StructInstType * inst ) {
    322342                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    323343                        if ( inst->name == destAsInst->name ) {
     
    327347        }
    328348
    329         void ConversionCost::visit( UnionInstType * inst ) {
     349        void ConversionCost::postvisit( UnionInstType * inst ) {
    330350                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
    331351                        if ( inst->name == destAsInst->name ) {
     
    335355        }
    336356
    337         void ConversionCost::visit( EnumInstType * ) {
     357        void ConversionCost::postvisit( EnumInstType * ) {
    338358                static Type::Qualifiers q;
    339359                static BasicType integer( q, BasicType::SignedInt );
    340                 integer.accept( *this );  // safe if dest >= int
     360                cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
    341361                if ( cost < Cost::unsafe ) {
    342362                        cost.incSafe();
     
    344364        }
    345365
    346         void ConversionCost::visit( TraitInstType * ) {}
    347 
    348         void ConversionCost::visit( TypeInstType *inst ) {
    349                 EqvClass eqvClass;
    350                 NamedTypeDecl *namedType;
    351                 if ( env.lookup( inst->get_name(), eqvClass ) ) {
    352                         cost = conversionCost( eqvClass.type, dest, indexer, env );
     366        void ConversionCost::postvisit( TraitInstType * ) {}
     367
     368        void ConversionCost::postvisit( TypeInstType *inst ) {
     369                if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
     370                        cost = costFunc( eqvClass->type, dest, indexer, env );
    353371                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
    354                         if ( inst->get_name() == destAsInst->get_name() ) {
     372                        if ( inst->name == destAsInst->name ) {
    355373                                cost = Cost::zero;
    356374                        }
    357                 } else if ( ( namedType = indexer.lookupType( inst->get_name() ) ) ) {
     375                } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
    358376                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    359377                        // all typedefs should be gone by this point
    360378                        assert( type );
    361                         if ( type->get_base() ) {
    362                                 cost = conversionCost( type->get_base(), dest, indexer, env ) + Cost::safe;
    363                         } // if
    364                 } // if
    365         }
    366 
    367         void ConversionCost::visit( TupleType * tupleType ) {
     379                        if ( type->base ) {
     380                                cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
     381                        } // if
     382                } // if
     383        }
     384
     385        void ConversionCost::postvisit( TupleType * tupleType ) {
    368386                Cost c = Cost::zero;
    369387                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
    370                         std::list< Type * >::const_iterator srcIt = tupleType->get_types().begin();
    371                         std::list< Type * >::const_iterator destIt = destAsTuple->get_types().begin();
    372                         while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
    373                                 Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
     388                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
     389                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
     390                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
     391                                Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
    374392                                if ( newCost == Cost::infinity ) {
    375393                                        return;
     
    377395                                c += newCost;
    378396                        } // while
    379                         if ( destIt != destAsTuple->get_types().end() ) {
     397                        if ( destIt != destAsTuple->types.end() ) {
    380398                                cost = Cost::infinity;
    381399                        } else {
     
    385403        }
    386404
    387         void ConversionCost::visit( VarArgsType * ) {
     405        void ConversionCost::postvisit( VarArgsType * ) {
    388406                if ( dynamic_cast< VarArgsType* >( dest ) ) {
    389407                        cost = Cost::zero;
     
    391409        }
    392410
    393         void ConversionCost::visit( ZeroType * ) {
     411        void ConversionCost::postvisit( ZeroType * ) {
    394412                if ( dynamic_cast< ZeroType * >( dest ) ) {
    395413                        cost = Cost::zero;
     
    408426        }
    409427
    410         void ConversionCost::visit( OneType * ) {
     428        void ConversionCost::postvisit( OneType * ) {
    411429                if ( dynamic_cast< OneType * >( dest ) ) {
    412430                        cost = Cost::zero;
Note: See TracChangeset for help on using the changeset viewer.