Changeset 24d6572 for src/GenPoly
- Timestamp:
- Jun 12, 2023, 2:45:32 PM (2 years ago)
- Branches:
- ast-experimental, master
- Children:
- 62d62db
- Parents:
- 34b4268 (diff), 251ce80 (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/GenPoly
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r34b4268 r24d6572 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Dec 13 23:40:34 201913 // Update Count : 34 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Dec 19 16:36:00 2022 13 // Update Count : 348 14 14 // 15 16 #include "Box.h" 15 17 16 18 #include <algorithm> // for mismatch … … 24 26 #include <utility> // for pair 25 27 26 #include "Box.h"27 28 28 #include "CodeGen/OperatorTable.h" 29 29 #include "Common/PassVisitor.h" // for PassVisitor … … 31 31 #include "Common/SemanticError.h" // for SemanticError 32 32 #include "Common/UniqueName.h" // for UniqueName 33 #include "Common/ utility.h" // for toString33 #include "Common/ToString.hpp" // for toCString 34 34 #include "FindFunction.h" // for findFunction, findAndReplace... 35 35 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_i... … … 37 37 #include "InitTweak/InitTweak.h" // for getFunctionName, isAssignment 38 38 #include "Lvalue.h" // for generalizedLvalue 39 #include "ResolvExpr/ typeops.h"// for typesCompatible39 #include "ResolvExpr/Unify.h" // for typesCompatible 40 40 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iter... 41 41 #include "ScrubTyVars.h" // for ScrubTyVars … … 72 72 }; 73 73 74 /// Updates the call sites of polymorphic functions. 74 75 /// Replaces polymorphic return types with out-parameters, 75 76 /// replaces calls to polymorphic functions with adapter calls, 76 77 /// and adds appropriate type variables to the function call. 77 class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {78 class CallAdapter final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<CallAdapter>, public WithShortCircuiting { 78 79 public: 79 Pass1(); 80 80 CallAdapter(); 81 82 void premutate( Declaration * declaration ); 81 83 void premutate( FunctionDecl * functionDecl ); 82 84 void premutate( TypeDecl * typeDecl ); … … 138 140 }; 139 141 142 /// Updates declarations (and types) that require adapters. 140 143 /// * Moves polymorphic returns in function types to pointer-type parameters 141 144 /// * adds type size and assertion parameters to parameter lists 142 struct Pass2final : public BoxPass, public WithGuards {145 struct DeclAdapter final : public BoxPass, public WithGuards { 143 146 void handleAggDecl(); 144 147 … … 210 213 }; 211 214 215 /// Erases unneeded/unwanted polymorphic information. 212 216 /// Replaces initialization of polymorphic values with alloca, 213 217 /// declaration of dtype/ftype with appropriate void expression, 214 218 /// sizeof expressions of polymorphic types with the proper variable, 215 219 /// and strips fields from generic struct declarations. 216 struct Pass3 final : public BoxPass, public WithGuards { 217 template< typename DeclClass > 218 void handleDecl( DeclClass * decl, Type * type ); 219 220 struct Eraser final { 220 221 void premutate( ObjectDecl * objectDecl ); 221 222 void premutate( FunctionDecl * functionDecl ); … … 223 224 void premutate( StructDecl * structDecl ); 224 225 void premutate( UnionDecl * unionDecl ); 225 void premutate( TypeDecl * typeDecl );226 void premutate( PointerType * pointerType );227 void premutate( FunctionType * funcType );228 226 }; 229 227 } // anonymous namespace … … 231 229 void box( std::list< Declaration *>& translationUnit ) { 232 230 PassVisitor<LayoutFunctionBuilder> layoutBuilder; 233 PassVisitor< Pass1> pass1;234 PassVisitor< Pass2> pass2;231 PassVisitor<CallAdapter> callAdapter; 232 PassVisitor<DeclAdapter> declAdapter; 235 233 PassVisitor<PolyGenericCalculator> polyCalculator; 236 PassVisitor< Pass3> pass3;234 PassVisitor<Eraser> eraser; 237 235 238 236 acceptAll( translationUnit, layoutBuilder ); 239 mutateAll( translationUnit, pass1);240 mutateAll( translationUnit, pass2);237 mutateAll( translationUnit, callAdapter ); 238 mutateAll( translationUnit, declAdapter ); 241 239 mutateAll( translationUnit, polyCalculator ); 242 mutateAll( translationUnit, pass3);240 mutateAll( translationUnit, eraser ); 243 241 } 244 242 245 ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////243 ////////////////////////////////// LayoutFunctionBuilder //////////////////////////////////////// 246 244 247 245 /// Get a list of type declarations that will affect a layout function … … 423 421 } 424 422 425 ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////423 ////////////////////////////////////////////// CallAdapter ////////////////////////////////////// 426 424 427 425 namespace { 428 426 std::string makePolyMonoSuffix( FunctionType const * function, const TyVarMap &tyVars ) { 429 std::stringstream name;430 431 427 // NOTE: this function previously used isPolyObj, which failed to produce 432 428 // the correct thing in some situations. It's not clear to me why this wasn't working. … … 435 431 // to take those polymorphic types as pointers. Therefore, there can be two different functions 436 432 // with the same mangled name, so we need to further mangle the names. 433 std::stringstream name; 437 434 for ( DeclarationWithType const * const ret : function->returnVals ) { 438 if ( isPolyType( ret->get_type(), tyVars ) ) { 439 name << "P"; 440 } else { 441 name << "M"; 442 } 443 } 444 name << "_"; 435 name << ( isPolyType( ret->get_type(), tyVars ) ? 'P' : 'M' ); 436 } 437 name << '_'; 445 438 for ( DeclarationWithType const * const arg : function->parameters ) { 446 if ( isPolyType( arg->get_type(), tyVars ) ) { 447 name << "P"; 448 } else { 449 name << "M"; 450 } 451 } // for 439 name << ( isPolyType( arg->get_type(), tyVars ) ? 'P' : 'M' ); 440 } 452 441 return name.str(); 453 442 } … … 465 454 Type *replaceWithConcrete( Type *type, TypeSubstitution const * env, bool doClone = true ); 466 455 467 Pass1::Pass1() : tempNamer( "_temp" ) {} 468 469 void Pass1::premutate( FunctionDecl *functionDecl ) { 456 CallAdapter::CallAdapter() : tempNamer( "_temp" ) {} 457 458 void CallAdapter::premutate( Declaration * ) { 459 // Prevent type declaration information from leaking out. 460 GuardScope( scopeTyVars ); 461 } 462 463 void CallAdapter::premutate( FunctionDecl *functionDecl ) { 470 464 if ( functionDecl->get_statements() ) { // empty routine body ? 471 465 // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl; … … 500 494 for ( FunctionType const * const funType : functions ) { 501 495 std::string mangleName = mangleAdapterName( funType, scopeTyVars ); 502 if ( adapters.find( mangleName ) == adapters.end() ) {496 if ( !adapters.contains( mangleName ) ) { 503 497 std::string adapterName = makeAdapterName( mangleName ); 504 498 adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, nullptr, new PointerType( Type::Qualifiers(), makeAdapterType( funType, scopeTyVars ) ), nullptr ) ) ); … … 509 503 } 510 504 511 void Pass1::premutate( TypeDecl *typeDecl ) {505 void CallAdapter::premutate( TypeDecl *typeDecl ) { 512 506 addToTyVarMap( typeDecl, scopeTyVars ); 513 507 } 514 508 515 void Pass1::premutate( CommaExpr *commaExpr ) {509 void CallAdapter::premutate( CommaExpr *commaExpr ) { 516 510 // Attempting to find application expressions that were mutated by the copy constructor passes 517 511 // to use an explicit return variable, so that the variable can be reused as a parameter to the … … 531 525 } 532 526 533 std::list< Expression *>::iterator Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) {527 std::list< Expression *>::iterator CallAdapter::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 534 528 Type *polyType = isPolyType( parmType, exprTyVars ); 535 529 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { … … 558 552 } 559 553 560 std::list< Expression *>::iterator Pass1::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ) {554 std::list< Expression *>::iterator CallAdapter::passTypeVars( ApplicationExpr *appExpr, Type *polyRetType, const TyVarMap &exprTyVars ) { 561 555 assert( env ); 562 556 std::list< Expression *>::iterator arg = appExpr->args.begin(); … … 568 562 // even when converted to strings, sort in the original order. 569 563 // (At least, that is the best explination I have.) 570 for ( std::pair< std::string, TypeDecl::Data> const & tyParam : exprTyVars ) {564 for ( std::pair<const std::string, TypeDecl::Data> const & tyParam : exprTyVars ) { 571 565 if ( !tyParam.second.isComplete ) continue; 572 566 Type *concrete = env->lookup( tyParam.first ); … … 611 605 } 612 606 613 ObjectDecl * Pass1::makeTemporary( Type *type ) {607 ObjectDecl *CallAdapter::makeTemporary( Type *type ) { 614 608 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, type, 0 ); 615 609 stmtsToAddBefore.push_back( new DeclStmt( newObj ) ); … … 617 611 } 618 612 619 Expression * Pass1::addRetParam( ApplicationExpr *appExpr, Type *retType ) {613 Expression *CallAdapter::addRetParam( ApplicationExpr *appExpr, Type *retType ) { 620 614 // Create temporary to hold return value of polymorphic function and produce that temporary as a result 621 615 // using a comma expression. … … 680 674 } 681 675 682 Expression * Pass1::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) {676 Expression *CallAdapter::addDynRetParam( ApplicationExpr *appExpr, Type *dynType ) { 683 677 Type *concrete = replaceWithConcrete( dynType, env ); 684 678 // add out-parameter for return value … … 686 680 } 687 681 688 Expression * Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) {682 Expression *CallAdapter::applyAdapter( ApplicationExpr *appExpr, FunctionType *function ) { 689 683 Expression *ret = appExpr; 690 684 if ( isDynRet( function, scopeTyVars ) ) { … … 735 729 } 736 730 737 void Pass1::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) {731 void CallAdapter::boxParam( Expression *&arg, Type *param, const TyVarMap &exprTyVars ) { 738 732 assertf( arg->result, "arg does not have result: %s", toString( arg ).c_str() ); 739 733 addCast( arg, param, exprTyVars ); … … 770 764 } 771 765 772 void Pass1::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) {766 void CallAdapter::boxParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *function, const TyVarMap &exprTyVars ) { 773 767 for ( DeclarationWithType * param : function->parameters ) { 774 768 assertf( arg != appExpr->args.end(), "boxParams: missing argument for param %s to %s in %s", toString( param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); … … 778 772 } 779 773 780 void Pass1::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) {774 void CallAdapter::addInferredParams( ApplicationExpr *appExpr, std::list< Expression *>::iterator arg, FunctionType *functionType, const TyVarMap &tyVars ) { 781 775 for ( TypeDecl * const tyVar : functionType->forall ) { 782 776 for ( DeclarationWithType * const assert : tyVar->assertions ) { … … 846 840 } 847 841 848 FunctionDecl * Pass1::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) {842 FunctionDecl *CallAdapter::makeAdapter( FunctionType const *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { 849 843 FunctionType *adapterType = makeAdapterType( adaptee, tyVars ); 850 844 adapterType = ScrubTyVars::scrub( adapterType, tyVars ); … … 906 900 } 907 901 908 void Pass1::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) {902 void CallAdapter::passAdapters( ApplicationExpr * appExpr, FunctionType * functionType, const TyVarMap & exprTyVars ) { 909 903 // collect a list of function types passed as parameters or implicit parameters (assertions) 910 904 std::list<FunctionType const *> functions; … … 923 917 924 918 for ( FunctionType const * const funType : functions ) { 925 FunctionType *originalFunction = funType->clone(); 926 FunctionType *realFunction = funType->clone(); 927 std::string mangleName = SymTab::Mangler::mangle( realFunction ); 919 std::string mangleName = SymTab::Mangler::mangle( funType ); 928 920 929 921 // only attempt to create an adapter or pass one as a parameter if we haven't already done so for this 930 922 // pre-substitution parameter function type. 931 923 // The second part of the insert result is "is the value new". 932 if ( adaptersDone.insert( mangleName ).second ) { 933 934 // apply substitution to type variables to figure out what the adapter's type should look like 935 assert( env ); 936 env->apply( realFunction ); 937 mangleName = SymTab::Mangler::mangle( realFunction ); 938 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 939 940 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 941 AdapterIter adapter = adapters.find( mangleName ); 942 if ( adapter == adapters.end() ) { 943 // adapter has not been created yet in the current scope, so define it 944 FunctionDecl *newAdapter = makeAdapter( funType, realFunction, mangleName, exprTyVars ); 945 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) ); 946 adapter = answer.first; 947 stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) ); 948 } // if 949 assert( adapter != adapters.end() ); 950 951 // add the appropriate adapter as a parameter 952 appExpr->get_args().push_front( new VariableExpr( adapter->second ) ); 924 if ( !adaptersDone.insert( mangleName ).second ) continue; 925 926 // Apply substitution to type variables to figure out what the adapter's type should look like. 927 assert( env ); 928 FunctionType *realType = funType->clone(); 929 env->apply( realType ); 930 mangleName = SymTab::Mangler::mangle( realType ); 931 mangleName += makePolyMonoSuffix( funType, exprTyVars ); 932 933 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter; 934 AdapterIter adapter = adapters.find( mangleName ); 935 if ( adapter == adapters.end() ) { 936 // Adapter has not been created yet in the current scope, so define it. 937 FunctionDecl *newAdapter = makeAdapter( funType, realType, mangleName, exprTyVars ); 938 std::pair< AdapterIter, bool > answer = adapters.insert( mangleName, newAdapter ); 939 adapter = answer.first; 940 stmtsToAddBefore.push_back( new DeclStmt( newAdapter ) ); 953 941 } // if 942 assert( adapter != adapters.end() ); 943 944 // Add the appropriate adapter as a parameter. 945 appExpr->args.push_front( new VariableExpr( adapter->second ) ); 954 946 } // for 955 947 } // passAdapters … … 974 966 } 975 967 976 Expression * Pass1::handleIntrinsics( ApplicationExpr *appExpr ) {968 Expression *CallAdapter::handleIntrinsics( ApplicationExpr *appExpr ) { 977 969 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr *>( appExpr->function ) ) { 978 970 if ( varExpr->var->linkage == LinkageSpec::Intrinsic ) { … … 1097 1089 } 1098 1090 1099 Expression * Pass1::postmutate( ApplicationExpr *appExpr ) {1091 Expression *CallAdapter::postmutate( ApplicationExpr *appExpr ) { 1100 1092 // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl; 1101 1093 // for ( auto tyVar : scopeTyVars ) { … … 1169 1161 } 1170 1162 1171 Expression * Pass1::postmutate( UntypedExpr *expr ) {1163 Expression * CallAdapter::postmutate( UntypedExpr *expr ) { 1172 1164 if ( isPolyDeref( expr, scopeTyVars, env ) ) { 1173 1165 Expression *ret = expr->args.front(); … … 1179 1171 } 1180 1172 1181 void Pass1::premutate( AddressExpr * ) { visit_children = false; }1182 1183 Expression * Pass1::postmutate( AddressExpr * addrExpr ) {1173 void CallAdapter::premutate( AddressExpr * ) { visit_children = false; } 1174 1175 Expression * CallAdapter::postmutate( AddressExpr * addrExpr ) { 1184 1176 assert( addrExpr->arg->result && ! addrExpr->arg->result->isVoid() ); 1185 1177 … … 1212 1204 } 1213 1205 1214 void Pass1::premutate( ReturnStmt *returnStmt ) {1206 void CallAdapter::premutate( ReturnStmt *returnStmt ) { 1215 1207 if ( retval && returnStmt->expr ) { 1216 1208 assert( returnStmt->expr->result && ! returnStmt->expr->result->isVoid() ); … … 1220 1212 } 1221 1213 1222 void Pass1::premutate( PointerType *pointerType ) {1214 void CallAdapter::premutate( PointerType *pointerType ) { 1223 1215 GuardScope( scopeTyVars ); 1224 1216 makeTyVarMap( pointerType, scopeTyVars ); 1225 1217 } 1226 1218 1227 void Pass1::premutate( FunctionType *functionType ) {1219 void CallAdapter::premutate( FunctionType *functionType ) { 1228 1220 GuardScope( scopeTyVars ); 1229 1221 makeTyVarMap( functionType, scopeTyVars ); 1230 1222 } 1231 1223 1232 void Pass1::beginScope() {1224 void CallAdapter::beginScope() { 1233 1225 adapters.beginScope(); 1234 1226 } 1235 1227 1236 void Pass1::endScope() {1228 void CallAdapter::endScope() { 1237 1229 adapters.endScope(); 1238 1230 } 1239 1231 1240 ////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////1241 1242 void Pass2::addAdapters( FunctionType *functionType ) {1232 ////////////////////////////////////////// DeclAdapter ////////////////////////////////////////// 1233 1234 void DeclAdapter::addAdapters( FunctionType *functionType ) { 1243 1235 std::list< FunctionType const *> functions; 1244 1236 for ( DeclarationWithType * const arg : functionType->parameters ) { … … 1260 1252 } 1261 1253 1262 DeclarationWithType * Pass2::postmutate( FunctionDecl *functionDecl ) {1254 DeclarationWithType * DeclAdapter::postmutate( FunctionDecl *functionDecl ) { 1263 1255 FunctionType * ftype = functionDecl->type; 1264 1256 if ( ! ftype->returnVals.empty() && functionDecl->statements ) { … … 1285 1277 } 1286 1278 1287 void Pass2::premutate( StructDecl * ) {1279 void DeclAdapter::premutate( StructDecl * ) { 1288 1280 // prevent tyVars from leaking into containing scope 1289 1281 GuardScope( scopeTyVars ); 1290 1282 } 1291 1283 1292 void Pass2::premutate( UnionDecl * ) {1284 void DeclAdapter::premutate( UnionDecl * ) { 1293 1285 // prevent tyVars from leaking into containing scope 1294 1286 GuardScope( scopeTyVars ); 1295 1287 } 1296 1288 1297 void Pass2::premutate( TraitDecl * ) {1289 void DeclAdapter::premutate( TraitDecl * ) { 1298 1290 // prevent tyVars from leaking into containing scope 1299 1291 GuardScope( scopeTyVars ); 1300 1292 } 1301 1293 1302 void Pass2::premutate( TypeDecl *typeDecl ) {1294 void DeclAdapter::premutate( TypeDecl *typeDecl ) { 1303 1295 addToTyVarMap( typeDecl, scopeTyVars ); 1304 1296 } 1305 1297 1306 void Pass2::premutate( PointerType *pointerType ) {1298 void DeclAdapter::premutate( PointerType *pointerType ) { 1307 1299 GuardScope( scopeTyVars ); 1308 1300 makeTyVarMap( pointerType, scopeTyVars ); 1309 1301 } 1310 1302 1311 void Pass2::premutate( FunctionType *funcType ) {1303 void DeclAdapter::premutate( FunctionType *funcType ) { 1312 1304 GuardScope( scopeTyVars ); 1313 1305 makeTyVarMap( funcType, scopeTyVars ); … … 1393 1385 } 1394 1386 1395 ////////////////////////////////////////// PolyGenericCalculator //////////////////////////////// ////////////////////1387 ////////////////////////////////////////// PolyGenericCalculator //////////////////////////////// 1396 1388 1397 1389 PolyGenericCalculator::PolyGenericCalculator() … … 1474 1466 // make sure that any type information passed into the function is accounted for 1475 1467 for ( DeclarationWithType * const fnParam : funcType->get_parameters() ) { 1476 // condition here duplicates that in Pass2::mutate( FunctionType* )1468 // condition here duplicates that in DeclAdapter::mutate( FunctionType* ) 1477 1469 Type *polyType = isPolyType( fnParam->get_type(), scopeTyVars ); 1478 1470 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { … … 1501 1493 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 1502 1494 // do not try to monomorphize generic parameters 1503 if ( scopeTyVars. find( typeInst->get_name() ) != scopeTyVars.end() && ! genericParams.count( typeInst->name ) ) {1495 if ( scopeTyVars.contains( typeInst->get_name() ) && ! genericParams.count( typeInst->name ) ) { 1504 1496 // polymorphic aggregate members should be converted into monomorphic members. 1505 1497 // Using char[size_T] here respects the expected sizing rules of an aggregate type. … … 1710 1702 1711 1703 if ( auto typeInst = dynamic_cast< TypeInstType const * >( ty ) ) { 1712 if ( scopeTyVars. find( typeInst->get_name() ) != scopeTyVars.end() ) {1704 if ( scopeTyVars.contains( typeInst->get_name() ) ) { 1713 1705 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set 1714 1706 return true; … … 1718 1710 // check if this type already has a layout generated for it 1719 1711 std::string typeName = mangleType( ty ); 1720 if ( knownLayouts. find( typeName ) != knownLayouts.end() ) return true;1712 if ( knownLayouts.contains( typeName ) ) return true; 1721 1713 1722 1714 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized … … 1755 1747 // check if this type already has a layout generated for it 1756 1748 std::string typeName = mangleType( ty ); 1757 if ( knownLayouts. find( typeName ) != knownLayouts.end() ) return true;1749 if ( knownLayouts.contains( typeName ) ) return true; 1758 1750 1759 1751 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized … … 1846 1838 } else { 1847 1839 std::string offsetName = offsetofName( mangleType( ty ) ); 1848 if ( knownOffsets. find( offsetName ) != knownOffsets.end() ) {1840 if ( knownOffsets.contains( offsetName ) ) { 1849 1841 // use the already-generated offsets for this type 1850 1842 ret = new NameExpr( offsetName ); … … 1884 1876 } 1885 1877 1886 ////////////////////////////////////////// Pass3 //////////////////////////////////////////////////// 1887 1888 template< typename DeclClass > 1889 void Pass3::handleDecl( DeclClass * decl, Type * type ) { 1890 GuardScope( scopeTyVars ); 1891 makeTyVarMap( type, scopeTyVars ); 1892 ScrubTyVars::scrubAll( decl ); 1893 } 1894 1895 void Pass3::premutate( ObjectDecl * objectDecl ) { 1896 handleDecl( objectDecl, objectDecl->type ); 1897 } 1898 1899 void Pass3::premutate( FunctionDecl * functionDecl ) { 1900 handleDecl( functionDecl, functionDecl->type ); 1901 } 1902 1903 void Pass3::premutate( TypedefDecl * typedefDecl ) { 1904 handleDecl( typedefDecl, typedefDecl->base ); 1878 ////////////////////////////////////////// Eraser /////////////////////////////////////////////// 1879 1880 void Eraser::premutate( ObjectDecl * objectDecl ) { 1881 ScrubTyVars::scrubAll( objectDecl ); 1882 } 1883 1884 void Eraser::premutate( FunctionDecl * functionDecl ) { 1885 ScrubTyVars::scrubAll( functionDecl ); 1886 } 1887 1888 void Eraser::premutate( TypedefDecl * typedefDecl ) { 1889 ScrubTyVars::scrubAll( typedefDecl ); 1905 1890 } 1906 1891 1907 1892 /// Strips the members from a generic aggregate 1908 void stripGenericMembers(AggregateDecl * decl) {1893 static void stripGenericMembers( AggregateDecl * decl ) { 1909 1894 if ( ! decl->parameters.empty() ) decl->members.clear(); 1910 1895 } 1911 1896 1912 void Pass3::premutate( StructDecl * structDecl ) {1897 void Eraser::premutate( StructDecl * structDecl ) { 1913 1898 stripGenericMembers( structDecl ); 1914 1899 } 1915 1900 1916 void Pass3::premutate( UnionDecl * unionDecl ) {1901 void Eraser::premutate( UnionDecl * unionDecl ) { 1917 1902 stripGenericMembers( unionDecl ); 1918 }1919 1920 void Pass3::premutate( TypeDecl * typeDecl ) {1921 addToTyVarMap( typeDecl, scopeTyVars );1922 }1923 1924 void Pass3::premutate( PointerType * pointerType ) {1925 GuardScope( scopeTyVars );1926 makeTyVarMap( pointerType, scopeTyVars );1927 }1928 1929 void Pass3::premutate( FunctionType * functionType ) {1930 GuardScope( scopeTyVars );1931 makeTyVarMap( functionType, scopeTyVars );1932 1903 } 1933 1904 } // anonymous namespace … … 1939 1910 // compile-command: "make install" // 1940 1911 // End: // 1941 -
src/GenPoly/ErasableScopedMap.h
r34b4268 r24d6572 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ScopedMap.h --7 // ErasableScopedMap.h -- 8 8 // 9 9 // Author : Aaron B. Moss … … 51 51 typedef typename Scope::const_pointer const_pointer; 52 52 53 // Both iterator types are complete bidirection iterators, definedbelow.53 // Both iterator types are complete bidirectional iterators, see below. 54 54 class iterator; 55 55 class const_iterator; … … 118 118 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 119 119 120 Value& operator[] ( const Key &key ) { 121 iterator slot = find( key ); 122 if ( slot != end() ) return slot->second; 123 return insert( key, Value() ).first->second; 124 } 125 120 126 /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise 121 127 size_type erase( const Key &key ) { … … 130 136 } 131 137 132 Value& operator[] ( const Key &key ) { 133 iterator slot = find( key ); 134 if ( slot != end() ) return slot->second; 135 return insert( key, Value() ).first->second; 138 bool contains( const Key & key ) const { 139 return find( key ) != cend(); 136 140 } 137 141 }; -
src/GenPoly/FindFunction.cc
r34b4268 r24d6572 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Fri Feb 05 12:22:20 201613 // Update Count : 611 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 7 17:05:20 2022 13 // Update Count : 7 14 14 // 15 15 … … 18 18 #include <utility> // for pair 19 19 20 #include "AST/Pass.hpp" // for Pass 21 #include "AST/Type.hpp" 20 22 #include "Common/PassVisitor.h" // for PassVisitor 21 23 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::iterator … … 89 91 handleForall( pointerType->get_forall() ); 90 92 } 93 94 namespace { 95 96 struct FindFunctionCore : 97 public ast::WithGuards, 98 public ast::WithShortCircuiting, 99 public ast::WithVisitorRef<FindFunctionCore> { 100 FindFunctionCore( 101 std::vector<ast::ptr<ast::FunctionType>> & functions, 102 const TypeVarMap & typeVars, FindFunctionPred predicate, 103 bool replaceMode ); 104 105 void previsit( ast::FunctionType const * type ); 106 ast::Type const * postvisit( ast::FunctionType const * type ); 107 void previsit( ast::PointerType const * type ); 108 private: 109 void handleForall( const ast::FunctionType::ForallList & forall ); 110 111 std::vector<ast::ptr<ast::FunctionType>> &functions; 112 TypeVarMap typeVars; 113 FindFunctionPred predicate; 114 bool replaceMode; 115 }; 116 117 FindFunctionCore::FindFunctionCore( 118 std::vector<ast::ptr<ast::FunctionType>> & functions, 119 const TypeVarMap &typeVars, FindFunctionPred predicate, 120 bool replaceMode ) : 121 functions( functions ), typeVars( typeVars ), 122 predicate( predicate ), replaceMode( replaceMode ) {} 123 124 void FindFunctionCore::handleForall( const ast::FunctionType::ForallList & forall ) { 125 for ( const ast::ptr<ast::TypeInstType> & td : forall ) { 126 TypeVarMap::iterator var = typeVars.find( *td ); 127 if ( var != typeVars.end() ) { 128 typeVars.erase( var->first ); 129 } // if 130 } // for 131 } 132 133 void FindFunctionCore::previsit( ast::FunctionType const * type ) { 134 visit_children = false; 135 GuardScope( typeVars ); 136 handleForall( type->forall ); 137 //ast::accept_all( type->returns, *visitor ); 138 // This might have to become ast::mutate_each with return. 139 ast::accept_each( type->returns, *visitor ); 140 } 141 142 ast::Type const * FindFunctionCore::postvisit( ast::FunctionType const * type ) { 143 ast::Type const * ret = type; 144 if ( predicate( type, typeVars ) ) { 145 functions.push_back( type ); 146 if ( replaceMode ) { 147 // replace type parameters in function type with void* 148 ret = scrubTypeVars( ast::deepCopy( type ), typeVars ); 149 } // if 150 } // if 151 return ret; 152 } 153 154 void FindFunctionCore::previsit( ast::PointerType const * /*type*/ ) { 155 GuardScope( typeVars ); 156 //handleForall( type->forall ); 157 } 158 159 } // namespace 160 161 void findFunction( const ast::Type * type, 162 std::vector<ast::ptr<ast::FunctionType>> & functions, 163 const TypeVarMap & typeVars, FindFunctionPred predicate ) { 164 ast::Pass<FindFunctionCore> pass( functions, typeVars, predicate, false ); 165 type->accept( pass ); 166 //(void)type; 167 //(void)functions; 168 //(void)typeVars; 169 //(void)predicate; 170 } 171 172 const ast::Type * findAndReplaceFunction( const ast::Type * type, 173 std::vector<ast::ptr<ast::FunctionType>> & functions, 174 const TypeVarMap & typeVars, FindFunctionPred predicate ) { 175 ast::Pass<FindFunctionCore> pass( functions, typeVars, predicate, true ); 176 return type->accept( pass ); 177 //(void)functions; 178 //(void)typeVars; 179 //(void)predicate; 180 //return type; 181 } 182 91 183 } // namespace GenPoly 92 184 -
src/GenPoly/FindFunction.h
r34b4268 r24d6572 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:23:36 201713 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 7 10:30:00 2022 13 // Update Count : 3 14 14 // 15 15 … … 30 30 /// like `findFunction`, but also replaces the function type with void ()(void) 31 31 void findAndReplaceFunction( Type *&type, std::list< FunctionType const * > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 32 33 typedef bool (*FindFunctionPred)( const ast::FunctionType *, const TypeVarMap & ); 34 35 /// Recursively walks `type`, placing all functions that match `predicate` 36 /// under `typeVars` into `functions`. 37 void findFunction( const ast::Type * type, 38 std::vector<ast::ptr<ast::FunctionType>> & functions, 39 const TypeVarMap & typeVars, FindFunctionPred predicate ); 40 /// Like findFunction, but also replaces the function type with `void ()(void)`. 41 const ast::Type * findAndReplaceFunction( const ast::Type * type, 42 std::vector<ast::ptr<ast::FunctionType>> & functions, 43 const TypeVarMap & typeVars, FindFunctionPred predicate ); 44 32 45 } // namespace GenPoly 33 46 -
src/GenPoly/GenPoly.cc
r34b4268 r24d6572 24 24 #include <vector> // for vector 25 25 26 #include "AST/Expr.hpp" 26 27 #include "AST/Type.hpp" 28 #include "AST/TypeSubstitution.hpp" 27 29 #include "GenPoly/ErasableScopedMap.h" // for ErasableScopedMap<>::const_it... 28 30 #include "ResolvExpr/typeops.h" // for flatten … … 170 172 171 173 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 172 if ( tyVars. find( typeInst->get_name() ) != tyVars.end() ) {174 if ( tyVars.contains( typeInst->get_name() ) ) { 173 175 return type; 174 176 } … … 187 189 188 190 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 189 return tyVars.find(typeInst->typeString()) != tyVars.end() ? type : nullptr;191 if ( tyVars.contains( typeInst->typeString() ) ) return type; 190 192 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) { 191 193 return isPolyType( arrayType->base, env ); … … 203 205 204 206 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 205 if ( typeVars. find( *inst ) != typeVars.end() ) return type;207 if ( typeVars.contains( *inst ) ) return type; 206 208 } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) { 207 209 return isPolyType( array->base, subst ); … … 272 274 return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes ); 273 275 } 276 277 const ast::BaseInstType *isDynRet( const ast::FunctionType * func ) { 278 if ( func->returns.empty() ) return nullptr; 279 280 TypeVarMap forallTypes = { ast::TypeData() }; 281 makeTypeVarMap( func, forallTypes ); 282 return isDynType( func->returns.front(), forallTypes ); 283 } 274 284 275 285 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { … … 317 327 return 0; 318 328 } 329 330 const ast::Type * isPolyPtr( 331 const ast::Type * type, const TypeVarMap & typeVars, 332 const ast::TypeSubstitution * typeSubs ) { 333 type = replaceTypeInst( type, typeSubs ); 334 335 if ( auto * ptr = dynamic_cast<ast::PointerType const *>( type ) ) { 336 return isPolyType( ptr->base, typeVars, typeSubs ); 337 } 338 return nullptr; 339 } 319 340 320 341 Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) { … … 391 412 392 413 if ( TypeInstType *typeInstType = dynamic_cast< TypeInstType * >( type ) ) { 393 if ( tyVars. find( typeInstType->get_name() ) != tyVars.end() ) {414 if ( tyVars.contains( typeInstType->get_name() ) ) { 394 415 return true; 395 416 } … … 490 511 } 491 512 513 /// Flattens a list of types. 514 // There is another flattenList in Unify. 492 515 void flattenList( vector<ast::ptr<ast::Type>> const & src, 493 516 vector<ast::ptr<ast::Type>> & out ) { … … 792 815 } 793 816 817 void addToTypeVarMap( const ast::TypeDecl * decl, TypeVarMap & typeVars ) { 818 typeVars.insert( ast::TypeEnvKey( decl, 0, 0 ), ast::TypeData( decl ) ); 819 } 820 794 821 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) { 795 typeVars.insert( *type, ast::TypeData( type->base ) );822 typeVars.insert( ast::TypeEnvKey( *type ), ast::TypeData( type->base ) ); 796 823 } 797 824 … … 818 845 } 819 846 847 void makeTypeVarMap( const ast::FunctionDecl * decl, TypeVarMap & typeVars ) { 848 for ( auto & typeDecl : decl->type_params ) { 849 addToTypeVarMap( typeDecl, typeVars ); 850 } 851 } 852 820 853 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) { 821 854 for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) { -
src/GenPoly/GenPoly.h
r34b4268 r24d6572 111 111 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ); 112 112 void addToTypeVarMap( const ast::TypeDecl * type, TypeVarMap & typeVars ); 113 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ); 113 114 114 115 /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap` 115 116 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 116 117 void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ); 118 void makeTypeVarMap( const ast::FunctionDecl * decl, TypeVarMap & typeVars ); 117 119 118 120 /// Prints type variable map -
src/GenPoly/InstantiateGeneric.cc
r34b4268 r24d6572 28 28 #include "GenPoly.h" // for isPolyType, typesPolyCompatible 29 29 #include "InitTweak/InitTweak.h" 30 #include "ResolvExpr/typeops.h" 30 #include "ResolvExpr/AdjustExprType.hpp" // for adjustExprType 31 #include "ResolvExpr/Unify.h" // for typesCompatible 31 32 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 32 33 #include "ScrubTyVars.h" // for ScrubTyVars -
src/GenPoly/InstantiateGenericNew.cpp
r34b4268 r24d6572 32 32 #include "GenPoly/GenPoly.h" // for isPolyType, typesPolyCompatible 33 33 #include "GenPoly/ScrubTyVars.h" // for scrubAll 34 #include "ResolvExpr/typeops.h" // for typesCompatible 34 #include "ResolvExpr/AdjustExprType.hpp" // for adjustExprType 35 #include "ResolvExpr/Unify.h" // for typesCompatible 35 36 36 37 namespace GenPoly { … … 361 362 ResolvExpr::typesCompatible( 362 363 memberExpr->result, 363 memberExpr->member->get_type() , ast::SymbolTable()) ) {364 memberExpr->member->get_type() ) ) { 364 365 return memberExpr; 365 366 } -
src/GenPoly/Lvalue.cc
r34b4268 r24d6572 17 17 #include <string> // for string 18 18 19 #include "Common/ToString.hpp" // for toCString 19 20 #include "Common/UniqueName.h" 20 21 #include "Common/PassVisitor.h" -
src/GenPoly/LvalueNew.cpp
r34b4268 r24d6572 25 25 #include "AST/Pass.hpp" 26 26 #include "Common/SemanticError.h" // for SemanticWarning 27 #include "Common/ToString.hpp" // for toCString 27 28 #include "Common/UniqueName.h" // for UniqueName 28 29 #include "GenPoly/GenPoly.h" // for genFunctionType … … 358 359 !ResolvExpr::typesCompatible( 359 360 srcType, 360 strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base, 361 ast::SymbolTable() ) ) { 361 strict_dynamic_cast<ast::ReferenceType const *>( dstType )->base ) ) { 362 362 // Must keep cast if cast-to type is different from the actual type. 363 363 return ast::mutate_field( expr, &ast::CastExpr::arg, ret ); … … 376 376 if ( !ResolvExpr::typesCompatibleIgnoreQualifiers( 377 377 dstType->stripReferences(), 378 srcType->stripReferences(), 379 ast::SymbolTable() ) ) { 378 srcType->stripReferences() ) ) { 380 379 return ast::mutate_field( expr, &ast::CastExpr::arg, ret ); 381 380 } … … 392 391 ResolvExpr::typesCompatible( 393 392 expr->result, 394 expr->arg->result , ast::SymbolTable()) ) {393 expr->arg->result ) ) { 395 394 PRINT( 396 395 std::cerr << "types are compatible, removing cast: " << expr << '\n'; … … 589 588 ast::OpenVarSet openVars; 590 589 ResolvExpr::unify( ret->arg2->result, ret->arg3->result, newEnv, 591 needAssertions, haveAssertions, openVars, 592 ast::SymbolTable(), common ); 590 needAssertions, haveAssertions, openVars, common ); 593 591 ret->result = common ? common : ast::deepCopy( ret->arg2->result ); 594 592 return ret; -
src/GenPoly/ScopedSet.h
r34b4268 r24d6572 21 21 22 22 namespace GenPoly { 23 /// A set where the items are placed into nested scopes; 24 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward 25 template<typename Value> 26 class ScopedSet { 27 typedef std::set< Value > Scope; 28 typedef std::vector< Scope > ScopeList; 29 30 ScopeList scopes; ///< scoped list of sets 31 public: 32 typedef typename Scope::key_type key_type; 33 typedef typename Scope::value_type value_type; 34 typedef typename ScopeList::size_type size_type; 35 typedef typename ScopeList::difference_type difference_type; 36 typedef typename Scope::reference reference; 37 typedef typename Scope::const_reference const_reference; 38 typedef typename Scope::pointer pointer; 39 typedef typename Scope::const_pointer const_pointer; 40 41 class iterator : public std::iterator< std::bidirectional_iterator_tag, 42 value_type > { 43 friend class ScopedSet; 44 friend class const_iterator; 45 typedef typename std::set< Value >::iterator wrapped_iterator; 46 typedef typename std::vector< std::set< Value > > scope_list; 47 typedef typename scope_list::size_type size_type; 48 49 /// Checks if this iterator points to a valid item 50 bool is_valid() const { 51 return it != (*scopes)[i].end(); 52 } 53 54 /// Increments on invalid 55 iterator& next_valid() { 56 if ( ! is_valid() ) { ++(*this); } 57 return *this; 58 } 59 60 /// Decrements on invalid 61 iterator& prev_valid() { 62 if ( ! is_valid() ) { --(*this); } 63 return *this; 64 } 65 66 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 67 : scopes(&_scopes), it(_it), i(_i) {} 68 public: 69 iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 70 iterator& operator= (const iterator &that) { 71 scopes = that.scopes; i = that.i; it = that.it; 72 return *this; 73 } 74 75 reference operator* () { return *it; } 76 pointer operator-> () { return it.operator->(); } 77 78 iterator& operator++ () { 79 if ( it == (*scopes)[i].end() ) { 80 if ( i == 0 ) return *this; 81 --i; 82 it = (*scopes)[i].begin(); 83 } else { 84 ++it; 85 } 86 return next_valid(); 87 } 88 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 89 90 iterator& operator-- () { 91 // may fail if this is the begin iterator; allowed by STL spec 92 if ( it == (*scopes)[i].begin() ) { 93 ++i; 94 it = (*scopes)[i].end(); 95 } 96 --it; 97 return prev_valid(); 98 } 99 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 100 101 bool operator== (const iterator &that) { 102 return scopes == that.scopes && i == that.i && it == that.it; 103 } 104 bool operator!= (const iterator &that) { return !( *this == that ); } 105 106 size_type get_level() const { return i; } 107 108 private: 109 scope_list const *scopes; 110 wrapped_iterator it; 111 size_type i; 112 }; 113 114 class const_iterator : public std::iterator< std::bidirectional_iterator_tag, 115 value_type > { 116 friend class ScopedSet; 117 typedef typename std::set< Value >::iterator wrapped_iterator; 118 typedef typename std::set< Value >::const_iterator wrapped_const_iterator; 119 typedef typename std::vector< std::set< Value > > scope_list; 120 typedef typename scope_list::size_type size_type; 121 122 /// Checks if this iterator points to a valid item 123 bool is_valid() const { 124 return it != (*scopes)[i].end(); 125 } 126 127 /// Increments on invalid 128 const_iterator& next_valid() { 129 if ( ! is_valid() ) { ++(*this); } 130 return *this; 131 } 132 133 /// Decrements on invalid 134 const_iterator& prev_valid() { 135 if ( ! is_valid() ) { --(*this); } 136 return *this; 137 } 138 139 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 140 : scopes(&_scopes), it(_it), i(_i) {} 141 public: 142 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 143 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 144 const_iterator& operator= (const iterator &that) { 145 scopes = that.scopes; i = that.i; it = that.it; 146 return *this; 147 } 148 const_iterator& operator= (const const_iterator &that) { 149 scopes = that.scopes; i = that.i; it = that.it; 150 return *this; 151 } 152 153 const_reference operator* () { return *it; } 154 const_pointer operator-> () { return it.operator->(); } 155 156 const_iterator& operator++ () { 157 if ( it == (*scopes)[i].end() ) { 158 if ( i == 0 ) return *this; 159 --i; 160 it = (*scopes)[i].begin(); 161 } else { 162 ++it; 163 } 164 return next_valid(); 165 } 166 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 167 168 const_iterator& operator-- () { 169 // may fail if this is the begin iterator; allowed by STL spec 170 if ( it == (*scopes)[i].begin() ) { 171 ++i; 172 it = (*scopes)[i].end(); 173 } 174 --it; 175 return prev_valid(); 176 } 177 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 178 179 bool operator== (const const_iterator &that) { 180 return scopes == that.scopes && i == that.i && it == that.it; 181 } 182 bool operator!= (const const_iterator &that) { return !( *this == that ); } 183 184 size_type get_level() const { return i; } 185 186 private: 187 scope_list const *scopes; 188 wrapped_const_iterator it; 189 size_type i; 190 }; 191 192 /// Starts a new scope 193 void beginScope() { 194 Scope scope; 195 scopes.push_back(scope); 196 } 197 198 /// Ends a scope; invalidates any iterators pointing to elements of that scope 199 void endScope() { 200 scopes.pop_back(); 201 } 202 203 /// Default constructor initializes with one scope 204 ScopedSet() { beginScope(); } 205 206 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 207 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 208 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 209 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 210 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 211 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 212 213 /// Gets the index of the current scope (counted from 1) 214 size_type currentScope() const { return scopes.size(); } 215 216 /// Finds the given key in the outermost scope it occurs; returns end() for none such 217 iterator find( const Value &key ) { 218 for ( size_type i = scopes.size() - 1; ; --i ) { 219 typename Scope::iterator val = scopes[i].find( key ); 220 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 221 if ( i == 0 ) break; 222 } 223 return end(); 224 } 225 const_iterator find( const Value &key ) const { 226 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 227 } 228 229 /// Finds the given key in the outermost scope inside the given scope where it occurs 230 iterator findNext( const_iterator &it, const Value &key ) { 231 if ( it.i == 0 ) return end(); 23 24 /// A set where the items are placed into nested scopes; 25 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward 26 template<typename Value> 27 class ScopedSet { 28 typedef std::set< Value > Scope; 29 typedef std::vector< Scope > ScopeList; 30 31 /// Scoped list of sets. 32 ScopeList scopes; 33 public: 34 typedef typename Scope::key_type key_type; 35 typedef typename Scope::value_type value_type; 36 typedef typename ScopeList::size_type size_type; 37 typedef typename ScopeList::difference_type difference_type; 38 typedef typename Scope::reference reference; 39 typedef typename Scope::const_reference const_reference; 40 typedef typename Scope::pointer pointer; 41 typedef typename Scope::const_pointer const_pointer; 42 43 // Both iterator types are complete bidirectional iterators, see below. 44 class iterator; 45 class const_iterator; 46 47 /// Starts a new scope 48 void beginScope() { 49 Scope scope; 50 scopes.push_back(scope); 51 } 52 53 /// Ends a scope; invalidates any iterators pointing to elements of that scope 54 void endScope() { 55 scopes.pop_back(); 56 } 57 58 /// Default constructor initializes with one scope 59 ScopedSet() { beginScope(); } 60 61 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 62 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 63 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 64 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 65 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } 66 const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); } 67 68 /// Gets the index of the current scope (counted from 1) 69 size_type currentScope() const { return scopes.size(); } 70 71 /// Finds the given key in the outermost scope it occurs; returns end() for none such 72 iterator find( const Value &key ) { 73 for ( size_type i = scopes.size() - 1; ; --i ) { 74 typename Scope::iterator val = scopes[i].find( key ); 75 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 76 if ( i == 0 ) break; 77 } 78 return end(); 79 } 80 const_iterator find( const Value &key ) const { 81 return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) ); 82 } 83 84 /// Finds the given key in the outermost scope inside the given scope where it occurs 85 iterator findNext( const_iterator &it, const Value &key ) { 86 if ( it.i == 0 ) return end(); 232 87 for ( size_type i = it.i - 1; ; --i ) { 233 typename Scope::iterator val = scopes[i].find( key ); 234 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 235 if ( i == 0 ) break; 236 } 237 return end(); 238 } 239 const_iterator findNext( const_iterator &it, const Value &key ) const { 240 return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) ); 241 } 242 243 /// Inserts the given value into the outermost scope 244 std::pair< iterator, bool > insert( const value_type &value ) { 245 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 246 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 247 } 248 249 }; 88 typename Scope::iterator val = scopes[i].find( key ); 89 if ( val != scopes[i].end() ) return iterator( scopes, val, i ); 90 if ( i == 0 ) break; 91 } 92 return end(); 93 } 94 const_iterator findNext( const_iterator &it, const Value &key ) const { 95 return const_iterator( const_cast< ScopedSet< Value >* >(this)->findNext( it, key ) ); 96 } 97 98 /// Inserts the given value into the outermost scope 99 std::pair< iterator, bool > insert( const value_type &value ) { 100 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value ); 101 return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second ); 102 } 103 104 bool contains( const Value & key ) const { 105 return find( key ) != cend(); 106 } 107 }; 108 109 template<typename Value> 110 class ScopedSet<Value>::iterator : 111 public std::iterator< std::bidirectional_iterator_tag, value_type > { 112 friend class ScopedSet; 113 friend class const_iterator; 114 typedef typename std::set< Value >::iterator wrapped_iterator; 115 typedef typename std::vector< std::set< Value > > scope_list; 116 typedef typename scope_list::size_type size_type; 117 118 /// Checks if this iterator points to a valid item 119 bool is_valid() const { 120 return it != (*scopes)[i].end(); 121 } 122 123 /// Increments on invalid 124 iterator& next_valid() { 125 if ( ! is_valid() ) { ++(*this); } 126 return *this; 127 } 128 129 /// Decrements on invalid 130 iterator& prev_valid() { 131 if ( ! is_valid() ) { --(*this); } 132 return *this; 133 } 134 135 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 136 : scopes(&_scopes), it(_it), i(_i) {} 137 public: 138 iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 139 iterator& operator= (const iterator &that) { 140 scopes = that.scopes; i = that.i; it = that.it; 141 return *this; 142 } 143 144 reference operator* () { return *it; } 145 pointer operator-> () { return it.operator->(); } 146 147 iterator& operator++ () { 148 if ( it == (*scopes)[i].end() ) { 149 if ( i == 0 ) return *this; 150 --i; 151 it = (*scopes)[i].begin(); 152 } else { 153 ++it; 154 } 155 return next_valid(); 156 } 157 iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } 158 159 iterator& operator-- () { 160 // may fail if this is the begin iterator; allowed by STL spec 161 if ( it == (*scopes)[i].begin() ) { 162 ++i; 163 it = (*scopes)[i].end(); 164 } 165 --it; 166 return prev_valid(); 167 } 168 iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; } 169 170 bool operator== (const iterator &that) { 171 return scopes == that.scopes && i == that.i && it == that.it; 172 } 173 bool operator!= (const iterator &that) { return !( *this == that ); } 174 175 size_type get_level() const { return i; } 176 177 private: 178 scope_list const *scopes; 179 wrapped_iterator it; 180 size_type i; 181 }; 182 183 template<typename Value> 184 class ScopedSet<Value>::const_iterator : 185 public std::iterator< std::bidirectional_iterator_tag, value_type > { 186 friend class ScopedSet; 187 typedef typename std::set< Value >::iterator wrapped_iterator; 188 typedef typename std::set< Value >::const_iterator wrapped_const_iterator; 189 typedef typename std::vector< std::set< Value > > scope_list; 190 typedef typename scope_list::size_type size_type; 191 192 /// Checks if this iterator points to a valid item 193 bool is_valid() const { 194 return it != (*scopes)[i].end(); 195 } 196 197 /// Increments on invalid 198 const_iterator& next_valid() { 199 if ( ! is_valid() ) { ++(*this); } 200 return *this; 201 } 202 203 /// Decrements on invalid 204 const_iterator& prev_valid() { 205 if ( ! is_valid() ) { --(*this); } 206 return *this; 207 } 208 209 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 210 : scopes(&_scopes), it(_it), i(_i) {} 211 public: 212 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 213 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), i(that.i) {} 214 const_iterator& operator= (const iterator &that) { 215 scopes = that.scopes; i = that.i; it = that.it; 216 return *this; 217 } 218 const_iterator& operator= (const const_iterator &that) { 219 scopes = that.scopes; i = that.i; it = that.it; 220 return *this; 221 } 222 223 const_reference operator* () { return *it; } 224 const_pointer operator-> () { return it.operator->(); } 225 226 const_iterator& operator++ () { 227 if ( it == (*scopes)[i].end() ) { 228 if ( i == 0 ) return *this; 229 --i; 230 it = (*scopes)[i].begin(); 231 } else { 232 ++it; 233 } 234 return next_valid(); 235 } 236 const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } 237 238 const_iterator& operator-- () { 239 // may fail if this is the begin iterator; allowed by STL spec 240 if ( it == (*scopes)[i].begin() ) { 241 ++i; 242 it = (*scopes)[i].end(); 243 } 244 --it; 245 return prev_valid(); 246 } 247 const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } 248 249 bool operator== (const const_iterator &that) { 250 return scopes == that.scopes && i == that.i && it == that.it; 251 } 252 bool operator!= (const const_iterator &that) { return !( *this == that ); } 253 254 size_type get_level() const { return i; } 255 256 private: 257 scope_list const *scopes; 258 wrapped_const_iterator it; 259 size_type i; 260 }; 261 250 262 } // namespace GenPoly 251 263 -
src/GenPoly/ScrubTyVars.cc
r34b4268 r24d6572 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 7 15:42:00 202213 // Update Count : 512 // Last Modified On : Wed Dec 7 17:01:00 2022 13 // Update Count : 6 14 14 // 15 15 … … 117 117 namespace { 118 118 119 enum class ScrubMode {120 FromMap,121 DynamicFromMap,122 All,123 };124 125 119 struct ScrubTypeVars : 126 120 public ast::WithGuards, … … 184 178 185 179 ast::Type const * ScrubTypeVars::postvisit( ast::TypeInstType const * type ) { 180 ast::TypeDecl::Kind kind; 186 181 // This implies that mode == ScrubMode::All. 187 182 if ( !typeVars ) { 188 if ( ast::TypeDecl::Ftype == type->kind ) { 189 return new ast::PointerType( 190 new ast::FunctionType( ast::FixedArgs ) ); 191 } else { 192 return new ast::PointerType( 193 new ast::VoidType( type->qualifiers ) ); 194 } 195 } 196 197 auto typeVar = typeVars->find( *type ); 198 if ( typeVar == typeVars->end() ) { 199 return type; 200 } 201 202 switch ( typeVar->second.kind ) { 203 case ::TypeDecl::Dtype: 204 case ::TypeDecl::Ttype: 183 kind = type->kind; 184 } else { 185 // Otherwise, only scrub the type var if it is in map. 186 auto typeVar = typeVars->find( *type ); 187 if ( typeVar == typeVars->end() ) { 188 return type; 189 } 190 kind = typeVar->second.kind; 191 } 192 193 switch ( kind ) { 194 case ast::TypeDecl::Dtype: 195 case ast::TypeDecl::Ttype: 205 196 return new ast::PointerType( 206 197 new ast::VoidType( type->qualifiers ) ); 207 case ::TypeDecl::Ftype:198 case ast::TypeDecl::Ftype: 208 199 return new ast::PointerType( 209 200 new ast::FunctionType( ast::VariableArgs ) ); 210 201 default: 211 assertf( false, 212 "Unhandled type variable kind: %d", typeVar->second.kind ); 202 assertf( false, "Unhandled type variable kind: %d", kind ); 213 203 throw; // Just in case the assert is removed, stop here. 214 204 } … … 253 243 } 254 244 245 } // namespace 246 255 247 const ast::Node * scrubTypeVarsBase( 256 const ast::Node * target, 257 ScrubMode mode, const TypeVarMap * typeVars ) { 248 const ast::Node * node, const TypeVarMap * typeVars, ScrubMode mode ) { 258 249 if ( ScrubMode::All == mode ) { 259 250 assert( nullptr == typeVars ); … … 262 253 } 263 254 ast::Pass<ScrubTypeVars> visitor( mode, typeVars ); 264 return target->accept( visitor ); 265 } 266 267 } // namespace 268 269 template<> 270 ast::Node const * scrubTypeVars<ast::Node>( 271 const ast::Node * target, const TypeVarMap & typeVars ) { 272 return scrubTypeVarsBase( target, ScrubMode::FromMap, &typeVars ); 273 } 274 275 template<> 276 ast::Node const * scrubTypeVarsDynamic<ast::Node>( 277 ast::Node const * target, const TypeVarMap & typeVars ) { 278 return scrubTypeVarsBase( target, ScrubMode::DynamicFromMap, &typeVars ); 279 } 280 281 template<> 282 ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target ) { 283 return scrubTypeVarsBase( target, ScrubMode::All, nullptr ); 255 return node->accept( visitor ); 284 256 } 285 257 -
src/GenPoly/ScrubTyVars.h
r34b4268 r24d6572 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Oct 7 15:51:00 202213 // Update Count : 412 // Last Modified On : Wed Dec 7 16:57:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 109 109 } 110 110 111 // ScrubMode and scrubTypeVarsBase are internal. 112 enum class ScrubMode { FromMap, DynamicFromMap, All }; 113 114 const ast::Node * scrubTypeVarsBase( 115 const ast::Node * target, const TypeVarMap * typeVars, ScrubMode mode ); 116 117 111 118 /// For all polymorphic types with type variables in `typeVars`, 112 119 /// replaces generic types, dtypes, and ftypes with the appropriate void type, … … 116 123 node_t const * target, const TypeVarMap & typeVars ) { 117 124 return strict_dynamic_cast<node_t const *>( 118 scrubTypeVars <ast::Node>( target, typeVars) );125 scrubTypeVarsBase( target, &typeVars, ScrubMode::FromMap ) ); 119 126 } 120 127 … … 123 130 /// and sizeof/alignof expressions with the proper variable. 124 131 template<typename node_t> 125 ast::Nodeconst * scrubTypeVarsDynamic(132 node_t const * scrubTypeVarsDynamic( 126 133 node_t const * target, const TypeVarMap & typeVars ) { 127 134 return strict_dynamic_cast<node_t const *>( 128 scrubTypeVars Dynamic<ast::Node>( target, typeVars) );135 scrubTypeVarsBase( target, &typeVars, ScrubMode::DynamicFromMap ) ); 129 136 } 130 137 … … 134 141 node_t const * scrubAllTypeVars( node_t const * target ) { 135 142 return strict_dynamic_cast<node_t const *>( 136 scrub AllTypeVars<ast::Node>( target) );143 scrubTypeVarsBase( target, nullptr, ScrubMode::All ) ); 137 144 } 138 139 // We specialize for Node as a base case.140 template<>141 ast::Node const * scrubTypeVars<ast::Node>(142 const ast::Node * target, const TypeVarMap & typeVars );143 144 template<>145 ast::Node const * scrubTypeVarsDynamic<ast::Node>(146 ast::Node const * target, const TypeVarMap & typeVars );147 148 template<>149 ast::Node const * scrubAllTypeVars<ast::Node>( const ast::Node * target );150 145 151 146 } // namespace GenPoly -
src/GenPoly/SpecializeNew.cpp
r34b4268 r24d6572 16 16 #include "Specialize.h" 17 17 18 #include "AST/Copy.hpp" // for deepCopy 18 19 #include "AST/Inspect.hpp" // for isIntrinsicCallExpr 19 20 #include "AST/Pass.hpp" // for Pass
Note:
See TracChangeset
for help on using the changeset viewer.