- Timestamp:
- Nov 19, 2015, 3:49:00 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:
- 05587c2, 63afee0, ed94eac
- Parents:
- a2eda27
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
ra2eda27 r258eb5c9 36 36 namespace GenPoly { 37 37 38 class Instantiate : public PolyMutator { 39 public: 40 /// Key for a unique concrete type; generic base type paired with type parameter list 41 struct ConcreteType { 42 ConcreteType() : base(NULL), params() {} 43 44 ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); } 45 46 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 47 48 /// Extracts types from a list of Expression* (which should be TypeExpr*) 49 ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() { 50 for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) { 51 TypeExpr *param = dynamic_cast< TypeExpr* >(*it); 52 assert(param && "Aggregate parameters should be type expressions"); 53 params.push_back( param->get_type()->clone() ); 38 /// Key for a unique concrete type; generic base type paired with type parameter list 39 struct ConcreteType { 40 ConcreteType() : base(NULL), params() {} 41 42 ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); } 43 44 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 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() ); 52 } 53 } 54 55 ConcreteType& operator= (const ConcreteType& that) { 56 deleteAll( params ); 57 params.clear(); 58 59 base = that.base; 60 cloneAll( that.params, params ); 61 62 return *this; 63 } 64 65 ~ConcreteType() { deleteAll( params ); } 66 67 bool operator== (const ConcreteType& that) const { 68 SymTab::Indexer dummy; 69 70 if ( base != that.base ) return false; 71 if ( params.size() != that.params.size() ) return false; 72 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 73 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; 74 } 75 return true; 76 } 77 78 AggregateDecl *base; ///< Base generic type 79 std::list< Type* > params; ///< Instantiation parameters 80 }; 81 82 /// Maps a concrete type to the instantiated struct type, accounting for scope 83 class InstantiationMap { 84 /// Pair of concrete type and declaration that instantiates it 85 typedef std::pair< ConcreteType, AggregateDecl* > Instantiation; 86 /// Map of generic types to instantiations of them 87 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope; 88 89 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost 90 91 public: 92 /// Starts a new scope 93 void beginScope() { 94 Scope scope; 95 scopes.push_back(scope); 96 } 97 98 /// Ends a scope 99 void endScope() { 100 scopes.pop_back(); 101 } 102 103 /// Default constructor initializes with one scope 104 InstantiationMap() { beginScope(); } 105 106 private: 107 /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope. 108 /// Returns NULL on none such. 109 AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) { 110 ConcreteType key(generic, params); 111 // scan scopes from innermost out 112 for ( std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) { 113 // skip scope if no instantiations of this generic type 114 Scope::const_iterator insts = scope->find( generic ); 115 if ( insts == scope->end() ) continue; 116 // look through instantiations for matches to concrete type 117 for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) { 118 if ( inst->first == key ) return inst->second; 54 119 } 55 120 } 56 57 ConcreteType& operator= (const ConcreteType& that) { 58 deleteAll( params ); 59 params.clear(); 60 61 base = that.base; 62 cloneAll( that.params, params ); 63 64 return *this; 65 } 66 67 ~ConcreteType() { deleteAll( params ); } 68 69 bool operator== (const ConcreteType& that) const { 70 SymTab::Indexer dummy; 71 72 if ( base != that.base ) return false; 73 if ( params.size() != that.params.size() ) return false; 74 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 75 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; 76 } 77 return true; 78 } 79 80 AggregateDecl *base; ///< Base generic type 81 std::list< Type* > params; ///< Instantiation parameters 82 }; 121 // no matching instantiation found 122 return NULL; 123 } 124 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() ); } 127 128 private: 129 /// Adds a declaration for a concrete type to the current scope 130 void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) { 131 ConcreteType key(generic, params); 132 scopes.back()[generic].push_back( std::make_pair( key, decl ) ); 133 } 134 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 ); } 137 }; 138 139 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 140 class Instantiate : public PolyMutator { 141 InstantiationMap instantiations; 142 UniqueName typeNamer; 143 144 public: 145 Instantiate() : instantiations(), typeNamer("_conc_") {} 146 147 /// Mutates the whole translation unit, inserting new struct declarations as appropriate 148 void mutateAll( std::list< Declaration* >& translationUnit ); 83 149 84 /// Maps a concrete type to the instantiated struct type, accounting for scope85 class InstantiationMap {86 /// Pair of concrete type and declaration that instantiates it87 typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;88 /// Map of generic types to instantiations of them89 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;90 91 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost92 93 public:94 /// Starts a new scope95 void beginScope() {96 Scope scope;97 scopes.push_back(scope);98 }99 100 /// Ends a scope101 void endScope() {102 scopes.pop_back();103 }104 105 /// Default constructor initializes with one scope106 InstantiationMap() { beginScope(); }107 108 private:109 /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.110 /// Returns NULL on none such.111 AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {112 ConcreteType key(generic, params);113 // scan scopes from innermost out114 for ( std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {115 // skip scope if no instantiations of this generic type116 Scope::const_iterator insts = scope->find( generic );117 if ( insts == scope->end() ) continue;118 // look through instantiations for matches to concrete type119 for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {120 if ( inst->first == key ) return inst->second;121 }122 }123 // no matching instantiation found124 return NULL;125 }126 public:127 StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters() ); }128 UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters() ); }129 130 private:131 /// Adds a declaration for a concrete type to the current scope132 void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {133 ConcreteType key(generic, params);134 scopes.back()[generic].push_back( std::make_pair( key, decl ) );135 }136 public:137 void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }138 void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }139 };140 141 150 virtual Type* mutate( StructInstType *inst ); 142 151 virtual Type* mutate( UnionInstType *inst ); … … 148 157 /// Adds a declaration to the current environment and the statements to add 149 158 void addDeclaration( AggregateDecl *decl ) { 150 std::list< Label > labels;151 DeclStmt *stmt = new DeclStmt( labels, decl );159 std::list< Label > nolabels; 160 DeclStmt *stmt = new DeclStmt( nolabels, decl ); 152 161 PolyMutator::stmtsToAdd.push_back( stmt ); 153 162 } 154 155 InstantiationMap instantiations;156 UniqueName typeNamer;157 163 }; 158 164 159 165 void instantiateGeneric( std::list< Declaration* >& translationUnit ) { 160 166 Instantiate instantiator; 161 mutateAll( translationUnit, instantiator ); 167 // mutateAll( translationUnit, instantiator ); 168 instantiator.mutateAll( translationUnit ); 169 } 170 171 void Instantiate::mutateAll( std::list< Declaration* >& translationUnit ) { 172 // below copied and modified from Mutator.h:mutateAll() 173 SemanticError errors; 174 for ( std::list< Declaration* >::iterator decl = translationUnit.begin(); decl != translationUnit.end(); ++decl ) { 175 try { 176 if ( *decl ) { 177 *decl = dynamic_cast< Declaration* >( (*decl)->acceptMutator( *this ) ); 178 assert( *decl ); 179 // account for missing top-level declarations 180 for ( std::list< Statement* >::const_iterator stmt = PolyMutator::stmtsToAdd.begin(); stmt != PolyMutator::stmtsToAdd.end(); ++stmt ) { 181 DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *stmt ); 182 assert( declStmt ); 183 translationUnit.insert( decl, declStmt->get_decl() ); 184 } 185 PolyMutator::stmtsToAdd.clear(); 186 } // if 187 } catch( SemanticError &e ) { 188 errors.append( e ); 189 } // try 190 } // for 191 if ( ! errors.isEmpty() ) { 192 throw errors; 193 } // if 162 194 } 163 195
Note: See TracChangeset
for help on using the changeset viewer.