Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ConversionCost.cc

    r849720f r00ac42e  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 07:06:19 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Aug 12 10:21:00 2019
    13 // Update Count     : 27
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Sep 25 15:43:34 2017
     13// Update Count     : 10
    1414//
    1515
     
    2828
    2929namespace ResolvExpr {
    30 #if 0
    31         const Cost Cost::zero =      Cost{  0,  0,  0,  0,  0,  0,  0 };
    32         const Cost Cost::infinity =  Cost{ -1, -1, -1, -1, -1,  1, -1 };
    33         const Cost Cost::unsafe =    Cost{  1,  0,  0,  0,  0,  0,  0 };
    34         const Cost Cost::poly =      Cost{  0,  1,  0,  0,  0,  0,  0 };
    35         const Cost Cost::safe =      Cost{  0,  0,  1,  0,  0,  0,  0 };
    36         const Cost Cost::sign =      Cost{  0,  0,  0,  1,  0,  0,  0 };
    37         const Cost Cost::var =       Cost{  0,  0,  0,  0,  1,  0,  0 };
    38         const Cost Cost::spec =      Cost{  0,  0,  0,  0,  0, -1,  0 };
    39         const Cost Cost::reference = Cost{  0,  0,  0,  0,  0,  0,  1 };
    40 #endif
     30        const Cost Cost::zero =      Cost(  0,  0,  0,  0 );
     31        const Cost Cost::infinity =  Cost( -1, -1, -1, -1 );
     32        const Cost Cost::unsafe =    Cost(  1,  0,  0,  0 );
     33        const Cost Cost::poly =      Cost(  0,  1,  0,  0 );
     34        const Cost Cost::safe =      Cost(  0,  0,  1,  0 );
     35        const Cost Cost::reference = Cost(  0,  0,  0,  1 );
    4136
    4237#if 0
     
    4540#define PRINT(x)
    4641#endif
    47 
    48         Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
    49                         const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    50                 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
     42        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     43                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    5144                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
    52                         if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
     45                        if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
    5346                                if ( eqvClass->type ) {
    54                                         return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env );
     47                                        return conversionCost( src, eqvClass->type, indexer, env );
    5548                                } else {
    5649                                        return Cost::infinity;
    5750                                }
    58                         } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
     51                        } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
    5952                                PRINT( std::cerr << " found" << std::endl; )
    60                                 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
     53                                TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    6154                                // all typedefs should be gone by this point
    6255                                assert( type );
    6356                                if ( type->base ) {
    64                                         return conversionCost( src, type->base, srcIsLvalue, indexer, env )
    65                                                 + Cost::safe;
     57                                        return conversionCost( src, type->base, indexer, env ) + Cost::safe;
    6658                                } // if
    6759                        } // if
     
    7971                        PRINT( std::cerr << "compatible!" << std::endl; )
    8072                        return Cost::zero;
    81                 } else if ( dynamic_cast< const VoidType * >( dest ) ) {
     73                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    8274                        return Cost::safe;
    83                 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
     75                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
    8476                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    85                         return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
     77                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    8678                                return ptrsAssignable( t1, t2, env );
    8779                        });
    8880                } else {
    89                         PassVisitor<ConversionCost> converter(
    90                                 dest, srcIsLvalue, indexer, env,
    91                                 (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
    92                                         conversionCost );
     81                        PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
    9382                        src->accept( converter );
    9483                        if ( converter.pass.get_cost() == Cost::infinity ) {
     
    10089        }
    10190
    102         static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue,
    103                         int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     91        Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    10492                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    10593                if ( diff > 0 ) {
    10694                        // TODO: document this
    107                         Cost cost = convertToReferenceCost(
    108                                 strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue,
    109                                 diff-1, indexer, env, func );
     95                        Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
    11096                        cost.incReference();
    11197                        return cost;
    11298                } else if ( diff < -1 ) {
    11399                        // TODO: document this
    114                         Cost cost = convertToReferenceCost(
    115                                 src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue,
    116                                 diff+1, indexer, env, func );
     100                        Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
    117101                        cost.incReference();
    118102                        return cost;
    119103                } else if ( diff == 0 ) {
    120                         const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src );
    121                         const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
     104                        ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
     105                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
    122106                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    123107                                PRINT( std::cerr << "converting between references" << std::endl; )
    124                                 Type::Qualifiers tq1 = srcAsRef->base->tq;
    125                                 Type::Qualifiers tq2 = destAsRef->base->tq;
     108                                Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
     109                                Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
    126110                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
    127111                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    144128                        } else {
    145129                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    146                                 PassVisitor<ConversionCost> converter(
    147                                         dest, srcIsLvalue, indexer, env,
    148                                         (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
    149                                                 conversionCost );
     130                                PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
    150131                                src->accept( converter );
    151132                                return converter.pass.get_cost();
    152133                        } // if
    153134                } else {
    154                         const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
     135                        ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
    155136                        assert( diff == -1 && destAsRef );
    156137                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
    157138                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
    158139                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    159                                 if ( srcIsLvalue ) {
     140                                if ( src->get_lvalue() ) {
    160141                                        PRINT(
    161142                                                std::cerr << "lvalue to reference conversion" << std::endl;
     
    163144                                        )
    164145                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    165                                         if ( src->tq == destAsRef->base->tq ) {
     146                                        if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
    166147                                                return Cost::reference; // cost needs to be non-zero to add cast
    167                                         } if ( src->tq < destAsRef->base->tq ) {
     148                                        } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
    168149                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    169150                                        } else {
     
    185166        }
    186167
    187         Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
    188                         const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     168        Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    189169                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    190                 Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func );
     170                Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
    191171                PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
    192172                return cost;
    193173        }
    194174
    195         ConversionCost::ConversionCost( const Type * dest, bool srcIsLvalue, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    196                 : dest( dest ), srcIsLvalue( srcIsLvalue ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
    197         }
    198 
    199         // GENERATED START, DO NOT EDIT
    200         // GENERATED BY BasicTypes-gen.cc
    201         /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
    202                                  _Bool
    203         char                signed char         unsigned char
    204                   signed short int         unsigned short int
    205                   signed int               unsigned int
    206                   signed long int          unsigned long int
    207                   signed long long int     unsigned long long int
    208                   __int128                 unsigned __int128
    209                   _Float16                 _Float16 _Complex
    210                   _Float32                 _Float32 _Complex
    211                   float                    float _Complex
    212                   _Float32x                _Float32x _Complex
    213                   _Float64                 _Float64 _Complex
    214                   double                   double _Complex
    215                   _Float64x                _Float64x _Complex
    216                              __float80
    217                   _Float128                _Float128 _Complex
    218                             __float128
    219                   long double              long double _Complex
    220                   _Float128x               _Float128x _Complex
    221         */
    222         // GENERATED END
    223 
    224         // GENERATED START, DO NOT EDIT
    225         // GENERATED BY BasicTypes-gen.cc
    226         static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
    227                 /*               B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
    228                 /*      B */ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
    229                 /*      C */ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    230                 /*     SC */ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    231                 /*     UC */ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
    232                 /*     SI */ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
    233                 /*    SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
    234                 /*      I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
    235                 /*     UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
    236                 /*     LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
    237                 /*    LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
    238                 /*    LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
    239                 /*   LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
    240                 /*     IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
    241                 /*    UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
    242                 /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
    243                 /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
    244                 /*     _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
    245                 /*    _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
    246                 /*      F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
    247                 /*     FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
    248                 /*    _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
    249                 /*   _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
    250                 /*     FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
    251                 /*   _FDC */ {  -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,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
    252                 /*      D */ {  -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,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
    253                 /*     DC */ {  -1,  -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,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
    254                 /*   F80X */ {  -1,  -1,  -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,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
    255                 /*  _FDXC */ {  -1,  -1,  -1,  -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,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
    256                 /*    F80 */ {  -1,  -1,  -1,  -1,  -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,   1,   2,   2,   3,   3,   4,   4, },
    257                 /*    _FB */ {  -1,  -1,  -1,  -1,  -1,  -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,   1,   1,   2,   2,   3,   3, },
    258                 /*  _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -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,  -1,  -1,   1,  -1,   2, },
    259                 /*     FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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,   1,   2,   2,   3, },
    260                 /*     LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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,   1,   1,   2, },
    261                 /*    LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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,  -1,   1, },
    262                 /*   _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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,   1, },
    263                 /* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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, },
    264         }; // costMatrix
    265         static const int maxIntCost = 15;
    266         // GENERATED END
     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 ) {
     177        }
     178
     179/*
     180            Old
     181            ===
     182           Double
     183             |
     184           Float
     185             |
     186           ULong
     187           /   \
     188        UInt    Long
     189           \   /
     190            Int
     191             |
     192           Ushort
     193             |
     194           Short
     195             |
     196           Uchar
     197           /   \
     198        Schar   Char
     199
     200                                New
     201                                ===
     202                       +-----LongDoubleComplex--+
     203           LongDouble--+          |             +-LongDoubleImag
     204             |         +---DoubleComplex---+         |
     205           Double------+        |          +----DoubleImag
     206             |           +-FloatComplex-+            |
     207           Float---------+              +-------FloatImag
     208             |
     209          ULongLong
     210             |
     211          LongLong
     212             |
     213           ULong
     214           /   \
     215        UInt    Long
     216           \   /
     217            Int
     218             |
     219           Ushort
     220             |
     221           Short
     222             |
     223           Uchar
     224           /   \
     225        Schar   Char
     226           \   /
     227            Bool
     228*/
     229
     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},
     260        };
    267261        static_assert(
    268                 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
    269                 "Missing row in the cost matrix"
     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"
    270264        );
    271265
    272         // GENERATED START, DO NOT EDIT
    273         // GENERATED BY BasicTypes-gen.cc
    274         static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
    275                 /*               B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
    276                 /*      B */ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    277                 /*      C */ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    278                 /*     SC */ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    279                 /*     UC */ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    280                 /*     SI */ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    281                 /*    SUI */ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    282                 /*      I */ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    283                 /*     UI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    284                 /*     LI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    285                 /*    LUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    286                 /*    LLI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    287                 /*   LLUI */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    288                 /*     IB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    289                 /*    UIB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    290                 /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    291                 /*    _FH */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    292                 /*     _F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    293                 /*    _FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    294                 /*      F */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    295                 /*     FC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    296                 /*    _FX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    297                 /*   _FXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    298                 /*     FD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    299                 /*   _FDC */ {  -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,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    300                 /*      D */ {  -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,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    301                 /*     DC */ {  -1,  -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,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    302                 /*   F80X */ {  -1,  -1,  -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,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
    303                 /*  _FDXC */ {  -1,  -1,  -1,  -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,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
    304                 /*    F80 */ {  -1,  -1,  -1,  -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,   0,   0,   0,   0,   0,   0,   0,   0, },
    305                 /*    _FB */ {  -1,  -1,  -1,  -1,  -1,  -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,   0,   0,   0,   0,   0,   0, },
    306                 /*  _FLDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -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,  -1,  -1,   0,  -1,   0, },
    307                 /*     FB */ {  -1,  -1,  -1,  -1,  -1,  -1,  -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,   0,   0,   0,   0,   0, },
    308                 /*     LD */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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,   0,   0,   0, },
    309                 /*    LDC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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,  -1,   0, },
    310                 /*   _FBX */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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,   0, },
    311                 /* _FLDXC */ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -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, },
    312         }; // signMatrix
    313         // GENERATED END
    314         static_assert(
    315                 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
    316                 "Missing row in the sign matrix"
    317         );
    318 
    319         void ConversionCost::postvisit( const VoidType * ) {
     266
     267        void ConversionCost::postvisit( VoidType * ) {
    320268                cost = Cost::infinity;
    321269        }
    322270
    323         void ConversionCost::postvisit(const BasicType * basicType) {
    324                 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
    325                         int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ];
     271        void ConversionCost::postvisit(BasicType *basicType) {
     272                if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     273                        int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
    326274                        if ( tableResult == -1 ) {
    327275                                cost = Cost::unsafe;
     
    329277                                cost = Cost::zero;
    330278                                cost.incSafe( tableResult );
    331                                 cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] );
    332                         } // if
    333                 } else if ( dynamic_cast< const EnumInstType * >( dest ) ) {
     279                        } // if
     280                } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
    334281                        // xxx - not positive this is correct, but appears to allow casting int => enum
    335282                        cost = Cost::unsafe;
     
    338285        }
    339286
    340         void ConversionCost::postvisit( const PointerType * pointerType ) {
    341                 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
     287        void ConversionCost::postvisit( PointerType * pointerType ) {
     288                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    342289                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
    343                         Type::Qualifiers tq1 = pointerType->base->tq;
    344                         Type::Qualifiers tq2 = destAsPtr->base->tq;
     290                        Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
     291                        Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
    345292                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    346293                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    351298                                        // types are the same, except otherPointer has more qualifiers
    352299                                        cost = Cost::safe;
    353                                 } // if
     300                                }
    354301                        } else {
    355302                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
     
    371318        }
    372319
    373         void ConversionCost::postvisit( const ArrayType * ) {}
    374 
    375         void ConversionCost::postvisit( const ReferenceType * refType ) {
     320        void ConversionCost::postvisit( ArrayType * ) {}
     321
     322        void ConversionCost::postvisit( ReferenceType * refType ) {
    376323                // Note: dest can never be a reference, since it would have been caught in an earlier check
    377                 assert( ! dynamic_cast< const ReferenceType * >( dest ) );
     324                assert( ! dynamic_cast< ReferenceType * >( dest ) );
    378325                // convert reference to rvalue: cv T1 & => T2
    379326                // recursively compute conversion cost from T1 to T2.
    380327                // cv can be safely dropped because of 'implicit dereference' behavior.
    381                 cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env );
    382                 if ( refType->base->tq == dest->tq ) {
     328                cost = costFunc( refType->base, dest, indexer, env );
     329                if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
    383330                        cost.incReference();  // prefer exact qualifiers
    384                 } else if ( refType->base->tq < dest->tq ) {
     331                } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
    385332                        cost.incSafe(); // then gaining qualifiers
    386333                } else {
     
    390337        }
    391338
    392         void ConversionCost::postvisit( const FunctionType * ) {}
    393 
    394         void ConversionCost::postvisit( const StructInstType * inst ) {
    395                 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {
     339        void ConversionCost::postvisit( FunctionType * ) {}
     340
     341        void ConversionCost::postvisit( StructInstType * inst ) {
     342                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    396343                        if ( inst->name == destAsInst->name ) {
    397344                                cost = Cost::zero;
     
    400347        }
    401348
    402         void ConversionCost::postvisit( const UnionInstType * inst ) {
    403                 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {
     349        void ConversionCost::postvisit( UnionInstType * inst ) {
     350                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
    404351                        if ( inst->name == destAsInst->name ) {
    405352                                cost = Cost::zero;
     
    408355        }
    409356
    410         void ConversionCost::postvisit( const EnumInstType * ) {
     357        void ConversionCost::postvisit( EnumInstType * ) {
    411358                static Type::Qualifiers q;
    412359                static BasicType integer( q, BasicType::SignedInt );
    413                 cost = costFunc( &integer, dest, srcIsLvalue, indexer, env );  // safe if dest >= int
     360                cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
    414361                if ( cost < Cost::unsafe ) {
    415362                        cost.incSafe();
     
    417364        }
    418365
    419         void ConversionCost::postvisit( const TraitInstType * ) {}
    420 
    421         void ConversionCost::postvisit( const TypeInstType * inst ) {
    422                 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
    423                         cost = costFunc( eqvClass->type, dest, srcIsLvalue, indexer, env );
    424                 } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
     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 );
     371                } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
    425372                        if ( inst->name == destAsInst->name ) {
    426373                                cost = Cost::zero;
    427374                        }
    428                 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) {
    429                         const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
     375                } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
     376                        TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
    430377                        // all typedefs should be gone by this point
    431378                        assert( type );
    432379                        if ( type->base ) {
    433                                 cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe;
    434                         } // if
    435                 } // if
    436         }
    437 
    438         void ConversionCost::postvisit( const TupleType * tupleType ) {
     380                                cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
     381                        } // if
     382                } // if
     383        }
     384
     385        void ConversionCost::postvisit( TupleType * tupleType ) {
    439386                Cost c = Cost::zero;
    440                 if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) {
     387                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
    441388                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
    442389                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
    443390                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
    444                                 Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env );
     391                                Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
    445392                                if ( newCost == Cost::infinity ) {
    446393                                        return;
     
    456403        }
    457404
    458         void ConversionCost::postvisit( const VarArgsType * ) {
    459                 if ( dynamic_cast< const VarArgsType * >( dest ) ) {
     405        void ConversionCost::postvisit( VarArgsType * ) {
     406                if ( dynamic_cast< VarArgsType* >( dest ) ) {
    460407                        cost = Cost::zero;
    461408                }
    462409        }
    463410
    464         void ConversionCost::postvisit( const ZeroType * ) {
    465                 if ( dynamic_cast< const ZeroType * >( dest ) ) {
     411        void ConversionCost::postvisit( ZeroType * ) {
     412                if ( dynamic_cast< ZeroType * >( dest ) ) {
    466413                        cost = Cost::zero;
    467                 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
    468                         // copied from visit(BasicType *) for signed int, but +1 for safe conversions
    469                         int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
     414                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     415                        // copied from visit(BasicType*) for signed int, but +1 for safe conversions
     416                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
    470417                        if ( tableResult == -1 ) {
    471418                                cost = Cost::unsafe;
     
    473420                                cost = Cost::zero;
    474421                                cost.incSafe( tableResult + 1 );
    475                                 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
    476                         } // if
    477                 } else if ( dynamic_cast< const PointerType * >( dest ) ) {
     422                        }
     423                } else if ( dynamic_cast< PointerType* >( dest ) ) {
     424                        cost = Cost::safe;
     425                }
     426        }
     427
     428        void ConversionCost::postvisit( OneType * ) {
     429                if ( dynamic_cast< OneType * >( dest ) ) {
    478430                        cost = Cost::zero;
    479                         cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
    480                 } // if
    481         }
    482 
    483         void ConversionCost::postvisit( const OneType * ) {
    484                 if ( dynamic_cast< const OneType * >( dest ) ) {
    485                         cost = Cost::zero;
    486                 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
    487                         // copied from visit(BasicType *) for signed int, but +1 for safe conversions
    488                         int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
     431                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     432                        // copied from visit(BasicType*) for signed int, but +1 for safe conversions
     433                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
    489434                        if ( tableResult == -1 ) {
    490435                                cost = Cost::unsafe;
     
    492437                                cost = Cost::zero;
    493438                                cost.incSafe( tableResult + 1 );
    494                                 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
    495                         } // if
    496                 } // if
    497         }
    498 
    499 static int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2,
    500                 const ast::SymbolTable &, const ast::TypeEnvironment & env ) {
    501         return ptrsAssignable( t1, t2, env );
    502 }
    503 
    504 // TODO: This is used for overload resolution. It might be able to be dropped once the old system
    505 // is removed.
    506 static Cost localConversionCost(
    507         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    508         const ast::TypeEnvironment & env
    509 ) { return conversionCost( src, dst, symtab, env ); }
    510 
    511 Cost conversionCost(
    512         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    513         const ast::TypeEnvironment & env
    514 ) {
    515         if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
    516                 if ( const ast::EqvClass * eqv = env.lookup( inst->name ) ) {
    517                         if ( eqv->bound ) {
    518                                 return conversionCost(src, eqv->bound, symtab, env );
    519                         } else {
    520                                 return Cost::infinity;
    521                         }
    522                 } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
    523                         const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named );
    524                         assertf( type, "Unexpected typedef." );
    525                         if ( type->base ) {
    526                                 return conversionCost( src, type->base, symtab, env ) + Cost::safe;
    527439                        }
    528440                }
    529441        }
    530         if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {
    531                 return Cost::zero;
    532         } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
    533                 return Cost::safe;
    534         } else if ( const ast::ReferenceType * refType =
    535                          dynamic_cast< const ast::ReferenceType * >( dst ) ) {
    536                 return convertToReferenceCost( src, refType, symtab, env, localPtrsAssignable );
    537         } else {
    538                 ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost );
    539                 src->accept( converter );
    540                 return converter.pass.cost;
    541         }
    542 }
    543 
    544 static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst,
    545                 int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
    546                 NumCostCalculation func ) {
    547         if ( 0 < diff ) {
    548                 Cost cost = convertToReferenceCost(
    549                         strict_dynamic_cast< const ast::ReferenceType * >( src )->base,
    550                         dst, (diff - 1), symtab, env, func );
    551                 cost.incReference();
    552                 return cost;
    553         } else if ( diff < -1 ) {
    554                 Cost cost = convertToReferenceCost(
    555                         src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,
    556                         (diff + 1), symtab, env, func );
    557                 cost.incReference();
    558                 return cost;
    559         } else if ( 0 == diff ) {
    560                 const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );
    561                 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
    562                 if ( srcAsRef && dstAsRef ) {
    563                         ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;
    564                         ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
    565                         if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
    566                                         srcAsRef->base, dstAsRef->base, symtab, env ) ) {
    567                                 if ( tq1 == tq2 ) {
    568                                         return Cost::zero;
    569                                 } else {
    570                                         return Cost::safe;
    571                                 }
    572                         } else {
    573                                 int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );
    574                                 if ( 0 < assignResult ) {
    575                                         return Cost::safe;
    576                                 } else if ( assignResult < 0 ) {
    577                                         return Cost::unsafe;
    578                                 }
    579                         }
    580                 } else {
    581                         ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost );
    582                         src->accept( converter );
    583                         return converter.pass.cost;
    584                 }
    585         } else {
    586                 assert( -1 == diff );
    587                 const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
    588                 assert( dstAsRef );
    589                 if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, symtab, env ) ) {
    590                         if ( src->is_lvalue() ) {
    591                                 if ( src->qualifiers == dstAsRef->base->qualifiers ) {
    592                                         return Cost::reference;
    593                                 } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
    594                                         return Cost::safe;
    595                                 } else {
    596                                         return Cost::unsafe;
    597                                 }
    598                         } else if ( dstAsRef->base->is_const() ) {
    599                                 return Cost::safe;
    600                         } else {
    601                                 return Cost::unsafe;
    602                         }
    603                 }
    604         }
    605         return Cost::infinity;
    606 }
    607 
    608 Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
    609             const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
    610                 NumCostCalculation func ) {
    611         int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
    612         return convertToReferenceCost( src, dst, sdepth - ddepth, symtab, env, func );
    613 }
    614 
    615 void ConversionCost_new::postvisit( const ast::VoidType * voidType ) {
    616         (void)voidType;
    617         cost = Cost::infinity;
    618 }
    619 
    620 void ConversionCost_new::postvisit( const ast::BasicType * basicType ) {
    621         if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    622                 int tableResult = costMatrix[ basicType->kind ][ dstAsBasic->kind ];
    623                 if ( tableResult == -1 ) {
    624                         cost = Cost::unsafe;
    625                 } else {
    626                         cost = Cost::zero;
    627                         cost.incSafe( tableResult );
    628                         cost.incSign( signMatrix[ basicType->kind ][ dstAsBasic->kind ] );
    629                 }
    630         } else if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    631                 // xxx - not positive this is correct, but appears to allow casting int => enum
    632                 cost = Cost::unsafe;
    633         }
    634 }
    635 
    636 void ConversionCost_new::postvisit( const ast::PointerType * pointerType ) {
    637         if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
    638                 ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
    639                 ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
    640                 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
    641                                 pointerType->base, dstAsPtr->base, symtab, env ) ) {
    642                         if ( tq1 == tq2 ) {
    643                                 cost = Cost::zero;
    644                         } else {
    645                                 cost = Cost::safe;
    646                         }
    647                 } else {
    648                         int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
    649                         if ( 0 < assignResult && tq1 <= tq2 ) {
    650                                 if ( tq1 == tq2 ) {
    651                                         cost = Cost::safe;
    652                                 } else {
    653                                         cost = Cost::safe + Cost::safe;
    654                                 }
    655                         } else if ( assignResult < 0 ) {
    656                                 cost = Cost::unsafe;
    657                         } // else Cost::infinity
    658                 }
    659         }
    660 }
    661 
    662 void ConversionCost_new::postvisit( const ast::ArrayType * arrayType ) {
    663         (void)arrayType;
    664 }
    665 
    666 void ConversionCost_new::postvisit( const ast::ReferenceType * refType ) {
    667         assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
    668 
    669         cost = costCalc( refType->base, dst, symtab, env );
    670         if ( refType->base->qualifiers == dst->qualifiers ) {
    671                 cost.incReference();
    672         } else if ( refType->base->qualifiers < dst->qualifiers ) {
    673                 cost.incSafe();
    674         } else {
    675                 cost.incUnsafe();
    676         }
    677 }
    678 
    679 void ConversionCost_new::postvisit( const ast::FunctionType * functionType ) {
    680         (void)functionType;
    681 }
    682 
    683 void ConversionCost_new::postvisit( const ast::StructInstType * structInstType ) {
    684         if ( const ast::StructInstType * dstAsInst =
    685                         dynamic_cast< const ast::StructInstType * >( dst ) ) {
    686                 if ( structInstType->name == dstAsInst->name ) {
    687                         cost = Cost::zero;
    688                 }
    689         }
    690 }
    691 
    692 void ConversionCost_new::postvisit( const ast::UnionInstType * unionInstType ) {
    693         if ( const ast::UnionInstType * dstAsInst =
    694                         dynamic_cast< const ast::UnionInstType * >( dst ) ) {
    695                 if ( unionInstType->name == dstAsInst->name ) {
    696                         cost = Cost::zero;
    697                 }
    698         }
    699 }
    700 
    701 void ConversionCost_new::postvisit( const ast::EnumInstType * enumInstType ) {
    702         (void)enumInstType;
    703         static const ast::BasicType integer( ast::BasicType::SignedInt );
    704         cost = costCalc( &integer, dst, symtab, env );
    705         if ( cost < Cost::unsafe ) {
    706                 cost.incSafe();
    707         }
    708 }
    709 
    710 void ConversionCost_new::postvisit( const ast::TraitInstType * traitInstType ) {
    711         (void)traitInstType;
    712 }
    713 
    714 void ConversionCost_new::postvisit( const ast::TypeInstType * typeInstType ) {
    715         if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
    716                 cost = costCalc( eqv->bound, dst, symtab, env );
    717         } else if ( const ast::TypeInstType * dstAsInst =
    718                         dynamic_cast< const ast::TypeInstType * >( dst ) ) {
    719                 if ( typeInstType->name == dstAsInst->name ) {
    720                         cost = Cost::zero;
    721                 }
    722         } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
    723                 const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
    724                 assertf( type, "Unexpected typedef.");
    725                 if ( type->base ) {
    726                         cost = costCalc( type->base, dst, symtab, env ) + Cost::safe;
    727                 }
    728         }
    729 }
    730 
    731 void ConversionCost_new::postvisit( const ast::TupleType * tupleType ) {
    732         Cost c = Cost::zero;
    733         if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
    734                 auto srcIt = tupleType->types.begin();
    735                 auto dstIt = dstAsTuple->types.begin();
    736                 auto srcEnd = tupleType->types.end();
    737                 auto dstEnd = dstAsTuple->types.end();
    738                 while ( srcIt != srcEnd && dstIt != dstEnd ) {
    739                         Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env );
    740                         if ( newCost == Cost::infinity ) {
    741                                 return;
    742                         }
    743                         c += newCost;
    744                 }
    745                 if ( dstIt != dstEnd ) {
    746                         cost = Cost::infinity;
    747                 } else {
    748                         cost = c;
    749                 }
    750         }
    751 }
    752 
    753 void ConversionCost_new::postvisit( const ast::VarArgsType * varArgsType ) {
    754         (void)varArgsType;
    755         if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
    756                 cost = Cost::zero;
    757         }
    758 }
    759 
    760 void ConversionCost_new::postvisit( const ast::ZeroType * zeroType ) {
    761         (void)zeroType;
    762         if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
    763                 cost = Cost::zero;
    764         } else if ( const ast::BasicType * dstAsBasic =
    765                         dynamic_cast< const ast::BasicType * >( dst ) ) {
    766                 int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
    767                 if ( -1 == tableResult ) {
    768                         cost = Cost::unsafe;
    769                 } else {
    770                         cost = Cost::zero;
    771                         cost.incSafe( tableResult + 1 );
    772                         cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
    773                 }
    774         }
    775 }
    776 
    777 void ConversionCost_new::postvisit( const ast::OneType * oneType ) {
    778         (void)oneType;
    779         if ( dynamic_cast< const ast::OneType * >( dst ) ) {
    780                 cost = Cost::zero;
    781         } else if ( const ast::BasicType * dstAsBasic =
    782                         dynamic_cast< const ast::BasicType * >( dst ) ) {
    783                 int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
    784                 if ( -1 == tableResult ) {
    785                         cost = Cost::unsafe;
    786                 } else {
    787                         cost = Cost::zero;
    788                         cost.incSafe( tableResult + 1 );
    789                         cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
    790                 }
    791         } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
    792                 cost = Cost::zero;
    793                 cost.incSafe( maxIntCost + 2 );
    794         }
    795 }
    796 
    797 
    798442} // namespace ResolvExpr
    799443
Note: See TracChangeset for help on using the changeset viewer.