Changeset 81e1f32b for src/ResolvExpr
- Timestamp:
- Jan 23, 2018, 10:49:53 AM (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:
- 15d248e, f7d6bb0
- Parents:
- d2d50d7 (diff), fc67d6f (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:
-
- 1 deleted
- 10 edited
-
AlternativeFinder.cc (modified) (41 diffs)
-
AlternativeFinder.h (modified) (2 diffs)
-
CommonType.cc (modified) (10 diffs)
-
CurrentObject.cc (modified) (1 diff)
-
PtrsAssignable.cc (modified) (6 diffs)
-
PtrsCastable.cc (modified) (7 diffs)
-
RenameVars.cc (modified) (2 diffs)
-
RenameVars.h (modified) (1 diff)
-
Resolver.cc (modified) (1 diff)
-
TypeMap.h (deleted)
-
Unify.cc (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AlternativeFinder.cc
rd2d50d7 r81e1f32b 60 60 61 61 namespace ResolvExpr { 62 struct AlternativeFinder::Finder : public WithShortCircuiting { 63 Finder( AlternativeFinder & altFinder ) : altFinder( altFinder ), indexer( altFinder.indexer ), alternatives( altFinder.alternatives ), env( altFinder.env ), targetType( altFinder.targetType ) {} 64 65 void previsit( BaseSyntaxNode * ) { visit_children = false; } 66 67 void postvisit( ApplicationExpr * applicationExpr ); 68 void postvisit( UntypedExpr * untypedExpr ); 69 void postvisit( AddressExpr * addressExpr ); 70 void postvisit( LabelAddressExpr * labelExpr ); 71 void postvisit( CastExpr * castExpr ); 72 void postvisit( VirtualCastExpr * castExpr ); 73 void postvisit( UntypedMemberExpr * memberExpr ); 74 void postvisit( MemberExpr * memberExpr ); 75 void postvisit( NameExpr * variableExpr ); 76 void postvisit( VariableExpr * variableExpr ); 77 void postvisit( ConstantExpr * constantExpr ); 78 void postvisit( SizeofExpr * sizeofExpr ); 79 void postvisit( AlignofExpr * alignofExpr ); 80 void postvisit( UntypedOffsetofExpr * offsetofExpr ); 81 void postvisit( OffsetofExpr * offsetofExpr ); 82 void postvisit( OffsetPackExpr * offsetPackExpr ); 83 void postvisit( AttrExpr * attrExpr ); 84 void postvisit( LogicalExpr * logicalExpr ); 85 void postvisit( ConditionalExpr * conditionalExpr ); 86 void postvisit( CommaExpr * commaExpr ); 87 void postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ); 88 void postvisit( ConstructorExpr * ctorExpr ); 89 void postvisit( RangeExpr * rangeExpr ); 90 void postvisit( UntypedTupleExpr * tupleExpr ); 91 void postvisit( TupleExpr * tupleExpr ); 92 void postvisit( TupleIndexExpr * tupleExpr ); 93 void postvisit( TupleAssignExpr * tupleExpr ); 94 void postvisit( UniqueExpr * unqExpr ); 95 void postvisit( StmtExpr * stmtExpr ); 96 void postvisit( UntypedInitExpr * initExpr ); 97 98 /// Adds alternatives for anonymous members 99 void addAnonConversions( const Alternative & alt ); 100 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 101 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 102 /// Adds alternatives for member expressions where the left side has tuple type 103 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 104 /// Adds alternatives for offsetof expressions, given the base type and name of the member 105 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 106 /// Takes a final result and checks if its assertions can be satisfied 107 template<typename OutputIterator> 108 void validateFunctionAlternative( const Alternative &func, ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out ); 109 /// Finds matching alternatives for a function, given a set of arguments 110 template<typename OutputIterator> 111 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out ); 112 /// Checks if assertion parameters match for a new alternative 113 template< typename OutputIterator > 114 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); 115 private: 116 AlternativeFinder & altFinder; 117 const SymTab::Indexer &indexer; 118 AltList & alternatives; 119 const TypeEnvironment &env; 120 Type *& targetType; 121 }; 122 62 123 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) { 63 124 CastExpr *castToVoid = new CastExpr( expr ); … … 152 213 153 214 void renameTypes( Expression *expr ) { 154 expr->get_result()->accept( global_renamer);215 renameTyVars( expr->result ); 155 216 } 156 217 } // namespace … … 185 246 186 247 void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast ) { 187 expr->accept( *this ); 248 PassVisitor<Finder> finder( *this ); 249 expr->accept( finder ); 188 250 if ( failFast && alternatives.empty() ) { 189 251 PRINT( … … 244 306 } 245 307 246 void AlternativeFinder:: addAnonConversions( const Alternative & alt ) {308 void AlternativeFinder::Finder::addAnonConversions( const Alternative & alt ) { 247 309 // adds anonymous member interpretations whenever an aggregate value type is seen. 248 310 // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value … … 265 327 266 328 template< typename StructOrUnionType > 267 void AlternativeFinder:: addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {329 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 268 330 // by this point, member must be a name expr 269 331 NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ); … … 284 346 } 285 347 286 void AlternativeFinder:: addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {348 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 287 349 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 288 350 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning … … 308 370 } 309 371 310 void AlternativeFinder:: visit( ApplicationExpr *applicationExpr ) {372 void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) { 311 373 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) ); 312 374 } … … 485 547 Type *adjType = candidate->get_type()->clone(); 486 548 adjustExprType( adjType, newEnv, indexer ); 487 adjType->accept( global_renamer);549 renameTyVars( adjType ); 488 550 PRINT( 489 551 std::cerr << "unifying "; … … 541 603 542 604 template< typename OutputIterator > 543 void AlternativeFinder:: inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {605 void AlternativeFinder::Finder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) { 544 606 // PRINT( 545 607 // std::cerr << "inferParameters: assertions needed are" << std::endl; … … 595 657 596 658 ArgPack() 597 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 659 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 598 660 tupleStart(0), nextExpl(0), explAlt(0) {} 599 661 … … 706 768 707 769 if ( nTuples > 0 || ! results[i].expr ) { 708 // first iteration or no expression to clone, 770 // first iteration or no expression to clone, 709 771 // push empty tuple expression 710 772 newResult.parent = i; … … 892 954 893 955 template<typename OutputIterator> 894 void AlternativeFinder:: validateFunctionAlternative( const Alternative &func, ArgPack& result,956 void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 895 957 const std::vector<ArgPack>& results, OutputIterator out ) { 896 958 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); … … 915 977 916 978 template<typename OutputIterator> 917 void AlternativeFinder:: makeFunctionAlternatives( const Alternative &func,979 void AlternativeFinder::Finder::makeFunctionAlternatives( const Alternative &func, 918 980 FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) { 919 981 OpenVarSet funcOpenVars; … … 1022 1084 } 1023 1085 1024 void AlternativeFinder:: visit( UntypedExpr *untypedExpr ) {1086 void AlternativeFinder::Finder::postvisit( UntypedExpr *untypedExpr ) { 1025 1087 AlternativeFinder funcFinder( indexer, env ); 1026 1088 funcFinder.findWithAdjustment( untypedExpr->get_function() ); … … 1029 1091 1030 1092 std::vector< AlternativeFinder > argAlternatives; 1031 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(),1093 altFinder.findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), 1032 1094 back_inserter( argAlternatives ) ); 1033 1095 1034 1096 // take care of possible tuple assignments 1035 1097 // if not tuple assignment, assignment is taken care of as a normal function call 1036 Tuples::handleTupleAssignment( *this, untypedExpr, argAlternatives );1098 Tuples::handleTupleAssignment( altFinder, untypedExpr, argAlternatives ); 1037 1099 1038 1100 // find function operators … … 1172 1234 // fix this issue in a more robust way. 1173 1235 targetType = nullptr; 1174 visit( untypedExpr );1236 postvisit( untypedExpr ); 1175 1237 } 1176 1238 } … … 1181 1243 } 1182 1244 1183 void AlternativeFinder:: visit( AddressExpr *addressExpr ) {1245 void AlternativeFinder::Finder::postvisit( AddressExpr *addressExpr ) { 1184 1246 AlternativeFinder finder( indexer, env ); 1185 1247 finder.find( addressExpr->get_arg() ); … … 1192 1254 } 1193 1255 1194 void AlternativeFinder:: visit( LabelAddressExpr * expr ) {1256 void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) { 1195 1257 alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } ); 1196 1258 } … … 1223 1285 } 1224 1286 1225 void AlternativeFinder:: visit( CastExpr *castExpr ) {1287 void AlternativeFinder::Finder::postvisit( CastExpr *castExpr ) { 1226 1288 Type *& toType = castExpr->get_result(); 1227 1289 assert( toType ); … … 1278 1340 } 1279 1341 1280 void AlternativeFinder:: visit( VirtualCastExpr * castExpr ) {1342 void AlternativeFinder::Finder::postvisit( VirtualCastExpr * castExpr ) { 1281 1343 assertf( castExpr->get_result(), "Implicate virtual cast targets not yet supported." ); 1282 1344 AlternativeFinder finder( indexer, env ); … … 1290 1352 } 1291 1353 1292 void AlternativeFinder:: visit( UntypedMemberExpr *memberExpr ) {1354 void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) { 1293 1355 AlternativeFinder funcFinder( indexer, env ); 1294 1356 funcFinder.findWithAdjustment( memberExpr->get_aggregate() ); … … 1312 1374 } 1313 1375 1314 void AlternativeFinder:: visit( MemberExpr *memberExpr ) {1376 void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) { 1315 1377 alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) ); 1316 1378 } 1317 1379 1318 void AlternativeFinder:: visit( NameExpr *nameExpr ) {1380 void AlternativeFinder::Finder::postvisit( NameExpr *nameExpr ) { 1319 1381 std::list< SymTab::Indexer::IdData > declList; 1320 1382 indexer.lookupId( nameExpr->get_name(), declList ); … … 1337 1399 } 1338 1400 1339 void AlternativeFinder:: visit( VariableExpr *variableExpr ) {1401 void AlternativeFinder::Finder::postvisit( VariableExpr *variableExpr ) { 1340 1402 // not sufficient to clone here, because variable's type may have changed 1341 1403 // since the VariableExpr was originally created. … … 1343 1405 } 1344 1406 1345 void AlternativeFinder:: visit( ConstantExpr *constantExpr ) {1407 void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) { 1346 1408 alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) ); 1347 1409 } 1348 1410 1349 void AlternativeFinder:: visit( SizeofExpr *sizeofExpr ) {1411 void AlternativeFinder::Finder::postvisit( SizeofExpr *sizeofExpr ) { 1350 1412 if ( sizeofExpr->get_isType() ) { 1351 1413 Type * newType = sizeofExpr->get_type()->clone(); … … 1368 1430 } 1369 1431 1370 void AlternativeFinder:: visit( AlignofExpr *alignofExpr ) {1432 void AlternativeFinder::Finder::postvisit( AlignofExpr *alignofExpr ) { 1371 1433 if ( alignofExpr->get_isType() ) { 1372 1434 Type * newType = alignofExpr->get_type()->clone(); … … 1390 1452 1391 1453 template< typename StructOrUnionType > 1392 void AlternativeFinder:: addOffsetof( StructOrUnionType *aggInst, const std::string &name ) {1454 void AlternativeFinder::Finder::addOffsetof( StructOrUnionType *aggInst, const std::string &name ) { 1393 1455 std::list< Declaration* > members; 1394 1456 aggInst->lookup( name, members ); … … 1403 1465 } 1404 1466 1405 void AlternativeFinder:: visit( UntypedOffsetofExpr *offsetofExpr ) {1467 void AlternativeFinder::Finder::postvisit( UntypedOffsetofExpr *offsetofExpr ) { 1406 1468 AlternativeFinder funcFinder( indexer, env ); 1407 1469 // xxx - resolveTypeof? … … 1413 1475 } 1414 1476 1415 void AlternativeFinder:: visit( OffsetofExpr *offsetofExpr ) {1477 void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) { 1416 1478 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) ); 1417 1479 } 1418 1480 1419 void AlternativeFinder:: visit( OffsetPackExpr *offsetPackExpr ) {1481 void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) { 1420 1482 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) ); 1421 1483 } … … 1444 1506 } 1445 1507 1446 void AlternativeFinder:: visit( AttrExpr *attrExpr ) {1508 void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) { 1447 1509 // assume no 'pointer-to-attribute' 1448 1510 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); … … 1458 1520 if ( function->get_parameters().size() == 1 ) { 1459 1521 if ( attrExpr->get_isType() ) { 1460 resolveAttr( data, function, attrExpr->get_type(), env, *this);1522 resolveAttr( data, function, attrExpr->get_type(), env, altFinder); 1461 1523 } else { 1462 1524 AlternativeFinder finder( indexer, env ); … … 1464 1526 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 1465 1527 if ( choice->expr->get_result()->size() == 1 ) { 1466 resolveAttr(data, function, choice->expr->get_result(), choice->env, *this);1528 resolveAttr(data, function, choice->expr->get_result(), choice->env, altFinder ); 1467 1529 } // fi 1468 1530 } // for … … 1479 1541 } 1480 1542 1481 void AlternativeFinder:: visit( LogicalExpr *logicalExpr ) {1543 void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) { 1482 1544 AlternativeFinder firstFinder( indexer, env ); 1483 1545 firstFinder.findWithAdjustment( logicalExpr->get_arg1() ); … … 1492 1554 } 1493 1555 1494 void AlternativeFinder:: visit( ConditionalExpr *conditionalExpr ) {1556 void AlternativeFinder::Finder::postvisit( ConditionalExpr *conditionalExpr ) { 1495 1557 // find alternatives for condition 1496 1558 AlternativeFinder firstFinder( indexer, env ); … … 1524 1586 } 1525 1587 1526 void AlternativeFinder:: visit( CommaExpr *commaExpr ) {1588 void AlternativeFinder::Finder::postvisit( CommaExpr *commaExpr ) { 1527 1589 TypeEnvironment newEnv( env ); 1528 1590 Expression *newFirstArg = resolveInVoidContext( commaExpr->get_arg1(), indexer, newEnv ); … … 1535 1597 } 1536 1598 1537 void AlternativeFinder:: visit( RangeExpr * rangeExpr ) {1599 void AlternativeFinder::Finder::postvisit( RangeExpr * rangeExpr ) { 1538 1600 // resolve low and high, accept alternatives whose low and high types unify 1539 1601 AlternativeFinder firstFinder( indexer, env ); … … 1557 1619 } 1558 1620 1559 void AlternativeFinder:: visit( UntypedTupleExpr *tupleExpr ) {1621 void AlternativeFinder::Finder::postvisit( UntypedTupleExpr *tupleExpr ) { 1560 1622 std::vector< AlternativeFinder > subExprAlternatives; 1561 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(),1623 altFinder.findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 1562 1624 back_inserter( subExprAlternatives ) ); 1563 1625 std::vector< AltList > possibilities; … … 1575 1637 } 1576 1638 1577 void AlternativeFinder:: visit( TupleExpr *tupleExpr ) {1639 void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) { 1578 1640 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) ); 1579 1641 } 1580 1642 1581 void AlternativeFinder:: visit( ImplicitCopyCtorExpr * impCpCtorExpr ) {1643 void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 1582 1644 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) ); 1583 1645 } 1584 1646 1585 void AlternativeFinder:: visit( ConstructorExpr * ctorExpr ) {1647 void AlternativeFinder::Finder::postvisit( ConstructorExpr * ctorExpr ) { 1586 1648 AlternativeFinder finder( indexer, env ); 1587 1649 // don't prune here, since it's guaranteed all alternatives will have the same type … … 1593 1655 } 1594 1656 1595 void AlternativeFinder:: visit( TupleIndexExpr *tupleExpr ) {1657 void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) { 1596 1658 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) ); 1597 1659 } 1598 1660 1599 void AlternativeFinder:: visit( TupleAssignExpr *tupleAssignExpr ) {1661 void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) { 1600 1662 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) ); 1601 1663 } 1602 1664 1603 void AlternativeFinder:: visit( UniqueExpr *unqExpr ) {1665 void AlternativeFinder::Finder::postvisit( UniqueExpr *unqExpr ) { 1604 1666 AlternativeFinder finder( indexer, env ); 1605 1667 finder.findWithAdjustment( unqExpr->get_expr() ); … … 1611 1673 } 1612 1674 1613 void AlternativeFinder:: visit( StmtExpr *stmtExpr ) {1675 void AlternativeFinder::Finder::postvisit( StmtExpr *stmtExpr ) { 1614 1676 StmtExpr * newStmtExpr = stmtExpr->clone(); 1615 1677 ResolvExpr::resolveStmtExpr( newStmtExpr, indexer ); … … 1618 1680 } 1619 1681 1620 void AlternativeFinder:: visit( UntypedInitExpr *initExpr ) {1682 void AlternativeFinder::Finder::postvisit( UntypedInitExpr *initExpr ) { 1621 1683 // handle each option like a cast 1622 1684 AltList candidates; 1623 PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; ) 1685 PRINT( 1686 std::cerr << "untyped init expr: " << initExpr << std::endl; 1687 ) 1624 1688 // O(N^2) checks of d-types with e-types 1625 1689 for ( InitAlternative & initAlt : initExpr->get_initAlts() ) { … … 1637 1701 AssertionSet needAssertions, haveAssertions; 1638 1702 OpenVarSet openVars; // find things in env that don't have a "representative type" and claim those are open vars? 1639 PRINT( std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; ) 1703 PRINT( 1704 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1705 ) 1640 1706 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1641 1707 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results -
src/ResolvExpr/AlternativeFinder.h
rd2d50d7 r81e1f32b 38 38 using ExplodedArgs = std::vector< std::vector< ExplodedActual > >; 39 39 40 class AlternativeFinder : public Visitor{40 class AlternativeFinder { 41 41 public: 42 42 AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env ); … … 94 94 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ); 95 95 private: 96 virtual void visit( ApplicationExpr *applicationExpr ); 97 virtual void visit( UntypedExpr *untypedExpr ); 98 virtual void visit( AddressExpr *addressExpr ); 99 virtual void visit( LabelAddressExpr *labelExpr ); 100 virtual void visit( CastExpr *castExpr ); 101 virtual void visit( VirtualCastExpr *castExpr ); 102 virtual void visit( UntypedMemberExpr *memberExpr ); 103 virtual void visit( MemberExpr *memberExpr ); 104 virtual void visit( NameExpr *variableExpr ); 105 virtual void visit( VariableExpr *variableExpr ); 106 virtual void visit( ConstantExpr *constantExpr ); 107 virtual void visit( SizeofExpr *sizeofExpr ); 108 virtual void visit( AlignofExpr *alignofExpr ); 109 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 110 virtual void visit( OffsetofExpr *offsetofExpr ); 111 virtual void visit( OffsetPackExpr *offsetPackExpr ); 112 virtual void visit( AttrExpr *attrExpr ); 113 virtual void visit( LogicalExpr *logicalExpr ); 114 virtual void visit( ConditionalExpr *conditionalExpr ); 115 virtual void visit( CommaExpr *commaExpr ); 116 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ); 117 virtual void visit( ConstructorExpr * ctorExpr ); 118 virtual void visit( RangeExpr * rangeExpr ); 119 virtual void visit( UntypedTupleExpr *tupleExpr ); 120 virtual void visit( TupleExpr *tupleExpr ); 121 virtual void visit( TupleIndexExpr *tupleExpr ); 122 virtual void visit( TupleAssignExpr *tupleExpr ); 123 virtual void visit( UniqueExpr *unqExpr ); 124 virtual void visit( StmtExpr *stmtExpr ); 125 virtual void visit( UntypedInitExpr *initExpr ); 126 127 /// Adds alternatives for anonymous members 128 void addAnonConversions( const Alternative & alt ); 129 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 130 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 131 /// Adds alternatives for member expressions where the left side has tuple type 132 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 133 /// Adds alternatives for offsetof expressions, given the base type and name of the member 134 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 135 /// Takes a final result and checks if its assertions can be satisfied 136 template<typename OutputIterator> 137 void validateFunctionAlternative( const Alternative &func, ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out ); 138 /// Finds matching alternatives for a function, given a set of arguments 139 template<typename OutputIterator> 140 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out ); 141 /// Checks if assertion parameters match for a new alternative 142 template< typename OutputIterator > 143 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); 144 96 struct Finder; 145 97 const SymTab::Indexer &indexer; 146 98 AltList alternatives; -
src/ResolvExpr/CommonType.cc
rd2d50d7 r81e1f32b 18 18 #include <utility> // for pair 19 19 20 #include "Common/PassVisitor.h" 20 21 #include "ResolvExpr/TypeEnvironment.h" // for OpenVarSet, AssertionSet 21 22 #include "SymTab/Indexer.h" // for Indexer … … 29 30 30 31 namespace ResolvExpr { 31 class CommonType : public Visitor { 32 public: 32 struct CommonType : public WithShortCircuiting { 33 33 CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 34 34 Type *get_result() const { return result; } 35 36 void previsit( BaseSyntaxNode * ) { visit_children = false; } 37 38 void postvisit( VoidType * voidType ); 39 void postvisit( BasicType * basicType ); 40 void postvisit( PointerType * pointerType ); 41 void postvisit( ArrayType * arrayType ); 42 void postvisit( ReferenceType * refType ); 43 void postvisit( FunctionType * functionType ); 44 void postvisit( StructInstType * aggregateUseType ); 45 void postvisit( UnionInstType * aggregateUseType ); 46 void postvisit( EnumInstType * aggregateUseType ); 47 void postvisit( TraitInstType * aggregateUseType ); 48 void postvisit( TypeInstType * aggregateUseType ); 49 void postvisit( TupleType * tupleType ); 50 void postvisit( VarArgsType * varArgsType ); 51 void postvisit( ZeroType * zeroType ); 52 void postvisit( OneType * oneType ); 53 35 54 private: 36 virtual void visit( VoidType *voidType );37 virtual void visit( BasicType *basicType );38 virtual void visit( PointerType *pointerType );39 virtual void visit( ArrayType *arrayType );40 virtual void visit( ReferenceType *refType );41 virtual void visit( FunctionType *functionType );42 virtual void visit( StructInstType *aggregateUseType );43 virtual void visit( UnionInstType *aggregateUseType );44 virtual void visit( EnumInstType *aggregateUseType );45 virtual void visit( TraitInstType *aggregateUseType );46 virtual void visit( TypeInstType *aggregateUseType );47 virtual void visit( TupleType *tupleType );48 virtual void visit( VarArgsType *varArgsType );49 virtual void visit( ZeroType *zeroType );50 virtual void visit( OneType *oneType );51 52 55 template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ); 53 56 template< typename RefType > void handleRefType( RefType *inst, Type *other ); … … 80 83 81 84 Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) { 82 CommonTypevisitor( type2, widenFirst, widenSecond, indexer, env, openVars );85 PassVisitor<CommonType> visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 83 86 84 87 int depth1 = type1->referenceDepth(); … … 116 119 117 120 type1->accept( visitor ); 118 Type *result = visitor. get_result();121 Type *result = visitor.pass.get_result(); 119 122 if ( ! result ) { 120 123 // this appears to be handling for opaque type declarations … … 188 191 } 189 192 190 void CommonType:: visit( VoidType * ) {}191 192 void CommonType:: visit( BasicType *basicType ) {193 void CommonType::postvisit( VoidType * ) {} 194 195 void CommonType::postvisit( BasicType *basicType ) { 193 196 if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) { 194 197 BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ]; … … 219 222 } 220 223 221 void CommonType:: visit( PointerType *pointerType ) {224 void CommonType::postvisit( PointerType *pointerType ) { 222 225 if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) { 223 226 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl; … … 254 257 } 255 258 256 void CommonType:: visit( ArrayType * ) {}257 258 void CommonType:: visit( ReferenceType *refType ) {259 void CommonType::postvisit( ArrayType * ) {} 260 261 void CommonType::postvisit( ReferenceType *refType ) { 259 262 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) { 260 263 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl; … … 291 294 } 292 295 293 void CommonType:: visit( FunctionType * ) {}294 void CommonType:: visit( StructInstType * ) {}295 void CommonType:: visit( UnionInstType * ) {}296 297 void CommonType:: visit( EnumInstType *enumInstType ) {296 void CommonType::postvisit( FunctionType * ) {} 297 void CommonType::postvisit( StructInstType * ) {} 298 void CommonType::postvisit( UnionInstType * ) {} 299 300 void CommonType::postvisit( EnumInstType *enumInstType ) { 298 301 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) { 299 302 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 300 ValueGuard< Type * > temp( type2 ); 301 type2 = enumInstType; 302 temp.old->accept( *this ); 303 } // if 304 } 305 306 void CommonType::visit( TraitInstType * ) { 307 } 308 309 void CommonType::visit( TypeInstType *inst ) { 303 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars ); 304 } // if 305 } 306 307 void CommonType::postvisit( TraitInstType * ) { 308 } 309 310 void CommonType::postvisit( TypeInstType *inst ) { 310 311 if ( widenFirst ) { 311 312 NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ); … … 329 330 } 330 331 331 void CommonType:: visit( TupleType * ) {}332 void CommonType:: visit( VarArgsType * ) {}333 334 void CommonType:: visit( ZeroType *zeroType ) {332 void CommonType::postvisit( TupleType * ) {} 333 void CommonType::postvisit( VarArgsType * ) {} 334 335 void CommonType::postvisit( ZeroType *zeroType ) { 335 336 if ( widenFirst ) { 336 337 if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) { … … 346 347 } 347 348 348 void CommonType:: visit( OneType *oneType ) {349 void CommonType::postvisit( OneType *oneType ) { 349 350 if ( widenFirst ) { 350 351 if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) { -
src/ResolvExpr/CurrentObject.cc
rd2d50d7 r81e1f32b 443 443 return new UnionIterator( uit ); 444 444 } else { 445 assertf( dynamic_cast< TypeInstType * >( type ), "some other reftotype");445 assertf( dynamic_cast< EnumInstType * >( type ) || dynamic_cast< TypeInstType * >( type ), "Encountered unhandled ReferenceToType in createMemberIterator: %s", toString( type ).c_str() ); 446 446 return new SimpleIterator( type ); 447 447 } -
src/ResolvExpr/PtrsAssignable.cc
rd2d50d7 r81e1f32b 14 14 // 15 15 16 #include "Common/PassVisitor.h" 16 17 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 17 18 #include "SynTree/Type.h" // for TypeInstType, Type, BasicType … … 20 21 21 22 namespace ResolvExpr { 22 class PtrsAssignable : public Visitor { 23 public: 23 struct PtrsAssignable : public WithShortCircuiting { 24 24 PtrsAssignable( Type *dest, const TypeEnvironment &env ); 25 25 26 26 int get_result() const { return result; } 27 27 28 virtual void visit( VoidType *voidType ); 29 virtual void visit( BasicType *basicType ); 30 virtual void visit( PointerType *pointerType ); 31 virtual void visit( ArrayType *arrayType ); 32 virtual void visit( FunctionType *functionType ); 33 virtual void visit( StructInstType *inst ); 34 virtual void visit( UnionInstType *inst ); 35 virtual void visit( EnumInstType *inst ); 36 virtual void visit( TraitInstType *inst ); 37 virtual void visit( TypeInstType *inst ); 38 virtual void visit( TupleType *tupleType ); 39 virtual void visit( VarArgsType *varArgsType ); 40 virtual void visit( ZeroType *zeroType ); 41 virtual void visit( OneType *oneType ); 28 void previsit( Type * ) { visit_children = false; } 29 30 void postvisit( VoidType * voidType ); 31 void postvisit( BasicType * basicType ); 32 void postvisit( PointerType * pointerType ); 33 void postvisit( ArrayType * arrayType ); 34 void postvisit( FunctionType * functionType ); 35 void postvisit( StructInstType * inst ); 36 void postvisit( UnionInstType * inst ); 37 void postvisit( EnumInstType * inst ); 38 void postvisit( TraitInstType * inst ); 39 void postvisit( TypeInstType * inst ); 40 void postvisit( TupleType * tupleType ); 41 void postvisit( VarArgsType * varArgsType ); 42 void postvisit( ZeroType * zeroType ); 43 void postvisit( OneType * oneType ); 42 44 private: 43 45 Type *dest; … … 59 61 return -1; 60 62 } else { 61 P trsAssignableptrs( dest, env );63 PassVisitor<PtrsAssignable> ptrs( dest, env ); 62 64 src->accept( ptrs ); 63 return ptrs. get_result();65 return ptrs.pass.get_result(); 64 66 } // if 65 67 } … … 67 69 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {} 68 70 69 void PtrsAssignable:: visit( VoidType * ) {71 void PtrsAssignable::postvisit( VoidType * ) { 70 72 // T * = void * is disallowed - this is a change from C, where any 71 73 // void * can be assigned or passed to a non-void pointer without a cast. 72 74 } 73 75 74 void PtrsAssignable:: visit( __attribute__((unused)) BasicType *basicType ) {}75 void PtrsAssignable:: visit( __attribute__((unused)) PointerType *pointerType ) {}76 void PtrsAssignable:: visit( __attribute__((unused)) ArrayType *arrayType ) {}77 void PtrsAssignable:: visit( __attribute__((unused)) FunctionType *functionType ) {}76 void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {} 77 void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {} 78 void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {} 79 void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {} 78 80 79 void PtrsAssignable:: visit( __attribute__((unused)) StructInstType *inst ) {}80 void PtrsAssignable:: visit( __attribute__((unused)) UnionInstType *inst ) {}81 void PtrsAssignable::postvisit( __attribute__((unused)) StructInstType *inst ) {} 82 void PtrsAssignable::postvisit( __attribute__((unused)) UnionInstType *inst ) {} 81 83 82 void PtrsAssignable:: visit( EnumInstType * ) {84 void PtrsAssignable::postvisit( EnumInstType * ) { 83 85 if ( dynamic_cast< BasicType* >( dest ) ) { 84 86 // int * = E *, etc. is safe. This isn't technically correct, as each … … 91 93 } 92 94 93 void PtrsAssignable:: visit( __attribute__((unused)) TraitInstType *inst ) {}94 void PtrsAssignable:: visit( TypeInstType *inst ) {95 void PtrsAssignable::postvisit( __attribute__((unused)) TraitInstType *inst ) {} 96 void PtrsAssignable::postvisit( TypeInstType *inst ) { 95 97 EqvClass eqvClass; 96 98 if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) { … … 100 102 } 101 103 102 void PtrsAssignable:: visit( __attribute__((unused)) TupleType *tupleType ) {}103 void PtrsAssignable:: visit( __attribute__((unused)) VarArgsType *varArgsType ) {}104 void PtrsAssignable:: visit( __attribute__((unused)) ZeroType *zeroType ) {}105 void PtrsAssignable:: visit( __attribute__((unused)) OneType *oneType ) {}104 void PtrsAssignable::postvisit( __attribute__((unused)) TupleType *tupleType ) {} 105 void PtrsAssignable::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) {} 106 void PtrsAssignable::postvisit( __attribute__((unused)) ZeroType *zeroType ) {} 107 void PtrsAssignable::postvisit( __attribute__((unused)) OneType *oneType ) {} 106 108 107 109 } // namespace ResolvExpr -
src/ResolvExpr/PtrsCastable.cc
rd2d50d7 r81e1f32b 14 14 // 15 15 16 #include "Common/PassVisitor.h" 16 17 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 17 18 #include "SymTab/Indexer.h" // for Indexer … … 21 22 #include "typeops.h" // for ptrsAssignable 22 23 23 24 24 namespace ResolvExpr { 25 class PtrsCastable : public Visitor{25 struct PtrsCastable : public WithShortCircuiting { 26 26 public: 27 27 PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); … … 29 29 int get_result() const { return result; } 30 30 31 virtual void visit(VoidType *voidType); 32 virtual void visit(BasicType *basicType); 33 virtual void visit(PointerType *pointerType); 34 virtual void visit(ArrayType *arrayType); 35 virtual void visit(FunctionType *functionType); 36 virtual void visit(StructInstType *inst); 37 virtual void visit(UnionInstType *inst); 38 virtual void visit(EnumInstType *inst); 39 virtual void visit(TraitInstType *inst); 40 virtual void visit(TypeInstType *inst); 41 virtual void visit(TupleType *tupleType); 42 virtual void visit(VarArgsType *varArgsType); 43 virtual void visit(ZeroType *zeroType); 44 virtual void visit(OneType *oneType); 31 void previsit( Type * ) { visit_children = false; } 32 33 void postvisit( VoidType * voidType ); 34 void postvisit( BasicType * basicType ); 35 void postvisit( PointerType * pointerType ); 36 void postvisit( ArrayType * arrayType ); 37 void postvisit( FunctionType * functionType ); 38 void postvisit( StructInstType * inst ); 39 void postvisit( UnionInstType * inst ); 40 void postvisit( EnumInstType * inst ); 41 void postvisit( TraitInstType * inst ); 42 void postvisit( TypeInstType * inst ); 43 void postvisit( TupleType * tupleType ); 44 void postvisit( VarArgsType * varArgsType ); 45 void postvisit( ZeroType * zeroType ); 46 void postvisit( OneType * oneType ); 45 47 private: 46 48 Type *dest; … … 79 81 EqvClass eqvClass; 80 82 if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { 83 // xxx - should this be ptrsCastable? 81 84 return ptrsAssignable( src, eqvClass.type, env ); 82 85 } // if … … 85 88 return objectCast( src, env, indexer ); 86 89 } else { 87 P trsCastableptrs( dest, env, indexer );90 PassVisitor<PtrsCastable> ptrs( dest, env, indexer ); 88 91 src->accept( ptrs ); 89 return ptrs. get_result();92 return ptrs.pass.get_result(); 90 93 } // if 91 94 } … … 95 98 } 96 99 97 void PtrsCastable:: visit( VoidType * ) {100 void PtrsCastable::postvisit( VoidType * ) { 98 101 result = objectCast( dest, env, indexer ); 99 102 } 100 103 101 void PtrsCastable:: visit( BasicType * ) {104 void PtrsCastable::postvisit( BasicType * ) { 102 105 result = objectCast( dest, env, indexer ); 103 106 } 104 107 105 void PtrsCastable:: visit( PointerType * ) {108 void PtrsCastable::postvisit( PointerType * ) { 106 109 result = objectCast( dest, env, indexer ); 107 110 } 108 111 109 void PtrsCastable:: visit( ArrayType * ) {112 void PtrsCastable::postvisit( ArrayType * ) { 110 113 result = objectCast( dest, env, indexer ); 111 114 } 112 115 113 void PtrsCastable:: visit( FunctionType * ) {116 void PtrsCastable::postvisit( FunctionType * ) { 114 117 // result = -1; 115 118 result = functionCast( dest, env, indexer ); 116 119 } 117 120 118 void PtrsCastable:: visit( StructInstType * ) {121 void PtrsCastable::postvisit( StructInstType * ) { 119 122 result = objectCast( dest, env, indexer ); 120 123 } 121 124 122 void PtrsCastable:: visit( UnionInstType * ) {125 void PtrsCastable::postvisit( UnionInstType * ) { 123 126 result = objectCast( dest, env, indexer ); 124 127 } 125 128 126 void PtrsCastable:: visit( EnumInstType * ) {129 void PtrsCastable::postvisit( EnumInstType * ) { 127 130 if ( dynamic_cast< EnumInstType* >( dest ) ) { 128 131 result = 1; … … 138 141 } 139 142 140 void PtrsCastable:: visit( TraitInstType * ) {}143 void PtrsCastable::postvisit( TraitInstType * ) {} 141 144 142 void PtrsCastable:: visit(TypeInstType *inst) {145 void PtrsCastable::postvisit(TypeInstType *inst) { 143 146 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1; 144 147 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1; 145 148 } 146 149 147 void PtrsCastable:: visit( TupleType * ) {150 void PtrsCastable::postvisit( TupleType * ) { 148 151 result = objectCast( dest, env, indexer ); 149 152 } 150 153 151 void PtrsCastable:: visit( VarArgsType * ) {154 void PtrsCastable::postvisit( VarArgsType * ) { 152 155 result = objectCast( dest, env, indexer ); 153 156 } 154 157 155 void PtrsCastable:: visit( ZeroType * ) {158 void PtrsCastable::postvisit( ZeroType * ) { 156 159 result = objectCast( dest, env, indexer ); 157 160 } 158 161 159 void PtrsCastable:: visit( OneType * ) {162 void PtrsCastable::postvisit( OneType * ) { 160 163 result = objectCast( dest, env, indexer ); 161 164 } -
src/ResolvExpr/RenameVars.cc
rd2d50d7 r81e1f32b 19 19 #include <utility> // for pair 20 20 21 #include "Common/PassVisitor.h" 21 22 #include "Common/SemanticError.h" // for SemanticError 22 23 #include "RenameVars.h" … … 27 28 28 29 namespace ResolvExpr { 29 RenameVars global_renamer; 30 namespace { 31 struct RenameVars { 32 RenameVars(); 33 void reset(); 30 34 31 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 32 mapStack.push_front( std::map< std::string, std::string >() ); 35 void previsit( TypeInstType * instType ); 36 void previsit( Type * ); 37 void postvisit( Type * ); 38 39 private: 40 int level, resetCount; 41 std::list< std::map< std::string, std::string > > mapStack; 42 }; 43 44 PassVisitor<RenameVars> global_renamer; 45 } // namespace 46 47 void renameTyVars( Type * t ) { 48 t->accept( global_renamer ); 33 49 } 34 50 35 void RenameVars::reset() { 36 level = 0; 37 resetCount++; 51 void resetTyVarRenaming() { 52 global_renamer.pass.reset(); 38 53 } 39 54 40 void RenameVars::visit( VoidType *voidType ){41 typeBefore( voidType );42 typeAfter( voidType);43 }55 namespace { 56 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 57 mapStack.push_front( std::map< std::string, std::string >() ); 58 } 44 59 45 void RenameVars::visit( BasicType *basicType) {46 typeBefore( basicType );47 typeAfter( basicType );48 }60 void RenameVars::reset() { 61 level = 0; 62 resetCount++; 63 } 49 64 50 void RenameVars::visit( PointerType *pointerType ) { 51 typeBefore( pointerType ); 52 maybeAccept( pointerType->get_base(), *this ); 53 typeAfter( pointerType ); 54 } 65 void RenameVars::previsit( TypeInstType * instType ) { 66 previsit( (Type *)instType ); 67 std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name ); 68 if ( i != mapStack.front().end() ) { 69 instType->name = i->second; 70 } // if 71 } 55 72 56 void RenameVars::visit( ArrayType *arrayType ) { 57 typeBefore( arrayType ); 58 maybeAccept( arrayType->get_dimension(), *this ); 59 maybeAccept( arrayType->get_base(), *this ); 60 typeAfter( arrayType ); 61 } 73 void RenameVars::previsit( Type * type ) { 74 if ( ! type->forall.empty() ) { 75 // copies current name mapping into new mapping 76 mapStack.push_front( mapStack.front() ); 77 // renames all "forall" type names to `_${level}_${name}' 78 for ( auto td : type->forall ) { 79 std::ostringstream output; 80 output << "_" << resetCount << "_" << level << "_" << td->name; 81 std::string newname( output.str() ); 82 mapStack.front()[ td->get_name() ] = newname; 83 td->name = newname; 84 // ditto for assertion names, the next level in 85 level++; 86 // acceptAll( td->assertions, *this ); 87 } // for 88 } // if 89 } 62 90 63 void RenameVars::visit( FunctionType *functionType ) { 64 typeBefore( functionType ); 65 acceptAll( functionType->get_returnVals(), *this ); 66 acceptAll( functionType->get_parameters(), *this ); 67 typeAfter( functionType ); 68 } 69 70 void RenameVars::visit( StructInstType *aggregateUseType ) { 71 typeBefore( aggregateUseType ); 72 acceptAll( aggregateUseType->get_parameters(), *this ); 73 typeAfter( aggregateUseType ); 74 } 75 76 void RenameVars::visit( UnionInstType *aggregateUseType ) { 77 typeBefore( aggregateUseType ); 78 acceptAll( aggregateUseType->get_parameters(), *this ); 79 typeAfter( aggregateUseType ); 80 } 81 82 void RenameVars::visit( EnumInstType *aggregateUseType ) { 83 typeBefore( aggregateUseType ); 84 acceptAll( aggregateUseType->get_parameters(), *this ); 85 typeAfter( aggregateUseType ); 86 } 87 88 void RenameVars::visit( TraitInstType *aggregateUseType ) { 89 typeBefore( aggregateUseType ); 90 acceptAll( aggregateUseType->get_parameters(), *this ); 91 typeAfter( aggregateUseType ); 92 } 93 94 void RenameVars::visit( TypeInstType *instType ) { 95 typeBefore( instType ); 96 std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->get_name() ); 97 if ( i != mapStack.front().end() ) { 98 instType->set_name( i->second ); 99 } else { 100 } // if 101 acceptAll( instType->get_parameters(), *this ); 102 typeAfter( instType ); 103 } 104 105 void RenameVars::visit( TupleType *tupleType ) { 106 typeBefore( tupleType ); 107 acceptAll( tupleType->get_types(), *this ); 108 typeAfter( tupleType ); 109 } 110 111 void RenameVars::visit( VarArgsType *varArgsType ) { 112 typeBefore( varArgsType ); 113 typeAfter( varArgsType ); 114 } 115 116 void RenameVars::visit( ZeroType *zeroType ) { 117 typeBefore( zeroType ); 118 typeAfter( zeroType ); 119 } 120 121 void RenameVars::visit( OneType *oneType ) { 122 typeBefore( oneType ); 123 typeAfter( oneType ); 124 } 125 126 void RenameVars::typeBefore( Type *type ) { 127 if ( ! type->get_forall().empty() ) { 128 // copies current name mapping into new mapping 129 mapStack.push_front( mapStack.front() ); 130 // renames all "forall" type names to `_${level}_${name}' 131 for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 132 std::ostringstream output; 133 output << "_" << resetCount << "_" << level << "_" << (*i)->get_name(); 134 std::string newname( output.str() ); 135 mapStack.front()[ (*i)->get_name() ] = newname; 136 (*i)->set_name( newname ); 137 // ditto for assertion names, the next level in 138 level++; 139 acceptAll( (*i)->get_assertions(), *this ); 140 } // for 141 } // if 142 } 143 144 void RenameVars::typeAfter( Type *type ) { 145 // clears name mapping added by typeBefore() 146 if ( ! type->get_forall().empty() ) { 147 mapStack.pop_front(); 148 } // if 149 } 150 91 void RenameVars::postvisit( Type * type ) { 92 // clears name mapping added by typeBefore() 93 if ( ! type->forall.empty() ) { 94 mapStack.pop_front(); 95 } // if 96 } 97 } // namespace 151 98 } // namespace ResolvExpr 152 99 -
src/ResolvExpr/RenameVars.h
rd2d50d7 r81e1f32b 24 24 25 25 namespace ResolvExpr { 26 /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID 27 void renameTyVars( Type * ); 26 28 27 /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID 28 class RenameVars : public Visitor { 29 public: 30 RenameVars(); 31 void reset(); 32 private: 33 virtual void visit( VoidType *basicType ); 34 virtual void visit( BasicType *basicType ); 35 virtual void visit( PointerType *pointerType ); 36 virtual void visit( ArrayType *arrayType ); 37 virtual void visit( FunctionType *functionType ); 38 virtual void visit( StructInstType *aggregateUseType ); 39 virtual void visit( UnionInstType *aggregateUseType ); 40 virtual void visit( EnumInstType *aggregateUseType ); 41 virtual void visit( TraitInstType *aggregateUseType ); 42 virtual void visit( TypeInstType *aggregateUseType ); 43 virtual void visit( TupleType *tupleType ); 44 virtual void visit( VarArgsType *varArgsType ); 45 virtual void visit( ZeroType *zeroType ); 46 virtual void visit( OneType *oneType ); 47 48 void typeBefore( Type *type ); 49 void typeAfter( Type *type ); 50 int level, resetCount; 51 std::list< std::map< std::string, std::string > > mapStack; 52 }; 53 54 extern RenameVars global_renamer; 29 /// resets internal state of renamer to avoid overflow 30 void resetTyVarRenaming(); 55 31 } // namespace ResolvExpr 56 32 -
src/ResolvExpr/Resolver.cc
rd2d50d7 r81e1f32b 132 132 133 133 void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) { 134 global_renamer.reset();134 resetTyVarRenaming(); 135 135 TypeEnvironment env; 136 136 Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); -
src/ResolvExpr/Unify.cc
rd2d50d7 r81e1f32b 44 44 namespace ResolvExpr { 45 45 46 class Unify : public Visitor { 47 public: 46 struct Unify : public WithShortCircuiting { 48 47 Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 49 48 50 49 bool get_result() const { return result; } 50 51 void previsit( BaseSyntaxNode * ) { visit_children = false; } 52 53 void postvisit( VoidType * voidType ); 54 void postvisit( BasicType * basicType ); 55 void postvisit( PointerType * pointerType ); 56 void postvisit( ArrayType * arrayType ); 57 void postvisit( ReferenceType * refType ); 58 void postvisit( FunctionType * functionType ); 59 void postvisit( StructInstType * aggregateUseType ); 60 void postvisit( UnionInstType * aggregateUseType ); 61 void postvisit( EnumInstType * aggregateUseType ); 62 void postvisit( TraitInstType * aggregateUseType ); 63 void postvisit( TypeInstType * aggregateUseType ); 64 void postvisit( TupleType * tupleType ); 65 void postvisit( VarArgsType * varArgsType ); 66 void postvisit( ZeroType * zeroType ); 67 void postvisit( OneType * oneType ); 68 51 69 private: 52 virtual void visit(VoidType *voidType);53 virtual void visit(BasicType *basicType);54 virtual void visit(PointerType *pointerType);55 virtual void visit(ArrayType *arrayType);56 virtual void visit(ReferenceType *refType);57 virtual void visit(FunctionType *functionType);58 virtual void visit(StructInstType *aggregateUseType);59 virtual void visit(UnionInstType *aggregateUseType);60 virtual void visit(EnumInstType *aggregateUseType);61 virtual void visit(TraitInstType *aggregateUseType);62 virtual void visit(TypeInstType *aggregateUseType);63 virtual void visit(TupleType *tupleType);64 virtual void visit(VarArgsType *varArgsType);65 virtual void visit(ZeroType *zeroType);66 virtual void visit(OneType *oneType);67 68 70 template< typename RefType > void handleRefType( RefType *inst, Type *other ); 69 71 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other ); … … 325 327 result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 326 328 } else { 327 Unifycomparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );329 PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 328 330 type1->accept( comparator ); 329 result = comparator. get_result();331 result = comparator.pass.get_result(); 330 332 } // if 331 333 #ifdef DEBUG … … 404 406 } 405 407 406 void Unify:: visit( __attribute__((unused)) VoidType *voidType) {408 void Unify::postvisit( __attribute__((unused)) VoidType *voidType) { 407 409 result = dynamic_cast< VoidType* >( type2 ); 408 410 } 409 411 410 void Unify:: visit(BasicType *basicType) {412 void Unify::postvisit(BasicType *basicType) { 411 413 if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) { 412 414 result = basicType->get_kind() == otherBasic->get_kind(); … … 436 438 } 437 439 438 void Unify:: visit(PointerType *pointerType) {440 void Unify::postvisit(PointerType *pointerType) { 439 441 if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) { 440 442 result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); … … 444 446 } 445 447 446 void Unify:: visit(ReferenceType *refType) {448 void Unify::postvisit(ReferenceType *refType) { 447 449 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) { 448 450 result = unifyExact( refType->get_base(), otherRef->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); … … 452 454 } 453 455 454 void Unify:: visit(ArrayType *arrayType) {456 void Unify::postvisit(ArrayType *arrayType) { 455 457 ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 ); 456 458 // to unify, array types must both be VLA or both not VLA … … 567 569 } 568 570 569 void Unify:: visit(FunctionType *functionType) {571 void Unify::postvisit(FunctionType *functionType) { 570 572 FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 ); 571 573 if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) { … … 669 671 } 670 672 671 void Unify:: visit(StructInstType *structInst) {673 void Unify::postvisit(StructInstType *structInst) { 672 674 handleGenericRefType( structInst, type2 ); 673 675 } 674 676 675 void Unify:: visit(UnionInstType *unionInst) {677 void Unify::postvisit(UnionInstType *unionInst) { 676 678 handleGenericRefType( unionInst, type2 ); 677 679 } 678 680 679 void Unify:: visit(EnumInstType *enumInst) {681 void Unify::postvisit(EnumInstType *enumInst) { 680 682 handleRefType( enumInst, type2 ); 681 683 } 682 684 683 void Unify:: visit(TraitInstType *contextInst) {685 void Unify::postvisit(TraitInstType *contextInst) { 684 686 handleRefType( contextInst, type2 ); 685 687 } 686 688 687 void Unify:: visit(TypeInstType *typeInst) {689 void Unify::postvisit(TypeInstType *typeInst) { 688 690 assert( openVars.find( typeInst->get_name() ) == openVars.end() ); 689 691 TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 ); … … 740 742 } 741 743 742 void Unify:: visit(TupleType *tupleType) {744 void Unify::postvisit(TupleType *tupleType) { 743 745 if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) { 744 746 std::unique_ptr<TupleType> flat1( tupleType->clone() ); … … 757 759 } 758 760 759 void Unify:: visit( __attribute__((unused)) VarArgsType *varArgsType ) {761 void Unify::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) { 760 762 result = dynamic_cast< VarArgsType* >( type2 ); 761 763 } 762 764 763 void Unify:: visit( __attribute__((unused)) ZeroType *zeroType ) {765 void Unify::postvisit( __attribute__((unused)) ZeroType *zeroType ) { 764 766 result = dynamic_cast< ZeroType* >( type2 ); 765 767 } 766 768 767 void Unify:: visit( __attribute__((unused)) OneType *oneType ) {769 void Unify::postvisit( __attribute__((unused)) OneType *oneType ) { 768 770 result = dynamic_cast< OneType* >( type2 ); 769 771 }
Note:
See TracChangeset
for help on using the changeset viewer.