Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ConversionCost.cc

    r00ac42e rb0837e4  
    4242        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    4343                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    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 );
     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 );
    4850                                } else {
    4951                                        return Cost::infinity;
    5052                                }
    51                         } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
     53                        } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) {
    5254                                PRINT( std::cerr << " found" << std::endl; )
    5355                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    5456                                // all typedefs should be gone by this point
    5557                                assert( type );
    56                                 if ( type->base ) {
    57                                         return conversionCost( src, type->base, indexer, env ) + Cost::safe;
     58                                if ( type->get_base() ) {
     59                                        return conversionCost( src, type->get_base(), indexer, env ) + Cost::safe;
    5860                                } // if
    5961                        } // if
     
    7577                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    7678                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    77                         return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
     79                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer &){
    7880                                return ptrsAssignable( t1, t2, env );
    7981                        });
    8082                } else {
    81                         PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
     83                        ConversionCost converter( dest, indexer, env );
    8284                        src->accept( converter );
    83                         if ( converter.pass.get_cost() == Cost::infinity ) {
     85                        if ( converter.get_cost() == Cost::infinity ) {
    8486                                return Cost::infinity;
    8587                        } else {
    86                                 return converter.pass.get_cost() + Cost::zero;
     88                                return converter.get_cost() + Cost::zero;
    8789                        } // if
    8890                } // if
     
    9092
    9193        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    92                 PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
     94                PRINT( std::cerr << "convert to reference cost... diff " << diff << std::endl; )
    9395                if ( diff > 0 ) {
    9496                        // TODO: document this
    95                         Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
     97                        Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->get_base(), dest, diff-1, indexer, env, func );
    9698                        cost.incReference();
    9799                        return cost;
    98100                } else if ( diff < -1 ) {
    99101                        // TODO: document this
    100                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
     102                        Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->get_base(), diff+1, indexer, env, func );
    101103                        cost.incReference();
    102104                        return cost;
     
    106108                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    107109                                PRINT( std::cerr << "converting between references" << std::endl; )
    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                                         }
     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;
    119112                                } else {  // xxx - this discards reference qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    120                                         int assignResult = func( srcAsRef->base, destAsRef->base, indexer, env );
     113                                        int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
    121114                                        PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
    122115                                        if ( assignResult > 0 ) {
     
    128121                        } else {
    129122                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    130                                 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
     123                                ConversionCost converter( dest, indexer, env );
    131124                                src->accept( converter );
    132                                 return converter.pass.get_cost();
     125                                return converter.get_cost();
    133126                        } // if
    134127                } else {
     
    136129                        assert( diff == -1 && destAsRef );
    137130                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
    138                         if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
     131                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) {
    139132                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    140133                                if ( src->get_lvalue() ) {
     
    144137                                        )
    145138                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    146                                         if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
     139                                        if ( src->get_qualifiers() == destAsRef->get_base()->get_qualifiers() ) {
    147140                                                return Cost::reference; // cost needs to be non-zero to add cast
    148                                         } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
     141                                        } if ( src->get_qualifiers() < destAsRef->get_base()->get_qualifiers() ) {
    149142                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    150143                                        } else {
    151144                                                return Cost::unsafe;
    152145                                        } // if
    153                                 } else if ( destAsRef->base->get_const() ) {
     146                                } else if ( destAsRef->get_base()->get_const() ) {
    154147                                        PRINT( std::cerr << "rvalue to const ref conversion" << std::endl; )
    155148                                        // rvalue-to-const-reference conversion: T => const T &
     
    168161        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    169162                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    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 ) {
     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 ) {
    177168        }
    178169
     
    228219*/
    229220
    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},
     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,      },
    260248        };
    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 * ) {
     249
     250        void ConversionCost::visit( __attribute((unused)) VoidType *voidType ) {
    268251                cost = Cost::infinity;
    269252        }
    270253
    271         void ConversionCost::postvisit(BasicType *basicType) {
     254        void ConversionCost::visit(BasicType *basicType) {
    272255                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    273256                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
     
    281264                        // xxx - not positive this is correct, but appears to allow casting int => enum
    282265                        cost = Cost::unsafe;
    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 ) {
     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 ) {
    288272                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    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; )
     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 ) ) {
    294277                                if ( tq1 == tq2 ) {
    295278                                        // types are the same
     
    297280                                } else {
    298281                                        // types are the same, except otherPointer has more qualifiers
     282                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
    299283                                        cost = Cost::safe;
    300284                                }
    301                         } else {
     285                        } else {  // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    302286                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
    303287                                PRINT( std::cerr << " :: " << assignResult << std::endl; )
    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                                         }
     288                                if ( assignResult > 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
     289                                        cost = Cost::safe;
    311290                                } else if ( assignResult < 0 ) {
    312291                                        cost = Cost::unsafe;
     
    314293                                // assignResult == 0 means Cost::Infinity
    315294                        } // if
    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 ) {
     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 ) {
    323303                // Note: dest can never be a reference, since it would have been caught in an earlier check
    324304                assert( ! dynamic_cast< ReferenceType * >( dest ) );
     
    326306                // recursively compute conversion cost from T1 to T2.
    327307                // cv can be safely dropped because of 'implicit dereference' behavior.
    328                 cost = costFunc( refType->base, dest, indexer, env );
     308                refType->base->accept( *this );
    329309                if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
    330310                        cost.incReference();  // prefer exact qualifiers
     
    337317        }
    338318
    339         void ConversionCost::postvisit( FunctionType * ) {}
    340 
    341         void ConversionCost::postvisit( StructInstType * inst ) {
     319        void ConversionCost::visit( FunctionType * ) {}
     320
     321        void ConversionCost::visit( StructInstType * inst ) {
    342322                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    343323                        if ( inst->name == destAsInst->name ) {
     
    347327        }
    348328
    349         void ConversionCost::postvisit( UnionInstType * inst ) {
     329        void ConversionCost::visit( UnionInstType * inst ) {
    350330                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
    351331                        if ( inst->name == destAsInst->name ) {
     
    355335        }
    356336
    357         void ConversionCost::postvisit( EnumInstType * ) {
     337        void ConversionCost::visit( EnumInstType * ) {
    358338                static Type::Qualifiers q;
    359339                static BasicType integer( q, BasicType::SignedInt );
    360                 cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
     340                integer.accept( *this );  // safe if dest >= int
    361341                if ( cost < Cost::unsafe ) {
    362342                        cost.incSafe();
     
    364344        }
    365345
    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 );
     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 );
    371353                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
    372                         if ( inst->name == destAsInst->name ) {
     354                        if ( inst->get_name() == destAsInst->get_name() ) {
    373355                                cost = Cost::zero;
    374356                        }
    375                 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
     357                } else if ( ( namedType = indexer.lookupType( inst->get_name() ) ) ) {
    376358                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    377359                        // all typedefs should be gone by this point
    378360                        assert( type );
    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 ) {
     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 ) {
    386368                Cost c = Cost::zero;
    387369                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
    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 );
     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 );
    392374                                if ( newCost == Cost::infinity ) {
    393375                                        return;
     
    395377                                c += newCost;
    396378                        } // while
    397                         if ( destIt != destAsTuple->types.end() ) {
     379                        if ( destIt != destAsTuple->get_types().end() ) {
    398380                                cost = Cost::infinity;
    399381                        } else {
     
    403385        }
    404386
    405         void ConversionCost::postvisit( VarArgsType * ) {
     387        void ConversionCost::visit( VarArgsType * ) {
    406388                if ( dynamic_cast< VarArgsType* >( dest ) ) {
    407389                        cost = Cost::zero;
     
    409391        }
    410392
    411         void ConversionCost::postvisit( ZeroType * ) {
     393        void ConversionCost::visit( ZeroType * ) {
    412394                if ( dynamic_cast< ZeroType * >( dest ) ) {
    413395                        cost = Cost::zero;
     
    426408        }
    427409
    428         void ConversionCost::postvisit( OneType * ) {
     410        void ConversionCost::visit( OneType * ) {
    429411                if ( dynamic_cast< OneType * >( dest ) ) {
    430412                        cost = Cost::zero;
Note: See TracChangeset for help on using the changeset viewer.