Changeset 4389966 for src/GenPoly/InstantiateGeneric.cc
- Timestamp:
- Dec 15, 2015, 4:14:01 PM (10 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 5f6c42c
- Parents:
- cf16f94 (diff), 78dd0da (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. - File:
-
- 1 edited
-
src/GenPoly/InstantiateGeneric.cc (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
rcf16f94 r4389966 44 44 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 45 45 46 /// Extracts types from a list of Expression* (which should be TypeExpr*) 47 ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() { 48 for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) { 49 TypeExpr *param = dynamic_cast< TypeExpr* >(*it); 50 assert(param && "Aggregate parameters should be type expressions"); 51 params.push_back( param->get_type()->clone() ); 46 /// Extracts types from a list of TypeExpr* 47 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() { 48 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 49 params.push_back( (*param)->get_type()->clone() ); 52 50 } 53 51 } … … 66 64 67 65 bool operator== (const ConcreteType& that) const { 66 if ( base != that.base ) return false; 67 68 68 SymTab::Indexer dummy; 69 70 if ( base != that.base ) return false;71 69 if ( params.size() != that.params.size() ) return false; 72 70 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { … … 79 77 std::list< Type* > params; ///< Instantiation parameters 80 78 }; 81 79 82 80 /// Maps a concrete type to the instantiated struct type, accounting for scope 83 81 class InstantiationMap { 84 /// Pair of concrete type and declaration that instantiates it 85 typedef std::pair< ConcreteType, AggregateDecl* > Instantiation; 82 /// Instantiation of a generic type, with key information to find it 83 struct Instantiation { 84 ConcreteType key; ///< Instantiation parameters for this type 85 AggregateDecl *decl; ///< Declaration of the instantiated generic type 86 87 Instantiation() : key(), decl(0) {} 88 Instantiation(const ConcreteType &_key, AggregateDecl *_decl) : key(_key), decl(_decl) {} 89 }; 86 90 /// Map of generic types to instantiations of them 87 91 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope; … … 107 111 /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope. 108 112 /// Returns NULL on none such. 109 AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {113 AggregateDecl* lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) { 110 114 ConcreteType key(generic, params); 111 115 // scan scopes from innermost out … … 116 120 // look through instantiations for matches to concrete type 117 121 for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) { 118 if ( inst-> first == key ) return inst->second;122 if ( inst->key == key ) return inst->decl; 119 123 } 120 124 } … … 123 127 } 124 128 public: 125 StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters()); }126 UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters()); }129 StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); } 130 UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); } 127 131 128 132 private: 129 133 /// Adds a declaration for a concrete type to the current scope 130 void insert( AggregateDecl *generic, std::list< Expression* >¶ms, AggregateDecl *decl ) {134 void insert( AggregateDecl *generic, const std::list< TypeExpr* > ¶ms, AggregateDecl *decl ) { 131 135 ConcreteType key(generic, params); 132 scopes.back()[generic].push_back( std::make_pair( key, decl ) );136 scopes.back()[generic].push_back( Instantiation( key, decl ) ); 133 137 } 134 138 public: 135 void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }136 void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }139 void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); } 140 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); } 137 141 }; 138 142 139 143 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 140 144 class Instantiate : public DeclMutator { 145 /// Map of (generic type, parameter list) pairs to concrete type instantiations 141 146 InstantiationMap instantiations; 147 /// Namer for concrete types 142 148 UniqueName typeNamer; 143 149 … … 147 153 virtual Type* mutate( StructInstType *inst ); 148 154 virtual Type* mutate( UnionInstType *inst ); 155 156 // virtual Expression* mutate( MemberExpr *memberExpr ); 149 157 150 158 virtual void doBeginScope(); … … 157 165 } 158 166 159 /// Substitutes types of members of in according to baseParams => params, appending the result to out 160 void substituteMembers( const std::list< Declaration* >& in, 161 const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params, 167 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type 168 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 169 bool allConcrete = true; // will finish the substitution list even if they're not all concrete 170 171 // substitute concrete types for given parameters, and incomplete types for placeholders 172 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 173 std::list< Expression* >::const_iterator param = params.begin(); 174 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) { 175 // switch ( (*baseParam)->get_kind() ) { 176 // case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics 177 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 178 assert(paramType && "Aggregate parameters should be type expressions"); 179 out.push_back( paramType->clone() ); 180 // check that the substituted type isn't a type variable itself 181 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) { 182 allConcrete = false; 183 } 184 // break; 185 // } 186 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 187 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 188 // break; 189 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 190 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 191 // break; 192 // } 193 } 194 195 // if any parameters left over, not done 196 if ( baseParam != baseParams.end() ) return false; 197 // // if not enough parameters given, substitute remaining incomplete types for placeholders 198 // for ( ; baseParam != baseParams.end(); ++baseParam ) { 199 // switch ( (*baseParam)->get_kind() ) { 200 // case TypeDecl::Any: // no more substitutions here, fail early 201 // return false; 202 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 203 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 204 // break; 205 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 206 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 207 // break; 208 // } 209 // } 210 211 return allConcrete; 212 } 213 214 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out 215 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, 162 216 std::list< Declaration* >& out ) { 163 217 // substitute types into new members 164 TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );218 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 165 219 for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) { 166 220 Declaration *newMember = (*member)->clone(); … … 178 232 // exit early if no need for further mutation 179 233 if ( inst->get_parameters().empty() ) return inst; 234 assert( inst->get_baseParameters() && "Base struct has parameters" ); 235 236 // check if type can be concretely instantiated; put substitutions into typeSubs 237 std::list< TypeExpr* > typeSubs; 238 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 239 deleteAll( typeSubs ); 240 return inst; 241 } 180 242 181 243 // make concrete instantiation of generic type 182 StructDecl *concDecl = instantiations.lookup( inst );244 StructDecl *concDecl = instantiations.lookup( inst, typeSubs ); 183 245 if ( ! concDecl ) { 184 assert( inst->get_baseParameters() && "Base struct has parameters" );185 246 // set concDecl to new type, insert type declaration into statements to add 186 247 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) ); 187 substituteMembers( inst->get_baseStruct()->get_members(), 188 *inst->get_baseParameters(), inst->get_parameters(), 189 concDecl->get_members() ); 248 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 190 249 DeclMutator::addDeclaration( concDecl ); 191 instantiations.insert( inst, concDecl );250 instantiations.insert( inst, typeSubs, concDecl ); 192 251 } 193 252 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); 194 253 newInst->set_baseStruct( concDecl ); 254 255 deleteAll( typeSubs ); 195 256 delete inst; 196 257 return newInst; … … 205 266 // exit early if no need for further mutation 206 267 if ( inst->get_parameters().empty() ) return inst; 207 268 assert( inst->get_baseParameters() && "Base union has parameters" ); 269 270 // check if type can be concretely instantiated; put substitutions into typeSubs 271 std::list< TypeExpr* > typeSubs; 272 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 273 deleteAll( typeSubs ); 274 return inst; 275 } 276 208 277 // make concrete instantiation of generic type 209 UnionDecl *concDecl = instantiations.lookup( inst );278 UnionDecl *concDecl = instantiations.lookup( inst, typeSubs ); 210 279 if ( ! concDecl ) { 211 280 // set concDecl to new type, insert type declaration into statements to add 212 assert( inst->get_baseParameters() && "Base union has parameters" );213 281 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) ); 214 substituteMembers( inst->get_baseUnion()->get_members(), 215 *inst->get_baseParameters(), inst->get_parameters(), 216 concDecl->get_members() ); 282 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 217 283 DeclMutator::addDeclaration( concDecl ); 218 instantiations.insert( inst, concDecl );284 instantiations.insert( inst, typeSubs, concDecl ); 219 285 } 220 286 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); 221 287 newInst->set_baseUnion( concDecl ); 288 289 deleteAll( typeSubs ); 222 290 delete inst; 223 291 return newInst; 224 292 } 293 294 // /// Gets the base struct or union declaration for a member expression; NULL if not applicable 295 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) { 296 // // get variable for member aggregate 297 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() ); 298 // if ( ! varExpr ) return NULL; 299 // 300 // // get object for variable 301 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 302 // if ( ! objectDecl ) return NULL; 303 // 304 // // get base declaration from object type 305 // Type *objectType = objectDecl->get_type(); 306 // StructInstType *structType = dynamic_cast< StructInstType* >( objectType ); 307 // if ( structType ) return structType->get_baseStruct(); 308 // UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ); 309 // if ( unionType ) return unionType->get_baseUnion(); 310 // 311 // return NULL; 312 // } 313 // 314 // /// Finds the declaration with the given name, returning decls.end() if none such 315 // std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) { 316 // for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 317 // if ( (*decl)->get_name() == name ) return decl; 318 // } 319 // return decls.end(); 320 // } 321 // 322 // Expression* Instantiate::mutate( MemberExpr *memberExpr ) { 323 // // mutate, exiting early if no longer MemberExpr 324 // Expression *expr = Mutator::mutate( memberExpr ); 325 // memberExpr = dynamic_cast< MemberExpr* >( expr ); 326 // if ( ! memberExpr ) return expr; 327 // 328 // // get declaration of member and base declaration of member, exiting early if not found 329 // AggregateDecl *memberBase = getMemberBaseDecl( memberExpr ); 330 // if ( ! memberBase ) return memberExpr; 331 // DeclarationWithType *memberDecl = memberExpr->get_member(); 332 // std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() ); 333 // if ( baseIt == memberBase->get_members().end() ) return memberExpr; 334 // DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt ); 335 // if ( ! baseDecl ) return memberExpr; 336 // 337 // // check if stated type of the member is not the type of the member's declaration; if so, need a cast 338 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker 339 // SymTab::Indexer dummy; 340 // if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr; 341 // else return new CastExpr( memberExpr, memberDecl->get_type() ); 342 // } 225 343 226 344 void Instantiate::doBeginScope() { 227 345 DeclMutator::doBeginScope(); 228 // push a new concrete type scope229 346 instantiations.beginScope(); 230 347 } … … 232 349 void Instantiate::doEndScope() { 233 350 DeclMutator::doEndScope(); 234 // pop the last concrete type scope235 351 instantiations.endScope(); 236 352 }
Note:
See TracChangeset
for help on using the changeset viewer.