Ignore:
Timestamp:
Oct 29, 2019, 4:01:24 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
773db65, 9421f3d8
Parents:
7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/ConversionCost.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 07:06:19 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:43:34 2017
    13 // Update Count     : 10
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Aug 12 10:21:00 2019
     13// Update Count     : 27
    1414//
    1515
     
    2828
    2929namespace ResolvExpr {
    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 );
     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
    3641
    3742#if 0
     
    4045#define PRINT(x)
    4146#endif
    42         Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    43                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     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 ) ) {
    4451                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
    45                         if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
     52                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
    4653                                if ( eqvClass->type ) {
    47                                         return conversionCost( src, eqvClass->type, indexer, env );
     54                                        return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env );
    4855                                } else {
    4956                                        return Cost::infinity;
    5057                                }
    51                         } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
     58                        } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
    5259                                PRINT( std::cerr << " found" << std::endl; )
    53                                 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     60                                const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
    5461                                // all typedefs should be gone by this point
    5562                                assert( type );
    5663                                if ( type->base ) {
    57                                         return conversionCost( src, type->base, indexer, env ) + Cost::safe;
     64                                        return conversionCost( src, type->base, srcIsLvalue, indexer, env )
     65                                                + Cost::safe;
    5866                                } // if
    5967                        } // if
     
    7179                        PRINT( std::cerr << "compatible!" << std::endl; )
    7280                        return Cost::zero;
    73                 } else if ( dynamic_cast< VoidType* >( dest ) ) {
     81                } else if ( dynamic_cast< const VoidType * >( dest ) ) {
    7482                        return Cost::safe;
    75                 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
     83                } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
    7684                        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 ){
     85                        return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    7886                                return ptrsAssignable( t1, t2, env );
    7987                        });
    8088                } else {
    81                         PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
     89                        PassVisitor<ConversionCost> converter(
     90                                dest, srcIsLvalue, indexer, env,
     91                                (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
     92                                        conversionCost );
    8293                        src->accept( converter );
    8394                        if ( converter.pass.get_cost() == Cost::infinity ) {
     
    89100        }
    90101
    91         Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     102        static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue,
     103                        int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    92104                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    93105                if ( diff > 0 ) {
    94106                        // TODO: document this
    95                         Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
     107                        Cost cost = convertToReferenceCost(
     108                                strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue,
     109                                diff-1, indexer, env, func );
    96110                        cost.incReference();
    97111                        return cost;
    98112                } else if ( diff < -1 ) {
    99113                        // TODO: document this
    100                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
     114                        Cost cost = convertToReferenceCost(
     115                                src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue,
     116                                diff+1, indexer, env, func );
    101117                        cost.incReference();
    102118                        return cost;
    103119                } else if ( diff == 0 ) {
    104                         ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
    105                         ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
     120                        const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src );
     121                        const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
    106122                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    107123                                PRINT( std::cerr << "converting between references" << std::endl; )
    108                                 Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
    109                                 Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
     124                                Type::Qualifiers tq1 = srcAsRef->base->tq;
     125                                Type::Qualifiers tq2 = destAsRef->base->tq;
    110126                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
    111127                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    128144                        } else {
    129145                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    130                                 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
     146                                PassVisitor<ConversionCost> converter(
     147                                        dest, srcIsLvalue, indexer, env,
     148                                        (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
     149                                                conversionCost );
    131150                                src->accept( converter );
    132151                                return converter.pass.get_cost();
    133152                        } // if
    134153                } else {
    135                         ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
     154                        const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
    136155                        assert( diff == -1 && destAsRef );
    137156                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
    138157                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
    139158                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    140                                 if ( src->get_lvalue() ) {
     159                                if ( srcIsLvalue ) {
    141160                                        PRINT(
    142161                                                std::cerr << "lvalue to reference conversion" << std::endl;
     
    144163                                        )
    145164                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    146                                         if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
     165                                        if ( src->tq == destAsRef->base->tq ) {
    147166                                                return Cost::reference; // cost needs to be non-zero to add cast
    148                                         } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
     167                                        } if ( src->tq < destAsRef->base->tq ) {
    149168                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    150169                                        } else {
     
    166185        }
    167186
    168         Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     187        Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
     188                        const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    169189                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    170                 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
     190                Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func );
    171191                PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
    172192                return cost;
    173193        }
    174194
    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         };
     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
    261267        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"
     268                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
     269                "Missing row in the cost matrix"
    264270        );
    265271
    266 
    267         void ConversionCost::postvisit( VoidType * ) {
     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 * ) {
    268320                cost = Cost::infinity;
    269321        }
    270322
    271         void ConversionCost::postvisit(BasicType *basicType) {
    272                 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    273                         int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
     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 ];
    274326                        if ( tableResult == -1 ) {
    275327                                cost = Cost::unsafe;
     
    277329                                cost = Cost::zero;
    278330                                cost.incSafe( tableResult );
    279                         } // if
    280                 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
     331                                cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] );
     332                        } // if
     333                } else if ( dynamic_cast< const EnumInstType * >( dest ) ) {
    281334                        // xxx - not positive this is correct, but appears to allow casting int => enum
    282335                        cost = Cost::unsafe;
     
    285338        }
    286339
    287         void ConversionCost::postvisit( PointerType * pointerType ) {
    288                 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
     340        void ConversionCost::postvisit( const PointerType * pointerType ) {
     341                if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
    289342                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
    290                         Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
    291                         Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
     343                        Type::Qualifiers tq1 = pointerType->base->tq;
     344                        Type::Qualifiers tq2 = destAsPtr->base->tq;
    292345                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    293346                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    298351                                        // types are the same, except otherPointer has more qualifiers
    299352                                        cost = Cost::safe;
    300                                 }
     353                                } // if
    301354                        } else {
    302355                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
     
    318371        }
    319372
    320         void ConversionCost::postvisit( ArrayType * ) {}
    321 
    322         void ConversionCost::postvisit( ReferenceType * refType ) {
     373        void ConversionCost::postvisit( const ArrayType * ) {}
     374
     375        void ConversionCost::postvisit( const ReferenceType * refType ) {
    323376                // Note: dest can never be a reference, since it would have been caught in an earlier check
    324                 assert( ! dynamic_cast< ReferenceType * >( dest ) );
     377                assert( ! dynamic_cast< const ReferenceType * >( dest ) );
    325378                // convert reference to rvalue: cv T1 & => T2
    326379                // recursively compute conversion cost from T1 to T2.
    327380                // cv can be safely dropped because of 'implicit dereference' behavior.
    328                 cost = costFunc( refType->base, dest, indexer, env );
    329                 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
     381                cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env );
     382                if ( refType->base->tq == dest->tq ) {
    330383                        cost.incReference();  // prefer exact qualifiers
    331                 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
     384                } else if ( refType->base->tq < dest->tq ) {
    332385                        cost.incSafe(); // then gaining qualifiers
    333386                } else {
     
    337390        }
    338391
    339         void ConversionCost::postvisit( FunctionType * ) {}
    340 
    341         void ConversionCost::postvisit( StructInstType * inst ) {
    342                 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
     392        void ConversionCost::postvisit( const FunctionType * ) {}
     393
     394        void ConversionCost::postvisit( const StructInstType * inst ) {
     395                if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {
    343396                        if ( inst->name == destAsInst->name ) {
    344397                                cost = Cost::zero;
     
    347400        }
    348401
    349         void ConversionCost::postvisit( UnionInstType * inst ) {
    350                 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
     402        void ConversionCost::postvisit( const UnionInstType * inst ) {
     403                if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {
    351404                        if ( inst->name == destAsInst->name ) {
    352405                                cost = Cost::zero;
     
    355408        }
    356409
    357         void ConversionCost::postvisit( EnumInstType * ) {
     410        void ConversionCost::postvisit( const EnumInstType * ) {
    358411                static Type::Qualifiers q;
    359412                static BasicType integer( q, BasicType::SignedInt );
    360                 cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
     413                cost = costFunc( &integer, dest, srcIsLvalue, indexer, env );  // safe if dest >= int
    361414                if ( cost < Cost::unsafe ) {
    362415                        cost.incSafe();
     
    364417        }
    365418
    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 ) ) {
     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 ) ) {
    372425                        if ( inst->name == destAsInst->name ) {
    373426                                cost = Cost::zero;
    374427                        }
    375                 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
    376                         TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     428                } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) {
     429                        const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
    377430                        // all typedefs should be gone by this point
    378431                        assert( type );
    379432                        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 ) {
     433                                cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe;
     434                        } // if
     435                } // if
     436        }
     437
     438        void ConversionCost::postvisit( const TupleType * tupleType ) {
    386439                Cost c = Cost::zero;
    387                 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
     440                if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) {
    388441                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
    389442                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
    390443                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
    391                                 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
     444                                Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env );
    392445                                if ( newCost == Cost::infinity ) {
    393446                                        return;
     
    403456        }
    404457
    405         void ConversionCost::postvisit( VarArgsType * ) {
    406                 if ( dynamic_cast< VarArgsType* >( dest ) ) {
    407                         cost = Cost::zero;
    408                 }
    409         }
    410 
    411         void ConversionCost::postvisit( ZeroType * ) {
    412                 if ( dynamic_cast< ZeroType * >( dest ) ) {
    413                         cost = Cost::zero;
    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() ];
     458        void ConversionCost::postvisit( const VarArgsType * ) {
     459                if ( dynamic_cast< const VarArgsType * >( dest ) ) {
     460                        cost = Cost::zero;
     461                }
     462        }
     463
     464        void ConversionCost::postvisit( const ZeroType * ) {
     465                if ( dynamic_cast< const ZeroType * >( dest ) ) {
     466                        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 ];
    417470                        if ( tableResult == -1 ) {
    418471                                cost = Cost::unsafe;
     
    420473                                cost = Cost::zero;
    421474                                cost.incSafe( tableResult + 1 );
    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 ) ) {
    430                         cost = Cost::zero;
    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() ];
     475                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
     476                        } // if
     477                } else if ( dynamic_cast< const PointerType * >( dest ) ) {
     478                        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 ];
    434489                        if ( tableResult == -1 ) {
    435490                                cost = Cost::unsafe;
     
    437492                                cost = Cost::zero;
    438493                                cost.incSafe( tableResult + 1 );
     494                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
     495                        } // if
     496                } // if
     497        }
     498
     499static 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.
     506static 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
     511Cost 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;
    439521                        }
    440                 }
    441         }
     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;
     527                        }
     528                }
     529        }
     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
     544static 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
     608Cost 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
     615void ConversionCost_new::postvisit( const ast::VoidType * voidType ) {
     616        (void)voidType;
     617        cost = Cost::infinity;
     618}
     619
     620void 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
     636void 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
     662void ConversionCost_new::postvisit( const ast::ArrayType * arrayType ) {
     663        (void)arrayType;
     664}
     665
     666void 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
     679void ConversionCost_new::postvisit( const ast::FunctionType * functionType ) {
     680        (void)functionType;
     681}
     682
     683void 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
     692void 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
     701void 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
     710void ConversionCost_new::postvisit( const ast::TraitInstType * traitInstType ) {
     711        (void)traitInstType;
     712}
     713
     714void 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
     731void 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
     753void 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
     760void 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
     777void 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
    442798} // namespace ResolvExpr
    443799
Note: See TracChangeset for help on using the changeset viewer.