Changeset f53acdf8 for src/ResolvExpr


Ignore:
Timestamp:
Jul 19, 2019, 2:16:01 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
4eb43fa
Parents:
1f1c102 (diff), 8ac3b0e (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' into new-ast

Location:
src/ResolvExpr
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AdjustExprType.cc

    r1f1c102 rf53acdf8  
    4747                void premutate( OneType * ) { visit_children = false; }
    4848
    49                 Type * postmutate( ArrayType *arrayType );
    50                 Type * postmutate( FunctionType *functionType );
    51                 Type * postmutate( TypeInstType *aggregateUseType );
     49                Type * postmutate( ArrayType * arrayType );
     50                Type * postmutate( FunctionType * functionType );
     51                Type * postmutate( TypeInstType * aggregateUseType );
    5252
    5353                private:
     
    6161
    6262        Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) {
    63                 PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
     63                PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
    6464                arrayType->base = nullptr;
    6565                delete arrayType;
     
    7272
    7373        Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) {
    74                 if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) {
     74                if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
    7575                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
    7676                                return new PointerType{ Type::Qualifiers(), typeInst };
    7777                        }
    78                 } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    79                         if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
     78                } else if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     79                        if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl * >( ntDecl ) ) {
    8080                                if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
    8181                                        return new PointerType{ Type::Qualifiers(), typeInst };
     
    8989void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    9090        PassVisitor<AdjustExprType_old> adjuster( env, indexer );
    91         Type *newType = type->acceptMutator( adjuster );
     91        Type * newType = type->acceptMutator( adjuster );
    9292        type = newType;
    9393}
     
    149149} // anonymous namespace
    150150
    151 const ast::Type * adjustExprType( 
    152         const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
     151const ast::Type * adjustExprType(
     152        const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
    153153) {
    154154        ast::Pass<AdjustExprType_new> adjuster{ env, symtab };
  • src/ResolvExpr/AlternativeFinder.cc

    r1f1c102 rf53acdf8  
    336336                }
    337337
    338                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
     338                if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
    339339                        addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
    340                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
     340                } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    341341                        addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
    342342                } // if
     
    344344
    345345        template< typename StructOrUnionType >
    346         void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {
     346        void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression * expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {
    347347                std::list< Declaration* > members;
    348348                aggInst->lookup( name, members );
    349349
    350350                for ( Declaration * decl : members ) {
    351                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     351                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
    352352                                // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
    353353                                // can't construct in place and use vector::back
     
    362362        }
    363363
    364         void AlternativeFinder::Finder::addTupleMembers( TupleType *tupleType, Expression *expr,                        const Alternative &alt, const Cost &newCost, Expression *member ) {
     364        void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression * member ) {
    365365                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    366366                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
     
    368368                        std::string tmp;
    369369                        if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
    370                                 alternatives.push_back( Alternative{ 
     370                                alternatives.push_back( Alternative{
    371371                                        alt, new TupleIndexExpr( expr->clone(), val ), newCost } );
    372372                        } // if
     
    374374        }
    375375
    376         void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) {
     376        void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {
    377377                alternatives.push_back( Alternative{ applicationExpr->clone(), env } );
    378378        }
     
    475475                }
    476476
    477                 // specialization cost of return types can't be accounted for directly, it disables 
     477                // specialization cost of return types can't be accounted for directly, it disables
    478478                // otherwise-identical calls, like this example based on auto-newline in the I/O lib:
    479479                //
     
    12261226                                // count one safe conversion for each value that is thrown away
    12271227                                thisCost.incSafe( discardedValues );
    1228                                 Alternative newAlt{ 
    1229                                         restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 
     1228                                Alternative newAlt{
     1229                                        restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ),
    12301230                                        alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost };
    12311231                                inferParameters( newAlt, back_inserter( candidates ) );
     
    13281328                if ( sizeofExpr->get_isType() ) {
    13291329                        Type * newType = sizeofExpr->get_type()->clone();
    1330                         alternatives.push_back( Alternative{ 
     1330                        alternatives.push_back( Alternative{
    13311331                                new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } );
    13321332                } else {
     
    13431343                        Alternative &choice = winners.front();
    13441344                        referenceToRvalueConversion( choice.expr, choice.cost );
    1345                         alternatives.push_back( Alternative{ 
     1345                        alternatives.push_back( Alternative{
    13461346                                choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } );
    13471347                } // if
     
    13511351                if ( alignofExpr->get_isType() ) {
    13521352                        Type * newType = alignofExpr->get_type()->clone();
    1353                         alternatives.push_back( Alternative{ 
     1353                        alternatives.push_back( Alternative{
    13541354                                new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } );
    13551355                } else {
     
    13661366                        Alternative &choice = winners.front();
    13671367                        referenceToRvalueConversion( choice.expr, choice.cost );
    1368                         alternatives.push_back( Alternative{ 
     1368                        alternatives.push_back( Alternative{
    13691369                                choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } );
    13701370                } // if
     
    13771377                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    13781378                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    1379                                 alternatives.push_back( Alternative{ 
     1379                                alternatives.push_back( Alternative{
    13801380                                        new OffsetofExpr{ aggInst->clone(), dwt }, env } );
    13811381                                renameTypes( alternatives.back().expr );
     
    14051405
    14061406        namespace {
    1407                 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
     1407                void resolveAttr( SymTab::Indexer::IdData data, const FunctionType * function, Type * argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
    14081408                        // assume no polymorphism
    14091409                        // assume no implicit conversions
    1410                         assert( function->get_parameters().size() == 1 );
     1410                        assert( function->parameters.size() == 1 );
    14111411                        PRINT(
    14121412                                std::cerr << "resolvAttr: funcDecl is ";
     
    14181418                        const SymTab::Indexer & indexer = finder.get_indexer();
    14191419                        AltList & alternatives = finder.get_alternatives();
    1420                         if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
     1420                        if ( typesCompatibleIgnoreQualifiers( argType, function->parameters.front()->get_type(), indexer, env ) ) {
    14211421                                Cost cost = Cost::zero;
    14221422                                Expression * newExpr = data.combine( cost );
    1423                                 alternatives.push_back( Alternative{ 
    1424                                         new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 
     1423                                alternatives.push_back( Alternative{
     1424                                        new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{},
    14251425                                        AssertionList{}, Cost::zero, cost } );
    14261426                                for ( DeclarationWithType * retVal : function->returnVals ) {
     
    14311431        }
    14321432
    1433         void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) {
     1433        void AlternativeFinder::Finder::postvisit( AttrExpr * attrExpr ) {
    14341434                // assume no 'pointer-to-attribute'
    1435                 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
     1435                NameExpr * nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    14361436                assert( nameExpr );
    14371437                std::list< SymTab::Indexer::IdData > attrList;
     
    14391439                if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
    14401440                        for ( auto & data : attrList ) {
    1441                                 DeclarationWithType * id = data.id;
     1441                                const DeclarationWithType * id = data.id;
    14421442                                // check if the type is function
    1443                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {
     1443                                if ( const FunctionType * function = dynamic_cast< const FunctionType * >( id->get_type() ) ) {
    14441444                                        // assume exactly one parameter
    1445                                         if ( function->get_parameters().size() == 1 ) {
     1445                                        if ( function->parameters.size() == 1 ) {
    14461446                                                if ( attrExpr->get_isType() ) {
    14471447                                                        resolveAttr( data, function, attrExpr->get_type(), env, altFinder);
     
    14621462                                Cost cost = Cost::zero;
    14631463                                Expression * newExpr = data.combine( cost );
    1464                                 alternatives.push_back( Alternative{ 
     1464                                alternatives.push_back( Alternative{
    14651465                                        newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } );
    14661466                                renameTypes( alternatives.back().expr );
     
    14691469        }
    14701470
    1471         void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) {
     1471        void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {
    14721472                AlternativeFinder firstFinder( indexer, env );
    14731473                firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
     
    14861486                                cloneAll( second.need, need );
    14871487
    1488                                 LogicalExpr *newExpr = new LogicalExpr{ 
     1488                                LogicalExpr *newExpr = new LogicalExpr{
    14891489                                        first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() };
    1490                                 alternatives.push_back( Alternative{ 
    1491                                         newExpr, std::move(compositeEnv), std::move(openVars), 
     1490                                alternatives.push_back( Alternative{
     1491                                        newExpr, std::move(compositeEnv), std::move(openVars),
    14921492                                        AssertionList( need.begin(), need.end() ), first.cost + second.cost } );
    14931493                        }
     
    15221522                                        cloneAll( third.need, need );
    15231523                                        AssertionSet have;
    1524                                        
     1524
    15251525                                        // unify true and false types, then infer parameters to produce new alternatives
    15261526                                        Type* commonType = nullptr;
    1527                                         if ( unify( second.expr->result, third.expr->result, compositeEnv, 
     1527                                        if ( unify( second.expr->result, third.expr->result, compositeEnv,
    15281528                                                        need, have, openVars, indexer, commonType ) ) {
    1529                                                 ConditionalExpr *newExpr = new ConditionalExpr{ 
     1529                                                ConditionalExpr *newExpr = new ConditionalExpr{
    15301530                                                        first.expr->clone(), second.expr->clone(), third.expr->clone() };
    15311531                                                newExpr->result = commonType ? commonType : second.expr->result->clone();
    15321532                                                // convert both options to the conditional result type
    15331533                                                Cost cost = first.cost + second.cost + third.cost;
    1534                                                 cost += computeExpressionConversionCost( 
     1534                                                cost += computeExpressionConversionCost(
    15351535                                                        newExpr->arg2, newExpr->result, indexer, compositeEnv );
    1536                                                 cost += computeExpressionConversionCost( 
     1536                                                cost += computeExpressionConversionCost(
    15371537                                                        newExpr->arg3, newExpr->result, indexer, compositeEnv );
    15381538                                                // output alternative
    1539                                                 Alternative newAlt{ 
    1540                                                         newExpr, std::move(compositeEnv), std::move(openVars), 
     1539                                                Alternative newAlt{
     1540                                                        newExpr, std::move(compositeEnv), std::move(openVars),
    15411541                                                        AssertionList( need.begin(), need.end() ), cost };
    15421542                                                inferParameters( newAlt, back_inserter( alternatives ) );
     
    15531553                secondFinder.findWithAdjustment( commaExpr->get_arg2() );
    15541554                for ( const Alternative & alt : secondFinder.alternatives ) {
    1555                         alternatives.push_back( Alternative{ 
     1555                        alternatives.push_back( Alternative{
    15561556                                alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } );
    15571557                } // for
     
    15791579
    15801580                                Type* commonType = nullptr;
    1581                                 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 
     1581                                if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have,
    15821582                                                openVars, indexer, commonType ) ) {
    1583                                         RangeExpr * newExpr = 
     1583                                        RangeExpr * newExpr =
    15841584                                                new RangeExpr{ first.expr->clone(), second.expr->clone() };
    15851585                                        newExpr->result = commonType ? commonType : first.expr->result->clone();
    1586                                         Alternative newAlt{ 
    1587                                                 newExpr, std::move(compositeEnv), std::move(openVars), 
     1586                                        Alternative newAlt{
     1587                                                newExpr, std::move(compositeEnv), std::move(openVars),
    15881588                                                AssertionList( need.begin(), need.end() ), first.cost + second.cost };
    15891589                                        inferParameters( newAlt, back_inserter( alternatives ) );
     
    16121612                                cloneAll( alt.need, need );
    16131613                        }
    1614                        
    1615                         alternatives.push_back( Alternative{ 
    1616                                 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 
     1614
     1615                        alternatives.push_back( Alternative{
     1616                                new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars),
    16171617                                AssertionList( need.begin(), need.end() ), sumCost( alts ) } );
    16181618                } // for
     
    16331633                finder.findWithoutPrune( ctorExpr->get_callExpr() );
    16341634                for ( Alternative & alt : finder.alternatives ) {
    1635                         alternatives.push_back( Alternative{ 
     1635                        alternatives.push_back( Alternative{
    16361636                                alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } );
    16371637                }
     
    16851685                                cloneAll( alt.need, need );
    16861686                                AssertionSet have;
    1687                                 OpenVarSet openVars( alt.openVars ); 
    1688                                 // xxx - find things in env that don't have a "representative type" and claim 
     1687                                OpenVarSet openVars( alt.openVars );
     1688                                // xxx - find things in env that don't have a "representative type" and claim
    16891689                                // those are open vars?
    16901690                                PRINT(
    16911691                                        std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl;
    16921692                                )
    1693                                 // It's possible that a cast can throw away some values in a multiply-valued 
    1694                                 // expression. (An example is a cast-to-void, which casts from one value to 
    1695                                 // zero.)  Figure out the prefix of the subexpression results that are cast 
    1696                                 // directly.  The candidate is invalid if it has fewer results than there are 
     1693                                // It's possible that a cast can throw away some values in a multiply-valued
     1694                                // expression. (An example is a cast-to-void, which casts from one value to
     1695                                // zero.)  Figure out the prefix of the subexpression results that are cast
     1696                                // directly.  The candidate is invalid if it has fewer results than there are
    16971697                                // types to cast to.
    16981698                                int discardedValues = alt.expr->result->size() - toType->size();
    16991699                                if ( discardedValues < 0 ) continue;
    1700                                 // xxx - may need to go into tuple types and extract relevant types and use 
    1701                                 // unifyList. Note that currently, this does not allow casting a tuple to an 
     1700                                // xxx - may need to go into tuple types and extract relevant types and use
     1701                                // unifyList. Note that currently, this does not allow casting a tuple to an
    17021702                                // atomic type (e.g. (int)([1, 2, 3]))
    1703                                
     1703
    17041704                                // unification run for side-effects
    17051705                                unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer );
     
    17101710                                        // count one safe conversion for each value that is thrown away
    17111711                                        thisCost.incSafe( discardedValues );
    1712                                         Alternative newAlt{ 
    1713                                                 new InitExpr{ 
    1714                                                         restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 
    1715                                                 std::move(newEnv), std::move(openVars), 
     1712                                        Alternative newAlt{
     1713                                                new InitExpr{
     1714                                                        restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() },
     1715                                                std::move(newEnv), std::move(openVars),
    17161716                                                AssertionList( need.begin(), need.end() ), alt.cost, thisCost };
    17171717                                        inferParameters( newAlt, back_inserter( candidates ) );
  • src/ResolvExpr/CastCost.cc

    r1f1c102 rf53acdf8  
    3737        struct CastCost_old : public ConversionCost {
    3838          public:
    39                 CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
     39                CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
    4040
    4141                using ConversionCost::previsit;
    4242                using ConversionCost::postvisit;
    43                 void postvisit( BasicType * basicType );
    44                 void postvisit( PointerType * pointerType );
     43                void postvisit( const BasicType * basicType );
     44                void postvisit( const PointerType * pointerType );
    4545        };
    4646
    47         Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    48                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    49                         if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     47        Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     48                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
     49                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
    5050                                if ( eqvClass->type ) {
    5151                                        return castCost( src, eqvClass->type, indexer, env );
     
    5353                                        return Cost::infinity;
    5454                                }
    55                         } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) {
     55                        } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
    5656                                // all typedefs should be gone by this point
    57                                 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );
     57                                const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );
    5858                                if ( type->base ) {
    5959                                        return castCost( src, type->base, indexer, env ) + Cost::safe;
     
    7474                        PRINT( std::cerr << "compatible!" << std::endl; )
    7575                        return Cost::zero;
    76                 } else if ( dynamic_cast< VoidType* >( dest ) ) {
     76                } else if ( dynamic_cast< const VoidType * >( dest ) ) {
    7777                        return Cost::safe;
    78                 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
     78                } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
    7979                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    80                         return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     80                        return convertToReferenceCost( src, refType, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
    8181                                return ptrsCastable( t1, t2, env, indexer );
    8282                        });
    8383                } else {
    84                         PassVisitor<CastCost_old> converter( 
    85                                 dest, indexer, env, 
    86                                 (Cost (*)( Type *, Type *, const SymTab::Indexer &, const TypeEnvironment & ))
     84                        PassVisitor<CastCost_old> converter(
     85                                dest, indexer, env,
     86                                (Cost (*)( const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment & ))
    8787                                        castCost );
    8888                        src->accept( converter );
     
    9696        }
    9797
    98         CastCost_old::CastCost_old( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     98        CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    9999                : ConversionCost( dest, indexer, env, costFunc ) {
    100100        }
    101101
    102         void CastCost_old::postvisit( BasicType *basicType ) {
    103                 PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
     102        void CastCost_old::postvisit( const BasicType * basicType ) {
     103                const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest );
    104104                if ( destAsPointer && basicType->isInteger() ) {
    105                         // necessary for, e.g. unsigned long => void*
     105                        // necessary for, e.g. unsigned long => void *
    106106                        cost = Cost::unsafe;
    107107                } else {
     
    110110        }
    111111
    112         void CastCost_old::postvisit( PointerType *pointerType ) {
    113                 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    114                         if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
     112        void CastCost_old::postvisit( const PointerType * pointerType ) {
     113                if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
     114                        if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    115115                                cost = Cost::safe;
    116116                        } else {
     
    125125                                } // if
    126126                        } // if
    127                 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     127                } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
    128128                        if ( destAsBasic->isInteger() ) {
    129                                 // necessary for, e.g. void* => unsigned long
     129                                // necessary for, e.g. void * => unsigned long
    130130                                cost = Cost::unsafe;
    131131                        } // if
     
    138138                using ConversionCost_new::postvisit;
    139139
    140                 CastCost_new( 
    141                         const ast::Type * dst, const ast::SymbolTable & symtab, 
     140                CastCost_new(
     141                        const ast::Type * dst, const ast::SymbolTable & symtab,
    142142                        const ast::TypeEnvironment & env, CostCalculation costFunc )
    143143                : ConversionCost_new( dst, symtab, env, costFunc ) {}
     
    182182} // anonymous namespace
    183183
    184 Cost castCost( 
    185         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
    186         const ast::TypeEnvironment & env 
     184Cost castCost(
     185        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     186        const ast::TypeEnvironment & env
    187187) {
    188188        if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     
    220220                PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    221221                #warning cast on ptrsCastable artifact of having two functions, remove when port done
    222                 return convertToReferenceCost( 
    223                         src, refType, symtab, env, 
    224                         ( int (*)( 
    225                                 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
     222                return convertToReferenceCost(
     223                        src, refType, symtab, env,
     224                        ( int (*)(
     225                                const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    226226                                const ast::TypeEnvironment & )
    227227                        ) ptrsCastable );
     
    229229                #warning cast on castCost artifact of having two functions, remove when port done
    230230                ast::Pass< CastCost_new > converter{
    231                         dst, symtab, env, 
    232                         ( Cost (*)( 
    233                                 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
     231                        dst, symtab, env,
     232                        ( Cost (*)(
     233                                const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    234234                                const ast::TypeEnvironment & )
    235235                        ) castCost };
  • src/ResolvExpr/CommonType.cc

    r1f1c102 rf53acdf8  
    3838namespace ResolvExpr {
    3939        struct CommonType_old : public WithShortCircuiting {
    40                 CommonType_old( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    41                 Type *get_result() const { return result; }
     40                CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     41                Type * get_result() const { return result; }
    4242
    4343                void previsit( BaseSyntaxNode * ) { visit_children = false; }
     
    6060
    6161          private:
    62                 template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer );
    63                 template< typename RefType > void handleRefType( RefType *inst, Type *other );
    64 
    65                 Type *result;
    66                 Type *type2;                            // inherited
     62                template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer );
     63                template< typename RefType > void handleRefType( RefType * inst, Type * other );
     64
     65                Type * result;
     66                Type * type2;                           // inherited
    6767                bool widenFirst, widenSecond;
    6868                const SymTab::Indexer &indexer;
     
    8080                                std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
    8181                        )
    82                         if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {
     82                        if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) {
    8383                                PRINT(
    8484                                        std::cerr << "widen okay" << std::endl;
    8585                                )
    86                                 common->get_qualifiers() |= t1->get_qualifiers();
    87                                 common->get_qualifiers() |= t2->get_qualifiers();
     86                                common->tq |= t1->tq;
     87                                common->tq |= t2->tq;
    8888                                return common;
    8989                        }
     
    9595        }
    9696
    97         Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
     97        Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
    9898                PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
    9999
     
    127127                                                std::cerr << "formal is reference; result should be reference" << std::endl;
    128128                                        )
    129                                         result = new ReferenceType( ref1->get_qualifiers(), result );
     129                                        result = new ReferenceType( ref1->tq, result );
    130130                                }
    131131                                PRINT(
     
    138138
    139139                type1->accept( visitor );
    140                 Type *result = visitor.pass.get_result();
     140                Type * result = visitor.pass.get_result();
    141141                if ( ! result ) {
    142142                        // this appears to be handling for opaque type declarations
    143143                        if ( widenSecond ) {
    144                                 if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {
    145                                         if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {
    146                                                 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );
     144                                if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) {
     145                                        if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) {
     146                                                const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
    147147                                                if ( type->get_base() ) {
    148                                                         Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
     148                                                        Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq;
    149149                                                        AssertionSet have, need;
    150150                                                        OpenVarSet newOpen( openVars );
    151                                                         type1->get_qualifiers() = Type::Qualifiers();
    152                                                         type->get_base()->get_qualifiers() = tq1;
     151                                                        type1->tq = Type::Qualifiers();
     152                                                        type->get_base()->tq = tq1;
    153153                                                        if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
    154154                                                                result = type1->clone();
    155                                                                 result->get_qualifiers() = tq1 | tq2;
     155                                                                result->tq = tq1 | tq2;
    156156                                                        } // if
    157                                                         type1->get_qualifiers() = tq1;
    158                                                         type->get_base()->get_qualifiers() = Type::Qualifiers();
     157                                                        type1->tq = tq1;
     158                                                        type->get_base()->tq = Type::Qualifiers();
    159159                                                } // if
    160160                                        } // if
     
    190190                                 */
    191191                                  {
    192                 /*     B*/                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     192                /*     B */                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    193193                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    194194                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    198198                                  },
    199199                                  {
    200                 /*     C*/                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     200                /*     C */                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    201201                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    202202                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    206206                                  },
    207207                                  {
    208                 /*    SC*/          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     208                /*    SC */          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    209209                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    210210                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    214214                                  },
    215215                                  {
    216                 /*    UC*/        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     216                /*    UC */        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
    217217                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    218218                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    222222                                  },
    223223                                  {
    224                 /*    SI*/      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
     224                /*    SI */      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
    225225                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    226226                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    230230                                  },
    231231                                  {
    232                 /*   SUI*/    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
     232                /*   SUI */    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
    233233                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    234234                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    238238                                  },
    239239                                  {
    240                 /*     I*/           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
     240                /*     I */           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
    241241                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    242242                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    246246                                  },
    247247                                  {
    248                 /*    UI*/         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
     248                /*    UI */         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
    249249                                           BT UnsignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    250250                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    254254                                  },
    255255                                  {
    256                 /*    LI*/       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
     256                /*    LI */       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
    257257                                         BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    258258                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    262262                                  },
    263263                                  {
    264                 /*   LUI*/     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
     264                /*   LUI */     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
    265265                                       BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    266266                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    270270                                  },
    271271                                  {
    272                 /*   LLI*/   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
     272                /*   LLI */   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
    273273                                     BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
    274274                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    278278                                  },
    279279                                  {
    280                 /*  LLUI*/ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
     280                /*  LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
    281281                                   BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
    282282                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    286286                                  },
    287287                                  {
    288                 /*    IB*/        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
     288                /*    IB */        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
    289289                                          BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
    290290                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    294294                                  },
    295295                                  {
    296                 /*   UIB*/      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
     296                /*   UIB */      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
    297297                                        BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
    298298                                        BT UnsignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    302302                                  },
    303303                                  {
    304                 /*   _FH*/            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
     304                /*   _FH */            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
    305305                                              BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
    306306                                              BT uFloat16,            BT uFloat16,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     
    310310                                  },
    311311                                  {
    312                 /*   _FH*/     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
     312                /*   _FH */     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
    313313                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
    314314                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     
    318318                                  },
    319319                                  {
    320                 /*    _F*/            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
     320                /*    _F */            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
    321321                                              BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
    322322                                              BT uFloat32,            BT uFloat32,            BT uFloat32,     BT uFloat32Complex,            BT uFloat32,     BT uFloat32Complex,
     
    326326                                  },
    327327                                  {
    328                 /*   _FC*/     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     328                /*   _FC */     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
    329329                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
    330330                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     
    334334                                  },
    335335                                  {
    336                 /*     F*/               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
     336                /*     F */               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
    337337                                                 BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
    338338                                                 BT Float,               BT Float,               BT Float,        BT FloatComplex,               BT Float,        BT FloatComplex,
     
    342342                                  },
    343343                                  {
    344                 /*    FC*/        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     344                /*    FC */        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
    345345                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
    346346                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     
    350350                                  },
    351351                                  {
    352                 /*   _FX*/           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
     352                /*   _FX */           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
    353353                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
    354354                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,
     
    358358                                  },
    359359                                  {
    360                 /*  _FXC*/    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     360                /*  _FXC */    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
    361361                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
    362362                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     
    366366                                  },
    367367                                  {
    368                 /*    FD*/            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
     368                /*    FD */            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
    369369                                              BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
    370370                                              BT uFloat64,            BT uFloat64,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
     
    374374                                  },
    375375                                  {
    376                 /*  _FDC*/     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     376                /*  _FDC */     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
    377377                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
    378378                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     
    382382                                  },
    383383                                  {
    384                 /*     D*/              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
     384                /*     D */              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
    385385                                                BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
    386386                                                BT Double,              BT Double,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
     
    390390                                  },
    391391                                  {
    392                 /*    DC*/       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     392                /*    DC */       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
    393393                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
    394394                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     
    398398                                  },
    399399                                  {
    400                 /*  F80X*/           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
     400                /*  F80X */           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
    401401                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
    402402                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
     
    406406                                  },
    407407                                  {
    408                 /* _FDXC*/    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     408                /* _FDXC */    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
    409409                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
    410410                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     
    422422                                  },
    423423                                  {
    424                 /*   _FB*/           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
     424                /*   _FB */           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
    425425                                             BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
    426426                                             BT uFloat128,           BT uFloat128,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
     
    430430                                  },
    431431                                  {
    432                 /* _FLDC*/    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     432                /* _FLDC */    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
    433433                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
    434434                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     
    438438                                  },
    439439                                  {
    440                 /*    FB*/          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
     440                /*    FB */          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
    441441                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
    442442                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
     
    446446                                  },
    447447                                  {
    448                 /*    LD*/          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
     448                /*    LD */          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
    449449                                            BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
    450450                                            BT LongDouble,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
     
    454454                                  },
    455455                                  {
    456                 /*   LDC*/   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     456                /*   LDC */   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
    457457                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
    458458                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     
    462462                                  },
    463463                                  {
    464                 /*  _FBX*/          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
     464                /*  _FBX */          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
    465465                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
    466466                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
     
    470470                                  },
    471471                                  {
    472                 /*_FLDXC*/   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     472                /* _FLDXC */   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
    473473                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
    474474                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     
    481481        // GENERATED END
    482482        static_assert(
    483                 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     483                sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
    484484                "Each basic type kind should have a corresponding row in the combined type matrix"
    485485        );
    486486
    487         CommonType_old::CommonType_old( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
     487        CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
    488488                : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) {
    489489        }
     
    491491        void CommonType_old::postvisit( VoidType * ) {}
    492492
    493         void CommonType_old::postvisit( BasicType *basicType ) {
    494                 if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
     493        void CommonType_old::postvisit( BasicType * basicType ) {
     494                if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) {
    495495                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ];
    496                         if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
    497                                 result = new BasicType( basicType->get_qualifiers() | otherBasic->get_qualifiers(), newType );
     496                        if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) {
     497                                result = new BasicType( basicType->tq | otherBasic->tq, newType );
    498498                        } // if
    499                 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
     499                } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
    500500                        // use signed int in lieu of the enum/zero/one type
    501501                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
    502                         if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers() ) || widenSecond ) ) {
    503                                 result = new BasicType( basicType->get_qualifiers() | type2->get_qualifiers(), newType );
     502                        if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) {
     503                                result = new BasicType( basicType->tq | type2->tq, newType );
    504504                        } // if
    505505                } // if
     
    507507
    508508        template< typename Pointer >
    509         void CommonType_old::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) {
    510                 if ( TypeInstType* var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {
     509        void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) {
     510                if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) {
    511511                        OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
    512512                        if ( entry != openVars.end() ) {
     
    517517                }
    518518                result = voidPointer->clone();
    519                 result->get_qualifiers() |= otherPointer->get_qualifiers();
    520         }
    521 
    522         void CommonType_old::postvisit( PointerType *pointerType ) {
    523                 if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
     519                result->tq |= otherPointer->tq;
     520        }
     521
     522        void CommonType_old::postvisit( PointerType * pointerType ) {
     523                if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) {
    524524                        // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
    525                         if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
     525                        if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
    526526                                getCommonWithVoidPointer( otherPointer, pointerType );
    527                         } else if ( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
     527                        } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
    528528                                getCommonWithVoidPointer( pointerType, otherPointer );
    529                         } else if ( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
    530                                            && ( pointerType->get_base()->get_qualifiers() <= otherPointer->get_base()->get_qualifiers() || widenSecond ) ) {
     529                        } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst )
     530                                           && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) {
    531531                                // std::cerr << "middle case" << std::endl;
    532                                 Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();
    533                                 pointerType->get_base()->get_qualifiers() = Type::Qualifiers();
    534                                 otherPointer->get_base()->get_qualifiers() = Type::Qualifiers();
     532                                Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq;
     533                                pointerType->get_base()->tq = Type::Qualifiers();
     534                                otherPointer->get_base()->tq = Type::Qualifiers();
    535535                                AssertionSet have, need;
    536536                                OpenVarSet newOpen( openVars );
     
    542542                                                result = otherPointer->clone();
    543543                                        } // if
    544                                         strict_dynamic_cast<PointerType*>(result)->base->get_qualifiers() = tq1 | tq2;
     544                                        strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2;
    545545                                } else {
    546546                                        /// std::cerr << "place for ptr-to-type" << std::endl;
    547547                                } // if
    548                                 pointerType->get_base()->get_qualifiers() = tq1;
    549                                 otherPointer->get_base()->get_qualifiers() = tq2;
     548                                pointerType->get_base()->tq = tq1;
     549                                otherPointer->get_base()->tq = tq2;
    550550                        } // if
    551                 } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
     551                } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
    552552                        result = pointerType->clone();
    553                         result->get_qualifiers() |= type2->get_qualifiers();
     553                        result->tq |= type2->tq;
    554554                } // if
    555555        }
     
    557557        void CommonType_old::postvisit( ArrayType * ) {}
    558558
    559         void CommonType_old::postvisit( ReferenceType *refType ) {
    560                 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
     559        void CommonType_old::postvisit( ReferenceType * refType ) {
     560                if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) {
    561561                        // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
    562                         // std::cerr << ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) << (refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond) << std::endl;
    563                         if ( widenFirst && dynamic_cast< VoidType* >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
     562                        // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl;
     563                        if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
    564564                                getCommonWithVoidPointer( otherRef, refType );
    565                         } else if ( widenSecond && dynamic_cast< VoidType* >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
     565                        } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
    566566                                getCommonWithVoidPointer( refType, otherRef );
    567                         } else if ( ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst )
    568                                            && ( refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond ) ) {
     567                        } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst )
     568                                           && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) {
    569569                                // std::cerr << "middle case" << std::endl;
    570                                 Type::Qualifiers tq1 = refType->get_base()->get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();
    571                                 refType->get_base()->get_qualifiers() = Type::Qualifiers();
    572                                 otherRef->get_base()->get_qualifiers() = Type::Qualifiers();
     570                                Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq;
     571                                refType->get_base()->tq = Type::Qualifiers();
     572                                otherRef->get_base()->tq = Type::Qualifiers();
    573573                                AssertionSet have, need;
    574574                                OpenVarSet newOpen( openVars );
     
    579579                                                result = otherRef->clone();
    580580                                        } // if
    581                                         strict_dynamic_cast<ReferenceType*>(result)->base->get_qualifiers() = tq1 | tq2;
     581                                        strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2;
    582582                                } else {
    583583                                        /// std::cerr << "place for ptr-to-type" << std::endl;
    584584                                } // if
    585                                 refType->get_base()->get_qualifiers() = tq1;
    586                                 otherRef->get_base()->get_qualifiers() = tq2;
     585                                refType->get_base()->tq = tq1;
     586                                otherRef->get_base()->tq = tq2;
    587587                        } // if
    588                 } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
     588                } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
    589589                        result = refType->clone();
    590                         result->get_qualifiers() |= type2->get_qualifiers();
     590                        result->tq |= type2->tq;
    591591                } // if
    592592        }
     
    596596        void CommonType_old::postvisit( UnionInstType * ) {}
    597597
    598         void CommonType_old::postvisit( EnumInstType *enumInstType ) {
    599                 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
     598        void CommonType_old::postvisit( EnumInstType * enumInstType ) {
     599                if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
    600600                        // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
    601601                        result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars );
     
    606606        }
    607607
    608         void CommonType_old::postvisit( TypeInstType *inst ) {
     608        void CommonType_old::postvisit( TypeInstType * inst ) {
    609609                if ( widenFirst ) {
    610                         NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
     610                        const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() );
    611611                        if ( nt ) {
    612                                 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );
     612                                const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
    613613                                if ( type->get_base() ) {
    614                                         Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers();
     614                                        Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq;
    615615                                        AssertionSet have, need;
    616616                                        OpenVarSet newOpen( openVars );
    617                                         type2->get_qualifiers() = Type::Qualifiers();
    618                                         type->get_base()->get_qualifiers() = tq1;
     617                                        type2->tq = Type::Qualifiers();
     618                                        type->get_base()->tq = tq1;
    619619                                        if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
    620620                                                result = type2->clone();
    621                                                 result->get_qualifiers() = tq1 | tq2;
     621                                                result->tq = tq1 | tq2;
    622622                                        } // if
    623                                         type2->get_qualifiers() = tq2;
    624                                         type->get_base()->get_qualifiers() = Type::Qualifiers();
     623                                        type2->tq = tq2;
     624                                        type->get_base()->tq = Type::Qualifiers();
    625625                                } // if
    626626                        } // if
     
    631631        void CommonType_old::postvisit( VarArgsType * ) {}
    632632
    633         void CommonType_old::postvisit( ZeroType *zeroType ) {
     633        void CommonType_old::postvisit( ZeroType * zeroType ) {
    634634                if ( widenFirst ) {
    635                         if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
    636                                 if ( widenSecond || zeroType->get_qualifiers() <= type2->get_qualifiers() ) {
     635                        if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
     636                                if ( widenSecond || zeroType->tq <= type2->tq ) {
    637637                                        result = type2->clone();
    638                                         result->get_qualifiers() |= zeroType->get_qualifiers();
    639                                 }
    640                         } else if ( widenSecond && dynamic_cast< OneType* >( type2 ) ) {
    641                                 result = new BasicType( zeroType->get_qualifiers(), BasicType::SignedInt );
    642                                 result->get_qualifiers() |= type2->get_qualifiers();
    643                         }
    644                 }
    645         }
    646 
    647         void CommonType_old::postvisit( OneType *oneType ) {
     638                                        result->tq |= zeroType->tq;
     639                                }
     640                        } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {
     641                                result = new BasicType( zeroType->tq, BasicType::SignedInt );
     642                                result->tq |= type2->tq;
     643                        }
     644                }
     645        }
     646
     647        void CommonType_old::postvisit( OneType * oneType ) {
    648648                if ( widenFirst ) {
    649                         if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
    650                                 if ( widenSecond || oneType->get_qualifiers() <= type2->get_qualifiers() ) {
     649                        if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
     650                                if ( widenSecond || oneType->tq <= type2->tq ) {
    651651                                        result = type2->clone();
    652                                         result->get_qualifiers() |= oneType->get_qualifiers();
    653                                 }
    654                         } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
    655                                 result = new BasicType( oneType->get_qualifiers(), BasicType::SignedInt );
    656                                 result->get_qualifiers() |= type2->get_qualifiers();
     652                                        result->tq |= oneType->tq;
     653                                }
     654                        } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
     655                                result = new BasicType( oneType->tq, BasicType::SignedInt );
     656                                result->tq |= type2->tq;
    657657                        }
    658658                }
     
    668668                ast::ptr< ast::Type > result;
    669669
    670                 CommonType_new( 
    671                         const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 
     670                CommonType_new(
     671                        const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
    672672                        ast::TypeEnvironment & env, const ast::OpenVarSet & o )
    673673                : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {}
     
    681681                                #warning remove casts when `commonTypes` moved to new AST
    682682                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
    683                                 if ( 
    684                                         ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 
    685                                                 || widen.first ) 
    686                                         && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 
    687                                                 || widen.second ) 
     683                                if (
     684                                        ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
     685                                                || widen.first )
     686                                        && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
     687                                                || widen.second )
    688688                                ) {
    689689                                        result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
    690690                                }
    691                         } else if ( 
    692                                 dynamic_cast< const ast::EnumInstType * >( type2 ) 
     691                        } else if (
     692                                dynamic_cast< const ast::EnumInstType * >( type2 )
    693693                                || dynamic_cast< const ast::ZeroType * >( type2 )
    694694                                || dynamic_cast< const ast::OneType * >( type2 )
     
    696696                                #warning remove casts when `commonTypes` moved to new AST
    697697                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
    698                                 if ( 
    699                                         ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 
    700                                                 || widen.first ) 
    701                                         && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 
    702                                                 || widen.second ) 
     698                                if (
     699                                        ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
     700                                                || widen.first )
     701                                        && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
     702                                                || widen.second )
    703703                                ) {
    704704                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
     
    715715                                if ( entry != open.end() ) {
    716716                                        ast::AssertionSet need, have;
    717                                         if ( ! tenv.bindVar( 
    718                                                 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 
     717                                        if ( ! tenv.bindVar(
     718                                                var, voidPtr->base, entry->second, need, have, open, widen, symtab )
    719719                                        ) return;
    720720                                }
     
    727727                void postvisit( const ast::PointerType * pointer ) {
    728728                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
    729                                 if ( 
    730                                         widen.first 
    731                                         && pointer2->base.as< ast::VoidType >() 
    732                                         && ! ast::isFtype( pointer->base ) 
     729                                if (
     730                                        widen.first
     731                                        && pointer2->base.as< ast::VoidType >()
     732                                        && ! ast::isFtype( pointer->base )
    733733                                ) {
    734734                                        getCommonWithVoidPointer( pointer2, pointer );
    735                                 } else if ( 
    736                                         widen.second 
    737                                         && pointer->base.as< ast::VoidType >() 
    738                                         && ! ast::isFtype( pointer2->base ) 
     735                                } else if (
     736                                        widen.second
     737                                        && pointer->base.as< ast::VoidType >()
     738                                        && ! ast::isFtype( pointer2->base )
    739739                                ) {
    740740                                        getCommonWithVoidPointer( pointer, pointer2 );
     
    746746                                        ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
    747747
    748                                         // force t{1,2} to be cloned if their qualifiers must be stripped, so that 
     748                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that
    749749                                        // pointer{,2}->base are unchanged
    750750                                        ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
    751751                                        reset_qualifiers( t1 );
    752752                                        reset_qualifiers( t2 );
    753                                        
     753
    754754                                        ast::AssertionSet have, need;
    755755                                        ast::OpenVarSet newOpen{ open };
     
    758758                                                if ( q1.val != q2.val ) {
    759759                                                        // reset result->base->qualifiers to be union of two base qualifiers
    760                                                         strict_dynamic_cast< ast::PointerType * >( 
    761                                                                 result.get_and_mutate() 
     760                                                        strict_dynamic_cast< ast::PointerType * >(
     761                                                                result.get_and_mutate()
    762762                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
    763763                                                }
     
    775775                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
    776776                                if (
    777                                         widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 
     777                                        widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
    778778                                ) {
    779779                                        getCommonWithVoidPointer( ref2, ref );
    780                                 } else if ( 
    781                                         widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 
     780                                } else if (
     781                                        widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
    782782                                ) {
    783783                                        getCommonWithVoidPointer( ref, ref2 );
     
    788788                                        ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
    789789
    790                                         // force t{1,2} to be cloned if their qualifiers must be stripped, so that 
     790                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that
    791791                                        // ref{,2}->base are unchanged
    792792                                        ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
     
    800800                                                if ( q1.val != q2.val ) {
    801801                                                        // reset result->base->qualifiers to be union of two base qualifiers
    802                                                         strict_dynamic_cast< ast::ReferenceType * >( 
    803                                                                 result.get_and_mutate() 
     802                                                        strict_dynamic_cast< ast::ReferenceType * >(
     803                                                                result.get_and_mutate()
    804804                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
    805805                                                }
     
    819819
    820820                void postvisit( const ast::EnumInstType * enumInst ) {
    821                         if ( 
    822                                 dynamic_cast< const ast::BasicType * >( type2 ) 
     821                        if (
     822                                dynamic_cast< const ast::BasicType * >( type2 )
    823823                                || dynamic_cast< const ast::ZeroType * >( type2 )
    824824                                || dynamic_cast< const ast::OneType * >( type2 )
     
    834834                        if ( ! widen.first ) return;
    835835                        if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
    836                                 if ( const ast::Type * base = 
    837                                                 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 
     836                                if ( const ast::Type * base =
     837                                                strict_dynamic_cast< const ast::TypeDecl * >( nt )->base
    838838                                ) {
    839839                                        ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers;
     
    860860                void postvisit( const ast::ZeroType * zero ) {
    861861                        if ( ! widen.first ) return;
    862                         if ( 
     862                        if (
    863863                                dynamic_cast< const ast::BasicType * >( type2 )
    864864                                || dynamic_cast< const ast::PointerType * >( type2 )
     
    870870                                }
    871871                        } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
    872                                 result = new ast::BasicType{ 
     872                                result = new ast::BasicType{
    873873                                        ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
    874874                        }
     
    877877                void postvisit( const ast::OneType * one ) {
    878878                        if ( ! widen.first ) return;
    879                         if ( 
     879                        if (
    880880                                dynamic_cast< const ast::BasicType * >( type2 )
    881881                                || dynamic_cast< const ast::EnumInstType * >( type2 )
     
    886886                                }
    887887                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
    888                                 result = new ast::BasicType{ 
     888                                result = new ast::BasicType{
    889889                                        ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
    890890                        }
     
    894894
    895895        namespace {
    896                 ast::ptr< ast::Type > handleReference( 
    897                         const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 
    898                         const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 
    899                         const ast::OpenVarSet & open 
     896                ast::ptr< ast::Type > handleReference(
     897                        const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
     898                        const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
     899                        const ast::OpenVarSet & open
    900900                ) {
    901901                        ast::ptr<ast::Type> common;
     
    926926
    927927        ast::ptr< ast::Type > commonType(
    928                         const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 
    929                         WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 
    930                         const ast::OpenVarSet & open 
     928                        const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
     929                        WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
     930                        const ast::OpenVarSet & open
    931931        ) {
    932932                unsigned depth1 = type1->referenceDepth();
     
    940940                        const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
    941941                        const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >();
    942                        
     942
    943943                        if ( depth1 > depth2 ) {
    944944                                assert( ref1 );
     
    978978                                                ast::OpenVarSet newOpen{ open };
    979979
    980                                                 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 
    981                                                 // type1 and type->base are left unchanged; calling convention forces 
     980                                                // force t{1,2} to be cloned if its qualifiers must be stripped, so that
     981                                                // type1 and type->base are left unchanged; calling convention forces
    982982                                                // {type1,type->base}->strong_ref >= 1
    983983                                                ast::ptr<ast::Type> t1{ type1 }, t2{ type->base };
    984984                                                reset_qualifiers( t1 );
    985985                                                reset_qualifiers( t2, q1 );
    986                                                
     986
    987987                                                if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) {
    988988                                                        result = t1;
  • src/ResolvExpr/ConversionCost.cc

    r1f1c102 rf53acdf8  
    4646#endif
    4747
    48         Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    49                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     48        Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     49                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    5050                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
    51                         if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
     51                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
    5252                                if ( eqvClass->type ) {
    5353                                        return conversionCost( src, eqvClass->type, indexer, env );
     
    5555                                        return Cost::infinity;
    5656                                }
    57                         } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
     57                        } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
    5858                                PRINT( std::cerr << " found" << std::endl; )
    59                                 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     59                                const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
    6060                                // all typedefs should be gone by this point
    6161                                assert( type );
     
    7777                        PRINT( std::cerr << "compatible!" << std::endl; )
    7878                        return Cost::zero;
    79                 } else if ( dynamic_cast< VoidType* >( dest ) ) {
     79                } else if ( dynamic_cast< const VoidType * >( dest ) ) {
    8080                        return Cost::safe;
    81                 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
     81                } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
    8282                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    83                         return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
     83                        return convertToReferenceCost( src, refType, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    8484                                return ptrsAssignable( t1, t2, env );
    8585                        });
    8686                } else {
    87                         PassVisitor<ConversionCost> converter( 
    88                                 dest, indexer, env, 
    89                                 (Cost (*)(Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))
     87                        PassVisitor<ConversionCost> converter(
     88                                dest, indexer, env,
     89                                (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
    9090                                        conversionCost );
    9191                        src->accept( converter );
     
    9898        }
    9999
    100         Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     100        Cost convertToReferenceCost( const Type * src, const Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    101101                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    102102                if ( diff > 0 ) {
    103103                        // TODO: document this
    104                         Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
     104                        Cost cost = convertToReferenceCost( strict_dynamic_cast< const ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
    105105                        cost.incReference();
    106106                        return cost;
    107107                } else if ( diff < -1 ) {
    108108                        // TODO: document this
    109                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
     109                        Cost cost = convertToReferenceCost( src, strict_dynamic_cast< const ReferenceType * >( dest )->base, diff+1, indexer, env, func );
    110110                        cost.incReference();
    111111                        return cost;
    112112                } else if ( diff == 0 ) {
    113                         ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
    114                         ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
     113                        const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src );
     114                        const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
    115115                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    116116                                PRINT( std::cerr << "converting between references" << std::endl; )
    117                                 Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
    118                                 Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
     117                                Type::Qualifiers tq1 = srcAsRef->base->tq;
     118                                Type::Qualifiers tq2 = destAsRef->base->tq;
    119119                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
    120120                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    137137                        } else {
    138138                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    139                                 PassVisitor<ConversionCost> converter( 
    140                                         dest, indexer, env, 
    141                                         (Cost (*)(Type*, Type*, const SymTab::Indexer&, const TypeEnvironment&))
     139                                PassVisitor<ConversionCost> converter(
     140                                        dest, indexer, env,
     141                                        (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&))
    142142                                                conversionCost );
    143143                                src->accept( converter );
     
    145145                        } // if
    146146                } else {
    147                         ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
     147                        const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
    148148                        assert( diff == -1 && destAsRef );
    149149                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
     
    156156                                        )
    157157                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    158                                         if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
     158                                        if ( src->tq == destAsRef->base->tq ) {
    159159                                                return Cost::reference; // cost needs to be non-zero to add cast
    160                                         } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
     160                                        } if ( src->tq < destAsRef->base->tq ) {
    161161                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    162162                                        } else {
     
    178178        }
    179179
    180         Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     180        Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    181181                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    182182                Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
     
    185185        }
    186186
    187         ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     187        ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    188188                : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
    189189        }
     
    193193        /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
    194194                                 _Bool
    195         char                signed char         unsigned char       
    196                   signed short int         unsigned short int       
    197                   signed int               unsigned int             
    198                   signed long int          unsigned long int       
    199                   signed long long int     unsigned long long int   
    200                   __int128                 unsigned __int128       
    201                   _Float16                 _Float16 _Complex       
    202                   _Float32                 _Float32 _Complex       
    203                   float                    float _Complex           
    204                   _Float32x                _Float32x _Complex       
    205                   _Float64                 _Float64 _Complex       
    206                   double                   double _Complex         
    207                   _Float64x                _Float64x _Complex       
     195        char                signed char         unsigned char
     196                  signed short int         unsigned short int
     197                  signed int               unsigned int
     198                  signed long int          unsigned long int
     199                  signed long long int     unsigned long long int
     200                  __int128                 unsigned __int128
     201                  _Float16                 _Float16 _Complex
     202                  _Float32                 _Float32 _Complex
     203                  float                    float _Complex
     204                  _Float32x                _Float32x _Complex
     205                  _Float64                 _Float64 _Complex
     206                  double                   double _Complex
     207                  _Float64x                _Float64x _Complex
    208208                             __float80
    209                   _Float128                _Float128 _Complex       
     209                  _Float128                _Float128 _Complex
    210210                            __float128
    211                   long double              long double _Complex     
    212                   _Float128x               _Float128x _Complex     
     211                  long double              long double _Complex
     212                  _Float128x               _Float128x _Complex
    213213        */
    214214        // GENERATED END
     
    218218        static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
    219219                /*             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 */
    220                 /*     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, },
    221                 /*     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, },
    222                 /*    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, },
    223                 /*    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, },
    224                 /*    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, },
    225                 /*   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, },
    226                 /*     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, },
    227                 /*    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, },
    228                 /*    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, },
    229                 /*   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, },
    230                 /*   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, },
    231                 /*  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, },
    232                 /*    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, },
    233                 /*   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, },
    234                 /*   _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, },
    235                 /*   _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, },
    236                 /*    _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, },
    237                 /*   _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, },
    238                 /*     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, },
    239                 /*    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, },
    240                 /*   _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, },
    241                 /*  _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, },
    242                 /*    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, },
    243                 /*  _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, },
    244                 /*     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, },
    245                 /*    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, },
    246                 /*  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, },
    247                 /* _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, },
     220                /*     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, },
     221                /*     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, },
     222                /*    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, },
     223                /*    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, },
     224                /*    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, },
     225                /*   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, },
     226                /*     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, },
     227                /*    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, },
     228                /*    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, },
     229                /*   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, },
     230                /*   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, },
     231                /*  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, },
     232                /*    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, },
     233                /*   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, },
     234                /*   _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, },
     235                /*   _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, },
     236                /*    _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, },
     237                /*   _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, },
     238                /*     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, },
     239                /*    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, },
     240                /*   _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, },
     241                /*  _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, },
     242                /*    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, },
     243                /*  _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, },
     244                /*     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, },
     245                /*    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, },
     246                /*  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, },
     247                /* _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, },
    248248                /*   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, },
    249                 /*   _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, },
    250                 /* _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, },
    251                 /*    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, },
    252                 /*    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, },
    253                 /*   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, },
    254                 /*  _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, },
    255                 /*_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, },
     249                /*   _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, },
     250                /* _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, },
     251                /*    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, },
     252                /*    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, },
     253                /*   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, },
     254                /*  _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, },
     255                /* _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, },
    256256        }; // costMatrix
    257257        static const int maxIntCost = 15;
    258258        // GENERATED END
    259259        static_assert(
    260                 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     260                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
    261261                "Missing row in the cost matrix"
    262262        );
     
    266266        static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
    267267                /*             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 */
    268                 /*     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, },
    269                 /*     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, },
    270                 /*    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, },
    271                 /*    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, },
    272                 /*    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, },
    273                 /*   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, },
    274                 /*     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, },
    275                 /*    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, },
    276                 /*    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, },
    277                 /*   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, },
    278                 /*   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, },
    279                 /*  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, },
    280                 /*    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, },
    281                 /*   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, },
    282                 /*   _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, },
    283                 /*   _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, },
    284                 /*    _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, },
    285                 /*   _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, },
    286                 /*     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, },
    287                 /*    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, },
    288                 /*   _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, },
    289                 /*  _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, },
    290                 /*    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, },
    291                 /*  _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, },
    292                 /*     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, },
    293                 /*    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, },
    294                 /*  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, },
    295                 /* _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, },
     268                /*     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, },
     269                /*     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, },
     270                /*    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, },
     271                /*    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, },
     272                /*    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, },
     273                /*   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, },
     274                /*     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, },
     275                /*    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, },
     276                /*    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, },
     277                /*   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, },
     278                /*   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, },
     279                /*  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, },
     280                /*    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, },
     281                /*   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, },
     282                /*   _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, },
     283                /*   _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, },
     284                /*    _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, },
     285                /*   _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, },
     286                /*     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, },
     287                /*    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, },
     288                /*   _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, },
     289                /*  _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, },
     290                /*    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, },
     291                /*  _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, },
     292                /*     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, },
     293                /*    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, },
     294                /*  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, },
     295                /* _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, },
    296296                /*   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, },
    297                 /*   _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, },
    298                 /* _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, },
    299                 /*    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, },
    300                 /*    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, },
    301                 /*   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, },
    302                 /*  _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, },
    303                 /*_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, },
     297                /*   _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, },
     298                /* _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, },
     299                /*    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, },
     300                /*    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, },
     301                /*   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, },
     302                /*  _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, },
     303                /* _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, },
    304304        }; // signMatrix
    305305        // GENERATED END
    306306        static_assert(
    307                 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     307                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
    308308                "Missing row in the sign matrix"
    309309        );
    310310
    311         void ConversionCost::postvisit( VoidType * ) {
     311        void ConversionCost::postvisit( const VoidType * ) {
    312312                cost = Cost::infinity;
    313313        }
    314314
    315         void ConversionCost::postvisit(BasicType *basicType) {
    316                 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    317                         int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
     315        void ConversionCost::postvisit(const BasicType * basicType) {
     316                if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
     317                        int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ];
    318318                        if ( tableResult == -1 ) {
    319319                                cost = Cost::unsafe;
     
    321321                                cost = Cost::zero;
    322322                                cost.incSafe( tableResult );
    323                                 cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
    324                         } // if
    325                 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
     323                                cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] );
     324                        } // if
     325                } else if ( dynamic_cast< const EnumInstType * >( dest ) ) {
    326326                        // xxx - not positive this is correct, but appears to allow casting int => enum
    327327                        cost = Cost::unsafe;
     
    330330        }
    331331
    332         void ConversionCost::postvisit( PointerType * pointerType ) {
    333                 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
     332        void ConversionCost::postvisit( const PointerType * pointerType ) {
     333                if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
    334334                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
    335                         Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
    336                         Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
     335                        Type::Qualifiers tq1 = pointerType->base->tq;
     336                        Type::Qualifiers tq2 = destAsPtr->base->tq;
    337337                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    338338                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    363363        }
    364364
    365         void ConversionCost::postvisit( ArrayType * ) {}
    366 
    367         void ConversionCost::postvisit( ReferenceType * refType ) {
     365        void ConversionCost::postvisit( const ArrayType * ) {}
     366
     367        void ConversionCost::postvisit( const ReferenceType * refType ) {
    368368                // Note: dest can never be a reference, since it would have been caught in an earlier check
    369                 assert( ! dynamic_cast< ReferenceType * >( dest ) );
     369                assert( ! dynamic_cast< const ReferenceType * >( dest ) );
    370370                // convert reference to rvalue: cv T1 & => T2
    371371                // recursively compute conversion cost from T1 to T2.
    372372                // cv can be safely dropped because of 'implicit dereference' behavior.
    373373                cost = costFunc( refType->base, dest, indexer, env );
    374                 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
     374                if ( refType->base->tq == dest->tq ) {
    375375                        cost.incReference();  // prefer exact qualifiers
    376                 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
     376                } else if ( refType->base->tq < dest->tq ) {
    377377                        cost.incSafe(); // then gaining qualifiers
    378378                } else {
     
    382382        }
    383383
    384         void ConversionCost::postvisit( FunctionType * ) {}
    385 
    386         void ConversionCost::postvisit( StructInstType * inst ) {
    387                 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
     384        void ConversionCost::postvisit( const FunctionType * ) {}
     385
     386        void ConversionCost::postvisit( const StructInstType * inst ) {
     387                if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {
    388388                        if ( inst->name == destAsInst->name ) {
    389389                                cost = Cost::zero;
     
    392392        }
    393393
    394         void ConversionCost::postvisit( UnionInstType * inst ) {
    395                 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
     394        void ConversionCost::postvisit( const UnionInstType * inst ) {
     395                if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {
    396396                        if ( inst->name == destAsInst->name ) {
    397397                                cost = Cost::zero;
     
    400400        }
    401401
    402         void ConversionCost::postvisit( EnumInstType * ) {
     402        void ConversionCost::postvisit( const EnumInstType * ) {
    403403                static Type::Qualifiers q;
    404404                static BasicType integer( q, BasicType::SignedInt );
     
    409409        }
    410410
    411         void ConversionCost::postvisit( TraitInstType * ) {}
    412 
    413         void ConversionCost::postvisit( TypeInstType *inst ) {
    414                 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
     411        void ConversionCost::postvisit( const TraitInstType * ) {}
     412
     413        void ConversionCost::postvisit( const TypeInstType * inst ) {
     414                if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
    415415                        cost = costFunc( eqvClass->type, dest, indexer, env );
    416                 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
     416                } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    417417                        if ( inst->name == destAsInst->name ) {
    418418                                cost = Cost::zero;
    419419                        }
    420                 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
    421                         TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     420                } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) {
     421                        const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
    422422                        // all typedefs should be gone by this point
    423423                        assert( type );
     
    428428        }
    429429
    430         void ConversionCost::postvisit( TupleType * tupleType ) {
     430        void ConversionCost::postvisit( const TupleType * tupleType ) {
    431431                Cost c = Cost::zero;
    432                 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
     432                if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) {
    433433                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
    434434                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
    435435                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
    436                                 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
     436                                Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env );
    437437                                if ( newCost == Cost::infinity ) {
    438438                                        return;
     
    448448        }
    449449
    450         void ConversionCost::postvisit( VarArgsType * ) {
    451                 if ( dynamic_cast< VarArgsType* >( dest ) ) {
    452                         cost = Cost::zero;
    453                 }
    454         }
    455 
    456         void ConversionCost::postvisit( ZeroType * ) {
    457                 if ( dynamic_cast< ZeroType * >( dest ) ) {
    458                         cost = Cost::zero;
    459                 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    460                         // copied from visit(BasicType*) for signed int, but +1 for safe conversions
    461                         int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
     450        void ConversionCost::postvisit( const VarArgsType * ) {
     451                if ( dynamic_cast< const VarArgsType * >( dest ) ) {
     452                        cost = Cost::zero;
     453                }
     454        }
     455
     456        void ConversionCost::postvisit( const ZeroType * ) {
     457                if ( dynamic_cast< const ZeroType * >( dest ) ) {
     458                        cost = Cost::zero;
     459                } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
     460                        // copied from visit(BasicType *) for signed int, but +1 for safe conversions
     461                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
    462462                        if ( tableResult == -1 ) {
    463463                                cost = Cost::unsafe;
     
    465465                                cost = Cost::zero;
    466466                                cost.incSafe( tableResult + 1 );
    467                                 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
    468                         } // if
    469                 } else if ( dynamic_cast< PointerType* >( dest ) ) {
     467                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
     468                        } // if
     469                } else if ( dynamic_cast< const PointerType * >( dest ) ) {
    470470                        cost = Cost::zero;
    471471                        cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
     
    473473        }
    474474
    475         void ConversionCost::postvisit( OneType * ) {
    476                 if ( dynamic_cast< OneType * >( dest ) ) {
    477                         cost = Cost::zero;
    478                 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    479                         // copied from visit(BasicType*) for signed int, but +1 for safe conversions
    480                         int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
     475        void ConversionCost::postvisit( const OneType * ) {
     476                if ( dynamic_cast< const OneType * >( dest ) ) {
     477                        cost = Cost::zero;
     478                } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
     479                        // copied from visit(BasicType *) for signed int, but +1 for safe conversions
     480                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
    481481                        if ( tableResult == -1 ) {
    482482                                cost = Cost::unsafe;
     
    484484                                cost = Cost::zero;
    485485                                cost.incSafe( tableResult + 1 );
    486                                 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
     486                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
    487487                        } // if
    488488                } // if
     
    729729                auto dstEnd = dstAsTuple->types.end();
    730730                while ( srcIt != srcEnd && dstIt != dstEnd ) {
    731                         Cost newCost = costCalc( *srcIt++, *dstIt++, symtab, env );
     731                        Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env );
    732732                        if ( newCost == Cost::infinity ) {
    733733                                return;
  • src/ResolvExpr/ConversionCost.h

    r1f1c102 rf53acdf8  
    3333        class TypeEnvironment;
    3434
    35         typedef std::function<Cost(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
     35        typedef std::function<Cost(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
    3636        struct ConversionCost : public WithShortCircuiting {
    3737          public:
    38                 ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
     38                ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
    3939
    4040                Cost get_cost() const { return cost; }
    4141
    42                 void previsit( BaseSyntaxNode * ) { visit_children = false; }
     42                void previsit( const BaseSyntaxNode * ) { visit_children = false; }
    4343
    44                 void postvisit( VoidType * voidType );
    45                 void postvisit( BasicType * basicType );
    46                 void postvisit( PointerType * pointerType );
    47                 void postvisit( ArrayType * arrayType );
    48                 void postvisit( ReferenceType * refType );
    49                 void postvisit( FunctionType * functionType );
    50                 void postvisit( StructInstType * aggregateUseType );
    51                 void postvisit( UnionInstType * aggregateUseType );
    52                 void postvisit( EnumInstType * aggregateUseType );
    53                 void postvisit( TraitInstType * aggregateUseType );
    54                 void postvisit( TypeInstType * aggregateUseType );
    55                 void postvisit( TupleType * tupleType );
    56                 void postvisit( VarArgsType * varArgsType );
    57                 void postvisit( ZeroType * zeroType );
    58                 void postvisit( OneType * oneType );
     44                void postvisit( const VoidType * voidType );
     45                void postvisit( const BasicType * basicType );
     46                void postvisit( const PointerType * pointerType );
     47                void postvisit( const ArrayType * arrayType );
     48                void postvisit( const ReferenceType * refType );
     49                void postvisit( const FunctionType * functionType );
     50                void postvisit( const StructInstType * aggregateUseType );
     51                void postvisit( const UnionInstType * aggregateUseType );
     52                void postvisit( const EnumInstType * aggregateUseType );
     53                void postvisit( const TraitInstType * aggregateUseType );
     54                void postvisit( const TypeInstType * aggregateUseType );
     55                void postvisit( const TupleType * tupleType );
     56                void postvisit( const VarArgsType * varArgsType );
     57                void postvisit( const ZeroType * zeroType );
     58                void postvisit( const OneType * oneType );
    5959          protected:
    60                 Type *dest;
     60                const Type * dest;
    6161                const SymTab::Indexer &indexer;
    6262                Cost cost;
     
    6565        };
    6666
    67         typedef std::function<int(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
    68         Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
     67        typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
     68        Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
    6969
    7070// Some function pointer types, differ in return type.
  • src/ResolvExpr/PtrsAssignable.cc

    r1f1c102 rf53acdf8  
    2727namespace ResolvExpr {
    2828        struct PtrsAssignable : public WithShortCircuiting {
    29                 PtrsAssignable( Type *dest, const TypeEnvironment &env );
     29                PtrsAssignable( const Type * dest, const TypeEnvironment &env );
    3030
    3131                int get_result() const { return result; }
    3232
    33                 void previsit( Type * ) { visit_children = false; }
    34 
    35                 void postvisit( VoidType * voidType );
    36                 void postvisit( BasicType * basicType );
    37                 void postvisit( PointerType * pointerType );
    38                 void postvisit( ArrayType * arrayType );
    39                 void postvisit( FunctionType * functionType );
    40                 void postvisit( StructInstType * inst );
    41                 void postvisit( UnionInstType * inst );
    42                 void postvisit( EnumInstType * inst );
    43                 void postvisit( TraitInstType * inst );
    44                 void postvisit( TypeInstType * inst );
    45                 void postvisit( TupleType * tupleType );
    46                 void postvisit( VarArgsType * varArgsType );
    47                 void postvisit( ZeroType * zeroType );
    48                 void postvisit( OneType * oneType );
     33                void previsit( const Type * ) { visit_children = false; }
     34
     35                void postvisit( const VoidType * voidType );
     36                void postvisit( const BasicType * basicType );
     37                void postvisit( const PointerType * pointerType );
     38                void postvisit( const ArrayType * arrayType );
     39                void postvisit( const FunctionType * functionType );
     40                void postvisit( const StructInstType * inst );
     41                void postvisit( const UnionInstType * inst );
     42                void postvisit( const EnumInstType * inst );
     43                void postvisit( const TraitInstType * inst );
     44                void postvisit( const TypeInstType * inst );
     45                void postvisit( const TupleType * tupleType );
     46                void postvisit( const VarArgsType * varArgsType );
     47                void postvisit( const ZeroType * zeroType );
     48                void postvisit( const OneType * oneType );
    4949          private:
    50                 Type *dest;
     50                const Type * dest;
    5151                int result;
    5252                const TypeEnvironment &env;
    5353        };
    5454
    55         int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
     55        int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) {
    5656                // std::cerr << "assignable: " << src << " | " << dest << std::endl;
    57                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    58                         if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     57                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
     58                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    5959                                return ptrsAssignable( src, eqvClass->type, env );
    6060                        } // if
    6161                } // if
    62                 if ( dynamic_cast< VoidType* >( dest ) ) {
     62                if ( dynamic_cast< const VoidType* >( dest ) ) {
    6363                        // void * = T * for any T is unsafe
    6464                        // xxx - this should be safe, but that currently breaks the build
     
    7171        }
    7272
    73         PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
    74 
    75         void PtrsAssignable::postvisit( VoidType * ) {
     73        PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
     74
     75        void PtrsAssignable::postvisit( const VoidType * ) {
    7676                // T * = void * is disallowed - this is a change from C, where any
    7777                // void * can be assigned or passed to a non-void pointer without a cast.
    7878        }
    7979
    80         void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {}
    81         void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {}
    82         void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {}
    83         void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {}
    84 
    85         void PtrsAssignable::postvisit(  __attribute__((unused)) StructInstType *inst ) {}
    86         void PtrsAssignable::postvisit(  __attribute__((unused)) UnionInstType *inst ) {}
    87 
    88         void PtrsAssignable::postvisit( EnumInstType * ) {
    89                 if ( dynamic_cast< BasicType* >( dest ) ) {
     80        void PtrsAssignable::postvisit( const BasicType * ) {}
     81        void PtrsAssignable::postvisit( const PointerType * ) {}
     82        void PtrsAssignable::postvisit( const ArrayType * ) {}
     83        void PtrsAssignable::postvisit( const FunctionType * ) {}
     84
     85        void PtrsAssignable::postvisit( const StructInstType * ) {}
     86        void PtrsAssignable::postvisit( const UnionInstType * ) {}
     87
     88        void PtrsAssignable::postvisit( const EnumInstType * ) {
     89                if ( dynamic_cast< const BasicType* >( dest ) ) {
    9090                        // int * = E *, etc. is safe. This isn't technically correct, as each
    9191                        // enum has one basic type that it is compatible with, an that type can
     
    9797        }
    9898
    99         void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
    100         void PtrsAssignable::postvisit( TypeInstType *inst ) {
    101                 if ( const EqvClass *eqvClass = env.lookup( inst->get_name() ) ) {
     99        void PtrsAssignable::postvisit(  const TraitInstType * ) {}
     100        void PtrsAssignable::postvisit( const TypeInstType * inst ) {
     101                if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
    102102                        if ( eqvClass->type ) {
    103103                                // T * = S * for any S depends on the type bound to T
     
    107107        }
    108108
    109         void PtrsAssignable::postvisit(  __attribute__((unused)) TupleType *tupleType ) {}
    110         void PtrsAssignable::postvisit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
    111         void PtrsAssignable::postvisit(  __attribute__((unused)) ZeroType *zeroType ) {}
    112         void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
     109        void PtrsAssignable::postvisit( const TupleType * ) {}
     110        void PtrsAssignable::postvisit( const VarArgsType * ) {}
     111        void PtrsAssignable::postvisit( const ZeroType * ) {}
     112        void PtrsAssignable::postvisit( const OneType * ) {}
    113113
    114114// TODO: Get rid of the `_new` suffix when the old version is removed.
  • src/ResolvExpr/PtrsCastable.cc

    r1f1c102 rf53acdf8  
    2929        struct PtrsCastable_old : public WithShortCircuiting  {
    3030          public:
    31                 PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     31                PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    3232
    3333                int get_result() const { return result; }
    3434
    35                 void previsit( Type * ) { visit_children = false; }
    36 
    37                 void postvisit( VoidType * voidType );
    38                 void postvisit( BasicType * basicType );
    39                 void postvisit( PointerType * pointerType );
    40                 void postvisit( ArrayType * arrayType );
    41                 void postvisit( FunctionType * functionType );
    42                 void postvisit( StructInstType * inst );
    43                 void postvisit( UnionInstType * inst );
    44                 void postvisit( EnumInstType * inst );
    45                 void postvisit( TraitInstType * inst );
    46                 void postvisit( TypeInstType * inst );
    47                 void postvisit( TupleType * tupleType );
    48                 void postvisit( VarArgsType * varArgsType );
    49                 void postvisit( ZeroType * zeroType );
    50                 void postvisit( OneType * oneType );
     35                void previsit( const Type * ) { visit_children = false; }
     36
     37                void postvisit( const VoidType * voidType );
     38                void postvisit( const BasicType * basicType );
     39                void postvisit( const PointerType * pointerType );
     40                void postvisit( const ArrayType * arrayType );
     41                void postvisit( const FunctionType * functionType );
     42                void postvisit( const StructInstType * inst );
     43                void postvisit( const UnionInstType * inst );
     44                void postvisit( const EnumInstType * inst );
     45                void postvisit( const TraitInstType * inst );
     46                void postvisit( const TypeInstType * inst );
     47                void postvisit( const TupleType * tupleType );
     48                void postvisit( const VarArgsType * varArgsType );
     49                void postvisit( const ZeroType * zeroType );
     50                void postvisit( const OneType * oneType );
    5151          private:
    52                 Type *dest;
     52                const Type * dest;
    5353                int result;
    5454                const TypeEnvironment &env;
     
    5757
    5858        namespace {
    59                 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    60                         if ( dynamic_cast< FunctionType* >( src ) ) {
     59                int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     60                        if ( dynamic_cast< const FunctionType* >( src ) ) {
    6161                                return -1;
    62                         } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
    63                                 if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    64                                         if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    65                                                 if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     62                        } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) {
     63                                if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) {
     64                                        if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) {
     65                                                if ( tyDecl->kind == TypeDecl::Ftype ) {
    6666                                                        return -1;
    6767                                                } // if
    6868                                        } //if
    69                                 } else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
     69                                } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
    7070                                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
    7171                                                return -1;
     
    7575                        return 1;
    7676                }
    77                 int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     77                int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    7878                        return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
    7979                }
    8080        }
    8181
    82         int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    83                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    84                         if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     82        int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     83                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
     84                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    8585                                // xxx - should this be ptrsCastable?
    8686                                return ptrsAssignable( src, eqvClass->type, env );
    8787                        } // if
    8888                } // if
    89                 if ( dynamic_cast< VoidType* >( dest ) ) {
     89                if ( dynamic_cast< const VoidType* >( dest ) ) {
    9090                        return objectCast( src, env, indexer );
    9191                } else {
     
    9696        }
    9797
    98         PtrsCastable_old::PtrsCastable_old( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
     98        PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    9999                : dest( dest ), result( 0 ), env( env ), indexer( indexer )     {
    100100        }
    101101
    102         void PtrsCastable_old::postvisit( VoidType * ) {
    103                 result = objectCast( dest, env, indexer );
    104         }
    105 
    106         void PtrsCastable_old::postvisit( BasicType * ) {
    107                 result = objectCast( dest, env, indexer );
    108         }
    109 
    110         void PtrsCastable_old::postvisit( PointerType * ) {
    111                 result = objectCast( dest, env, indexer );
    112         }
    113 
    114         void PtrsCastable_old::postvisit( ArrayType * ) {
    115                 result = objectCast( dest, env, indexer );
    116         }
    117 
    118         void PtrsCastable_old::postvisit( FunctionType * ) {
     102        void PtrsCastable_old::postvisit( const VoidType * ) {
     103                result = objectCast( dest, env, indexer );
     104        }
     105
     106        void PtrsCastable_old::postvisit( const BasicType * ) {
     107                result = objectCast( dest, env, indexer );
     108        }
     109
     110        void PtrsCastable_old::postvisit( const PointerType * ) {
     111                result = objectCast( dest, env, indexer );
     112        }
     113
     114        void PtrsCastable_old::postvisit( const ArrayType * ) {
     115                result = objectCast( dest, env, indexer );
     116        }
     117
     118        void PtrsCastable_old::postvisit( const FunctionType * ) {
    119119                // result = -1;
    120120                result = functionCast( dest, env, indexer );
    121121        }
    122122
    123         void PtrsCastable_old::postvisit( StructInstType * ) {
    124                 result = objectCast( dest, env, indexer );
    125         }
    126 
    127         void PtrsCastable_old::postvisit( UnionInstType * ) {
    128                 result = objectCast( dest, env, indexer );
    129         }
    130 
    131         void PtrsCastable_old::postvisit( EnumInstType * ) {
    132                 if ( dynamic_cast< EnumInstType* >( dest ) ) {
     123        void PtrsCastable_old::postvisit( const StructInstType * ) {
     124                result = objectCast( dest, env, indexer );
     125        }
     126
     127        void PtrsCastable_old::postvisit( const UnionInstType * ) {
     128                result = objectCast( dest, env, indexer );
     129        }
     130
     131        void PtrsCastable_old::postvisit( const EnumInstType * ) {
     132                if ( dynamic_cast< const EnumInstType * >( dest ) ) {
    133133                        result = 1;
    134                 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
    135                         if ( bt->get_kind() == BasicType::SignedInt ) {
     134                } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) {
     135                        if ( bt->kind == BasicType::SignedInt ) {
    136136                                result = 0;
    137137                        } else {
     
    143143        }
    144144
    145         void PtrsCastable_old::postvisit( TraitInstType * ) {}
    146 
    147         void PtrsCastable_old::postvisit(TypeInstType *inst ) {
     145        void PtrsCastable_old::postvisit( const TraitInstType * ) {}
     146
     147        void PtrsCastable_old::postvisit( const TypeInstType *inst ) {
    148148                //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
    149149                result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
    150150        }
    151151
    152         void PtrsCastable_old::postvisit( TupleType * ) {
    153                 result = objectCast( dest, env, indexer );
    154         }
    155 
    156         void PtrsCastable_old::postvisit( VarArgsType * ) {
    157                 result = objectCast( dest, env, indexer );
    158         }
    159 
    160         void PtrsCastable_old::postvisit( ZeroType * ) {
    161                 result = objectCast( dest, env, indexer );
    162         }
    163 
    164         void PtrsCastable_old::postvisit( OneType * ) {
     152        void PtrsCastable_old::postvisit( const TupleType * ) {
     153                result = objectCast( dest, env, indexer );
     154        }
     155
     156        void PtrsCastable_old::postvisit( const VarArgsType * ) {
     157                result = objectCast( dest, env, indexer );
     158        }
     159
     160        void PtrsCastable_old::postvisit( const ZeroType * ) {
     161                result = objectCast( dest, env, indexer );
     162        }
     163
     164        void PtrsCastable_old::postvisit( const OneType * ) {
    165165                result = objectCast( dest, env, indexer );
    166166        }
     
    168168namespace {
    169169        // can this type be cast to an object (1 for yes, -1 for no)
    170         int objectCast( 
    171                 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
     170        int objectCast(
     171                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
    172172        ) {
    173173                if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
     
    191191
    192192        // can this type be cast to a function (inverse of objectCast)
    193         int functionCast( 
    194                 const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 
     193        int functionCast(
     194                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
    195195        ) {
    196196                return -1 * objectCast( src, env, symtab );
     
    204204                int result;
    205205
    206                 PtrsCastable_new( 
     206                PtrsCastable_new(
    207207                        const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
    208208                : dst( d ), env( e ), symtab( syms ), result( 0 ) {}
     
    278278} // anonymous namespace
    279279
    280 int ptrsCastable( 
    281         const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
    282         const ast::TypeEnvironment & env 
     280int ptrsCastable(
     281        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     282        const ast::TypeEnvironment & env
    283283) {
    284284        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
  • src/ResolvExpr/ResolveAssertions.cc

    r1f1c102 rf53acdf8  
    99// Author           : Aaron B. Moss
    1010// Created On       : Fri Oct 05 13:46:00 2018
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Fri Oct 05 13:46:00 2018
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jul 10 16:10:37 2019
     13// Update Count     : 2
    1414//
    1515
     
    197197                        }
    198198                        if ( i == b.size() /* && i < a.size() */ ) return 1;
    199                        
     199
    200200                        int c = a[i].compare( b[i] );
    201201                        if ( c != 0 ) return c;
     
    220220
    221221                /// Initial resolution state for an alternative
    222                 ResnState( Alternative& a, SymTab::Indexer& indexer )
     222                ResnState( Alternative & a, SymTab::Indexer & indexer )
    223223                : alt(a), need(), newNeed(), deferred(), inferred(), costs{ Cost::zero }, indexer(indexer) {
    224224                        need.swap( a.need );
     
    226226
    227227                /// Updated resolution state with new need-list
    228                 ResnState( ResnState&& o, IterateFlag )
     228                ResnState( ResnState && o, IterateFlag )
    229229                : alt(std::move(o.alt)), need(o.newNeed.begin(), o.newNeed.end()), newNeed(), deferred(),
    230230                  inferred(std::move(o.inferred)), costs(o.costs), indexer(o.indexer) {
     
    234234
    235235        /// Binds a single assertion, updating resolution state
    236         void bindAssertion( const DeclarationWithType* decl, AssertionSetValue info, Alternative& alt,
    237                         AssnCandidate& match, InferCache& inferred ) {
    238 
    239                 DeclarationWithType* candidate = match.cdata.id;
    240                 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
    241 
    242                 Expression* varExpr = match.cdata.combine( alt.cvtCost );
     236        void bindAssertion( const DeclarationWithType * decl, AssertionSetValue info, Alternative & alt,
     237                        AssnCandidate & match, InferCache & inferred ) {
     238
     239                const DeclarationWithType * candidate = match.cdata.id;
     240                assertf( candidate->uniqueId, "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
     241
     242                Expression * varExpr = match.cdata.combine( alt.cvtCost );
    243243                delete varExpr->result;
    244244                varExpr->result = match.adjType->clone();
     
    247247                // place newly-inferred assertion in proper place in cache
    248248                inferred[ info.resnSlot ][ decl->get_uniqueId() ] = ParamEntry{
    249                                 candidate->get_uniqueId(), candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),
     249                                candidate->uniqueId, candidate->clone(), match.adjType->clone(), decl->get_type()->clone(),
    250250                                varExpr };
    251251        }
    252252
    253253        /// Adds a captured assertion to the symbol table
    254         void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
     254        void addToIndexer( AssertionSet & assertSet, SymTab::Indexer & indexer ) {
    255255                for ( auto&  i : assertSet ) {
    256256                        if ( i.second.isUsed ) {
     
    264264
    265265        /// Resolve a single assertion, in context
    266         bool resolveAssertion( AssertionItem& assn, ResnState& resn ) {
     266        bool resolveAssertion( AssertionItem & assn, ResnState & resn ) {
    267267                // skip unused assertions
    268268                if ( ! assn.info.isUsed ) return true;
     
    274274                // find the candidates that unify with the desired type
    275275                CandidateList matches;
    276                 for ( const auto& cdata : candidates ) {
    277                         DeclarationWithType* candidate = cdata.id;
     276                for ( const auto & cdata : candidates ) {
     277                        const DeclarationWithType * candidate = cdata.id;
    278278
    279279                        // build independent unification context for candidate
     
    281281                        TypeEnvironment newEnv{ resn.alt.env };
    282282                        OpenVarSet newOpenVars{ resn.alt.openVars };
    283                         Type* adjType = candidate->get_type()->clone();
     283                        Type * adjType = candidate->get_type()->clone();
    284284                        adjustExprType( adjType, newEnv, resn.indexer );
    285285                        renameTyVars( adjType );
     
    368368                std::string resKey = SymTab::Mangler::mangleType( resType );
    369369                delete resType;
    370                 return std::move( resKey );
    371         }
    372        
    373         /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning 
     370                return resKey;
     371        }
     372
     373        /// Replace resnSlots with inferParams and add alternative to output list, if meets pruning
    374374        /// threshold.
    375375        void finalizeAssertions( ResnState& resn, PruneMap & pruneThresholds, AltList& out ) {
     
    406406                ResnList resns{ ResnState{ alt, root_indexer } };
    407407                ResnList new_resns{};
    408                
     408
    409409                // Pruning thresholds by result type of the output alternatives.
    410410                // Alternatives *should* be generated in sorted order, so no need to retroactively prune
  • src/ResolvExpr/Resolver.cc

    r1f1c102 rf53acdf8  
    562562                // TODO: Replace *exception type with &exception type.
    563563                if ( throwStmt->get_expr() ) {
    564                         StructDecl * exception_decl =
    565                                 indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
     564                        const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
    566565                        assert( exception_decl );
    567                         Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
     566                        Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) );
    568567                        findSingleExpression( throwStmt->expr, exceptType, indexer );
    569568                }
     
    972971                /// Calls the CandidateFinder and finds the single best candidate
    973972                CandidateRef findUnfinishedKindExpression(
    974                         const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 
     973                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
    975974                        std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {}
    976975                ) {
     
    994993                        // produce invalid error if no candidates
    995994                        if ( candidates.empty() ) {
    996                                 SemanticError( untyped, 
    997                                         toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 
     995                                SemanticError( untyped,
     996                                        toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
    998997                                        "expression: ") );
    999998                        }
     
    10311030                        if ( winners.size() != 1 ) {
    10321031                                std::ostringstream stream;
    1033                                 stream << "Cannot choose between " << winners.size() << " alternatives for " 
     1032                                stream << "Cannot choose between " << winners.size() << " alternatives for "
    10341033                                        << kind << (kind != "" ? " " : "") << "expression\n";
    10351034                                ast::print( stream, untyped );
     
    10541053                struct StripCasts_new final {
    10551054                        const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
    1056                                 if ( 
    1057                                         castExpr->isGenerated 
    1058                                         && typesCompatible( castExpr->arg->result, castExpr->result ) 
     1055                                if (
     1056                                        castExpr->isGenerated
     1057                                        && typesCompatible( castExpr->arg->result, castExpr->result )
    10591058                                ) {
    10601059                                        // generated cast is the same type as its argument, remove it after keeping env
    1061                                         return ast::mutate_field( 
     1060                                        return ast::mutate_field(
    10621061                                                castExpr->arg.get(), &ast::Expr::env, castExpr->env );
    10631062                                }
     
    10881087
    10891088                /// Establish post-resolver invariants for expressions
    1090                 void finishExpr( 
    1091                         ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 
     1089                void finishExpr(
     1090                        ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
    10921091                        const ast::TypeSubstitution * oldenv = nullptr
    10931092                ) {
    10941093                        // set up new type substitution for expression
    1095                         ast::ptr< ast::TypeSubstitution > newenv = 
     1094                        ast::ptr< ast::TypeSubstitution > newenv =
    10961095                                 oldenv ? oldenv : new ast::TypeSubstitution{};
    10971096                        env.writeToSubstitution( *newenv.get_and_mutate() );
     
    11021101        } // anonymous namespace
    11031102
    1104                
     1103
    11051104        ast::ptr< ast::Expr > resolveInVoidContext(
    11061105                const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
    11071106        ) {
    11081107                assertf( expr, "expected a non-null expression" );
    1109                
     1108
    11101109                // set up and resolve expression cast to void
    11111110                ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr };
    1112                 CandidateRef choice = findUnfinishedKindExpression( 
     1111                CandidateRef choice = findUnfinishedKindExpression(
    11131112                        untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
    1114                
     1113
    11151114                // a cast expression has either 0 or 1 interpretations (by language rules);
    11161115                // if 0, an exception has already been thrown, and this code will not run
     
    11221121
    11231122        namespace {
    1124                 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 
     1123                /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
    11251124                /// context.
    1126                 ast::ptr< ast::Expr > findVoidExpression( 
     1125                ast::ptr< ast::Expr > findVoidExpression(
    11271126                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11281127                ) {
     
    11341133                }
    11351134
    1136                 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 
     1135                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
    11371136                /// lowest cost, returning the resolved version
    11381137                ast::ptr< ast::Expr > findKindExpression(
    1139                         const ast::Expr * untyped, const ast::SymbolTable & symtab, 
    1140                         std::function<bool(const Candidate &)> pred = anyCandidate, 
     1138                        const ast::Expr * untyped, const ast::SymbolTable & symtab,
     1139                        std::function<bool(const Candidate &)> pred = anyCandidate,
    11411140                        const std::string & kind = "", ResolvMode mode = {}
    11421141                ) {
    11431142                        if ( ! untyped ) return {};
    1144                         CandidateRef choice = 
     1143                        CandidateRef choice =
    11451144                                findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
    11461145                        finishExpr( choice->expr, choice->env, untyped->env );
     
    11491148
    11501149                /// Resolve `untyped` to the single expression whose candidate is the best match
    1151                 ast::ptr< ast::Expr > findSingleExpression( 
    1152                         const ast::Expr * untyped, const ast::SymbolTable & symtab 
     1150                ast::ptr< ast::Expr > findSingleExpression(
     1151                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11531152                ) {
    11541153                        return findKindExpression( untyped, symtab );
     
    11701169                bool hasIntegralType( const Candidate & i ) {
    11711170                        const ast::Type * type = i.expr->result;
    1172                        
     1171
    11731172                        if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
    11741173                                return bt->isInteger();
    1175                         } else if ( 
    1176                                 dynamic_cast< const ast::EnumInstType * >( type ) 
     1174                        } else if (
     1175                                dynamic_cast< const ast::EnumInstType * >( type )
    11771176                                || dynamic_cast< const ast::ZeroType * >( type )
    11781177                                || dynamic_cast< const ast::OneType * >( type )
     
    11831182
    11841183                /// Resolve `untyped` as an integral expression, returning the resolved version
    1185                 ast::ptr< ast::Expr > findIntegralExpression( 
    1186                         const ast::Expr * untyped, const ast::SymbolTable & symtab 
     1184                ast::ptr< ast::Expr > findIntegralExpression(
     1185                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11871186                ) {
    11881187                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
     
    11921191                bool isCharType( const ast::Type * t ) {
    11931192                        if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) {
    1194                                 return bt->kind == ast::BasicType::Char 
    1195                                         || bt->kind == ast::BasicType::SignedChar 
     1193                                return bt->kind == ast::BasicType::Char
     1194                                        || bt->kind == ast::BasicType::SignedChar
    11961195                                        || bt->kind == ast::BasicType::UnsignedChar;
    11971196                        }
     
    12531252        }
    12541253
    1255         ast::ptr< ast::Init > resolveCtorInit( 
    1256                 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 
     1254        ast::ptr< ast::Init > resolveCtorInit(
     1255                const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab
    12571256        ) {
    12581257                assert( ctorInit );
     
    12611260        }
    12621261
    1263         ast::ptr< ast::Expr > resolveStmtExpr( 
    1264                 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 
     1262        ast::ptr< ast::Expr > resolveStmtExpr(
     1263                const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab
    12651264        ) {
    12661265                assert( stmtExpr );
     
    13031302
    13041303        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    1305                 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 
    1306                 // class-variable `initContext` is changed multiple times because the LHS is analyzed 
    1307                 // twice. The second analysis changes `initContext` because a function type can contain 
    1308                 // object declarations in the return and parameter types. Therefore each value of 
    1309                 // `initContext` is retained so the type on the first analysis is preserved and used for 
     1304                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
     1305                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     1306                // twice. The second analysis changes `initContext` because a function type can contain
     1307                // object declarations in the return and parameter types. Therefore each value of
     1308                // `initContext` is retained so the type on the first analysis is preserved and used for
    13101309                // selecting the RHS.
    13111310                GuardValue( currentObject );
    13121311                currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
    13131312                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    1314                         // enumerator initializers should not use the enum type to initialize, since the 
     1313                        // enumerator initializers should not use the enum type to initialize, since the
    13151314                        // enum type is still incomplete at this point. Use `int` instead.
    1316                         currentObject = ast::CurrentObject{ 
     1315                        currentObject = ast::CurrentObject{
    13171316                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    13181317                }
     
    13251324        }
    13261325
    1327         const ast::StaticAssertDecl * Resolver_new::previsit( 
    1328                 const ast::StaticAssertDecl * assertDecl 
     1326        const ast::StaticAssertDecl * Resolver_new::previsit(
     1327                const ast::StaticAssertDecl * assertDecl
    13291328        ) {
    1330                 return ast::mutate_field( 
    1331                         assertDecl, &ast::StaticAssertDecl::cond, 
     1329                return ast::mutate_field(
     1330                        assertDecl, &ast::StaticAssertDecl::cond,
    13321331                        findIntegralExpression( assertDecl->cond, symtab ) );
    13331332        }
     
    13381337                        #warning should use new equivalent to Validate::SizeType rather than sizeType here
    13391338                        ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt };
    1340                         ast::mutate_field( 
    1341                                 type, &PtrType::dimension, 
     1339                        ast::mutate_field(
     1340                                type, &PtrType::dimension,
    13421341                                findSingleExpression( type->dimension, sizeType, symtab ) );
    13431342                }
     
    13561355                visit_children = false;
    13571356                assertf( exprStmt->expr, "ExprStmt has null expression in resolver" );
    1358                
    1359                 return ast::mutate_field( 
     1357
     1358                return ast::mutate_field(
    13601359                        exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) );
    13611360        }
     
    13641363                visit_children = false;
    13651364
    1366                 asmExpr = ast::mutate_field( 
     1365                asmExpr = ast::mutate_field(
    13671366                        asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
    1368                
     1367
    13691368                if ( asmExpr->inout ) {
    13701369                        asmExpr = ast::mutate_field(
    13711370                                asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) );
    13721371                }
    1373                
     1372
    13741373                return asmExpr;
    13751374        }
     
    13881387
    13891388        const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
    1390                 return ast::mutate_field( 
     1389                return ast::mutate_field(
    13911390                        whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) );
    13921391        }
     
    14091408                GuardValue( currentObject );
    14101409                switchStmt = ast::mutate_field(
    1411                         switchStmt, &ast::SwitchStmt::cond, 
     1410                        switchStmt, &ast::SwitchStmt::cond,
    14121411                        findIntegralExpression( switchStmt->cond, symtab ) );
    14131412                currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result };
     
    14201419                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
    14211420                                "expression." );
    1422                        
    1423                         ast::ptr< ast::Expr > untyped = 
     1421
     1422                        ast::ptr< ast::Expr > untyped =
    14241423                                new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
    14251424                        ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab );
    1426                        
    1427                         // case condition cannot have a cast in C, so it must be removed here, regardless of 
     1425
     1426                        // case condition cannot have a cast in C, so it must be removed here, regardless of
    14281427                        // whether it would perform a conversion.
    14291428                        if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) {
    14301429                                swap_and_save_env( newExpr, castExpr->arg );
    14311430                        }
    1432                        
     1431
    14331432                        caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr );
    14341433                }
     
    14431442                        ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} };
    14441443                        branchStmt = ast::mutate_field(
    1445                                 branchStmt, &ast::BranchStmt::computedTarget, 
     1444                                branchStmt, &ast::BranchStmt::computedTarget,
    14461445                                findSingleExpression( branchStmt->computedTarget, target, symtab ) );
    14471446                }
     
    14531452                if ( returnStmt->expr ) {
    14541453                        returnStmt = ast::mutate_field(
    1455                                 returnStmt, &ast::ReturnStmt::expr, 
     1454                                returnStmt, &ast::ReturnStmt::expr,
    14561455                                findSingleExpression( returnStmt->expr, functionReturn, symtab ) );
    14571456                }
     
    14621461                visit_children = false;
    14631462                if ( throwStmt->expr ) {
    1464                         const ast::StructDecl * exceptionDecl = 
     1463                        const ast::StructDecl * exceptionDecl =
    14651464                                symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" );
    14661465                        assert( exceptionDecl );
    1467                         ast::ptr< ast::Type > exceptType = 
     1466                        ast::ptr< ast::Type > exceptType =
    14681467                                new ast::PointerType{ new ast::StructInstType{ exceptionDecl } };
    14691468                        throwStmt = ast::mutate_field(
    1470                                 throwStmt, &ast::ThrowStmt::expr, 
     1469                                throwStmt, &ast::ThrowStmt::expr,
    14711470                                findSingleExpression( throwStmt->expr, exceptType, symtab ) );
    14721471                }
     
    14771476                if ( catchStmt->cond ) {
    14781477                        ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
    1479                         catchStmt = ast::mutate_field( 
    1480                                 catchStmt, &ast::CatchStmt::cond, 
     1478                        catchStmt = ast::mutate_field(
     1479                                catchStmt, &ast::CatchStmt::cond,
    14811480                                findSingleExpression( catchStmt->cond, boolType, symtab ) );
    14821481                }
     
    15061505
    15071506                        if ( clause.target.args.empty() ) {
    1508                                 SemanticError( stmt->location, 
     1507                                SemanticError( stmt->location,
    15091508                                        "Waitfor clause must have at least one mutex parameter");
    15101509                        }
    15111510
    15121511                        // Find all alternatives for all arguments in canonical form
    1513                         std::vector< CandidateFinder > argFinders = 
     1512                        std::vector< CandidateFinder > argFinders =
    15141513                                funcFinder.findSubExprs( clause.target.args );
    1515                        
     1514
    15161515                        // List all combinations of arguments
    15171516                        std::vector< CandidateList > possibilities;
     
    15191518
    15201519                        // For every possible function:
    1521                         // * try matching the arguments to the parameters, not the other way around because 
     1520                        // * try matching the arguments to the parameters, not the other way around because
    15221521                        //   more arguments than parameters
    15231522                        CandidateList funcCandidates;
     
    15261525                        for ( CandidateRef & func : funcFinder.candidates ) {
    15271526                                try {
    1528                                         auto pointerType = dynamic_cast< const ast::PointerType * >( 
     1527                                        auto pointerType = dynamic_cast< const ast::PointerType * >(
    15291528                                                func->expr->result->stripReferences() );
    15301529                                        if ( ! pointerType ) {
    1531                                                 SemanticError( stmt->location, func->expr->result.get(), 
     1530                                                SemanticError( stmt->location, func->expr->result.get(),
    15321531                                                        "candidate not viable: not a pointer type\n" );
    15331532                                        }
     
    15351534                                        auto funcType = pointerType->base.as< ast::FunctionType >();
    15361535                                        if ( ! funcType ) {
    1537                                                 SemanticError( stmt->location, func->expr->result.get(), 
     1536                                                SemanticError( stmt->location, func->expr->result.get(),
    15381537                                                        "candidate not viable: not a function type\n" );
    15391538                                        }
     
    15441543
    15451544                                                if( ! nextMutex( param, paramEnd ) ) {
    1546                                                         SemanticError( stmt->location, funcType, 
     1545                                                        SemanticError( stmt->location, funcType,
    15471546                                                                "candidate function not viable: no mutex parameters\n");
    15481547                                                }
     
    15601559                                                        ast::AssertionSet need, have;
    15611560                                                        ast::TypeEnvironment resultEnv{ func->env };
    1562                                                         // Add all type variables as open so that those not used in the 
     1561                                                        // Add all type variables as open so that those not used in the
    15631562                                                        // parameter list are still considered open
    15641563                                                        resultEnv.add( funcType->forall );
     
    15801579                                                        unsigned n_mutex_param = 0;
    15811580
    1582                                                         // For every argument of its set, check if it matches one of the 
     1581                                                        // For every argument of its set, check if it matches one of the
    15831582                                                        // parameters. The order is important
    15841583                                                        for ( auto & arg : argsList ) {
     
    15871586                                                                        // We ran out of parameters but still have arguments.
    15881587                                                                        // This function doesn't match
    1589                                                                         SemanticError( stmt->location, funcType, 
     1588                                                                        SemanticError( stmt->location, funcType,
    15901589                                                                                toString("candidate function not viable: too many mutex "
    15911590                                                                                "arguments, expected ", n_mutex_param, "\n" ) );
     
    15941593                                                                ++n_mutex_param;
    15951594
    1596                                                                 // Check if the argument matches the parameter type in the current 
     1595                                                                // Check if the argument matches the parameter type in the current
    15971596                                                                // scope
    15981597                                                                ast::ptr< ast::Type > paramType = (*param)->get_type();
    1599                                                                 if ( 
    1600                                                                         ! unify( 
    1601                                                                                 arg->expr->result, paramType, resultEnv, need, have, open, 
    1602                                                                                 symtab ) 
     1598                                                                if (
     1599                                                                        ! unify(
     1600                                                                                arg->expr->result, paramType, resultEnv, need, have, open,
     1601                                                                                symtab )
    16031602                                                                ) {
    16041603                                                                        // Type doesn't match
     
    16271626                                                                } while ( nextMutex( param, paramEnd ) );
    16281627
    1629                                                                 // We ran out of arguments but still have parameters left; this 
     1628                                                                // We ran out of arguments but still have parameters left; this
    16301629                                                                // function doesn't match
    1631                                                                 SemanticError( stmt->location, funcType, 
     1630                                                                SemanticError( stmt->location, funcType,
    16321631                                                                        toString( "candidate function not viable: too few mutex "
    16331632                                                                        "arguments, expected ", n_mutex_param, "\n" ) );
     
    16571656                        // Make sure correct number of arguments
    16581657                        if( funcCandidates.empty() ) {
    1659                                 SemanticErrorException top( stmt->location, 
     1658                                SemanticErrorException top( stmt->location,
    16601659                                        "No alternatives for function in call to waitfor" );
    16611660                                top.append( errors );
     
    16641663
    16651664                        if( argsCandidates.empty() ) {
    1666                                 SemanticErrorException top( stmt->location, 
    1667                                         "No alternatives for arguments in call to waitfor" ); 
     1665                                SemanticErrorException top( stmt->location,
     1666                                        "No alternatives for arguments in call to waitfor" );
    16681667                                top.append( errors );
    16691668                                throw top;
     
    16711670
    16721671                        if( funcCandidates.size() > 1 ) {
    1673                                 SemanticErrorException top( stmt->location, 
     1672                                SemanticErrorException top( stmt->location,
    16741673                                        "Ambiguous function in call to waitfor" );
    16751674                                top.append( errors );
     
    16861685                        // build new clause
    16871686                        ast::WaitForStmt::Clause clause2;
    1688                        
     1687
    16891688                        clause2.target.func = funcCandidates.front()->expr;
    1690                        
     1689
    16911690                        clause2.target.args.reserve( clause.target.args.size() );
    16921691                        for ( auto arg : argsCandidates.front() ) {
     
    17081707                        ast::WaitForStmt::Timeout timeout2;
    17091708
    1710                         ast::ptr< ast::Type > target = 
     1709                        ast::ptr< ast::Type > target =
    17111710                                new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
    17121711                        timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab );
     
    17401739        const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) {
    17411740                visit_children = false;
    1742                 // resolve initialization using the possibilities as determined by the `currentObject` 
     1741                // resolve initialization using the possibilities as determined by the `currentObject`
    17431742                // cursor.
    1744                 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 
     1743                ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{
    17451744                        singleInit->location, singleInit->value, currentObject.getOptions() };
    17461745                ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab );
     
    17511750
    17521751                // discard InitExpr wrapper and retain relevant pieces.
    1753                 // `initExpr` may have inferred params in the case where the expression specialized a 
    1754                 // function pointer, and newExpr may already have inferParams of its own, so a simple 
     1752                // `initExpr` may have inferred params in the case where the expression specialized a
     1753                // function pointer, and newExpr may already have inferParams of its own, so a simple
    17551754                // swap is not sufficient
    17561755                ast::Expr::InferUnion inferred = initExpr->inferred;
     
    17581757                newExpr.get_and_mutate()->inferred.splice( std::move(inferred) );
    17591758
    1760                 // get the actual object's type (may not exactly match what comes back from the resolver 
     1759                // get the actual object's type (may not exactly match what comes back from the resolver
    17611760                // due to conversions)
    17621761                const ast::Type * initContext = currentObject.getCurrentType();
     
    17701769                                if ( auto pt = newExpr->result.as< ast::PointerType >() ) {
    17711770                                        if ( isCharType( pt->base ) ) {
    1772                                                 // strip cast if we're initializing a char[] with a char* 
     1771                                                // strip cast if we're initializing a char[] with a char*
    17731772                                                // e.g. char x[] = "hello"
    17741773                                                if ( auto ce = newExpr.as< ast::CastExpr >() ) {
     
    17931792                assert( listInit->designations.size() == listInit->initializers.size() );
    17941793                for ( unsigned i = 0; i < listInit->designations.size(); ++i ) {
    1795                         // iterate designations and initializers in pairs, moving the cursor to the current 
     1794                        // iterate designations and initializers in pairs, moving the cursor to the current
    17961795                        // designated object and resolving the initializer against that object
    17971796                        listInit = ast::mutate_field_index(
    1798                                 listInit, &ast::ListInit::designations, i, 
     1797                                listInit, &ast::ListInit::designations, i,
    17991798                                currentObject.findNext( listInit->designations[i] ) );
    18001799                        listInit = ast::mutate_field_index(
     
    18181817                ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr );
    18191818
    1820                 // intrinsic single-parameter constructors and destructors do nothing. Since this was 
    1821                 // implicitly generated, there's no way for it to have side effects, so get rid of it to 
     1819                // intrinsic single-parameter constructors and destructors do nothing. Since this was
     1820                // implicitly generated, there's no way for it to have side effects, so get rid of it to
    18221821                // clean up generated code
    18231822                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
  • src/ResolvExpr/Unify.cc

    r1f1c102 rf53acdf8  
    9797        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer );
    9898
    99         bool unifyExact( 
    100                 const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
    101                 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
     99        bool unifyExact(
     100                const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
     101                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    102102                WidenMode widen, const ast::SymbolTable & symtab );
    103103
    104         bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     104        bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
    105105                TypeEnvironment newEnv;
    106106                OpenVarSet openVars, closedVars; // added closedVars
    107107                AssertionSet needAssertions, haveAssertions;
    108                 Type *newFirst = first->clone(), *newSecond = second->clone();
     108                Type * newFirst = first->clone(), * newSecond = second->clone();
    109109                env.apply( newFirst );
    110110                env.apply( newSecond );
     
    121121        }
    122122
    123         bool typesCompatible( 
    124                         const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 
     123        bool typesCompatible(
     124                        const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
    125125                        const ast::TypeEnvironment & env ) {
    126126                ast::TypeEnvironment newEnv;
     
    135135                findOpenVars( newSecond, open, closed, need, have, FirstOpen );
    136136
    137                 return unifyExact( 
     137                return unifyExact(
    138138                        newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
    139139        }
    140140
    141         bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     141        bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    142142                TypeEnvironment newEnv;
    143143                OpenVarSet openVars;
     
    163163        }
    164164
    165         bool typesCompatibleIgnoreQualifiers( 
    166                         const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab, 
     165        bool typesCompatibleIgnoreQualifiers(
     166                        const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
    167167                        const ast::TypeEnvironment & env ) {
    168168                ast::TypeEnvironment newEnv;
    169169                ast::OpenVarSet open;
    170170                ast::AssertionSet need, have;
    171                
     171
    172172                ast::ptr<ast::Type> newFirst{ first }, newSecond{ second };
    173173                env.apply( newFirst );
     
    176176                reset_qualifiers( newSecond );
    177177
    178                 return unifyExact( 
     178                return unifyExact(
    179179                        newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
    180180        }
     
    490490
    491491                        // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
    492                         if ( 
    493                                         (flatFunc->parameters.size() == flatOther->parameters.size() && 
    494                                                 flatFunc->returnVals.size() == flatOther->returnVals.size()) 
    495                                         || flatFunc->isTtype() 
    496                                         || flatOther->isTtype() 
     492                        if (
     493                                        (flatFunc->parameters.size() == flatOther->parameters.size() &&
     494                                                flatFunc->returnVals.size() == flatOther->returnVals.size())
     495                                        || flatFunc->isTtype()
     496                                        || flatOther->isTtype()
    497497                        ) {
    498498                                if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     
    711711                bool result;
    712712
    713                 Unify_new( 
    714                         const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need, 
    715                         ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen, 
     713                Unify_new(
     714                        const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need,
     715                        ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen,
    716716                        const ast::SymbolTable & symtab )
    717                 : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen), 
     717                : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen),
    718718                  symtab(symtab), result(false) {}
    719719
    720720                void previsit( const ast::Node * ) { visit_children = false; }
    721                
     721
    722722                void postvisit( const ast::VoidType * ) {
    723723                        result = dynamic_cast< const ast::VoidType * >( type2 );
     
    732732                void postvisit( const ast::PointerType * pointer ) {
    733733                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
    734                                 result = unifyExact( 
    735                                         pointer->base, pointer2->base, tenv, need, have, open, 
     734                                result = unifyExact(
     735                                        pointer->base, pointer2->base, tenv, need, have, open,
    736736                                        noWiden(), symtab );
    737737                        }
     
    742742                        if ( ! array2 ) return;
    743743
    744                         // to unify, array types must both be VLA or both not VLA and both must have a 
     744                        // to unify, array types must both be VLA or both not VLA and both must have a
    745745                        // dimension expression or not have a dimension
    746746                        if ( array->isVarLen != array2->isVarLen ) return;
    747                         if ( ! array->isVarLen && ! array2->isVarLen 
     747                        if ( ! array->isVarLen && ! array2->isVarLen
    748748                                        && array->dimension && array2->dimension ) {
    749749                                auto ce1 = array->dimension.as< ast::ConstantExpr >();
     
    751751
    752752                                // see C11 Reference Manual 6.7.6.2.6
    753                                 // two array types with size specifiers that are integer constant expressions are 
     753                                // two array types with size specifiers that are integer constant expressions are
    754754                                // compatible if both size specifiers have the same constant value
    755755                                if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return;
    756756                        }
    757757
    758                         result = unifyExact( 
    759                                 array->base, array2->base, tenv, need, have, open, noWiden(), 
     758                        result = unifyExact(
     759                                array->base, array2->base, tenv, need, have, open, noWiden(),
    760760                                symtab );
    761761                }
     
    763763                void postvisit( const ast::ReferenceType * ref ) {
    764764                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
    765                                 result = unifyExact( 
    766                                         ref->base, ref2->base, tenv, need, have, open, noWiden(), 
     765                                result = unifyExact(
     766                                        ref->base, ref2->base, tenv, need, have, open, noWiden(),
    767767                                        symtab );
    768768                        }
     
    771771        private:
    772772                /// Replaces ttype variables with their bound types.
    773                 /// If this isn't done when satifying ttype assertions, then argument lists can have 
     773                /// If this isn't done when satifying ttype assertions, then argument lists can have
    774774                /// different size and structure when they should be compatible.
    775775                struct TtypeExpander_new : public ast::WithShortCircuiting {
     
    800800                                auto types = flatten( d->get_type() );
    801801                                for ( ast::ptr< ast::Type > & t : types ) {
    802                                         // outermost const, volatile, _Atomic qualifiers in parameters should not play 
    803                                         // a role in the unification of function types, since they do not determine 
     802                                        // outermost const, volatile, _Atomic qualifiers in parameters should not play
     803                                        // a role in the unification of function types, since they do not determine
    804804                                        // whether a function is callable.
    805                                         // NOTE: **must** consider at least mutex qualifier, since functions can be 
    806                                         // overloaded on outermost mutex and a mutex function has different 
     805                                        // NOTE: **must** consider at least mutex qualifier, since functions can be
     806                                        // overloaded on outermost mutex and a mutex function has different
    807807                                        // requirements than a non-mutex function
    808808                                        remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
     
    818818                        std::vector< ast::ptr< ast::Type > > types;
    819819                        while ( crnt != end ) {
    820                                 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 
     820                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
    821821                                // that this results in a flat tuple
    822822                                flatten( (*crnt)->get_type(), types );
     
    829829
    830830                template< typename Iter >
    831                 static bool unifyDeclList( 
    832                         Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 
    833                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
     831                static bool unifyDeclList(
     832                        Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
     833                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    834834                        const ast::SymbolTable & symtab
    835835                ) {
     
    843843                                if ( isTuple1 && ! isTuple2 ) {
    844844                                        // combine remainder of list2, then unify
    845                                         return unifyExact( 
    846                                                 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 
     845                                        return unifyExact(
     846                                                t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
    847847                                                noWiden(), symtab );
    848848                                } else if ( ! isTuple1 && isTuple2 ) {
    849849                                        // combine remainder of list1, then unify
    850                                         return unifyExact( 
    851                                                 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 
     850                                        return unifyExact(
     851                                                tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
    852852                                                noWiden(), symtab );
    853853                                }
    854854
    855                                 if ( ! unifyExact( 
    856                                         t1, t2, env, need, have, open, noWiden(), symtab ) 
     855                                if ( ! unifyExact(
     856                                        t1, t2, env, need, have, open, noWiden(), symtab )
    857857                                ) return false;
    858858
     
    860860                        }
    861861
    862                         // May get to the end of one argument list before the other. This is only okay if the 
     862                        // May get to the end of one argument list before the other. This is only okay if the
    863863                        // other is a ttype
    864864                        if ( crnt1 != end1 ) {
     
    866866                                const ast::Type * t1 = (*crnt1)->get_type();
    867867                                if ( ! Tuples::isTtype( t1 ) ) return false;
    868                                 return unifyExact( 
    869                                         t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 
     868                                return unifyExact(
     869                                        t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
    870870                                        noWiden(), symtab );
    871871                        } else if ( crnt2 != end2 ) {
     
    873873                                const ast::Type * t2 = (*crnt2)->get_type();
    874874                                if ( ! Tuples::isTtype( t2 ) ) return false;
    875                                 return unifyExact( 
    876                                         tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 
     875                                return unifyExact(
     876                                        tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
    877877                                        noWiden(), symtab );
    878878                        }
     
    881881                }
    882882
    883                 static bool unifyDeclList( 
    884                         const std::vector< ast::ptr< ast::DeclWithType > > & list1, 
    885                         const std::vector< ast::ptr< ast::DeclWithType > > & list2, 
    886                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
     883                static bool unifyDeclList(
     884                        const std::vector< ast::ptr< ast::DeclWithType > > & list1,
     885                        const std::vector< ast::ptr< ast::DeclWithType > > & list2,
     886                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    887887                        const ast::OpenVarSet & open, const ast::SymbolTable & symtab
    888888                ) {
    889                         return unifyDeclList( 
    890                                 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 
     889                        return unifyDeclList(
     890                                list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
    891891                                symtab );
    892892                }
     
    900900
    901901                /// mark all assertions in `type` used in both `assn1` and `assn2`
    902                 static void markAssertions( 
    903                         ast::AssertionSet & assn1, ast::AssertionSet & assn2, 
    904                         const ast::ParameterizedType * type 
     902                static void markAssertions(
     903                        ast::AssertionSet & assn1, ast::AssertionSet & assn2,
     904                        const ast::ParameterizedType * type
    905905                ) {
    906906                        for ( const auto & tyvar : type->forall ) {
     
    918918
    919919                        if ( func->isVarArgs != func2->isVarArgs ) return;
    920                        
    921                         // Flatten the parameter lists for both functions so that tuple structure does not 
     920
     921                        // Flatten the parameter lists for both functions so that tuple structure does not
    922922                        // affect unification. Does not actually mutate function parameters.
    923923                        auto params = flattenList( func->params, tenv );
    924924                        auto params2 = flattenList( func2->params, tenv );
    925925
    926                         // sizes don't have to match if ttypes are involved; need to be more precise w.r.t. 
     926                        // sizes don't have to match if ttypes are involved; need to be more precise w.r.t.
    927927                        // where the ttype is to prevent errors
    928                         if ( 
     928                        if (
    929929                                ( params.size() != params2.size() || func->returns.size() != func2->returns.size() )
    930930                                && ! func->isTtype()
     
    933933
    934934                        if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return;
    935                         if ( ! unifyDeclList( 
     935                        if ( ! unifyDeclList(
    936936                                func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
    937                        
     937
    938938                        markAssertions( have, need, func );
    939939                        markAssertions( have, need, func2 );
     
    941941                        result = true;
    942942                }
    943        
     943
    944944        private:
    945945                template< typename RefType >
     
    953953                /// Creates a tuple type based on a list of TypeExpr
    954954                template< typename Iter >
    955                 static const ast::Type * tupleFromExprs( 
     955                static const ast::Type * tupleFromExprs(
    956956                        const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs
    957957                ) {
     
    973973                        const RefType * inst2 = handleRefType( inst, other );
    974974                        if ( ! inst2 ) return;
    975                        
     975
    976976                        // check that parameters of types unify, if any
    977977                        const std::vector< ast::ptr< ast::Expr > > & params = inst->params;
     
    10021002                                }
    10031003
    1004                                 if ( ! unifyExact( 
     1004                                if ( ! unifyExact(
    10051005                                                pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
    10061006                                        result = false;
     
    10381038        private:
    10391039                /// Creates a tuple type based on a list of Type
    1040                 static ast::ptr< ast::Type > tupleFromTypes( 
     1040                static ast::ptr< ast::Type > tupleFromTypes(
    10411041                        const std::vector< ast::ptr< ast::Type > > & tys
    10421042                ) {
    10431043                        std::vector< ast::ptr< ast::Type > > out;
    10441044                        for ( const ast::Type * ty : tys ) {
    1045                                 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 
     1045                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
    10461046                                // that this results in a flat tuple
    10471047                                flatten( ty, out );
     
    10511051                }
    10521052
    1053                 static bool unifyList( 
    1054                         const std::vector< ast::ptr< ast::Type > > & list1, 
    1055                         const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env, 
    1056                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
     1053                static bool unifyList(
     1054                        const std::vector< ast::ptr< ast::Type > > & list1,
     1055                        const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env,
     1056                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    10571057                        const ast::SymbolTable & symtab
    10581058                ) {
     
    10681068                                if ( isTuple1 && ! isTuple2 ) {
    10691069                                        // combine entirety of list2, then unify
    1070                                         return unifyExact( 
    1071                                                 t1, tupleFromTypes( list2 ), env, need, have, open, 
     1070                                        return unifyExact(
     1071                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    10721072                                                noWiden(), symtab );
    10731073                                } else if ( ! isTuple1 && isTuple2 ) {
    10741074                                        // combine entirety of list1, then unify
    10751075                                        return unifyExact(
    1076                                                 tupleFromTypes( list1 ), t2, env, need, have, open, 
     1076                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    10771077                                                noWiden(), symtab );
    10781078                                }
    10791079
    1080                                 if ( ! unifyExact( 
    1081                                         t1, t2, env, need, have, open, noWiden(), symtab ) 
     1080                                if ( ! unifyExact(
     1081                                        t1, t2, env, need, have, open, noWiden(), symtab )
    10821082                                ) return false;
    10831083
     
    10891089                                const ast::Type * t1 = *crnt1;
    10901090                                if ( ! Tuples::isTtype( t1 ) ) return false;
    1091                                 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 
     1091                                // xxx - this doesn't generate an empty tuple, contrary to comment; both ported
    10921092                                // from Rob's code
    1093                                 return unifyExact( 
    1094                                                 t1, tupleFromTypes( list2 ), env, need, have, open, 
     1093                                return unifyExact(
     1094                                                t1, tupleFromTypes( list2 ), env, need, have, open,
    10951095                                                noWiden(), symtab );
    10961096                        } else if ( crnt2 != list2.end() ) {
     
    10981098                                const ast::Type * t2 = *crnt2;
    10991099                                if ( ! Tuples::isTtype( t2 ) ) return false;
    1100                                 // xxx - this doesn't generate an empty tuple, contrary to comment; both ported 
     1100                                // xxx - this doesn't generate an empty tuple, contrary to comment; both ported
    11011101                                // from Rob's code
    11021102                                return unifyExact(
    1103                                                 tupleFromTypes( list1 ), t2, env, need, have, open, 
     1103                                                tupleFromTypes( list1 ), t2, env, need, have, open,
    11041104                                                noWiden(), symtab );
    11051105                        }
     
    11331133                void postvisit( const ast::OneType * ) {
    11341134                        result = dynamic_cast< const ast::OneType * >( type2 );
    1135                 }       
     1135                }
    11361136
    11371137          private:
     
    11401140        };
    11411141
    1142         bool unify( 
    1143                         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
    1144                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
     1142        bool unify(
     1143                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1144                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
    11451145                        ast::OpenVarSet & open, const ast::SymbolTable & symtab
    11461146        ) {
     
    11491149        }
    11501150
    1151         bool unify( 
    1152                         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
    1153                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
    1154                         ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common 
     1151        bool unify(
     1152                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1153                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1154                        ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
    11551155        ) {
    11561156                ast::OpenVarSet closed;
    11571157                findOpenVars( type1, open, closed, need, have, FirstClosed );
    11581158                findOpenVars( type2, open, closed, need, have, FirstOpen );
    1159                 return unifyInexact( 
     1159                return unifyInexact(
    11601160                        type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
    11611161        }
    11621162
    1163         bool unifyExact( 
    1164                         const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env, 
    1165                         ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, 
     1163        bool unifyExact(
     1164                        const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
     1165                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
    11661166                        WidenMode widen, const ast::SymbolTable & symtab
    11671167        ) {
     
    11701170                auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 );
    11711171                auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 );
    1172                 ast::OpenVarSet::const_iterator 
    1173                         entry1 = var1 ? open.find( var1->name ) : open.end(), 
     1172                ast::OpenVarSet::const_iterator
     1173                        entry1 = var1 ? open.find( var1->name ) : open.end(),
    11741174                        entry2 = var2 ? open.find( var2->name ) : open.end();
    11751175                bool isopen1 = entry1 != open.end();
     
    11781178                if ( isopen1 && isopen2 ) {
    11791179                        if ( entry1->second.kind != entry2->second.kind ) return false;
    1180                         return env.bindVarToVar( 
    1181                                 var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have, 
     1180                        return env.bindVarToVar(
     1181                                var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have,
    11821182                                open, widen, symtab );
    11831183                } else if ( isopen1 ) {
     
    11921192        }
    11931193
    1194         bool unifyInexact( 
    1195                         const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2, 
    1196                         ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 
    1197                         const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab, 
    1198                         ast::ptr<ast::Type> & common 
     1194        bool unifyInexact(
     1195                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1196                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1197                        const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     1198                        ast::ptr<ast::Type> & common
    11991199        ) {
    12001200                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
    1201                
    1202                 // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and 
     1201
     1202                // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and
    12031203                // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1
    12041204                ast::ptr<ast::Type> t1{ type1 }, t2{ type2 };
    12051205                reset_qualifiers( t1 );
    12061206                reset_qualifiers( t2 );
    1207                
     1207
    12081208                if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
    12091209                        t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones
  • src/ResolvExpr/typeops.h

    r1f1c102 rf53acdf8  
    2828#include "SynTree/SynTree.h"
    2929#include "SynTree/Type.h"
    30 #include "SymTab/Indexer.h"
     30
     31namespace SymTab {
     32        class Indexer;
     33}
    3134
    3235namespace ResolvExpr {
     
    6063        // in AdjustExprType.cc
    6164        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
    62         void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     65        void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
    6366
    6467        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer
     
    6669
    6770        template< typename ForwardIterator >
    68         void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     71        void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {
    6972                while ( begin != end ) {
    7073                        adjustExprType( *begin++, env, indexer );
     
    7376
    7477        /// Replaces array types with equivalent pointer, and function types with a pointer-to-function
    75         const ast::Type * adjustExprType( 
     78        const ast::Type * adjustExprType(
    7679                const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
    7780
    7881        // in CastCost.cc
    79         Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    80         Cost castCost( 
    81                 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
     82        Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     83        Cost castCost(
     84                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    8285                const ast::TypeEnvironment & env );
    8386
    8487        // in ConversionCost.cc
    85         Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    86         Cost conversionCost( 
    87                 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
     88        Cost conversionCost( const Type * src, const Type * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     89        Cost conversionCost(
     90                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    8891                const ast::TypeEnvironment & env );
    8992
    9093        // in AlternativeFinder.cc
    91         Cost computeConversionCost( Type *actualType, Type *formalType,
    92                 const SymTab::Indexer &indexer, const TypeEnvironment &env );
     94        Cost computeConversionCost( Type * actualType, Type * formalType,
     95                const SymTab::Indexer & indexer, const TypeEnvironment & env );
    9396
    9497        // in PtrsAssignable.cc
    95         int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
     98        int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );
    9699        int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
    97100                const ast::TypeEnvironment & env );
    98101
    99102        // in PtrsCastable.cc
    100         int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    101         int ptrsCastable( 
    102                 const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab, 
     103        int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer );
     104        int ptrsCastable(
     105                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
    103106                const ast::TypeEnvironment & env );
    104107
    105108        // in Unify.cc
    106         bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    107         bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    108 
    109         inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
     109        bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     110        bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     111
     112        inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
    110113                TypeEnvironment env;
    111114                return typesCompatible( t1, t2, indexer, env );
    112115        }
    113116
    114         inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
     117        inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
    115118                TypeEnvironment env;
    116119                return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
    117120        }
    118121
    119         bool typesCompatible( 
    120                 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {}, 
     122        bool typesCompatible(
     123                const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
    121124                const ast::TypeEnvironment & env = {} );
    122        
     125
    123126        bool typesCompatibleIgnoreQualifiers(
    124                 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 
     127                const ast::Type *, const ast::Type *, const ast::SymbolTable &,
    125128                const ast::TypeEnvironment & env = {} );
    126129
     
    131134
    132135        // in CommonType.cc
    133         Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     136        Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars );
    134137        ast::ptr< ast::Type > commonType(
    135                 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen, 
     138                const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen,
    136139                const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open );
    137140
    138141        // in PolyCost.cc
    139         int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    140         int polyCost( 
     142        int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
     143        int polyCost(
    141144                const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
    142145
    143146        // in SpecCost.cc
    144         int specCost( Type *type );
     147        int specCost( Type * type );
    145148        int specCost( const ast::Type * type );
    146149
    147150        // in Occurs.cc
    148         bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
     151        bool occurs( Type * type, std::string varName, const TypeEnvironment & env );
    149152        // new AST version in TypeEnvironment.cpp (only place it was used in old AST)
    150153
    151         template<typename Iter> 
    152         bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment &env ) {
     154        template<typename Iter>
     155        bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) {
    153156                while ( begin != end ) {
    154157                        if ( occurs( ty, *begin, env ) ) return true;
     
    176179
    177180        /// flatten tuple type into existing list of types
    178         static inline void flatten( 
    179                 const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out 
     181        static inline void flatten(
     182                const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out
    180183        ) {
    181                 if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {       
     184                if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {
    182185                        for ( const ast::Type * t : tupleType->types ) {
    183186                                flatten( t, out );
     
    197200
    198201        // in TypeEnvironment.cc
    199         bool isFtype( Type *type );
     202        bool isFtype( Type * type );
    200203} // namespace ResolvExpr
    201204
Note: See TracChangeset for help on using the changeset viewer.