Changeset 3f7e12cb for src/ResolvExpr
- Timestamp:
- Nov 8, 2017, 5:43:33 PM (8 years ago)
- 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. - Location:
- src/ResolvExpr
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AdjustExprType.cc
r78315272 r3f7e12cb 14 14 // 15 15 16 #include "Common/PassVisitor.h" 16 17 #include "SymTab/Indexer.h" // for Indexer 17 18 #include "SynTree/Declaration.h" // for TypeDecl, TypeDecl::Kind::Ftype … … 21 22 22 23 namespace ResolvExpr { 23 class AdjustExprType : public Mutator { 24 typedef Mutator Parent; 25 using Parent::mutate; 24 class AdjustExprType : public WithShortCircuiting { 26 25 public: 27 26 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 28 46 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 44 47 const TypeEnvironment &env; 45 48 const SymTab::Indexer &indexer; … … 47 50 48 51 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 49 AdjustExprTypeadjuster( env, indexer );52 PassVisitor<AdjustExprType> adjuster( env, indexer ); 50 53 Type *newType = type->acceptMutator( adjuster ); 51 54 type = newType; … … 56 59 } 57 60 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; 73 64 delete arrayType; 74 65 return pointerType; 75 66 } 76 67 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 ); 80 70 } 81 71 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 ) { 99 73 EqvClass eqvClass; 100 74 if ( env.lookup( typeInst->get_name(), eqvClass ) ) { … … 113 87 return typeInst; 114 88 } 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 }131 89 } // namespace ResolvExpr 132 90 -
src/ResolvExpr/Alternative.cc
r78315272 r3f7e12cb 66 66 } 67 67 68 void Alternative::print( std::ostream &os, intindent ) const {69 os << std::string( indent, ' ' ) <<"Cost " << cost << ": ";68 void Alternative::print( std::ostream &os, Indenter indent ) const { 69 os << "Cost " << cost << ": "; 70 70 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; 76 76 } else { 77 77 os << "Null expression!" << std::endl; 78 78 } // if 79 os << std::string( indent, ' ' )<< "Environment: ";80 env.print( os, indent+ 2);79 os << indent << "Environment: "; 80 env.print( os, indent+1 ); 81 81 os << std::endl; 82 82 } -
src/ResolvExpr/Alternative.h
r78315272 r3f7e12cb 39 39 ~Alternative(); 40 40 41 void print( std::ostream &os, int indent = 0) const;41 void print( std::ostream &os, Indenter indent = {} ) const; 42 42 43 43 Cost cost; -
src/ResolvExpr/AlternativeFinder.cc
r78315272 r3f7e12cb 76 76 77 77 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 }; 79 80 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 80 81 i->print( os, indent ); … … 122 123 ) 123 124 mapPlace->second.isAmbiguous = true; 125 } else { 126 PRINT( 127 std::cerr << "cost " << candidate->cost << " loses to " << mapPlace->second.candidate->cost << std::endl; 128 ) 124 129 } 125 130 } else { … … 127 132 } 128 133 } 129 130 PRINT(131 std::cerr << "there are " << selected.size() << " alternatives before elimination" << std::endl;132 )133 134 134 135 // accept the alternatives that were unambiguous … … 145 146 expr->get_result()->accept( global_renamer ); 146 147 } 147 148 void referenceToRvalueConversion( Expression *& expr ) {149 if ( dynamic_cast< ReferenceType * >( expr->get_result() ) ) {150 // cast away reference from expr151 expr = new CastExpr( expr, expr->get_result()->stripReferences()->clone() );152 }153 }154 148 } // 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 } 155 156 156 157 template< typename InputIterator, typename OutputIterator > … … 175 176 } 176 177 177 void AlternativeFinder::find( Expression *expr, bool adjust, bool prune ) {178 void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast ) { 178 179 expr->accept( *this ); 179 if ( alternatives.empty() ) {180 if ( failFast && alternatives.empty() ) { 180 181 throw SemanticError( "No reasonable alternatives for expression ", expr ); 181 182 } 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 }187 183 if ( prune ) { 184 auto oldsize = alternatives.size(); 188 185 PRINT( 189 186 std::cerr << "alternatives before prune:" << std::endl; … … 192 189 AltList::iterator oldBegin = alternatives.begin(); 193 190 pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives ) ); 194 if ( alternatives.begin() == oldBegin ) {191 if ( failFast && alternatives.begin() == oldBegin ) { 195 192 std::ostringstream stream; 196 193 AltList winners; 197 194 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"; 199 196 expr->print( stream ); 200 stream << "Alternatives are: ";201 printAlts( winners, stream, 8);197 stream << "Alternatives are:\n"; 198 printAlts( winners, stream, 1 ); 202 199 throw SemanticError( stream.str() ); 203 200 } 204 201 alternatives.erase( oldBegin, alternatives.end() ); 202 PRINT( 203 std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl; 204 ) 205 205 PRINT( 206 206 std::cerr << "there are " << alternatives.size() << " alternatives after elimination" << std::endl; 207 207 ) 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 } 208 214 } 209 215 … … 215 221 } 216 222 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 ); 219 233 } 220 234 … … 299 313 Cost convCost = conversionCost( actualType, formalType, indexer, env ); 300 314 PRINT( 301 std::cerr << std::endl << "cost is " << convCost << std::endl;315 std::cerr << std::endl << "cost is " << convCost << std::endl; 302 316 ) 303 317 if ( convCost == Cost::infinity ) { … … 305 319 } 306 320 convCost.incPoly( polyCost( formalType, env, indexer ) + polyCost( actualType, env, indexer ) ); 321 PRINT( 322 std::cerr << "cost with polycost is " << convCost << std::endl; 323 ) 307 324 return convCost; 308 325 } … … 310 327 Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) { 311 328 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. 317 333 Cost tmpCost = convCost; 318 334 tmpCost.incPoly( -tmpCost.get_polyCost() ); … … 357 373 if ( function->get_isVarArgs() ) { 358 374 convCost.incUnsafe(); 375 PRINT( std::cerr << "end of formals with varargs function: inc unsafe: " << convCost << std::endl; ; ) 359 376 // convert reference-typed expressions to value-typed expressions 360 377 referenceToRvalueConversion( *actualExpr ); … … 365 382 } 366 383 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 )376 384 convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env ); 377 385 ++formal; // can't be in for-loop update because of the continue … … 481 489 Alternative newerAlt( newAlt ); 482 490 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() ); 484 492 DeclarationWithType *candDecl = static_cast< DeclarationWithType* >( Declaration::declFromId( (*candidate)->get_uniqueId() ) ); 485 493 … … 507 515 std::cerr << std::endl; 508 516 ) 509 ApplicationExpr *appExpr = static_cast< ApplicationExpr* >( newerAlt.expr );510 517 // 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(); 512 519 for ( UniqueId id : cur->second.idChain ) { 513 520 inferParameters = (*inferParameters)[ id ].inferParams.get(); … … 786 793 787 794 return ! results.empty(); 788 } 795 } 789 796 790 797 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, 793 800 OutputIterator out ) { 794 801 OpenVarSet funcOpenVars; 795 802 AssertionSet funcNeed, funcHave; 796 TypeEnvironment funcEnv ;803 TypeEnvironment funcEnv( func.env ); 797 804 makeUnifiableVars( funcType, funcOpenVars, funcNeed ); 798 805 // add all type variables as open variables now so that those not used in the parameter 799 806 // list are still considered open. 800 807 funcEnv.add( funcType->get_forall() ); 801 808 802 809 if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) { 803 810 // 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(); 805 812 if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars, 806 813 indexer ) ) { … … 905 912 906 913 // find function operators 914 static NameExpr *opExpr = new NameExpr( "?()" ); 907 915 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); 914 918 PRINT( 915 919 std::cerr << "known function ops:" << std::endl; 916 printAlts( funcOpFinder.alternatives, std::cerr, 8);920 printAlts( funcOpFinder.alternatives, std::cerr, 1 ); 917 921 ) 918 922 … … 1028 1032 bool isLvalue( Expression *expr ) { 1029 1033 // 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() ) ); 1031 1035 } 1032 1036 … … 1103 1107 thisCost.incSafe( discardedValues ); 1104 1108 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 ) ); 1110 1110 } // if 1111 1111 } // for … … 1123 1123 AlternativeFinder finder( indexer, env ); 1124 1124 // 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() ); 1127 1126 for ( Alternative & alt : finder.alternatives ) { 1128 1127 alternatives.push_back( Alternative( … … 1163 1162 PRINT( std::cerr << "nameExpr is " << nameExpr->get_name() << std::endl; ) 1164 1163 for ( std::list< DeclarationWithType* >::iterator i = declList.begin(); i != declList.end(); ++i ) { 1165 VariableExpr newExpr( *i , nameExpr->get_argName());1164 VariableExpr newExpr( *i ); 1166 1165 alternatives.push_back( Alternative( newExpr.clone(), env, Cost::zero ) ); 1167 1166 PRINT( … … 1398 1397 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) ); 1399 1398 std::list< AltList > possibilities; 1400 // TODO re-write to use iterative method1401 1399 combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) ); 1402 1400 for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) { … … 1422 1420 // don't prune here, since it's guaranteed all alternatives will have the same type 1423 1421 // (giving the alternatives different types is half of the point of ConstructorExpr nodes) 1424 finder.findWith Adjustment( ctorExpr->get_callExpr(), false);1422 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1425 1423 for ( Alternative & alt : finder.alternatives ) { 1426 1424 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) ); … … 1459 1457 // O(N^2) checks of d-types with e-types 1460 1458 for ( InitAlternative & initAlt : initExpr->get_initAlts() ) { 1461 Type * toType = resolveTypeof( initAlt.type , indexer );1459 Type * toType = resolveTypeof( initAlt.type->clone(), indexer ); 1462 1460 SymTab::validateType( toType, &indexer ); 1463 1461 adjustExprType( toType, env, indexer ); … … 1488 1486 // count one safe conversion for each value that is thrown away 1489 1487 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 ) ); 1491 1490 } 1492 1491 } -
src/ResolvExpr/AlternativeFinder.h
r78315272 r3f7e12cb 61 61 } 62 62 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 ); 64 64 /// 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 ); 66 70 AltList &get_alternatives() { return alternatives; } 67 71 … … 77 81 const SymTab::Indexer &get_indexer() const { return indexer; } 78 82 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 ); 79 88 private: 80 89 virtual void visit( ApplicationExpr *applicationExpr ); … … 108 117 virtual void visit( StmtExpr *stmtExpr ); 109 118 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 );114 119 115 120 /// Adds alternatives for anonymous members … … 134 139 135 140 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ); 141 void referenceToRvalueConversion( Expression *& expr ); 136 142 137 143 template< typename InputIterator, typename OutputIterator > -
src/ResolvExpr/CastCost.cc
r78315272 r3f7e12cb 24 24 #include "typeops.h" // for typesCompatibleIgnoreQualifiers 25 25 26 #if 0 27 #define PRINT(x) x 28 #else 29 #define PRINT(x) 30 #endif 26 31 27 32 namespace ResolvExpr { … … 52 57 } // if 53 58 } // 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 54 69 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 70 PRINT( std::cerr << "compatible!" << std::endl; ) 55 71 return Cost::zero; 56 72 } else if ( dynamic_cast< VoidType* >( dest ) ) { 57 73 return Cost::safe; 58 74 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) { 75 PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; ) 59 76 return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const TypeEnvironment & env, const SymTab::Indexer & indexer) { 60 77 return ptrsCastable( t1, t2, env, indexer ); -
src/ResolvExpr/CommonType.cc
r78315272 r3f7e12cb 10 10 // Created On : Sun May 17 06:59:27 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 16 16:24:31201713 // Update Count : 712 // Last Modified On : Mon Sep 25 15:18:17 2017 13 // Update Count : 9 14 14 // 15 15 … … 61 61 }; 62 62 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; 65 65 AssertionSet have, need; 66 66 OpenVarSet newOpen( openVars ); 67 67 // 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; 88 79 } 89 80 … … 99 90 100 91 // 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; 105 105 } 106 106 // otherwise, both are reference types of the same depth and this is handled by the CommonType visitor. … … 150 150 static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = 151 151 { 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, }, 174 176 }; 175 177 -
src/ResolvExpr/ConversionCost.cc
r78315272 r3f7e12cb 10 10 // Created On : Sun May 17 07:06:19 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 17:35:46 201613 // Update Count : 612 // Last Modified On : Mon Sep 25 15:43:34 2017 13 // Update Count : 10 14 14 // 15 15 … … 28 28 29 29 namespace 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 ); 36 36 37 37 #if 0 … … 113 113 int assignResult = func( srcAsRef->get_base(), destAsRef->get_base(), env, indexer ); 114 114 PRINT( std::cerr << "comparing references: " << assignResult << " " << srcAsRef << " " << destAsRef << std::endl; ) 115 if ( assignResult <0 ) {115 if ( assignResult > 0 ) { 116 116 return Cost::safe; 117 } else if ( assignResult >0 ) {117 } else if ( assignResult < 0 ) { 118 118 return Cost::unsafe; 119 119 } // if … … 219 219 */ 220 220 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, }, 245 248 }; 246 249 … … 266 269 } 267 270 268 void ConversionCost::visit( PointerType *pointerType) {271 void ConversionCost::visit( PointerType * pointerType ) { 269 272 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 270 273 PRINT( std::cerr << pointerType << " ===> " << destAsPtr; ) … … 281 284 } 282 285 } 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 ); 284 287 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() ) { 286 289 cost = Cost::safe; 287 } else if ( assignResult >0 ) {290 } else if ( assignResult < 0 ) { 288 291 cost = Cost::unsafe; 289 292 } // if 290 293 // assignResult == 0 means Cost::Infinity 291 294 } // if 292 } else if ( dynamic_cast< ZeroType * >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr) {295 } else if ( dynamic_cast< ZeroType * >( dest ) ) { 293 296 cost = Cost::unsafe; 294 297 } // if 295 298 } 296 299 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 ) { 300 303 // Note: dest can never be a reference, since it would have been caught in an earlier check 301 304 assert( ! dynamic_cast< ReferenceType * >( dest ) ); … … 303 306 // recursively compute conversion cost from T1 to T2. 304 307 // 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() ) { 307 310 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() ) { 309 312 cost.incSafe(); // then gaining qualifiers 310 313 } else { … … 314 317 } 315 318 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 ) { 319 322 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 * ) { 335 338 static Type::Qualifiers q; 336 339 static BasicType integer( q, BasicType::SignedInt ); … … 341 344 } 342 345 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 ) { 347 349 EqvClass eqvClass; 348 350 NamedTypeDecl *namedType; … … 363 365 } 364 366 365 void ConversionCost::visit( __attribute((unused)) TupleType *tupleType) {367 void ConversionCost::visit( TupleType * tupleType ) { 366 368 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(); 370 372 while ( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) { 371 373 Cost newCost = conversionCost( *srcIt++, *destIt++, indexer, env ); … … 383 385 } 384 386 385 void ConversionCost::visit( __attribute((unused)) VarArgsType *varArgsType) {387 void ConversionCost::visit( VarArgsType * ) { 386 388 if ( dynamic_cast< VarArgsType* >( dest ) ) { 387 389 cost = Cost::zero; … … 389 391 } 390 392 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 ) ) { 393 395 cost = Cost::zero; 394 396 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { … … 406 408 } 407 409 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 ) ) { 410 412 cost = Cost::zero; 411 413 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { -
src/ResolvExpr/CurrentObject.cc
r78315272 r3f7e12cb 260 260 261 261 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 << ")"; ) 262 263 init(); 263 264 } -
src/ResolvExpr/PolyCost.cc
r78315272 r3f7e12cb 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // PolyCost.cc -- 7 // PolyCost.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 31 31 }; 32 32 33 int polyCost( Type *type, const TypeEnvironment & env, const SymTab::Indexer &indexer ) {33 int polyCost( Type *type, const TypeEnvironment & env, const SymTab::Indexer &indexer ) { 34 34 PolyCost coster( env, indexer ); 35 35 type->accept( coster ); … … 37 37 } 38 38 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 ) { 40 40 } 41 41 42 void PolyCost::visit(TypeInstType * typeInst) {42 void PolyCost::visit(TypeInstType * typeInst) { 43 43 EqvClass eqvClass; 44 if ( env.lookup( typeInst-> get_name(), eqvClass ) ) {44 if ( env.lookup( typeInst->name, eqvClass ) ) { 45 45 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 48 49 result += 1; 49 50 } // if 50 51 } else { 52 // bound to concrete type 51 53 result += 1; 52 54 } // if -
src/ResolvExpr/PtrsAssignable.cc
r78315272 r3f7e12cb 47 47 48 48 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) { 49 // std::cerr << "assignable: " << src << " | " << dest << std::endl; 49 50 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 50 51 EqvClass eqvClass; … … 54 55 } // if 55 56 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; 57 60 } else { 58 61 PtrsAssignable ptrs( dest, env ); … … 65 68 66 69 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; 71 74 } // if 72 75 } … … 75 78 void PtrsAssignable::visit( __attribute__((unused)) PointerType *pointerType ) {} 76 79 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 ) {} 80 81 81 82 void PtrsAssignable::visit( __attribute__((unused)) StructInstType *inst ) {} … … 83 84 84 85 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. 86 92 result = 1; 87 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {88 result = bt->get_kind() == BasicType::SignedInt;89 93 } 90 94 } … … 94 98 EqvClass eqvClass; 95 99 if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) { 100 // T * = S * for any S depends on the type bound to T 96 101 result = ptrsAssignable( eqvClass.type, dest, env ); 97 } else {98 result = 0;99 102 } // if 100 103 } -
src/ResolvExpr/PtrsCastable.cc
r78315272 r3f7e12cb 50 50 }; 51 51 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 ) { 60 66 return -1; 61 67 } // if 62 } //if63 } else if ( env.lookup( typeInst->get_name(), eqvClass ) ) {64 if ( eqvClass.data.kind == TypeDecl::Ftype ) {65 return -1;66 68 } // if 67 } // 68 } //if69 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 objectCast69 } //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 } 73 75 } 74 76 … … 93 95 } 94 96 95 void PtrsCastable::visit( __attribute__((unused)) VoidType *voidType) {97 void PtrsCastable::visit( VoidType * ) { 96 98 result = objectCast( dest, env, indexer ); 97 99 } 98 100 99 void PtrsCastable::visit( __attribute__((unused)) BasicType *basicType) {101 void PtrsCastable::visit( BasicType * ) { 100 102 result = objectCast( dest, env, indexer ); 101 103 } 102 104 103 void PtrsCastable::visit( __attribute__((unused)) PointerType *pointerType) {105 void PtrsCastable::visit( PointerType * ) { 104 106 result = objectCast( dest, env, indexer ); 105 107 } 106 108 107 void PtrsCastable::visit( __attribute__((unused)) ArrayType *arrayType) {109 void PtrsCastable::visit( ArrayType * ) { 108 110 result = objectCast( dest, env, indexer ); 109 111 } 110 112 111 void PtrsCastable::visit( __attribute__((unused)) FunctionType *functionType) {113 void PtrsCastable::visit( FunctionType * ) { 112 114 // result = -1; 113 115 result = functionCast( dest, env, indexer ); 114 116 } 115 117 116 void PtrsCastable::visit( __attribute__((unused)) StructInstType *inst) {118 void PtrsCastable::visit( StructInstType * ) { 117 119 result = objectCast( dest, env, indexer ); 118 120 } 119 121 120 void PtrsCastable::visit( __attribute__((unused)) UnionInstType *inst) {122 void PtrsCastable::visit( UnionInstType * ) { 121 123 result = objectCast( dest, env, indexer ); 122 124 } 123 125 124 void PtrsCastable::visit( __attribute__((unused)) EnumInstType *inst) {126 void PtrsCastable::visit( EnumInstType * ) { 125 127 if ( dynamic_cast< EnumInstType* >( dest ) ) { 126 128 result = 1; … … 136 138 } 137 139 138 void PtrsCastable::visit( __attribute__((unused)) TraitInstType *inst) {}140 void PtrsCastable::visit( TraitInstType * ) {} 139 141 140 142 void PtrsCastable::visit(TypeInstType *inst) { … … 143 145 } 144 146 145 void PtrsCastable::visit( __attribute__((unused)) TupleType *tupleType) {147 void PtrsCastable::visit( TupleType * ) { 146 148 result = objectCast( dest, env, indexer ); 147 149 } 148 150 149 void PtrsCastable::visit( __attribute__((unused)) VarArgsType *varArgsType) {151 void PtrsCastable::visit( VarArgsType * ) { 150 152 result = objectCast( dest, env, indexer ); 151 153 } 152 154 153 void PtrsCastable::visit( __attribute__((unused)) ZeroType *zeroType) {155 void PtrsCastable::visit( ZeroType * ) { 154 156 result = objectCast( dest, env, indexer ); 155 157 } 156 158 157 void PtrsCastable::visit( __attribute__((unused)) OneType *oneType) {159 void PtrsCastable::visit( OneType * ) { 158 160 result = objectCast( dest, env, indexer ); 159 161 } -
src/ResolvExpr/ResolveTypeof.cc
r78315272 r3f7e12cb 18 18 #include <cassert> // for assert 19 19 20 #include "Common/PassVisitor.h" // for PassVisitor 20 21 #include "Resolver.h" // for resolveInVoidContext 21 22 #include "SynTree/Expression.h" // for Expression … … 41 42 } 42 43 43 class ResolveTypeof : public Mutator{44 class ResolveTypeof : public WithShortCircuiting { 44 45 public: 45 46 ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {} 46 Type *mutate( TypeofType *typeofType ); 47 void premutate( TypeofType *typeofType ); 48 Type * postmutate( TypeofType *typeofType ); 47 49 48 50 private: … … 50 52 }; 51 53 52 Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {53 ResolveTypeofmutator( indexer );54 Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) { 55 PassVisitor<ResolveTypeof> mutator( indexer ); 54 56 return type->acceptMutator( mutator ); 55 57 } 56 58 57 Type *ResolveTypeof::mutate( TypeofType *typeofType ) { 59 void ResolveTypeof::premutate( TypeofType * ) { 60 visit_children = false; 61 } 62 63 Type * ResolveTypeof::postmutate( TypeofType *typeofType ) { 58 64 #if 0 59 std::c out<< "resolving typeof: ";60 typeofType->print( std::c out);61 std::c out<< std::endl;65 std::cerr << "resolving typeof: "; 66 typeofType->print( std::cerr ); 67 std::cerr << std::endl; 62 68 #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; 68 74 delete typeofType; 69 75 delete newExpr; -
src/ResolvExpr/Resolver.cc
r78315272 r3f7e12cb 40 40 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 41 41 #include "typeops.h" // for extractResultType 42 #include "Unify.h" // for unify 42 43 43 44 using namespace std; … … 52 53 void previsit( FunctionDecl *functionDecl ); 53 54 void postvisit( FunctionDecl *functionDecl ); 54 void previsit( ObjectDecl * functionDecl );55 void previsit( ObjectDecl *objectDecll ); 55 56 void previsit( TypeDecl *typeDecl ); 56 57 void previsit( EnumDecl * enumDecl ); … … 71 72 void previsit( ThrowStmt *throwStmt ); 72 73 void previsit( CatchStmt *catchStmt ); 74 void previsit( WaitForStmt * stmt ); 73 75 74 76 void previsit( SingleInit *singleInit ); … … 95 97 } 96 98 99 void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) { 100 PassVisitor<Resolver> resolver( indexer ); 101 maybeAccept( decl, resolver ); 102 } 103 97 104 // used in resolveTypeof 98 105 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) { … … 102 109 103 110 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; 106 113 env.makeSubstitution( *expr->get_env() ); 107 114 } 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 } 108 127 } // namespace 109 128 110 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {129 void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) { 111 130 global_renamer.reset(); 112 131 TypeEnvironment env; 113 132 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 ); 116 166 } 117 167 118 168 namespace { 119 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {120 TypeEnvironment env;121 AlternativeFinder finder( indexer, env );122 finder.find( untyped );123 #if 0124 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 } // for131 } // if132 #endif133 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 140 169 bool isIntegralType( Type *type ) { 141 170 if ( dynamic_cast< EnumInstType * >( type ) ) { … … 150 179 } 151 180 152 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {181 void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) { 153 182 TypeEnvironment env; 154 183 AlternativeFinder finder( indexer, env ); … … 179 208 throw SemanticError( "No interpretations for case control expression", untyped ); 180 209 } // if 181 finishExpr( newExpr, *newEnv ); 182 return newExpr; 210 finishExpr( newExpr, *newEnv, untyped->env ); 211 delete untyped; 212 untyped = newExpr; 183 213 } 184 214 … … 205 235 void Resolver::handlePtrType( PtrType * type ) { 206 236 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 ); 211 238 } 212 239 } … … 238 265 functionReturn = ResolvExpr::extractResultType( functionDecl->get_functionType() ); 239 266 } 240 241 267 242 268 void Resolver::postvisit( FunctionDecl *functionDecl ) { … … 262 288 void Resolver::previsit( ExprStmt *exprStmt ) { 263 289 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 ); 268 292 } 269 293 270 294 void Resolver::previsit( AsmExpr *asmExpr ) { 271 295 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 ); 275 297 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 ); 279 299 } // if 280 300 } … … 287 307 288 308 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 ); 292 310 } 293 311 294 312 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 ); 298 314 } 299 315 300 316 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 ); 305 319 } // if 306 320 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 ); 311 323 } // if 312 324 } … … 314 326 void Resolver::previsit( SwitchStmt *switchStmt ) { 315 327 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 ); 322 331 } 323 332 … … 326 335 std::list< InitAlternative > initAlts = currentObject.getOptions(); 327 336 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; 333 343 delete castExpr; 334 344 } … … 339 349 // must resolve the argument for a computed goto 340 350 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 ); 347 354 } // if 348 355 } // if … … 351 358 void Resolver::previsit( ReturnStmt *returnStmt ) { 352 359 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 ); 358 362 } // if 359 363 } … … 366 370 indexer.lookupStruct( "__cfaehm__base_exception_t" ); 367 371 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 ); 380 374 } 381 375 } 382 376 383 377 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 ); 390 569 } 391 570 } … … 403 582 visit_children = false; 404 583 // 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 ); 407 586 InitExpr * initExpr = strict_dynamic_cast< InitExpr * >( newExpr ); 408 587 … … 411 590 412 591 // 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 ) ; 417 596 delete initExpr; 418 597 419 598 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 420 599 Type * initContext = currentObject.getCurrentType(); 600 601 removeExtraneousCast( newExpr, indexer ); 421 602 422 603 // check if actual object's type is char[] … … 426 607 if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) { 427 608 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 } 433 616 } 434 617 } … … 437 620 438 621 // set initializer expr to resolved express 439 singleInit-> set_value( newExpr );622 singleInit->value = newExpr; 440 623 441 624 // move cursor to next object in preparation for next initializer -
src/ResolvExpr/Resolver.h
r78315272 r3f7e12cb 29 29 /// Checks types and binds syntactic constructs to typed representations 30 30 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 ); 33 35 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ); 34 36 void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ); -
src/ResolvExpr/TypeEnvironment.cc
r78315272 r3f7e12cb 68 68 } 69 69 70 void EqvClass::print( std::ostream &os, intindent ) const {71 os << std::string( indent, ' ' ) <<"( ";70 void EqvClass::print( std::ostream &os, Indenter indent ) const { 71 os << "( "; 72 72 std::copy( vars.begin(), vars.end(), std::ostream_iterator< std::string >( os, " " ) ); 73 73 os << ")"; 74 74 if ( type ) { 75 75 os << " -> "; 76 type->print( os, indent );76 type->print( os, indent+1 ); 77 77 } // if 78 78 if ( ! allowWidening ) { … … 123 123 for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) { 124 124 for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) { 125 /// std::c out<< "adding " << *theVar;125 /// std::cerr << "adding " << *theVar; 126 126 if ( theClass->type ) { 127 /// std::c out<< " bound to ";128 /// theClass->type->print( std::c out);129 /// std::c out<< std::endl;127 /// std::cerr << " bound to "; 128 /// theClass->type->print( std::cerr ); 129 /// std::cerr << std::endl; 130 130 sub.add( *theVar, theClass->type ); 131 131 } else if ( theVar != theClass->vars.begin() ) { 132 132 TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype ); 133 /// std::c out<< " bound to variable " << *theClass->vars.begin() << std::endl;133 /// std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl; 134 134 sub.add( *theVar, newTypeInst ); 135 135 delete newTypeInst; … … 144 144 } 145 145 146 void TypeEnvironment::print( std::ostream &os, intindent ) const {146 void TypeEnvironment::print( std::ostream &os, Indenter indent ) const { 147 147 for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) { 148 148 i->print( os, indent ); -
src/ResolvExpr/TypeEnvironment.h
r78315272 r3f7e12cb 68 68 EqvClass &operator=( const EqvClass &other ); 69 69 ~EqvClass(); 70 void print( std::ostream &os, int indent = 0) const;70 void print( std::ostream &os, Indenter indent = {} ) const; 71 71 }; 72 72 … … 80 80 void makeSubstitution( TypeSubstitution &result ) const; 81 81 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; 83 83 void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ); 84 84 void simpleCombine( const TypeEnvironment &second ); -
src/ResolvExpr/Unify.cc
r78315272 r3f7e12cb 17 17 #include <iterator> // for back_insert_iterator, back_inserter 18 18 #include <map> // for _Rb_tree_const_iterator, _Rb_tree_i... 19 #include <memory> // for unique_ptr , auto_ptr19 #include <memory> // for unique_ptr 20 20 #include <set> // for set 21 21 #include <string> // for string, operator==, operator!=, bas... 22 22 #include <utility> // for pair 23 23 24 #include "Common/PassVisitor.h" // for PassVisitor 24 25 #include "FindOpenVars.h" // for findOpenVars 25 26 #include "Parser/LinkageSpec.h" // for C … … 137 138 bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) { 138 139 switch ( data.kind ) { 139 case TypeDecl::Any:140 140 case TypeDecl::Dtype: 141 141 // to bind to an object type variable, the type must not be a function type. … … 169 169 Type *common = 0; 170 170 // 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() ); 172 172 newType->get_qualifiers() = typeInst->get_qualifiers(); 173 173 if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass.allowWidening, true ), indexer, common ) ) { … … 458 458 if ( otherArray && arrayType->get_isVarLen() == otherArray->get_isVarLen() ) { 459 459 460 // not positive this is correct in all cases, but it's needed for typedefs461 if ( arrayType->get_isVarLen() || otherArray->get_isVarLen() ) {462 return;463 }464 465 460 if ( ! arrayType->get_isVarLen() && ! otherArray->get_isVarLen() && 466 461 arrayType->get_dimension() != 0 && otherArray->get_dimension() != 0 ) { … … 537 532 /// If this isn't done then argument lists can have wildly different 538 533 /// 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 ) { 543 539 EqvClass eqvClass; 544 if ( env.lookup( typeInst->get_name(), eqvClass ) ) {540 if ( tenv.lookup( typeInst->get_name(), eqvClass ) ) { 545 541 if ( eqvClass.data.kind == TypeDecl::Ttype ) { 546 542 // expand ttype parameter into its actual type … … 560 556 dst.clear(); 561 557 for ( DeclarationWithType * dcl : src ) { 562 TtypeExpanderexpander( env );558 PassVisitor<TtypeExpander> expander( env ); 563 559 dcl->acceptMutator( expander ); 564 560 std::list< Type * > types; … … 750 746 std::list<Type *> types1, types2; 751 747 752 TtypeExpanderexpander( env );748 PassVisitor<TtypeExpander> expander( env ); 753 749 flat1->acceptMutator( expander ); 754 750 flat2->acceptMutator( expander );
Note:
See TracChangeset
for help on using the changeset viewer.