Changeset b940dc71
- Timestamp:
- Dec 21, 2016, 4:15:47 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 53e3b4a
- Parents:
- 626dbc10
- Location:
- src/GenPoly
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/GenPoly/Box.cc ¶
r626dbc10 rb940dc71 1127 1127 makeTyVarMap( function, exprTyVars ); // xxx - should this take into account the variables already bound in scopeTyVars (i.e. remove them from exprTyVars?) 1128 1128 ReferenceToType *dynRetType = isDynRet( function, exprTyVars ); 1129 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();// ?: dynRetType; // xxx - is concRetType a good name? 1130 1129 1130 // 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 1131 // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int)) 1132 // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome. 1131 1133 if ( dynRetType ) { 1134 Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result(); 1132 1135 ret = addDynRetParam( appExpr, function, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType 1133 1136 } else if ( needsAdapter( function, scopeTyVars ) && ! needsAdapter( function, exprTyVars) ) { // xxx - exprTyVars is used above...? … … 1142 1145 arg = appExpr->get_args().begin(); 1143 1146 1147 Type *concRetType = replaceWithConcrete( appExpr, dynRetType ); 1144 1148 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 1149 addInferredParams( appExpr, function, arg, exprTyVars ); -
TabularUnified src/GenPoly/InstantiateGeneric.cc ¶
r626dbc10 rb940dc71 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 );
Note: See TracChangeset
for help on using the changeset viewer.