Changeset 5bf4712 for src/GenPoly
- Timestamp:
- Dec 1, 2015, 2:44:13 PM (9 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:
- e58be8e, f8b961b
- Parents:
- b0b958a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
rb0b958a r5bf4712 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 ) { … … 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 … … 144 148 public: 145 149 Instantiate() : DeclMutator(), instantiations(), typeNamer("_conc_") {} 150 151 // virtual Declaration* mutate( StructDecl *aggregateDecl ); 152 // virtual Declaration* mutate( UnionDecl *aggregateDecl ); 146 153 147 154 virtual Type* mutate( StructInstType *inst ); … … 157 164 } 158 165 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, 166 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type 167 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 168 bool allConcrete = true; // will finish the substitution list even if they're not all concrete 169 170 // substitute concrete types for given parameters, and incomplete types for placeholders 171 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 172 std::list< Expression* >::const_iterator param = params.begin(); 173 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) { 174 switch ( (*baseParam)->get_kind() ) { 175 case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics 176 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 177 assert(paramType && "Aggregate parameters should be type expressions"); 178 out.push_back( paramType->clone() ); 179 // check that the substituted type isn't a type variable itself 180 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) { 181 allConcrete = false; 182 } 183 break; 184 } 185 case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 186 out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 187 break; 188 case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 189 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 190 break; 191 } 192 } 193 194 // if not enough parameters given, substitute remaining incomplete types for placeholders 195 for ( ; baseParam != baseParams.end(); ++baseParam ) { 196 switch ( (*baseParam)->get_kind() ) { 197 case TypeDecl::Any: // no more substitutions here, fail early 198 return false; 199 case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 200 out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 201 break; 202 case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 203 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 204 break; 205 } 206 } 207 208 return allConcrete; 209 } 210 211 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out 212 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, 162 213 std::list< Declaration* >& out ) { 163 214 // substitute types into new members 164 TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );215 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 165 216 for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) { 166 217 Declaration *newMember = (*member)->clone(); … … 178 229 // exit early if no need for further mutation 179 230 if ( inst->get_parameters().empty() ) return inst; 231 assert( inst->get_baseParameters() && "Base struct has parameters" ); 232 233 // check if type can be concretely instantiated; put substitutions into typeSubs 234 std::list< TypeExpr* > typeSubs; 235 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 236 deleteAll( typeSubs ); 237 return inst; 238 } 180 239 181 240 // make concrete instantiation of generic type 182 StructDecl *concDecl = instantiations.lookup( inst );241 StructDecl *concDecl = instantiations.lookup( inst, typeSubs ); 183 242 if ( ! concDecl ) { 184 assert( inst->get_baseParameters() && "Base struct has parameters" );185 243 // set concDecl to new type, insert type declaration into statements to add 186 244 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() ); 245 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 190 246 DeclMutator::addDeclaration( concDecl ); 191 instantiations.insert( inst, concDecl );247 instantiations.insert( inst, typeSubs, concDecl ); 192 248 } 193 249 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); 194 250 newInst->set_baseStruct( concDecl ); 251 252 deleteAll( typeSubs ); 195 253 delete inst; 196 254 return newInst; … … 205 263 // exit early if no need for further mutation 206 264 if ( inst->get_parameters().empty() ) return inst; 207 265 assert( inst->get_baseParameters() && "Base union has parameters" ); 266 267 // check if type can be concretely instantiated; put substitutions into typeSubs 268 std::list< TypeExpr* > typeSubs; 269 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 270 deleteAll( typeSubs ); 271 return inst; 272 } 273 208 274 // make concrete instantiation of generic type 209 UnionDecl *concDecl = instantiations.lookup( inst );275 UnionDecl *concDecl = instantiations.lookup( inst, typeSubs ); 210 276 if ( ! concDecl ) { 211 277 // set concDecl to new type, insert type declaration into statements to add 212 assert( inst->get_baseParameters() && "Base union has parameters" );213 278 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() ); 279 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 217 280 DeclMutator::addDeclaration( concDecl ); 218 instantiations.insert( inst, concDecl );281 instantiations.insert( inst, typeSubs, concDecl ); 219 282 } 220 283 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); 221 284 newInst->set_baseUnion( concDecl ); 285 286 deleteAll( typeSubs ); 222 287 delete inst; 223 288 return newInst;
Note: See TracChangeset
for help on using the changeset viewer.