Changeset 3f7e12cb for src/ResolvExpr


Ignore:
Timestamp:
Nov 8, 2017, 5:43:33 PM (8 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
954908d
Parents:
78315272 (diff), e35f30a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Location:
src/ResolvExpr
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AdjustExprType.cc

    r78315272 r3f7e12cb  
    1414//
    1515
     16#include "Common/PassVisitor.h"
    1617#include "SymTab/Indexer.h"       // for Indexer
    1718#include "SynTree/Declaration.h"  // for TypeDecl, TypeDecl::Kind::Ftype
     
    2122
    2223namespace ResolvExpr {
    23         class AdjustExprType : public Mutator {
    24                 typedef Mutator Parent;
    25                 using Parent::mutate;
     24        class AdjustExprType : public WithShortCircuiting {
    2625          public:
    2726                AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer );
     27                void premutate( VoidType * ) { visit_children = false; }
     28                void premutate( BasicType * ) { visit_children = false; }
     29                void premutate( PointerType * ) { visit_children = false; }
     30                void premutate( ArrayType * ) { visit_children = false; }
     31                void premutate( FunctionType * ) { visit_children = false; }
     32                void premutate( StructInstType * ) { visit_children = false; }
     33                void premutate( UnionInstType * ) { visit_children = false; }
     34                void premutate( EnumInstType * ) { visit_children = false; }
     35                void premutate( TraitInstType * ) { visit_children = false; }
     36                void premutate( TypeInstType * ) { visit_children = false; }
     37                void premutate( TupleType * ) { visit_children = false; }
     38                void premutate( VarArgsType * ) { visit_children = false; }
     39                void premutate( ZeroType * ) { visit_children = false; }
     40                void premutate( OneType * ) { visit_children = false; }
     41
     42                Type * postmutate( ArrayType *arrayType );
     43                Type * postmutate( FunctionType *functionType );
     44                Type * postmutate( TypeInstType *aggregateUseType );
     45
    2846          private:
    29                 virtual Type* mutate( VoidType *voidType );
    30                 virtual Type* mutate( BasicType *basicType );
    31                 virtual Type* mutate( PointerType *pointerType );
    32                 virtual Type* mutate( ArrayType *arrayType );
    33                 virtual Type* mutate( FunctionType *functionType );
    34                 virtual Type* mutate( StructInstType *aggregateUseType );
    35                 virtual Type* mutate( UnionInstType *aggregateUseType );
    36                 virtual Type* mutate( EnumInstType *aggregateUseType );
    37                 virtual Type* mutate( TraitInstType *aggregateUseType );
    38                 virtual Type* mutate( TypeInstType *aggregateUseType );
    39                 virtual Type* mutate( TupleType *tupleType );
    40                 virtual Type* mutate( VarArgsType *varArgsType );
    41                 virtual Type* mutate( ZeroType *zeroType );
    42                 virtual Type* mutate( OneType *oneType );
    43 
    4447                const TypeEnvironment &env;
    4548                const SymTab::Indexer &indexer;
     
    4750
    4851        void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    49                 AdjustExprType adjuster( env, indexer );
     52                PassVisitor<AdjustExprType> adjuster( env, indexer );
    5053                Type *newType = type->acceptMutator( adjuster );
    5154                type = newType;
     
    5659        }
    5760
    58         Type *AdjustExprType::mutate( VoidType *voidType ) {
    59                 return voidType;
    60         }
    61 
    62         Type *AdjustExprType::mutate( BasicType *basicType ) {
    63                 return basicType;
    64         }
    65 
    66         Type *AdjustExprType::mutate( PointerType *pointerType ) {
    67                 return pointerType;
    68         }
    69 
    70         Type *AdjustExprType::mutate( ArrayType *arrayType ) {
    71                 // need to recursively mutate the base type in order for multi-dimensional arrays to work.
    72                 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ) );
     61        Type * AdjustExprType::postmutate( ArrayType * arrayType ) {
     62                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base );
     63                arrayType->base = nullptr;
    7364                delete arrayType;
    7465                return pointerType;
    7566        }
    7667
    77         Type *AdjustExprType::mutate( FunctionType *functionType ) {
    78                 PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType );
    79                 return pointerType;
     68        Type * AdjustExprType::postmutate( FunctionType * functionType ) {
     69                return new PointerType( Type::Qualifiers(), functionType );
    8070        }
    8171
    82         Type *AdjustExprType::mutate( StructInstType *aggregateUseType ) {
    83                 return aggregateUseType;
    84         }
    85 
    86         Type *AdjustExprType::mutate( UnionInstType *aggregateUseType ) {
    87                 return aggregateUseType;
    88         }
    89 
    90         Type *AdjustExprType::mutate( EnumInstType *aggregateUseType ) {
    91                 return aggregateUseType;
    92         }
    93 
    94         Type *AdjustExprType::mutate( TraitInstType *aggregateUseType ) {
    95                 return aggregateUseType;
    96         }
    97 
    98         Type *AdjustExprType::mutate( TypeInstType *typeInst ) {
     72        Type * AdjustExprType::postmutate( TypeInstType * typeInst ) {
    9973                EqvClass eqvClass;
    10074                if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     
    11387                return typeInst;
    11488        }
    115 
    116         Type *AdjustExprType::mutate( TupleType *tupleType ) {
    117                 return tupleType;
    118         }
    119 
    120         Type *AdjustExprType::mutate( VarArgsType *varArgsType ) {
    121                 return varArgsType;
    122         }
    123 
    124         Type *AdjustExprType::mutate( ZeroType *zeroType ) {
    125                 return zeroType;
    126         }
    127 
    128         Type *AdjustExprType::mutate( OneType *oneType ) {
    129                 return oneType;
    130         }
    13189} // namespace ResolvExpr
    13290
  • src/ResolvExpr/Alternative.cc

    r78315272 r3f7e12cb  
    6666        }
    6767
    68         void Alternative::print( std::ostream &os, int indent ) const {
    69                 os << std::string( indent, ' ' ) << "Cost " << cost << ": ";
     68        void Alternative::print( std::ostream &os, Indenter indent ) const {
     69                os << "Cost " << cost << ": ";
    7070                if ( expr ) {
    71                         expr->print( os, indent );
    72                         os << "(types:" << std::endl;
    73                         os << std::string( indent+4, ' ' );
    74                         expr->get_result()->print( os, indent + 4 );
    75                         os << std::endl << ")" << std::endl;
     71                        expr->print( os, indent+1 );
     72                        os << std::endl << indent << "(types:" << std::endl;
     73                        os << indent+1;
     74                        expr->result->print( os, indent+1 );
     75                        os << std::endl << indent << ")" << std::endl;
    7676                } else {
    7777                        os << "Null expression!" << std::endl;
    7878                } // if
    79                 os << std::string( indent, ' ' ) << "Environment: ";
    80                 env.print( os, indent+2 );
     79                os << indent << "Environment: ";
     80                env.print( os, indent+1 );
    8181                os << std::endl;
    8282        }
  • src/ResolvExpr/Alternative.h

    r78315272 r3f7e12cb  
    3939                ~Alternative();
    4040
    41                 void print( std::ostream &os, int indent = 0 ) const;
     41                void print( std::ostream &os, Indenter indent = {} ) const;
    4242
    4343                Cost cost;
  • src/ResolvExpr/AlternativeFinder.cc

    r78315272 r3f7e12cb  
    7676
    7777        namespace {
    78                 void printAlts( const AltList &list, std::ostream &os, int indent = 0 ) {
     78                void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt = 0 ) {
     79                        Indenter indent = { Indenter::tabsize, indentAmt };
    7980                        for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    8081                                i->print( os, indent );
     
    122123                                                )
    123124                                                mapPlace->second.isAmbiguous = true;
     125                                        } else {
     126                                                PRINT(
     127                                                        std::cerr << "cost " << candidate->cost << " loses to " << mapPlace->second.candidate->cost << std::endl;
     128                                                )
    124129                                        }
    125130                                } else {
     
    127132                                }
    128133                        }
    129 
    130                         PRINT(
    131                                 std::cerr << "there are " << selected.size() << " alternatives before elimination" << std::endl;
    132                         )
    133134
    134135                        // accept the alternatives that were unambiguous
     
    145146                        expr->get_result()->accept( global_renamer );
    146147                }
    147 
    148                 void referenceToRvalueConversion( Expression *& expr ) {
    149                         if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
    150                                 // cast away reference from expr
    151                                 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
    152                         }
    153                 }
    154148        } // namespace
     149
     150        void referenceToRvalueConversion( Expression *& expr ) {
     151                if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
     152                        // cast away reference from expr
     153                        expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );
     154                }
     155        }
    155156
    156157        template< typename InputIterator, typename OutputIterator >
     
    175176        }
    176177
    177         void AlternativeFinder::find( Expression *expr, bool adjust, bool prune ) {
     178        void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast ) {
    178179                expr->accept( *this );
    179                 if ( alternatives.empty() ) {
     180                if ( failFast && alternatives.empty() ) {
    180181                        throw SemanticError( "No reasonable alternatives for expression ", expr );
    181182                }
    182                 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    183                         if ( adjust ) {
    184                                 adjustExprType( i->expr->get_result(), i->env, indexer );
    185                         }
    186                 }
    187183                if ( prune ) {
     184                        auto oldsize = alternatives.size();
    188185                        PRINT(
    189186                                std::cerr << "alternatives before prune:" << std::endl;
     
    192189                        AltList::iterator oldBegin = alternatives.begin();
    193190                        pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ) );
    194                         if ( alternatives.begin() == oldBegin ) {
     191                        if ( failFast && alternatives.begin() == oldBegin ) {
    195192                                std::ostringstream stream;
    196193                                AltList winners;
    197194                                findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
    198                                 stream << "Cannot choose between " << winners.size() << " alternatives for expression ";
     195                                stream << "Cannot choose between " << winners.size() << " alternatives for expression\n";
    199196                                expr->print( stream );
    200                                 stream << "Alternatives are:";
    201                                 printAlts( winners, stream, 8 );
     197                                stream << "Alternatives are:\n";
     198                                printAlts( winners, stream, 1 );
    202199                                throw SemanticError( stream.str() );
    203200                        }
    204201                        alternatives.erase( oldBegin, alternatives.end() );
     202                        PRINT(
     203                                std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl;
     204                        )
    205205                        PRINT(
    206206                                std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl;
    207207                        )
     208                }
     209                // adjust types after pruning so that types substituted by pruneAlternatives are correctly adjusted
     210                for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
     211                        if ( adjust ) {
     212                                adjustExprType( i->expr->get_result(), i->env, indexer );
     213                        }
    208214                }
    209215
     
    215221        }
    216222
    217         void AlternativeFinder::findWithAdjustment( Expression *expr, bool prune ) {
    218                 find( expr, true, prune );
     223        void AlternativeFinder::findWithAdjustment( Expression *expr ) {
     224                find( expr, true );
     225        }
     226
     227        void AlternativeFinder::findWithoutPrune( Expression * expr ) {
     228                find( expr, true, false );
     229        }
     230
     231        void AlternativeFinder::maybeFind( Expression * expr ) {
     232                find( expr, true, true, false );
    219233        }
    220234
     
    299313                Cost convCost = conversionCost( actualType, formalType, indexer, env );
    300314                PRINT(
    301                         std::cerr << std::endl << "cost is" << convCost << std::endl;
     315                        std::cerr << std::endl << "cost is " << convCost << std::endl;
    302316                )
    303317                if ( convCost == Cost::infinity ) {
     
    305319                }
    306320                convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) );
     321                PRINT(
     322                        std::cerr << "cost with polycost is " << convCost << std::endl;
     323                )
    307324                return convCost;
    308325        }
     
    310327        Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    311328                Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
    312                 // if ( convCost != Cost::zero ) {
    313 
    314                 // xxx - temporary -- ignore poly cost, since this causes some polymorphic functions to be cast, which causes the specialize
    315                 // pass to try to specialize them, which currently does not work. Once that is fixed, remove the next 3 lines and uncomment the
    316                 // previous line.
     329
     330                // if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion.
     331                // ignore poly cost for now, since this requires resolution of the cast to infer parameters and this
     332                // does not currently work for the reason stated below.
    317333                Cost tmpCost = convCost;
    318334                tmpCost.incPoly( -tmpCost.get_polyCost() );
     
    357373                                if ( function->get_isVarArgs() ) {
    358374                                        convCost.incUnsafe();
     375                                        PRINT( std::cerr << "end of formals with varargs function: inc unsafe: " << convCost << std::endl; ; )
    359376                                        // convert reference-typed expressions to value-typed expressions
    360377                                        referenceToRvalueConversion( *actualExpr );
     
    365382                        }
    366383                        Type * formalType = (*formal)->get_type();
    367                         PRINT(
    368                                 std::cerr << std::endl << "converting ";
    369                                 actualType->print( std::cerr, 8 );
    370                                 std::cerr << std::endl << " to ";
    371                                 formalType->print( std::cerr, 8 );
    372                                 std::cerr << std::endl << "environment is: ";
    373                                 alt.env.print( std::cerr, 8 );
    374                                 std::cerr << std::endl;
    375                         )
    376384                        convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
    377385                        ++formal; // can't be in for-loop update because of the continue
     
    481489                                Alternative newerAlt( newAlt );
    482490                                newerAlt.env = newEnv;
    483                                 assert( (*candidate)->get_uniqueId() );
     491                                assertf( (*candidate)->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( *candidate ).c_str() );
    484492                                DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) );
    485493
     
    507515                                        std::cerr << std::endl;
    508516                                )
    509                                 ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );
    510517                                // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
    511                                 InferredParams * inferParameters = &appExpr->get_inferParams();
     518                                InferredParams * inferParameters = &newerAlt.expr->get_inferParams();
    512519                                for ( UniqueId id : cur->second.idChain ) {
    513520                                        inferParameters = (*inferParameters)[ id ].inferParams.get();
     
    786793               
    787794                return ! results.empty();
    788         }
     795        }       
    789796
    790797        template<typename OutputIterator>
    791         void AlternativeFinder::makeFunctionAlternatives( const Alternative& func,
    792                         FunctionType* funcType, const std::vector< AlternativeFinder >& args,
     798        void AlternativeFinder::makeFunctionAlternatives( const Alternative &func,
     799                        FunctionType *funcType, const std::vector< AlternativeFinder > &args,
    793800                        OutputIterator out ) {
    794801                OpenVarSet funcOpenVars;
    795802                AssertionSet funcNeed, funcHave;
    796                 TypeEnvironment funcEnv;
     803                TypeEnvironment funcEnv( func.env );
    797804                makeUnifiableVars( funcType, funcOpenVars, funcNeed );
    798805                // add all type variables as open variables now so that those not used in the parameter
    799806                // list are still considered open.
    800807                funcEnv.add( funcType->get_forall() );
    801 
     808               
    802809                if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) {
    803810                        // attempt to narrow based on expected target type
    804                         Type* returnType = funcType->get_returnVals().front()->get_type();
     811                        Type * returnType = funcType->get_returnVals().front()->get_type();
    805812                        if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars,
    806813                                        indexer ) ) {
     
    905912
    906913                // find function operators
     914                static NameExpr *opExpr = new NameExpr( "?()" );
    907915                AlternativeFinder funcOpFinder( indexer, env );
    908                 NameExpr *opExpr = new NameExpr( "?()" );
    909                 try {
    910                         funcOpFinder.findWithAdjustment( opExpr );
    911                 } catch( SemanticError &e ) {
    912                         // it's ok if there aren't any defined function ops
    913                 }
     916                // it's ok if there aren't any defined function ops
     917                funcOpFinder.maybeFind( opExpr);
    914918                PRINT(
    915919                        std::cerr << "known function ops:" << std::endl;
    916                         printAlts( funcOpFinder.alternatives, std::cerr, 8 );
     920                        printAlts( funcOpFinder.alternatives, std::cerr, 1 );
    917921                )
    918922
     
    10281032        bool isLvalue( Expression *expr ) {
    10291033                // xxx - recurse into tuples?
    1030                 return expr->has_result() && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
     1034                return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
    10311035        }
    10321036
     
    11031107                                thisCost.incSafe( discardedValues );
    11041108                                Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost );
    1105                                 // xxx - this doesn't work at the moment, since inferParameters requires an ApplicationExpr as the alternative.
    1106                                 // Once this works, it should be possible to infer parameters on a cast expression and specialize any function.
    1107 
    1108                                 // inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    1109                                 candidates.emplace_back( std::move( newAlt ) );
     1109                                inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    11101110                        } // if
    11111111                } // for
     
    11231123                AlternativeFinder finder( indexer, env );
    11241124                // don't prune here, since it's guaranteed all alternatives will have the same type
    1125                 // (giving the alternatives different types is half of the point of ConstructorExpr nodes)
    1126                 finder.findWithAdjustment( castExpr->get_arg(), false );
     1125                finder.findWithoutPrune( castExpr->get_arg() );
    11271126                for ( Alternative & alt : finder.alternatives ) {
    11281127                        alternatives.push_back( Alternative(
     
    11631162                PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; )
    11641163                for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) {
    1165                         VariableExpr newExpr( *i, nameExpr->get_argName() );
     1164                        VariableExpr newExpr( *i );
    11661165                        alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) );
    11671166                        PRINT(
     
    13981397                findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) );
    13991398                std::list< AltList > possibilities;
    1400                 // TODO re-write to use iterative method
    14011399                combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) );
    14021400                for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) {
     
    14221420                // don't prune here, since it's guaranteed all alternatives will have the same type
    14231421                // (giving the alternatives different types is half of the point of ConstructorExpr nodes)
    1424                 finder.findWithAdjustment( ctorExpr->get_callExpr(), false );
     1422                finder.findWithoutPrune( ctorExpr->get_callExpr() );
    14251423                for ( Alternative & alt : finder.alternatives ) {
    14261424                        alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) );
     
    14591457                // O(N^2) checks of d-types with e-types
    14601458                for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
    1461                         Type * toType = resolveTypeof( initAlt.type, indexer );
     1459                        Type * toType = resolveTypeof( initAlt.type->clone(), indexer );
    14621460                        SymTab::validateType( toType, &indexer );
    14631461                        adjustExprType( toType, env, indexer );
     
    14881486                                        // count one safe conversion for each value that is thrown away
    14891487                                        thisCost.incSafe( discardedValues );
    1490                                         candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
     1488                                        Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
     1489                                        inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
    14911490                                }
    14921491                        }
  • src/ResolvExpr/AlternativeFinder.h

    r78315272 r3f7e12cb  
    6161                }
    6262
    63                 void find( Expression *expr, bool adjust = false, bool prune = true );
     63                void find( Expression *expr, bool adjust = false, bool prune = true, bool failFast = true );
    6464                /// Calls find with the adjust flag set; adjustment turns array and function types into equivalent pointer types
    65                 void findWithAdjustment( Expression *expr, bool prune = true );
     65                void findWithAdjustment( Expression *expr );
     66                /// Calls find with the adjust flag set and prune flag unset; pruning ensures there is at most one alternative per result type
     67                void findWithoutPrune( Expression *expr );
     68                /// Calls find with the adjust and prune flags set, failFast flags unset; fail fast ensures that there is at least one resulting alternative
     69                void maybeFind( Expression *expr );
    6670                AltList &get_alternatives() { return alternatives; }
    6771
     
    7781                const SymTab::Indexer &get_indexer() const { return indexer; }
    7882                const TypeEnvironment &get_environ() const { return env; }
     83
     84                /// Runs a new alternative finder on each element in [begin, end)
     85                /// and writes each alternative finder to out.
     86                template< typename InputIterator, typename OutputIterator >
     87                void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    7988          private:
    8089                virtual void visit( ApplicationExpr *applicationExpr );
     
    108117                virtual void visit( StmtExpr *stmtExpr );
    109118                virtual void visit( UntypedInitExpr *initExpr );
    110                 /// Runs a new alternative finder on each element in [begin, end)
    111                 /// and writes each alternative finder to out.
    112                 template< typename InputIterator, typename OutputIterator >
    113                 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    114119
    115120                /// Adds alternatives for anonymous members
     
    134139
    135140        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env );
     141        void referenceToRvalueConversion( Expression *& expr );
    136142
    137143        template< typename InputIterator, typename OutputIterator >
  • src/ResolvExpr/CastCost.cc

    r78315272 r3f7e12cb  
    2424#include "typeops.h"                     // for typesCompatibleIgnoreQualifiers
    2525
     26#if 0
     27#define PRINT(x) x
     28#else
     29#define PRINT(x)
     30#endif
    2631
    2732namespace ResolvExpr {
     
    5257                        } // if
    5358                } // if
     59
     60                PRINT(
     61                        std::cerr << "castCost ::: src is ";
     62                        src->print( std::cerr );
     63                        std::cerr << std::endl << "dest is ";
     64                        dest->print( std::cerr );
     65                        std::cerr << std::endl << "env is" << std::endl;
     66                        env.print( std::cerr, 8 );
     67                )
     68
    5469                if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) {
     70                        PRINT( std::cerr << "compatible!" << std::endl; )
    5571                        return Cost::zero;
    5672                } else if ( dynamic_cast< VoidType* >( dest ) ) {
    5773                        return Cost::safe;
    5874                } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
     75                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    5976                        return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer & indexer) {
    6077                                return ptrsCastable( t1, t2, env, indexer );
  • src/ResolvExpr/CommonType.cc

    r78315272 r3f7e12cb  
    1010// Created On       : Sun May 17 06:59:27 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 16:24:31 2017
    13 // Update Count     : 7
     12// Last Modified On : Mon Sep 25 15:18:17 2017
     13// Update Count     : 9
    1414//
    1515
     
    6161        };
    6262
    63         Type * handleReference( ReferenceType * refType, Type * other, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) {
    64                 Type * result = nullptr, * common = nullptr;
     63        Type * handleReference( Type * t1, Type * t2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment & env, const OpenVarSet &openVars ) {
     64                Type * common = nullptr;
    6565                AssertionSet have, need;
    6666                OpenVarSet newOpen( openVars );
    6767                // need unify to bind type variables
    68                 if ( unify( refType->get_base(), other, env, have, need, newOpen, indexer, common ) ) {
    69                         // std::cerr << "unify success" << std::endl;
    70                         if ( widenSecond ) {
    71                                 // std::cerr << "widen second" << std::endl;
    72                                 if ( widenFirst || other->get_qualifiers() <= refType->get_qualifiers() ) {
    73                                         result = new ReferenceType( refType->get_qualifiers(), common ); // refType->clone();
    74                                         result->get_qualifiers() |= other->get_qualifiers();
    75                                 }
    76                         } else if ( widenFirst ) {
    77                                 // std::cerr << "widen first" << std::endl;
    78                                 if ( widenSecond || refType->get_qualifiers() <= other->get_qualifiers() ) {
    79                                         result = common;
    80                                         result->get_qualifiers() |= refType->get_qualifiers();
    81                                 }
    82                         }
    83                 } else {
    84                         // std::cerr << "exact unify failed: " << refType << " " << other << std::endl;
    85                 }
    86                 // std::cerr << "common type of reference [" << refType << "] and non-reference [" << other << "] is [" << result << "]" << std::endl;
    87                 return result;
     68                if ( unify( t1, t2, env, have, need, newOpen, indexer, common ) ) {
     69                        // std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
     70                        if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {
     71                                // std::cerr << "widen okay" << std::endl;
     72                                common->get_qualifiers() |= t1->get_qualifiers();
     73                                common->get_qualifiers() |= t2->get_qualifiers();
     74                                return common;
     75                        }
     76                }
     77                // std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
     78                return nullptr;
    8879        }
    8980
     
    9990
    10091                        // special case where one type has a reference depth of 1 larger than the other
    101                         if ( diff > 0 ) {
    102                                 return handleReference( strict_dynamic_cast<ReferenceType *>( type1 ), type2, widenFirst, widenSecond, indexer, env, openVars );
    103                         } else if ( diff < 0 ) {
    104                                 return handleReference( strict_dynamic_cast<ReferenceType *>( type2 ), type1, widenSecond, widenFirst, indexer, env, openVars );
     92                        if ( diff > 0 || diff < 0 ) {
     93                                Type * result = nullptr;
     94                                if ( ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 ) ) {
     95                                        // formal is reference, so result should be reference
     96                                        result = handleReference( ref1->base, type2, widenFirst, widenSecond, indexer, env, openVars );
     97                                        if ( result ) result = new ReferenceType( ref1->get_qualifiers(), result );
     98                                } else {
     99                                        // formal is value, so result should be value
     100                                        ReferenceType * ref2 = strict_dynamic_cast< ReferenceType * > ( type2 );
     101                                        result = handleReference( type1, ref2->base, widenFirst, widenSecond, indexer, env, openVars );
     102                                }
     103                                // std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl;
     104                                return result;
    105105                        }
    106106                        // otherwise, both are reference types of the same depth and this is handled by the CommonType visitor.
     
    150150        static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
    151151        {
    152 /*              Bool            Char    SignedChar      UnsignedChar    ShortSignedInt  ShortUnsignedInt        SignedInt       UnsignedInt     LongSignedInt   LongUnsignedInt LongLongSignedInt       LongLongUnsignedInt     Float   Double  LongDouble      FloatComplex    DoubleComplex   LongDoubleComplex       FloatImaginary  DoubleImaginary LongDoubleImaginary */
    153                 /* Bool */      { BasicType::Bool,              BasicType::Char,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    154                 /* Char */      { BasicType::Char,              BasicType::Char,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    155                 /* SignedChar */        { BasicType::SignedChar,        BasicType::UnsignedChar,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    156                 /* UnsignedChar */      { BasicType::UnsignedChar,      BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    157                 /* ShortSignedInt */    { BasicType::ShortSignedInt,    BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    158                 /* ShortUnsignedInt */  { BasicType::ShortUnsignedInt,  BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    159                 /* SignedInt */         { BasicType::SignedInt,         BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    160                 /* UnsignedInt */       { BasicType::UnsignedInt,               BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    161                 /* LongSignedInt */     { BasicType::LongSignedInt,             BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    162                 /* LongUnsignedInt */   { BasicType::LongUnsignedInt,   BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    163                 /* LongLongSignedInt */         { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    164                 /* LongLongUnsignedInt */       { BasicType::LongLongUnsignedInt,       BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    165                 /* Float */     { BasicType::Float,     BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    166                 /* Double */    { BasicType::Double,    BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::LongDouble,  BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    167                 /* LongDouble */        { BasicType::LongDouble,                BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex },
    168                 /* FloatComplex */      { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    169                 /* DoubleComplex */     { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex },
    170                 /* LongDoubleComplex */         { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex },
    171                 /* FloatImaginary */    { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatImaginary,      BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary },
    172                 /* DoubleImaginary */   { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleImaginary,     BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary },
    173                 /* LongDoubleImaginary */       { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary }
     152/*              Bool            Char    SignedChar      UnsignedChar    ShortSignedInt  ShortUnsignedInt        SignedInt       UnsignedInt     LongSignedInt   LongUnsignedInt LongLongSignedInt       LongLongUnsignedInt     Float   Double  LongDouble      FloatComplex    DoubleComplex   LongDoubleComplex       FloatImaginary  DoubleImaginary LongDoubleImaginary   SignedInt128   UnsignedInt128 */
     153                /* Bool */      { BasicType::Bool,              BasicType::Char,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     154                /* Char */      { BasicType::Char,              BasicType::Char,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     155                /* SignedChar */        { BasicType::SignedChar,        BasicType::UnsignedChar,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     156                /* UnsignedChar */      { BasicType::UnsignedChar,      BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     157                /* ShortSignedInt */    { BasicType::ShortSignedInt,    BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     158                /* ShortUnsignedInt */  { BasicType::ShortUnsignedInt,  BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     159                /* SignedInt */         { BasicType::SignedInt,         BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     160                /* UnsignedInt */       { BasicType::UnsignedInt,               BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     161                /* LongSignedInt */     { BasicType::LongSignedInt,             BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     162                /* LongUnsignedInt */   { BasicType::LongUnsignedInt,   BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     163                /* LongLongSignedInt */         { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     164                /* LongLongUnsignedInt */       { BasicType::LongLongUnsignedInt,       BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     165                /* Float */     { BasicType::Float,     BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::Float,       BasicType::Float, },
     166                /* Double */    { BasicType::Double,    BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::LongDouble,  BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::Double,      BasicType::Double, },
     167                /* LongDouble */        { BasicType::LongDouble,                BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDouble,  BasicType::LongDouble, },
     168                /* FloatComplex */      { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::FloatComplex, },
     169                /* DoubleComplex */     { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex, },
     170                /* LongDoubleComplex */         { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex, },
     171                /* FloatImaginary */    { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatImaginary,      BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary, BasicType::FloatImaginary,      BasicType::FloatImaginary, },
     172                /* DoubleImaginary */   { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleImaginary,     BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary, BasicType::DoubleImaginary,     BasicType::DoubleImaginary, },
     173                /* LongDoubleImaginary */       { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary },
     174                /* SignedInt128 */      { BasicType::SignedInt128,      BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
     175                /* UnsignedInt128 */    { BasicType::UnsignedInt128,    BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::UnsignedInt128,      BasicType::UnsignedInt128, },
    174176        };
    175177
  • src/ResolvExpr/ConversionCost.cc

    r78315272 r3f7e12cb  
    1010// Created On       : Sun May 17 07:06:19 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:35:46 2016
    13 // Update Count     : 6
     12// Last Modified On : Mon Sep 25 15:43:34 2017
     13// Update Count     : 10
    1414//
    1515
     
    2828
    2929namespace ResolvExpr {
    30         const Cost Cost::zero = Cost( 0, 0, 0, 0 );
    31         const Cost Cost::infinity = Cost( -1, -1, -1, -1 );
    32         const Cost Cost::unsafe = Cost( 1, 0, 0, 0 );
    33         const Cost Cost::poly = Cost( 0, 1, 0, 0 );
    34         const Cost Cost::safe = Cost( 0, 0, 1, 0 );
    35         const Cost Cost::reference = Cost( 0, 0, 0, 1 );
     30        const Cost Cost::zero =      Cost(  0,  0,  0, 0 );
     31        const Cost Cost::infinity =  Cost( -1, -1, -1, -1 );
     32        const Cost Cost::unsafe =    Cost(  1,  0,  0, 0 );
     33        const Cost Cost::poly =      Cost(  0,  1,  0, 0 );
     34        const Cost Cost::safe =      Cost(  0,  0,  1, 0 );
     35        const Cost Cost::reference = Cost(  0,  0,  0, 1 );
    3636
    3737#if 0
     
    113113                                        int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer );
    114114                                        PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; )
    115                                         if ( assignResult < 0 ) {
     115                                        if ( assignResult > 0 ) {
    116116                                                return Cost::safe;
    117                                         } else if ( assignResult > 0 ) {
     117                                        } else if ( assignResult < 0 ) {
    118118                                                return Cost::unsafe;
    119119                                        } // if
     
    219219*/
    220220
    221         static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
    222         {
    223         /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag */
    224                 /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              10,             11,             12,             11,             12,             13,             -1,             -1,             -1 },
    225                 /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              9,              10,             11,             10,             11,             12,             -1,             -1,             -1 },
    226                 /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              9,              10,             11,             10,             11,             12,             -1,             -1,             -1 },
    227                 /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              8,              9,              10,             9,              10,             11,             -1,             -1,             -1 },
    228                 /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              7,              8,              9,              8,              9,              10,             -1,             -1,             -1 },
    229                 /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              6,              7,              8,              7,              8,              9,              -1,             -1,             -1 },
    230                 /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              5,              6,              7,              6,              7,              8,              -1,             -1,             -1 },
    231                 /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              4,              5,              6,              5,              6,              7,              -1,             -1,             -1 },
    232                 /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              5,              6,              5,              6,              7,              -1,             -1,             -1 },
    233                 /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              5,              4,              5,              6,              -1,             -1,             -1 },
    234                 /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              4,              3,              4,              5,              -1,             -1,             -1 },
    235                 /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              2,              3,              4,              -1,             -1,             -1 },
    236                 /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1 },
    237                 /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1 },
    238                 /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1 },
    239                 /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1 },
    240                 /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1 },
    241                 /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1 },
    242                 /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2 },
    243                 /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1 },
    244                 /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0 }
     221        static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
     222        /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag  I128,   U128 */
     223                /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              12,             13,             14,             12,             13,             14,             -1,             -1,             -1,             10,             11,     },
     224                /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,     },
     225                /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,     },
     226                /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              10,             11,             12,             10,             11,             12,             -1,             -1,             -1,             8,              9,      },
     227                /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              9,              10,             11,             9,              10,             11,             -1,             -1,             -1,             7,              8,      },
     228                /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              8,              9,              10,             8,              9,              10,             -1,             -1,             -1,             6,              7,      },
     229                /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              7,              8,              9,              7,              8,              9,              -1,             -1,             -1,             5,              6,      },
     230                /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,      },
     231                /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,      },
     232                /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              5,              6,              7,              5,              6,              7,              -1,             -1,             -1,             3,              4,      },
     233                /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              4,              5,              6,              4,              5,              6,              -1,             -1,             -1,             2,              3,      },
     234                /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              3,              4,              5,              3,              4,              5,              -1,             -1,             -1,             1,              2,      },
     235
     236                /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1,             -1,             -1,     },
     237                /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1,             -1,             -1,     },
     238                /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,     },
     239                /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1,             -1,             -1,     },
     240                /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1,             -1,             -1,     },
     241                /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1,             -1,             -1,     },
     242                /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2,              -1,             -1,     },
     243                /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1,              -1,             -1,     },
     244                /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0,              -1,             -1,     },
     245
     246                /* I128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             2,              3,              4,              3,              4,              5,              -1,             -1,             -1,             0,              1,      },
     247                /* U128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              2,              3,              4,              -1,             -1,             -1,             -1,             0,      },
    245248        };
    246249
     
    266269        }
    267270
    268         void ConversionCost::visit(PointerType *pointerType) {
     271        void ConversionCost::visit( PointerType * pointerType ) {
    269272                if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    270273                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr; )
     
    281284                                }
    282285                        } else {  // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right?
    283                                 int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env );
     286                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
    284287                                PRINT( std::cerr << " :: " << assignResult << std::endl; )
    285                                 if ( assignResult < 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
     288                                if ( assignResult > 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) {
    286289                                        cost = Cost::safe;
    287                                 } else if ( assignResult > 0 ) {
     290                                } else if ( assignResult < 0 ) {
    288291                                        cost = Cost::unsafe;
    289292                                } // if
    290293                                // assignResult == 0 means Cost::Infinity
    291294                        } // if
    292                 } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) {
     295                } else if ( dynamic_cast< ZeroType * >( dest ) ) {
    293296                        cost = Cost::unsafe;
    294297                } // if
    295298        }
    296299
    297         void ConversionCost::visit(__attribute((unused)) ArrayType *arrayType) {}
    298 
    299         void ConversionCost::visit(ReferenceType *refType) {
     300        void ConversionCost::visit( ArrayType * ) {}
     301
     302        void ConversionCost::visit( ReferenceType * refType ) {
    300303                // Note: dest can never be a reference, since it would have been caught in an earlier check
    301304                assert( ! dynamic_cast< ReferenceType * >( dest ) );
     
    303306                // recursively compute conversion cost from T1 to T2.
    304307                // cv can be safely dropped because of 'implicit dereference' behavior.
    305                 refType->get_base()->accept( *this );
    306                 if ( refType->get_base()->get_qualifiers() == dest->get_qualifiers() ) {
     308                refType->base->accept( *this );
     309                if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
    307310                        cost.incReference();  // prefer exact qualifiers
    308                 } else if ( refType->get_base()->get_qualifiers() < dest->get_qualifiers() ) {
     311                } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
    309312                        cost.incSafe(); // then gaining qualifiers
    310313                } else {
     
    314317        }
    315318
    316         void ConversionCost::visit(__attribute((unused)) FunctionType *functionType) {}
    317 
    318         void ConversionCost::visit(StructInstType *inst) {
     319        void ConversionCost::visit( FunctionType * ) {}
     320
     321        void ConversionCost::visit( StructInstType * inst ) {
    319322                if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    320                         if ( inst->get_name() == destAsInst->get_name() ) {
    321                                 cost = Cost::zero;
    322                         } // if
    323                 } // if
    324         }
    325 
    326         void ConversionCost::visit(UnionInstType *inst) {
    327                 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
    328                         if ( inst->get_name() == destAsInst->get_name() ) {
    329                                 cost = Cost::zero;
    330                         } // if
    331                 } // if
    332         }
    333 
    334         void ConversionCost::visit( __attribute((unused)) EnumInstType *inst ) {
     323                        if ( inst->name == destAsInst->name ) {
     324                                cost = Cost::zero;
     325                        } // if
     326                } // if
     327        }
     328
     329        void ConversionCost::visit( UnionInstType * inst ) {
     330                if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
     331                        if ( inst->name == destAsInst->name ) {
     332                                cost = Cost::zero;
     333                        } // if
     334                } // if
     335        }
     336
     337        void ConversionCost::visit( EnumInstType * ) {
    335338                static Type::Qualifiers q;
    336339                static BasicType integer( q, BasicType::SignedInt );
     
    341344        }
    342345
    343         void ConversionCost::visit( __attribute((unused)) TraitInstType *inst) {
    344         }
    345 
    346         void ConversionCost::visit(TypeInstType *inst) {
     346        void ConversionCost::visit( TraitInstType * ) {}
     347
     348        void ConversionCost::visit( TypeInstType *inst ) {
    347349                EqvClass eqvClass;
    348350                NamedTypeDecl *namedType;
     
    363365        }
    364366
    365         void ConversionCost::visit( __attribute((unused)) TupleType *tupleType) {
     367        void ConversionCost::visit( TupleType * tupleType ) {
    366368                Cost c = Cost::zero;
    367                 if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {
    368                         std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin();
    369                         std::list< Type* >::const_iterator destIt = destAsTuple->get_types().begin();
     369                if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
     370                        std::list< Type * >::const_iterator srcIt = tupleType->get_types().begin();
     371                        std::list< Type * >::const_iterator destIt = destAsTuple->get_types().begin();
    370372                        while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) {
    371373                                Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env );
     
    383385        }
    384386
    385         void ConversionCost::visit( __attribute((unused)) VarArgsType *varArgsType) {
     387        void ConversionCost::visit( VarArgsType * ) {
    386388                if ( dynamic_cast< VarArgsType* >( dest ) ) {
    387389                        cost = Cost::zero;
     
    389391        }
    390392
    391         void ConversionCost::visit( __attribute((unused)) ZeroType *zeroType) {
    392                 if ( dynamic_cast< ZeroType* >( dest ) ) {
     393        void ConversionCost::visit( ZeroType * ) {
     394                if ( dynamic_cast< ZeroType * >( dest ) ) {
    393395                        cost = Cost::zero;
    394396                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     
    406408        }
    407409
    408         void ConversionCost::visit( __attribute((unused)) OneType *oneType) {
    409                 if ( dynamic_cast< OneType* >( dest ) ) {
     410        void ConversionCost::visit( OneType * ) {
     411                if ( dynamic_cast< OneType * >( dest ) ) {
    410412                        cost = Cost::zero;
    411413                } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
  • src/ResolvExpr/CurrentObject.cc

    r78315272 r3f7e12cb  
    260260
    261261                AggregateIterator( const std::string & kind, const std::string & name, Type * inst, const MemberList & members ) : kind( kind ), name( name ), inst( inst ), members( members ), curMember( members.begin() ), sub( makeGenericSubstitution( inst ) ) {
     262                        PRINT( std::cerr << "Creating " << kind << "(" << name << ")"; )
    262263                        init();
    263264                }
  • src/ResolvExpr/PolyCost.cc

    r78315272 r3f7e12cb  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // PolyCost.cc -- 
     7// PolyCost.cc --
    88//
    99// Author           : Richard C. Bilson
     
    3131        };
    3232
    33         int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     33        int polyCost( Type *type, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {
    3434                PolyCost coster( env, indexer );
    3535                type->accept( coster );
     
    3737        }
    3838
    39         PolyCost::PolyCost( const TypeEnvironment &env, const SymTab::Indexer &indexer ) : result( 0 ), env( env ), indexer( indexer ) {
     39        PolyCost::PolyCost( const TypeEnvironment & env, const SymTab::Indexer & indexer ) : result( 0 ), env( env ), indexer( indexer ) {
    4040        }
    4141
    42         void PolyCost::visit(TypeInstType *typeInst) {
     42        void PolyCost::visit(TypeInstType * typeInst) {
    4343                EqvClass eqvClass;
    44                 if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     44                if ( env.lookup( typeInst->name, eqvClass ) ) {
    4545                        if ( eqvClass.type ) {
    46                                 if ( TypeInstType *otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
    47                                         if ( indexer.lookupType( otherTypeInst->get_name() ) ) {
     46                                if ( TypeInstType * otherTypeInst = dynamic_cast< TypeInstType* >( eqvClass.type ) ) {
     47                                        if ( indexer.lookupType( otherTypeInst->name ) ) {
     48                                                // bound to opaque type
    4849                                                result += 1;
    4950                                        } // if
    5051                                } else {
     52                                        // bound to concrete type
    5153                                        result += 1;
    5254                                } // if
  • src/ResolvExpr/PtrsAssignable.cc

    r78315272 r3f7e12cb  
    4747
    4848        int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
     49                // std::cerr << "assignable: " << src << " | " << dest << std::endl;
    4950                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    5051                        EqvClass eqvClass;
     
    5455                } // if
    5556                if ( dynamic_cast< VoidType* >( dest ) ) {
    56                         return 1;
     57                        // void * = T * for any T is unsafe
     58                        // xxx - this should be safe, but that currently breaks the build
     59                        return -1;
    5760                } else {
    5861                        PtrsAssignable ptrs( dest, env );
     
    6568
    6669        void PtrsAssignable::visit( __attribute((unused)) VoidType *voidType ) {
    67                 if ( dynamic_cast< FunctionType* >( dest ) ) {
    68                         result = 0;
    69                 } else {
    70                         result = -1;
     70                if ( ! dynamic_cast< FunctionType* >( dest ) ) {
     71                        // T * = void * is safe for any T that is not a function type.
     72                        // xxx - this should be unsafe...
     73                        result = 1;
    7174                } // if
    7275        }
     
    7578        void PtrsAssignable::visit( __attribute__((unused)) PointerType *pointerType ) {}
    7679        void PtrsAssignable::visit( __attribute__((unused)) ArrayType *arrayType ) {}
    77         void PtrsAssignable::visit( __attribute__((unused)) FunctionType *functionType ) {
    78                 result = -1;
    79         }
     80        void PtrsAssignable::visit( __attribute__((unused)) FunctionType *functionType ) {}
    8081
    8182        void PtrsAssignable::visit(  __attribute__((unused)) StructInstType *inst ) {}
     
    8384
    8485        void PtrsAssignable::visit( EnumInstType * ) {
    85                 if ( dynamic_cast< EnumInstType* >( dest ) ) {
     86                if ( dynamic_cast< BasicType* >( dest ) ) {
     87                        // int * = E *, etc. is safe. This isn't technically correct, as each
     88                        // enum has one basic type that it is compatible with, an that type can
     89                        // differ from enum to enum. Without replicating GCC's internal logic,
     90                        // there is no way to know which type this particular enum is compatible
     91                        // with, so punt on this for now.
    8692                        result = 1;
    87                 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
    88                         result = bt->get_kind() == BasicType::SignedInt;
    8993                }
    9094        }
     
    9498                EqvClass eqvClass;
    9599                if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) {
     100                        // T * = S * for any S depends on the type bound to T
    96101                        result = ptrsAssignable( eqvClass.type, dest, env );
    97                 } else {
    98                         result = 0;
    99102                } // if
    100103        }
  • src/ResolvExpr/PtrsCastable.cc

    r78315272 r3f7e12cb  
    5050        };
    5151
    52         int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    53                 if ( dynamic_cast< FunctionType* >( src ) ) {
    54                         return -1;
    55                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
    56                         EqvClass eqvClass;
    57                         if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    58                                 if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    59                                         if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     52        namespace {
     53                int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     54                        if ( dynamic_cast< FunctionType* >( src ) ) {
     55                                return -1;
     56                        } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
     57                                EqvClass eqvClass;
     58                                if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     59                                        if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
     60                                                if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     61                                                        return -1;
     62                                                } // if
     63                                        } //if
     64                                } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     65                                        if ( eqvClass.data.kind == TypeDecl::Ftype ) {
    6066                                                return -1;
    6167                                        } // if
    62                                 } //if
    63                         } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
    64                                 if ( eqvClass.data.kind == TypeDecl::Ftype ) {
    65                                         return -1;
    6668                                } // if
    67                         } // if
    68                 } //if
    69                 return 1;
    70         }
    71         int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    72                 return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
     69                        } //if
     70                        return 1;
     71                }
     72                int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     73                        return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
     74                }
    7375        }
    7476
     
    9395        }
    9496
    95         void PtrsCastable::visit( __attribute__((unused)) VoidType *voidType) {
     97        void PtrsCastable::visit( VoidType * ) {
    9698                result = objectCast( dest, env, indexer );
    9799        }
    98100
    99         void PtrsCastable::visit( __attribute__((unused)) BasicType *basicType) {
     101        void PtrsCastable::visit( BasicType * ) {
    100102                result = objectCast( dest, env, indexer );
    101103        }
    102104
    103         void PtrsCastable::visit( __attribute__((unused)) PointerType *pointerType) {
     105        void PtrsCastable::visit( PointerType * ) {
    104106                result = objectCast( dest, env, indexer );
    105107        }
    106108
    107         void PtrsCastable::visit( __attribute__((unused)) ArrayType *arrayType) {
     109        void PtrsCastable::visit( ArrayType * ) {
    108110                result = objectCast( dest, env, indexer );
    109111        }
    110112
    111         void PtrsCastable::visit( __attribute__((unused)) FunctionType *functionType) {
     113        void PtrsCastable::visit( FunctionType * ) {
    112114                // result = -1;
    113115                result = functionCast( dest, env, indexer );
    114116        }
    115117
    116         void PtrsCastable::visit( __attribute__((unused)) StructInstType *inst) {
     118        void PtrsCastable::visit( StructInstType * ) {
    117119                result = objectCast( dest, env, indexer );
    118120        }
    119121
    120         void PtrsCastable::visit( __attribute__((unused)) UnionInstType *inst) {
     122        void PtrsCastable::visit( UnionInstType * ) {
    121123                result = objectCast( dest, env, indexer );
    122124        }
    123125
    124         void PtrsCastable::visit( __attribute__((unused)) EnumInstType *inst) {
     126        void PtrsCastable::visit( EnumInstType * ) {
    125127                if ( dynamic_cast< EnumInstType* >( dest ) ) {
    126128                        result = 1;
     
    136138        }
    137139
    138         void PtrsCastable::visit( __attribute__((unused)) TraitInstType *inst ) {}
     140        void PtrsCastable::visit( TraitInstType * ) {}
    139141
    140142        void PtrsCastable::visit(TypeInstType *inst) {
     
    143145        }
    144146
    145         void PtrsCastable::visit( __attribute__((unused)) TupleType *tupleType) {
     147        void PtrsCastable::visit( TupleType * ) {
    146148                result = objectCast( dest, env, indexer );
    147149        }
    148150
    149         void PtrsCastable::visit( __attribute__((unused)) VarArgsType *varArgsType) {
     151        void PtrsCastable::visit( VarArgsType * ) {
    150152                result = objectCast( dest, env, indexer );
    151153        }
    152154
    153         void PtrsCastable::visit( __attribute__((unused)) ZeroType *zeroType) {
     155        void PtrsCastable::visit( ZeroType * ) {
    154156                result = objectCast( dest, env, indexer );
    155157        }
    156158
    157         void PtrsCastable::visit( __attribute__((unused)) OneType *oneType) {
     159        void PtrsCastable::visit( OneType * ) {
    158160                result = objectCast( dest, env, indexer );
    159161        }
  • src/ResolvExpr/ResolveTypeof.cc

    r78315272 r3f7e12cb  
    1818#include <cassert>               // for assert
    1919
     20#include "Common/PassVisitor.h"  // for PassVisitor
    2021#include "Resolver.h"            // for resolveInVoidContext
    2122#include "SynTree/Expression.h"  // for Expression
     
    4142        }
    4243
    43         class ResolveTypeof : public Mutator {
     44        class ResolveTypeof : public WithShortCircuiting {
    4445          public:
    4546                ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
    46                 Type *mutate( TypeofType *typeofType );
     47                void premutate( TypeofType *typeofType );
     48                Type * postmutate( TypeofType *typeofType );
    4749
    4850          private:
     
    5052        };
    5153
    52         Type *resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
    53                 ResolveTypeof mutator( indexer );
     54        Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
     55                PassVisitor<ResolveTypeof> mutator( indexer );
    5456                return type->acceptMutator( mutator );
    5557        }
    5658
    57         Type *ResolveTypeof::mutate( TypeofType *typeofType ) {
     59        void ResolveTypeof::premutate( TypeofType * ) {
     60                visit_children = false;
     61        }
     62
     63        Type * ResolveTypeof::postmutate( TypeofType *typeofType ) {
    5864#if 0
    59                 std::cout << "resolving typeof: ";
    60                 typeofType->print( std::cout );
    61                 std::cout << std::endl;
     65                std::cerr << "resolving typeof: ";
     66                typeofType->print( std::cerr );
     67                std::cerr << std::endl;
    6268#endif
    63                 if ( typeofType->get_expr() ) {
    64                         Expression *newExpr = resolveInVoidContext( typeofType->get_expr(), indexer );
    65                         assert( newExpr->has_result() && ! newExpr->get_result()->isVoid() );
    66                         Type *newType = newExpr->get_result();
    67                         newExpr->set_result( nullptr );
     69                if ( typeofType->expr ) {
     70                        Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );
     71                        assert( newExpr->result && ! newExpr->result->isVoid() );
     72                        Type * newType = newExpr->result;
     73                        newExpr->result = nullptr;
    6874                        delete typeofType;
    6975                        delete newExpr;
  • src/ResolvExpr/Resolver.cc

    r78315272 r3f7e12cb  
    4040#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    4141#include "typeops.h"                     // for extractResultType
     42#include "Unify.h"                       // for unify
    4243
    4344using namespace std;
     
    5253                void previsit( FunctionDecl *functionDecl );
    5354                void postvisit( FunctionDecl *functionDecl );
    54                 void previsit( ObjectDecl *functionDecl );
     55                void previsit( ObjectDecl *objectDecll );
    5556                void previsit( TypeDecl *typeDecl );
    5657                void previsit( EnumDecl * enumDecl );
     
    7172                void previsit( ThrowStmt *throwStmt );
    7273                void previsit( CatchStmt *catchStmt );
     74                void previsit( WaitForStmt * stmt );
    7375
    7476                void previsit( SingleInit *singleInit );
     
    9597        }
    9698
     99        void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
     100                PassVisitor<Resolver> resolver( indexer );
     101                maybeAccept( decl, resolver );
     102        }
     103
    97104        // used in resolveTypeof
    98105        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
     
    102109
    103110        namespace {
    104                 void finishExpr( Expression *expr, const TypeEnvironment &env ) {
    105                         expr->set_env( new TypeSubstitution );
     111                void finishExpr( Expression *expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
     112                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    106113                        env.makeSubstitution( *expr->get_env() );
    107114                }
     115
     116                void removeExtraneousCast( Expression *& expr, const SymTab::Indexer & indexer ) {
     117                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
     118                                if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {
     119                                        // cast is to the same type as its argument, so it's unnecessary -- remove it
     120                                        expr = castExpr->arg;
     121                                        castExpr->arg = nullptr;
     122                                        std::swap( expr->env, castExpr->env );
     123                                        delete castExpr;
     124                                }
     125                        }
     126                }
    108127        } // namespace
    109128
    110         Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     129        void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
    111130                global_renamer.reset();
    112131                TypeEnvironment env;
    113132                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    114                 finishExpr( newExpr, env );
    115                 return newExpr;
     133                finishExpr( newExpr, env, untyped->env );
     134                delete untyped;
     135                untyped = newExpr;
     136        }
     137
     138        void findSingleExpression( Expression *&untyped, const SymTab::Indexer &indexer ) {
     139                if ( ! untyped ) return;
     140                TypeEnvironment env;
     141                AlternativeFinder finder( indexer, env );
     142                finder.find( untyped );
     143                #if 0
     144                if ( finder.get_alternatives().size() != 1 ) {
     145                        std::cerr << "untyped expr is ";
     146                        untyped->print( std::cerr );
     147                        std::cerr << std::endl << "alternatives are:";
     148                        for ( const Alternative & alt : finder.get_alternatives() ) {
     149                                alt.print( std::cerr );
     150                        } // for
     151                } // if
     152                #endif
     153                assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );
     154                Alternative &choice = finder.get_alternatives().front();
     155                Expression *newExpr = choice.expr->clone();
     156                finishExpr( newExpr, choice.env, untyped->env );
     157                delete untyped;
     158                untyped = newExpr;
     159        }
     160
     161        void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) {
     162                assert( untyped && type );
     163                untyped = new CastExpr( untyped, type );
     164                findSingleExpression( untyped, indexer );
     165                removeExtraneousCast( untyped, indexer );
    116166        }
    117167
    118168        namespace {
    119                 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    120                         TypeEnvironment env;
    121                         AlternativeFinder finder( indexer, env );
    122                         finder.find( untyped );
    123 #if 0
    124                         if ( finder.get_alternatives().size() != 1 ) {
    125                                 std::cout << "untyped expr is ";
    126                                 untyped->print( std::cout );
    127                                 std::cout << std::endl << "alternatives are:";
    128                                 for ( std::list< Alternative >::const_iterator i = finder.get_alternatives().begin(); i != finder.get_alternatives().end(); ++i ) {
    129                                         i->print( std::cout );
    130                                 } // for
    131                         } // if
    132 #endif
    133                         assertf( finder.get_alternatives().size() == 1, "findSingleExpression: must have exactly one alternative at the end." );
    134                         Alternative &choice = finder.get_alternatives().front();
    135                         Expression *newExpr = choice.expr->clone();
    136                         finishExpr( newExpr, choice.env );
    137                         return newExpr;
    138                 }
    139 
    140169                bool isIntegralType( Type *type ) {
    141170                        if ( dynamic_cast< EnumInstType * >( type ) ) {
     
    150179                }
    151180
    152                 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     181                void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
    153182                        TypeEnvironment env;
    154183                        AlternativeFinder finder( indexer, env );
     
    179208                                throw SemanticError( "No interpretations for case control expression", untyped );
    180209                        } // if
    181                         finishExpr( newExpr, *newEnv );
    182                         return newExpr;
     210                        finishExpr( newExpr, *newEnv, untyped->env );
     211                        delete untyped;
     212                        untyped = newExpr;
    183213                }
    184214
     
    205235        void Resolver::handlePtrType( PtrType * type ) {
    206236                if ( type->get_dimension() ) {
    207                         CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
    208                         Expression *newExpr = findSingleExpression( castExpr, indexer );
    209                         delete type->get_dimension();
    210                         type->set_dimension( newExpr );
     237                        findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
    211238                }
    212239        }
     
    238265                functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() );
    239266        }
    240 
    241267
    242268        void Resolver::postvisit( FunctionDecl *functionDecl ) {
     
    262288        void Resolver::previsit( ExprStmt *exprStmt ) {
    263289                visit_children = false;
    264                 assertf( exprStmt->get_expr(), "ExprStmt has null Expression in resolver" );
    265                 Expression *newExpr = findVoidExpression( exprStmt->get_expr(), indexer );
    266                 delete exprStmt->get_expr();
    267                 exprStmt->set_expr( newExpr );
     290                assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" );
     291                findVoidExpression( exprStmt->expr, indexer );
    268292        }
    269293
    270294        void Resolver::previsit( AsmExpr *asmExpr ) {
    271295                visit_children = false;
    272                 Expression *newExpr = findVoidExpression( asmExpr->get_operand(), indexer );
    273                 delete asmExpr->get_operand();
    274                 asmExpr->set_operand( newExpr );
     296                findVoidExpression( asmExpr->operand, indexer );
    275297                if ( asmExpr->get_inout() ) {
    276                         newExpr = findVoidExpression( asmExpr->get_inout(), indexer );
    277                         delete asmExpr->get_inout();
    278                         asmExpr->set_inout( newExpr );
     298                        findVoidExpression( asmExpr->inout, indexer );
    279299                } // if
    280300        }
     
    287307
    288308        void Resolver::previsit( IfStmt *ifStmt ) {
    289                 Expression *newExpr = findSingleExpression( ifStmt->get_condition(), indexer );
    290                 delete ifStmt->get_condition();
    291                 ifStmt->set_condition( newExpr );
     309                findSingleExpression( ifStmt->condition, indexer );
    292310        }
    293311
    294312        void Resolver::previsit( WhileStmt *whileStmt ) {
    295                 Expression *newExpr = findSingleExpression( whileStmt->get_condition(), indexer );
    296                 delete whileStmt->get_condition();
    297                 whileStmt->set_condition( newExpr );
     313                findSingleExpression( whileStmt->condition, indexer );
    298314        }
    299315
    300316        void Resolver::previsit( ForStmt *forStmt ) {
    301                 if ( forStmt->get_condition() ) {
    302                         Expression * newExpr = findSingleExpression( forStmt->get_condition(), indexer );
    303                         delete forStmt->get_condition();
    304                         forStmt->set_condition( newExpr );
     317                if ( forStmt->condition ) {
     318                        findSingleExpression( forStmt->condition, indexer );
    305319                } // if
    306320
    307                 if ( forStmt->get_increment() ) {
    308                         Expression * newExpr = findVoidExpression( forStmt->get_increment(), indexer );
    309                         delete forStmt->get_increment();
    310                         forStmt->set_increment( newExpr );
     321                if ( forStmt->increment ) {
     322                        findVoidExpression( forStmt->increment, indexer );
    311323                } // if
    312324        }
     
    314326        void Resolver::previsit( SwitchStmt *switchStmt ) {
    315327                GuardValue( currentObject );
    316                 Expression *newExpr;
    317                 newExpr = findIntegralExpression( switchStmt->get_condition(), indexer );
    318                 delete switchStmt->get_condition();
    319                 switchStmt->set_condition( newExpr );
    320 
    321                 currentObject = CurrentObject( newExpr->get_result() );
     328                findIntegralExpression( switchStmt->condition, indexer );
     329
     330                currentObject = CurrentObject( switchStmt->condition->result );
    322331        }
    323332
     
    326335                        std::list< InitAlternative > initAlts = currentObject.getOptions();
    327336                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
    328                         CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    329                         Expression * newExpr = findSingleExpression( castExpr, indexer );
    330                         castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
    331                         caseStmt->set_condition( castExpr->get_arg() );
    332                         castExpr->set_arg( nullptr );
     337                        // must remove cast from case statement because RangeExpr cannot be cast.
     338                        Expression * newExpr = new CastExpr( caseStmt->condition, initAlts.front().type->clone() );
     339                        findSingleExpression( newExpr, indexer );
     340                        CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( newExpr );
     341                        caseStmt->condition = castExpr->arg;
     342                        castExpr->arg = nullptr;
    333343                        delete castExpr;
    334344                }
     
    339349                // must resolve the argument for a computed goto
    340350                if ( branchStmt->get_type() == BranchStmt::Goto ) { // check for computed goto statement
    341                         if ( Expression * arg = branchStmt->get_computedTarget() ) {
    342                                 VoidType v = Type::Qualifiers();                // cast to void * for the alternative finder
    343                                 PointerType pt( Type::Qualifiers(), v.clone() );
    344                                 CastExpr * castExpr = new CastExpr( arg, pt.clone() );
    345                                 Expression * newExpr = findSingleExpression( castExpr, indexer ); // find best expression
    346                                 branchStmt->set_target( newExpr );
     351                        if ( branchStmt->computedTarget ) {
     352                                // computed goto argument is void *
     353                                findSingleExpression( branchStmt->computedTarget, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), indexer );
    347354                        } // if
    348355                } // if
     
    351358        void Resolver::previsit( ReturnStmt *returnStmt ) {
    352359                visit_children = false;
    353                 if ( returnStmt->get_expr() ) {
    354                         CastExpr *castExpr = new CastExpr( returnStmt->get_expr(), functionReturn->clone() );
    355                         Expression *newExpr = findSingleExpression( castExpr, indexer );
    356                         delete castExpr;
    357                         returnStmt->set_expr( newExpr );
     360                if ( returnStmt->expr ) {
     361                        findSingleExpression( returnStmt->expr, functionReturn->clone(), indexer );
    358362                } // if
    359363        }
     
    366370                                indexer.lookupStruct( "__cfaehm__base_exception_t" );
    367371                        assert( exception_decl );
    368                         Expression * wrapped = new CastExpr(
    369                                 throwStmt->get_expr(),
    370                                 new PointerType(
    371                                         noQualifiers,
    372                                         new StructInstType(
    373                                                 noQualifiers,
    374                                                 exception_decl
    375                                                 )
    376                                         )
    377                                 );
    378                         Expression * newExpr = findSingleExpression( wrapped, indexer );
    379                         throwStmt->set_expr( newExpr );
     372                        Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
     373                        findSingleExpression( throwStmt->expr, exceptType, indexer );
    380374                }
    381375        }
    382376
    383377        void Resolver::previsit( CatchStmt *catchStmt ) {
    384                 if ( catchStmt->get_cond() ) {
    385                         Expression * wrapped = new CastExpr(
    386                                 catchStmt->get_cond(),
    387                                 new BasicType( noQualifiers, BasicType::Bool )
    388                                 );
    389                         catchStmt->set_cond( findSingleExpression( wrapped, indexer ) );
     378                if ( catchStmt->cond ) {
     379                        findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer );
     380                }
     381        }
     382
     383        template< typename iterator_t >
     384        inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) {
     385                while( it != end && !(*it)->get_type()->get_mutex() ) {
     386                        it++;
     387                }
     388
     389                return it != end;
     390        }
     391
     392        void Resolver::previsit( WaitForStmt * stmt ) {
     393                visit_children = false;
     394
     395                // Resolve all clauses first
     396                for( auto& clause : stmt->clauses ) {
     397
     398                        TypeEnvironment env;
     399                        AlternativeFinder funcFinder( indexer, env );
     400
     401                        // Find all alternatives for a function in canonical form
     402                        funcFinder.findWithAdjustment( clause.target.function );
     403
     404                        if ( funcFinder.get_alternatives().empty() ) {
     405                                stringstream ss;
     406                                ss << "Use of undeclared indentifier '";
     407                                ss << strict_dynamic_cast<NameExpr*>( clause.target.function )->name;
     408                                ss << "' in call to waitfor";
     409                                throw SemanticError( ss.str() );
     410                        }
     411
     412                        // Find all alternatives for all arguments in canonical form
     413                        std::list< AlternativeFinder > argAlternatives;
     414                        funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) );
     415
     416                        // List all combinations of arguments
     417                        std::list< AltList > possibilities;
     418                        combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) );
     419
     420                        AltList                func_candidates;
     421                        std::vector< AltList > args_candidates;
     422
     423                        // For every possible function :
     424                        //      try matching the arguments to the parameters
     425                        //      not the other way around because we have more arguments than parameters
     426                        SemanticError errors;
     427                        for ( Alternative & func : funcFinder.get_alternatives() ) {
     428                                try {
     429                                        PointerType * pointer = dynamic_cast< PointerType* >( func.expr->get_result()->stripReferences() );
     430                                        if( !pointer ) {
     431                                                throw SemanticError( "candidate not viable: not a pointer type\n", func.expr->get_result() );
     432                                        }
     433
     434                                        FunctionType * function = dynamic_cast< FunctionType* >( pointer->get_base() );
     435                                        if( !function ) {
     436                                                throw SemanticError( "candidate not viable: not a function type\n", pointer->get_base() );
     437                                        }
     438
     439
     440                                        {
     441                                                auto param     = function->parameters.begin();
     442                                                auto param_end = function->parameters.end();
     443
     444                                                if( !advance_to_mutex( param, param_end ) ) {
     445                                                        throw SemanticError("candidate function not viable: no mutex parameters\n", function);
     446                                                }
     447                                        }
     448
     449                                        Alternative newFunc( func );
     450                                        // Strip reference from function
     451                                        referenceToRvalueConversion( newFunc.expr );
     452
     453                                        // For all the set of arguments we have try to match it with the parameter of the current function alternative
     454                                        for ( auto & argsList : possibilities ) {
     455
     456                                                try {
     457                                                        // Declare data structures need for resolution
     458                                                        OpenVarSet openVars;
     459                                                        AssertionSet resultNeed, resultHave;
     460                                                        TypeEnvironment resultEnv;
     461
     462                                                        // Load type variables from arguemnts into one shared space
     463                                                        simpleCombineEnvironments( argsList.begin(), argsList.end(), resultEnv );
     464
     465                                                        // Make sure we don't widen any existing bindings
     466                                                        for ( auto & i : resultEnv ) {
     467                                                                i.allowWidening = false;
     468                                                        }
     469
     470                                                        // Find any unbound type variables
     471                                                        resultEnv.extractOpenVars( openVars );
     472
     473                                                        auto param     = function->parameters.begin();
     474                                                        auto param_end = function->parameters.end();
     475
     476                                                        // For every arguments of its set, check if it matches one of the parameter
     477                                                        // The order is important
     478                                                        for( auto & arg : argsList ) {
     479
     480                                                                // Ignore non-mutex arguments
     481                                                                if( !advance_to_mutex( param, param_end ) ) {
     482                                                                        // We ran out of parameters but still have arguments
     483                                                                        // this function doesn't match
     484                                                                        throw SemanticError("candidate function not viable: too many mutex arguments\n", function);
     485                                                                }
     486
     487                                                                // Check if the argument matches the parameter type in the current scope
     488                                                                if( ! unify( (*param)->get_type(), arg.expr->get_result(), resultEnv, resultNeed, resultHave, openVars, this->indexer ) ) {
     489                                                                        // Type doesn't match
     490                                                                        stringstream ss;
     491                                                                        ss << "candidate function not viable: no known convertion from '";
     492                                                                        arg.expr->get_result()->print( ss );
     493                                                                        ss << "' to '";
     494                                                                        (*param)->get_type()->print( ss );
     495                                                                        ss << "'\n";
     496                                                                        throw SemanticError(ss.str(), function);
     497                                                                }
     498
     499                                                                param++;
     500                                                        }
     501
     502                                                        // All arguments match !
     503
     504                                                        // Check if parameters are missing
     505                                                        if( advance_to_mutex( param, param_end ) ) {
     506                                                                // We ran out of arguments but still have parameters left
     507                                                                // this function doesn't match
     508                                                                throw SemanticError("candidate function not viable: too few mutex arguments\n", function);
     509                                                        }
     510
     511                                                        // All parameters match !
     512
     513                                                        // Finish the expressions to tie in the proper environments
     514                                                        finishExpr( newFunc.expr, resultEnv );
     515                                                        for( Alternative & alt : argsList ) {
     516                                                                finishExpr( alt.expr, resultEnv );
     517                                                        }
     518
     519                                                        // This is a match store it and save it for later
     520                                                        func_candidates.push_back( newFunc );
     521                                                        args_candidates.push_back( argsList );
     522
     523                                                }
     524                                                catch( SemanticError &e ) {
     525                                                        errors.append( e );
     526                                                }
     527                                        }
     528                                }
     529                                catch( SemanticError &e ) {
     530                                        errors.append( e );
     531                                }
     532                        }
     533
     534                        // Make sure we got the right number of arguments
     535                        if( func_candidates.empty() )    { SemanticError top( "No alternatives for function in call to waitfor"  ); top.append( errors ); throw top; }
     536                        if( args_candidates.empty() )    { SemanticError top( "No alternatives for arguments in call to waitfor" ); top.append( errors ); throw top; }
     537                        if( func_candidates.size() > 1 ) { SemanticError top( "Ambiguous function in call to waitfor"            ); top.append( errors ); throw top; }
     538                        if( args_candidates.size() > 1 ) { SemanticError top( "Ambiguous arguments in call to waitfor"           ); top.append( errors ); throw top; }
     539
     540
     541                        // Swap the results from the alternative with the unresolved values.
     542                        // Alternatives will handle deletion on destruction
     543                        std::swap( clause.target.function, func_candidates.front().expr );
     544                        for( auto arg_pair : group_iterate( clause.target.arguments, args_candidates.front() ) ) {
     545                                std::swap ( std::get<0>( arg_pair), std::get<1>( arg_pair).expr );
     546                        }
     547
     548                        // Resolve the conditions as if it were an IfStmt
     549                        // Resolve the statments normally
     550                        findSingleExpression( clause.condition, this->indexer );
     551                        clause.statement->accept( *visitor );
     552                }
     553
     554
     555                if( stmt->timeout.statement ) {
     556                        // Resolve the timeout as an size_t for now
     557                        // Resolve the conditions as if it were an IfStmt
     558                        // Resolve the statments normally
     559                        findSingleExpression( stmt->timeout.time, new BasicType( noQualifiers, BasicType::LongLongUnsignedInt ), this->indexer );
     560                        findSingleExpression( stmt->timeout.condition, this->indexer );
     561                        stmt->timeout.statement->accept( *visitor );
     562                }
     563
     564                if( stmt->orelse.statement ) {
     565                        // Resolve the conditions as if it were an IfStmt
     566                        // Resolve the statments normally
     567                        findSingleExpression( stmt->orelse.condition, this->indexer );
     568                        stmt->orelse.statement->accept( *visitor );
    390569                }
    391570        }
     
    403582                visit_children = false;
    404583                // resolve initialization using the possibilities as determined by the currentObject cursor
    405                 UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
    406                 Expression * newExpr = findSingleExpression( untyped, indexer );
     584                Expression * newExpr = new UntypedInitExpr( singleInit->value, currentObject.getOptions() );
     585                findSingleExpression( newExpr, indexer );
    407586                InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr );
    408587
     
    411590
    412591                // discard InitExpr wrapper and retain relevant pieces
    413                 newExpr = initExpr->get_expr();
    414                 newExpr->set_env( initExpr->get_env() );
    415                 initExpr->set_expr( nullptr );
    416                 initExpr->set_env( nullptr );
     592                newExpr = initExpr->expr;
     593                initExpr->expr = nullptr;
     594                std::swap( initExpr->env, newExpr->env );
     595                std::swap( initExpr->inferParams, newExpr->inferParams ) ;
    417596                delete initExpr;
    418597
    419598                // get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
    420599                Type * initContext = currentObject.getCurrentType();
     600
     601                removeExtraneousCast( newExpr, indexer );
    421602
    422603                // check if actual object's type is char[]
     
    426607                                if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    427608                                        if ( isCharType( pt->get_base() ) ) {
    428                                                 // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
    429                                                 CastExpr *ce = strict_dynamic_cast< CastExpr * >( newExpr );
    430                                                 newExpr = ce->get_arg();
    431                                                 ce->set_arg( nullptr );
    432                                                 delete ce;
     609                                                if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) {
     610                                                        // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
     611                                                        newExpr = ce->get_arg();
     612                                                        ce->set_arg( nullptr );
     613                                                        std::swap( ce->env, newExpr->env );
     614                                                        delete ce;
     615                                                }
    433616                                        }
    434617                                }
     
    437620
    438621                // set initializer expr to resolved express
    439                 singleInit->set_value( newExpr );
     622                singleInit->value = newExpr;
    440623
    441624                // move cursor to next object in preparation for next initializer
  • src/ResolvExpr/Resolver.h

    r78315272 r3f7e12cb  
    2929        /// Checks types and binds syntactic constructs to typed representations
    3030        void resolve( std::list< Declaration * > translationUnit );
    31         Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
    32         Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
     31        void resolveDecl( Declaration *, const SymTab::Indexer &indexer );
     32        Expression *resolveInVoidContext( Expression * expr, const SymTab::Indexer &indexer );
     33        void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer );
     34        void findSingleExpression( Expression *& untyped, const SymTab::Indexer &indexer );
    3335        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3436        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
  • src/ResolvExpr/TypeEnvironment.cc

    r78315272 r3f7e12cb  
    6868        }
    6969
    70         void EqvClass::print( std::ostream &os, int indent ) const {
    71                 os << std::string( indent, ' ' ) << "( ";
     70        void EqvClass::print( std::ostream &os, Indenter indent ) const {
     71                os << "( ";
    7272                std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) );
    7373                os << ")";
    7474                if ( type ) {
    7575                        os << " -> ";
    76                         type->print( os, indent );
     76                        type->print( os, indent+1 );
    7777                } // if
    7878                if ( ! allowWidening ) {
     
    123123                for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    124124                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    125 ///       std::cout << "adding " << *theVar;
     125///       std::cerr << "adding " << *theVar;
    126126                                if ( theClass->type ) {
    127 ///         std::cout << " bound to ";
    128 ///         theClass->type->print( std::cout );
    129 ///         std::cout << std::endl;
     127///         std::cerr << " bound to ";
     128///         theClass->type->print( std::cerr );
     129///         std::cerr << std::endl;
    130130                                        sub.add( *theVar, theClass->type );
    131131                                } else if ( theVar != theClass->vars.begin() ) {
    132132                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    133 ///         std::cout << " bound to variable " << *theClass->vars.begin() << std::endl;
     133///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
    134134                                        sub.add( *theVar, newTypeInst );
    135135                                        delete newTypeInst;
     
    144144        }
    145145
    146         void TypeEnvironment::print( std::ostream &os, int indent ) const {
     146        void TypeEnvironment::print( std::ostream &os, Indenter indent ) const {
    147147                for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
    148148                        i->print( os, indent );
  • src/ResolvExpr/TypeEnvironment.h

    r78315272 r3f7e12cb  
    6868                EqvClass &operator=( const EqvClass &other );
    6969                ~EqvClass();
    70                 void print( std::ostream &os, int indent = 0 ) const;
     70                void print( std::ostream &os, Indenter indent = {} ) const;
    7171        };
    7272
     
    8080                void makeSubstitution( TypeSubstitution &result ) const;
    8181                bool isEmpty() const { return env.empty(); }
    82                 void print( std::ostream &os, int indent = 0 ) const;
     82                void print( std::ostream &os, Indenter indent = {} ) const;
    8383                void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
    8484                void simpleCombine( const TypeEnvironment &second );
  • src/ResolvExpr/Unify.cc

    r78315272 r3f7e12cb  
    1717#include <iterator>               // for back_insert_iterator, back_inserter
    1818#include <map>                    // for _Rb_tree_const_iterator, _Rb_tree_i...
    19 #include <memory>                 // for unique_ptr, auto_ptr
     19#include <memory>                 // for unique_ptr
    2020#include <set>                    // for set
    2121#include <string>                 // for string, operator==, operator!=, bas...
    2222#include <utility>                // for pair
    2323
     24#include "Common/PassVisitor.h"   // for PassVisitor
    2425#include "FindOpenVars.h"         // for findOpenVars
    2526#include "Parser/LinkageSpec.h"   // for C
     
    137138        bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
    138139                switch ( data.kind ) {
    139                   case TypeDecl::Any:
    140140                  case TypeDecl::Dtype:
    141141                        // to bind to an object type variable, the type must not be a function type.
     
    169169                                Type *common = 0;
    170170                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    171                                 std::auto_ptr< Type > newType( curClass.type->clone() );
     171                                std::unique_ptr< Type > newType( curClass.type->clone() );
    172172                                newType->get_qualifiers() = typeInst->get_qualifiers();
    173173                                if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) {
     
    458458                if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) {
    459459
    460                         // not positive this is correct in all cases, but it's needed for typedefs
    461                         if ( arrayType->get_isVarLen() || otherArray->get_isVarLen() ) {
    462                                 return;
    463                         }
    464 
    465460                        if ( ! arrayType->get_isVarLen() && ! otherArray->get_isVarLen() &&
    466461                                arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0 ) {
     
    537532        /// If this isn't done then argument lists can have wildly different
    538533        /// size and structure, when they should be compatible.
    539         struct TtypeExpander : public Mutator {
    540                 TypeEnvironment & env;
    541                 TtypeExpander( TypeEnvironment & env ) : env( env ) {}
    542                 Type * mutate( TypeInstType * typeInst ) {
     534        struct TtypeExpander : public WithShortCircuiting {
     535                TypeEnvironment & tenv;
     536                TtypeExpander( TypeEnvironment & tenv ) : tenv( tenv ) {}
     537                void premutate( TypeInstType * ) { visit_children = false; }
     538                Type * postmutate( TypeInstType * typeInst ) {
    543539                        EqvClass eqvClass;
    544                         if ( env.lookup( typeInst->get_name(), eqvClass ) ) {
     540                        if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) {
    545541                                if ( eqvClass.data.kind == TypeDecl::Ttype ) {
    546542                                        // expand ttype parameter into its actual type
     
    560556                dst.clear();
    561557                for ( DeclarationWithType * dcl : src ) {
    562                         TtypeExpander expander( env );
     558                        PassVisitor<TtypeExpander> expander( env );
    563559                        dcl->acceptMutator( expander );
    564560                        std::list< Type * > types;
     
    750746                        std::list<Type *> types1, types2;
    751747
    752                         TtypeExpander expander( env );
     748                        PassVisitor<TtypeExpander> expander( env );
    753749                        flat1->acceptMutator( expander );
    754750                        flat2->acceptMutator( expander );
Note: See TracChangeset for help on using the changeset viewer.