Changeset 2162c2c for src/GenPoly
- Timestamp:
- Jan 11, 2017, 4:11:02 PM (9 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:
- 075734f
- Parents:
- bb82c03 (diff), d3a85240 (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:
-
- 4 edited
-
Box.cc (modified) (9 diffs)
-
InstantiateGeneric.cc (modified) (10 diffs)
-
ScrubTyVars.cc (modified) (1 diff)
-
Specialize.cc (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rbb82c03 r2162c2c 136 136 template< typename DeclClass > 137 137 DeclClass *handleDecl( DeclClass *decl, Type *type ); 138 139 using PolyMutator::mutate; 138 template< typename AggDecl > 139 AggDecl * handleAggDecl( AggDecl * aggDecl ); 140 141 typedef PolyMutator Parent; 142 using Parent::mutate; 140 143 virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override; 141 144 virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override; 145 virtual StructDecl *mutate( StructDecl *structDecl ) override; 146 virtual UnionDecl *mutate( UnionDecl *unionDecl ) override; 142 147 virtual TypeDecl *mutate( TypeDecl *typeDecl ) override; 143 148 virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override; … … 686 691 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 687 692 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 688 assert (paramType &&"Aggregate parameters should be type expressions");693 assertf(paramType, "Aggregate parameters should be type expressions"); 689 694 paramType->set_type( replaceWithConcrete( appExpr, paramType->get_type(), false ) ); 690 695 } … … 783 788 void Pass1::boxParams( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ) { 784 789 for ( std::list< DeclarationWithType *>::const_iterator param = function->get_parameters().begin(); param != function->get_parameters().end(); ++param, ++arg ) { 785 assert ( arg != appExpr->get_args().end() );790 assertf( arg != appExpr->get_args().end(), "boxParams: missing argument for param %s to %s in %s", toString( *param ).c_str(), toString( function ).c_str(), toString( appExpr ).c_str() ); 786 791 addCast( *arg, (*param)->get_type(), exprTyVars ); 787 792 boxParam( (*param)->get_type(), *arg, exprTyVars ); … … 1127 1132 makeTyVarMap( function, exprTyVars ); // xxx - should this take into account the variables already bound in scopeTyVars (i.e. remove them from exprTyVars?) 1128 1133 ReferenceToType *dynRetType = isDynRet( function, exprTyVars ); 1129 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();// ?: dynRetType; // xxx - is concRetType a good name? 1130 1134 1135 // NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr 1136 // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int)) 1137 // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome. 1131 1138 if ( dynRetType ) { 1139 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result(); 1132 1140 ret = addDynRetParam( appExpr, function, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType 1133 1141 } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...? … … 1142 1150 arg = appExpr->get_args().begin(); 1143 1151 1152 Type *concRetType = replaceWithConcrete( appExpr, dynRetType ); 1144 1153 passTypeVars( appExpr, concRetType, arg, exprTyVars ); // xxx - used to use dynRetType instead of concRetType; this changed so that the correct type paramaters are passed for return types (it should be the concrete type's parameters, not the formal type's) 1145 1154 addInferredParams( appExpr, function, arg, exprTyVars ); … … 1271 1280 template< typename DeclClass > 1272 1281 DeclClass * Pass2::handleDecl( DeclClass *decl, Type *type ) { 1273 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) );1282 DeclClass *ret = static_cast< DeclClass *>( Parent::mutate( decl ) ); 1274 1283 1275 1284 return ret; … … 1305 1314 } 1306 1315 1316 template< typename AggDecl > 1317 AggDecl * Pass2::handleAggDecl( AggDecl * aggDecl ) { 1318 // prevent tyVars from leaking into containing scope 1319 scopeTyVars.beginScope(); 1320 Parent::mutate( aggDecl ); 1321 scopeTyVars.endScope(); 1322 return aggDecl; 1323 } 1324 1325 StructDecl * Pass2::mutate( StructDecl *aggDecl ) { 1326 return handleAggDecl( aggDecl ); 1327 } 1328 1329 UnionDecl * Pass2::mutate( UnionDecl *aggDecl ) { 1330 return handleAggDecl( aggDecl ); 1331 } 1332 1307 1333 TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) { 1308 1334 addToTyVarMap( typeDecl, scopeTyVars ); … … 1310 1336 return handleDecl( typeDecl, typeDecl->get_base() ); 1311 1337 } else { 1312 return Mutator::mutate( typeDecl );1338 return Parent::mutate( typeDecl ); 1313 1339 } 1314 1340 } … … 1322 1348 makeTyVarMap( pointerType, scopeTyVars ); 1323 1349 1324 Type *ret = Mutator::mutate( pointerType );1350 Type *ret = Parent::mutate( pointerType ); 1325 1351 1326 1352 scopeTyVars.endScope(); -
src/GenPoly/InstantiateGeneric.cc
rbb82c03 r2162c2c 18 18 #include <utility> 19 19 #include <vector> 20 #include <unordered_map> 20 21 21 22 #include "InstantiateGeneric.h" … … 24 25 #include "GenPoly.h" 25 26 #include "ScopedSet.h" 27 #include "PolyMutator.h" 26 28 27 29 #include "ResolvExpr/typeops.h" … … 146 148 } 147 149 150 // collect the environments of each TypeInstType so that type variables can be replaced 151 // xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments. 152 class EnvFinder final : public GenPoly::PolyMutator { 153 public: 154 virtual Type * mutate( TypeInstType * inst ) override { 155 if ( env ) envMap[inst] = env; 156 return inst; 157 } 158 159 // don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)? 160 virtual Type * mutate( FunctionType * ftype ) override { 161 return ftype; 162 } 163 std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap; 164 }; 165 148 166 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 149 167 class GenericInstantiator final : public DeclMutator { … … 154 172 /// Namer for concrete types 155 173 UniqueName typeNamer; 156 174 /// Reference to mapping of environments 175 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap; 157 176 public: 158 GenericInstantiator( ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_") {}177 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {} 159 178 160 179 using DeclMutator::mutate; … … 174 193 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); } 175 194 195 void replaceParametersWithConcrete( std::list< Expression* >& params ); 196 Type *replaceWithConcrete( Type *type, bool doClone ); 197 176 198 /// Strips a dtype-static aggregate decl of its type parameters, marks it as stripped 177 199 void stripDtypeParams( AggregateDecl *base, std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs ); … … 179 201 180 202 void instantiateGeneric( std::list< Declaration* > &translationUnit ) { 181 GenericInstantiator instantiator; 203 EnvFinder finder; 204 mutateAll( translationUnit, finder ); 205 GenericInstantiator instantiator( finder.envMap ); 182 206 instantiator.mutateDeclarationList( translationUnit ); 183 207 } … … 209 233 // can pretend that any ftype is `void (*)(void)` 210 234 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 235 break; 236 case TypeDecl::Ttype: 237 assertf( false, "Ttype parameters are not currently allowed as parameters to generic types." ); 211 238 break; 212 239 } … … 253 280 } 254 281 282 /// xxx - more or less copied from box -- these should be merged with those somehow... 283 void GenericInstantiator::replaceParametersWithConcrete( std::list< Expression* >& params ) { 284 for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) { 285 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 286 assertf(paramType, "Aggregate parameters should be type expressions"); 287 paramType->set_type( replaceWithConcrete( paramType->get_type(), false ) ); 288 } 289 } 290 291 Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) { 292 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { 293 if ( envMap.count( typeInst ) ) { 294 TypeSubstitution * env = envMap.at( typeInst ); 295 Type *concrete = env->lookup( typeInst->get_name() ); 296 if ( concrete ) { 297 return concrete->clone(); 298 } 299 else return typeInst->clone(); 300 } 301 } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) { 302 if ( doClone ) { 303 structType = structType->clone(); 304 } 305 replaceParametersWithConcrete( structType->get_parameters() ); 306 return structType; 307 } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) { 308 if ( doClone ) { 309 unionType = unionType->clone(); 310 } 311 replaceParametersWithConcrete( unionType->get_parameters() ); 312 return unionType; 313 } 314 return type; 315 } 316 317 255 318 Type* GenericInstantiator::mutate( StructInstType *inst ) { 256 319 // mutate subtypes … … 262 325 if ( inst->get_parameters().empty() ) return inst; 263 326 327 // need to replace type variables to ensure that generic types are instantiated for the return values of polymorphic functions (in particular, for thunks, because they are not [currently] copy constructed). 328 replaceWithConcrete( inst, false ); 329 264 330 // check for an already-instantiatiated dtype-static type 265 331 if ( dtypeStatics.find( inst->get_baseStruct() ) != dtypeStatics.end() ) { … … 269 335 270 336 // check if type can be concretely instantiated; put substitutions into typeSubs 271 assert ( inst->get_baseParameters() &&"Base struct has parameters" );337 assertf( inst->get_baseParameters(), "Base struct has parameters" ); 272 338 std::list< TypeExpr* > typeSubs; 273 339 genericType gt = makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ); -
src/GenPoly/ScrubTyVars.cc
rbb82c03 r2162c2c 31 31 case TypeDecl::Any: 32 32 case TypeDecl::Dtype: 33 case TypeDecl::Ttype: 33 34 { 34 35 PointerType *ret = new PointerType( Type::Qualifiers(), new VoidType( typeInst->get_qualifiers() ) ); -
src/GenPoly/Specialize.cc
rbb82c03 r2162c2c 32 32 #include "Common/utility.h" 33 33 #include "InitTweak/InitTweak.h" 34 #include "Tuples/Tuples.h" 34 35 35 36 namespace GenPoly { 36 const std::list<Label> noLabels; 37 37 class Specializer; 38 38 class Specialize final : public PolyMutator { 39 friend class Specializer; 39 40 public: 40 Specialize( std::string paramPrefix = "_p" );41 42 41 using PolyMutator::mutate; 43 42 virtual Expression * mutate( ApplicationExpr *applicationExpr ) override; … … 48 47 // virtual Expression * mutate( CommaExpr *commaExpr ); 49 48 50 private: 51 Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams = 0 ); 52 Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 49 Specializer * specializer = nullptr; 53 50 void handleExplicitParams( ApplicationExpr *appExpr ); 54 55 UniqueName thunkNamer;56 std::string paramPrefix;57 51 }; 58 52 59 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 60 Specialize specializer; 61 mutateAll( translationUnit, specializer ); 62 } 63 64 Specialize::Specialize( std::string paramPrefix ) 65 : thunkNamer( "_thunk" ), paramPrefix( paramPrefix ) { 66 } 53 class Specializer { 54 public: 55 Specializer( Specialize & spec ) : spec( spec ), env( spec.env ), stmtsToAdd( spec.stmtsToAdd ) {} 56 virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) = 0; 57 virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) = 0; 58 virtual Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 ); 59 60 protected: 61 Specialize & spec; 62 std::string paramPrefix = "_p"; 63 TypeSubstitution *& env; 64 std::list< Statement * > & stmtsToAdd; 65 }; 66 67 // for normal polymorphic -> monomorphic function conversion 68 class PolySpecializer : public Specializer { 69 public: 70 PolySpecializer( Specialize & spec ) : Specializer( spec ) {} 71 virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) override; 72 virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) override; 73 }; 74 75 // // for tuple -> non-tuple function conversion 76 class TupleSpecializer : public Specializer { 77 public: 78 TupleSpecializer( Specialize & spec ) : Specializer( spec ) {} 79 virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) override; 80 virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) override; 81 }; 67 82 68 83 /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type. 69 bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {84 bool PolySpecializer::needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) { 70 85 if ( env ) { 71 86 using namespace ResolvExpr; … … 92 107 93 108 /// Generates a thunk that calls `actual` with type `funType` and returns its address 94 Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) { 109 Expression * PolySpecializer::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) { 110 static UniqueName thunkNamer( "_thunk" ); 111 95 112 FunctionType *newType = funType->clone(); 96 113 if ( env ) { 97 TypeSubstitution newEnv( *env );98 114 // it is important to replace only occurrences of type variables that occur free in the 99 115 // thunk's type 100 newEnv.applyFree( newType );116 env->applyFree( newType ); 101 117 } // if 102 118 // create new thunk with same signature as formal type (C linkage, empty body) … … 125 141 std::list< Statement* > oldStmts; 126 142 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 127 handleExplicitParams( appExpr );143 spec.handleExplicitParams( appExpr ); 128 144 paramPrefix = oldParamPrefix; 129 145 // write any statements added for recursive specializations into the thunk body … … 147 163 } 148 164 149 Expression * Specialize ::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {165 Expression * Specializer::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) { 150 166 assertf( actual->has_result(), "attempting to specialize an untyped expression" ); 151 167 if ( needsSpecialization( formalType, actual->get_result(), env ) ) { 152 FunctionType *funType; 153 if ( ( funType = getFunctionType( formalType ) ) ) { 168 if ( FunctionType *funType = getFunctionType( formalType ) ) { 154 169 ApplicationExpr *appExpr; 155 170 VariableExpr *varExpr; … … 170 185 } 171 186 187 bool TupleSpecializer::needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) { 188 if ( FunctionType * ftype = getFunctionType( formalType ) ) { 189 return ftype->isTtype(); 190 } 191 return false; 192 } 193 194 /// restructures arg to match the structure of a single formal parameter. Assumes that atomic types are compatible (as the Resolver should have ensured this) 195 template< typename OutIterator > 196 void matchOneFormal( Expression * arg, unsigned & idx, Type * formal, OutIterator out ) { 197 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formal ) ) { 198 std::list< Expression * > exprs; 199 for ( Type * t : *tupleType ) { 200 matchOneFormal( arg, idx, t, back_inserter( exprs ) ); 201 } 202 *out++ = new TupleExpr( exprs ); 203 } else { 204 *out++ = new TupleIndexExpr( arg->clone(), idx++ ); 205 } 206 } 207 208 /// restructures the ttype argument to match the structure of the formal parameters of the actual function. 209 // [begin, end) are the formal parameters. 210 // args is the list of arguments currently given to the actual function, the last of which needs to be restructured. 211 template< typename Iterator, typename OutIterator > 212 void fixLastArg( Expression * last, Iterator begin, Iterator end, OutIterator out ) { 213 // safe_dynamic_cast for the assertion 214 safe_dynamic_cast< TupleType * >( last->get_result() ); 215 unsigned idx = 0; 216 for ( ; begin != end; ++begin ) { 217 DeclarationWithType * formal = *begin; 218 Type * formalType = formal->get_type(); 219 matchOneFormal( last, idx, formalType, out ); 220 } 221 delete last; 222 } 223 224 Expression * TupleSpecializer::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) { 225 static UniqueName thunkNamer( "_tupleThunk" ); 226 227 FunctionType *newType = funType->clone(); 228 if ( env ) { 229 // it is important to replace only occurrences of type variables that occur free in the 230 // thunk's type 231 env->applyFree( newType ); 232 } // if 233 // create new thunk with same signature as formal type (C linkage, empty body) 234 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( noLabels ), false, false ); 235 thunkFunc->fixUniqueId(); 236 237 // thunks may be generated and not used - silence warning with attribute 238 thunkFunc->get_attributes().push_back( new Attribute( "unused" ) ); 239 240 // thread thunk parameters into call to actual function, naming thunk parameters as we go 241 UniqueName paramNamer( paramPrefix ); 242 ApplicationExpr *appExpr = new ApplicationExpr( actual ); 243 244 FunctionType * actualType = getFunctionType( actual->get_result() )->clone(); 245 if ( env ) { 246 // need to apply the environment to the actual function's type, since it may itself be polymorphic 247 env->apply( actualType ); 248 } 249 std::unique_ptr< FunctionType > actualTypeManager( actualType ); // for RAII 250 std::list< DeclarationWithType * >::iterator actualBegin = actualType->get_parameters().begin(); 251 std::list< DeclarationWithType * >::iterator actualEnd = actualType->get_parameters().end(); 252 std::list< DeclarationWithType * >::iterator formalBegin = funType->get_parameters().begin(); 253 std::list< DeclarationWithType * >::iterator formalEnd = funType->get_parameters().end(); 254 255 Expression * last = nullptr; 256 for ( DeclarationWithType* param : thunkFunc->get_functionType()->get_parameters() ) { 257 // walk the parameters to the actual function alongside the parameters to the thunk to find the location where the ttype parameter begins to satisfy parameters in the actual function. 258 param->set_name( paramNamer.newName() ); 259 assertf( formalBegin != formalEnd, "Reached end of formal parameters before finding ttype parameter" ); 260 if ( Tuples::isTtype((*formalBegin)->get_type()) ) { 261 last = new VariableExpr( param ); 262 break; 263 } 264 assertf( actualBegin != actualEnd, "reached end of actual function's arguments before finding ttype parameter" ); 265 ++actualBegin; 266 ++formalBegin; 267 268 appExpr->get_args().push_back( new VariableExpr( param ) ); 269 } // for 270 assert( last ); 271 fixLastArg( last, actualBegin, actualEnd, back_inserter( appExpr->get_args() ) ); 272 appExpr->set_env( maybeClone( env ) ); 273 if ( inferParams ) { 274 appExpr->get_inferParams() = *inferParams; 275 } // if 276 277 // handle any specializations that may still be present 278 std::string oldParamPrefix = paramPrefix; 279 paramPrefix += "p"; 280 // save stmtsToAdd in oldStmts 281 std::list< Statement* > oldStmts; 282 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 283 spec.mutate( appExpr ); 284 paramPrefix = oldParamPrefix; 285 // write any statements added for recursive specializations into the thunk body 286 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd ); 287 // restore oldStmts into stmtsToAdd 288 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts ); 289 290 // add return (or valueless expression) to the thunk 291 Statement *appStmt; 292 if ( funType->get_returnVals().empty() ) { 293 appStmt = new ExprStmt( noLabels, appExpr ); 294 } else { 295 appStmt = new ReturnStmt( noLabels, appExpr ); 296 } // if 297 thunkFunc->get_statements()->get_kids().push_back( appStmt ); 298 299 // add thunk definition to queue of statements to add 300 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) ); 301 // return address of thunk function as replacement expression 302 return new AddressExpr( new VariableExpr( thunkFunc ) ); 303 } 304 172 305 void Specialize::handleExplicitParams( ApplicationExpr *appExpr ) { 173 306 // create thunks for the explicit parameters … … 178 311 std::list< Expression* >::iterator actual; 179 312 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 180 *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );313 *actual = specializer->doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() ); 181 314 } 182 315 } … … 190 323 // don't need to do this for intrinsic calls, because they aren't actually passed 191 324 for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) { 192 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() );325 inferParam->second.expr = specializer->doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get() ); 193 326 } 194 195 327 handleExplicitParams( appExpr ); 196 328 } 197 198 329 return appExpr; 199 330 } … … 202 333 addrExpr->get_arg()->acceptMutator( *this ); 203 334 assert( addrExpr->has_result() ); 204 addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );335 addrExpr->set_arg( specializer->doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) ); 205 336 return addrExpr; 206 337 } … … 212 343 return castExpr; 213 344 } 214 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );345 Expression *specialized = specializer->doSpecialization( castExpr->get_result(), castExpr->get_arg() ); 215 346 if ( specialized != castExpr->get_arg() ) { 216 347 // assume here that the specialization incorporates the cast … … 236 367 // return commaExpr; 237 368 // } 369 370 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 371 Specialize spec; 372 373 TupleSpecializer tupleSpec( spec ); 374 spec.specializer = &tupleSpec; 375 mutateAll( translationUnit, spec ); 376 377 PolySpecializer polySpec( spec ); 378 spec.specializer = &polySpec; 379 mutateAll( translationUnit, spec ); 380 } 238 381 } // namespace GenPoly 239 382
Note:
See TracChangeset
for help on using the changeset viewer.