Changeset 4389966 for src/GenPoly
- 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. - Location:
- src/GenPoly
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
rcf16f94 r4389966 28 28 #include "Parser/ParseNode.h" 29 29 30 #include "SynTree/Constant.h" 30 31 #include "SynTree/Type.h" 31 32 #include "SynTree/Expression.h" … … 50 51 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 51 52 53 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 52 54 class Pass1 : public PolyMutator { 53 55 public: … … 88 90 }; 89 91 92 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 90 93 class Pass2 : public PolyMutator { 91 94 public: 92 Pass2();93 95 template< typename DeclClass > 94 96 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 105 107 }; 106 108 109 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable 107 110 class Pass3 : public PolyMutator { 108 111 public: … … 178 181 } 179 182 180 Pass1::Pass1() 181 : useRetval( false ), tempNamer( "_temp" ) { 183 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 182 184 adapters.push(AdapterMap()); 183 185 } … … 312 314 if ( concrete ) { 313 315 arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) ); 316 arg++; 317 arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) ); 314 318 arg++; 315 319 } else { … … 647 651 } 648 652 649 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {653 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) { 650 654 NameExpr *opExpr; 651 655 if ( isIncr ) { … … 660 664 addAssign->get_args().push_back( appExpr->get_args().front() ); 661 665 } // if 662 addAssign->get_args().push_back( new NameExpr( polyName) );666 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) ); 663 667 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 664 668 if ( appExpr->get_env() ) { … … 687 691 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 688 692 multiply->get_args().push_back( appExpr->get_args().back() ); 689 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );693 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) ); 690 694 ret->get_args().push_back( appExpr->get_args().front() ); 691 695 ret->get_args().push_back( multiply ); … … 693 697 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 694 698 multiply->get_args().push_back( appExpr->get_args().front() ); 695 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );699 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) ); 696 700 ret->get_args().push_back( multiply ); 697 701 ret->get_args().push_back( appExpr->get_args().back() ); … … 739 743 assignExpr->get_args().push_back( appExpr->get_args().front()->clone() ); 740 744 } // if 741 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst ->get_name(), varExpr->get_var()->get_name() == "?++" ) );745 CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "?++" ) ); 742 746 return new CommaExpr( firstComma, tempExpr ); 743 747 } // if … … 746 750 assert( appExpr->get_args().size() == 1 ); 747 751 if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) { 748 return makeIncrDecrExpr( appExpr, typeInst ->get_name(), varExpr->get_var()->get_name() == "++?" );752 return makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "++?" ); 749 753 } // if 750 754 } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) { … … 756 760 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 757 761 divide->get_args().push_back( appExpr ); 758 divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );762 divide->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) ); 759 763 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 760 764 if ( appExpr->get_env() ) { … … 766 770 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 767 771 multiply->get_args().push_back( appExpr->get_args().back() ); 768 multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );772 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) ); 769 773 appExpr->get_args().back() = multiply; 770 774 } else if ( typeInst2 ) { 771 775 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 772 776 multiply->get_args().push_back( appExpr->get_args().front() ); 773 multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );777 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) ); 774 778 appExpr->get_args().front() = multiply; 775 779 } // if … … 781 785 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 782 786 multiply->get_args().push_back( appExpr->get_args().back() ); 783 multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );787 multiply->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) ); 784 788 appExpr->get_args().back() = multiply; 785 789 } // if … … 963 967 ////////////////////////////////////////// Pass2 //////////////////////////////////////////////////// 964 968 965 Pass2::Pass2() {}966 967 969 void Pass2::addAdapters( FunctionType *functionType ) { 968 970 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); … … 1037 1039 std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin(); 1038 1040 std::list< DeclarationWithType *> inferredParams; 1039 ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );1040 // /ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );1041 ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 ); 1042 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 ); 1041 1043 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1042 ObjectDecl * thisParm;1043 // add all size parameters to parameter list1044 ObjectDecl *sizeParm, *alignParm; 1045 // add all size and alignment parameters to parameter list 1044 1046 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1045 thisParm = newObj->clone(); 1046 thisParm->set_name( (*tyParm)->get_name() ); 1047 last = funcType->get_parameters().insert( last, thisParm ); 1047 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1048 1049 sizeParm = newObj.clone(); 1050 sizeParm->set_name( sizeofName( &parmType ) ); 1051 last = funcType->get_parameters().insert( last, sizeParm ); 1052 ++last; 1053 1054 alignParm = newObj.clone(); 1055 alignParm->set_name( alignofName( &parmType ) ); 1056 last = funcType->get_parameters().insert( last, alignParm ); 1048 1057 ++last; 1049 1058 } 1050 1059 // move all assertions into parameter list 1051 1060 for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) { 1052 // /*assert = (*assert)->acceptMutator( *this );1061 // *assert = (*assert)->acceptMutator( *this ); 1053 1062 inferredParams.push_back( *assert ); 1054 1063 } 1055 1064 (*tyParm)->get_assertions().clear(); 1056 1065 } 1057 delete newObj;1058 1066 funcType->get_parameters().splice( last, inferredParams ); 1059 1067 addAdapters( funcType ); … … 1092 1100 1093 1101 TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) { 1094 // /Initializer *init = 0;1095 // /std::list< Expression *> designators;1096 // /scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();1097 // /if ( typeDecl->get_base() ) {1098 // /init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );1099 // /}1100 // /return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );1102 // Initializer *init = 0; 1103 // std::list< Expression *> designators; 1104 // scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1105 // if ( typeDecl->get_base() ) { 1106 // init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators ); 1107 // } 1108 // return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init ); 1101 1109 1102 1110 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); … … 1131 1139 assert( typeInst ); 1132 1140 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1133 alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );1141 alloc->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) ); 1134 1142 1135 1143 delete objectDecl->get_init(); -
src/GenPoly/FindFunction.h
rcf16f94 r4389966 23 23 typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& ); 24 24 25 /// recursively walk `type`, placing all functions that match `predicate` under `tyVars` into `functions` 25 26 void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 27 /// like `findFunction`, but also replaces the function type with void ()(void) 26 28 void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate ); 27 29 } // namespace GenPoly -
src/GenPoly/GenPoly.cc
rcf16f94 r4389966 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 1 15:18:54201513 // Update Count : 1 212 // Last Modified On : Tue Dec 15 16:11:18 2015 13 // Update Count : 13 14 14 // 15 15 … … 21 21 22 22 namespace GenPoly { 23 // A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type23 /// A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type 24 24 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) { 25 25 if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { -
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 } -
src/GenPoly/Lvalue.cc
rcf16f94 r4389966 35 35 const std::list<Label> noLabels; 36 36 37 /// Replace uses of lvalue returns with appropriate pointers 37 38 class Pass1 : public Mutator { 38 39 public: … … 46 47 }; 47 48 49 /// Replace declarations of lvalue returns with appropriate pointers 48 50 class Pass2 : public Visitor { 49 51 public: -
src/GenPoly/ScrubTyVars.cc
rcf16f94 r4389966 14 14 // 15 15 16 #include <sstream> 17 #include <string> 18 16 19 #include "GenPoly.h" 17 20 #include "ScrubTyVars.h" 21 22 #include "SymTab/Mangler.h" 18 23 19 24 #include "SynTree/Mutator.h" … … 42 47 43 48 Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) { 44 // sizeof( T ) => T parameter, which is the size of T49 // sizeof( T ) => _sizeof_T parameter, which is the size of T 45 50 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) { 46 Expression *expr = new NameExpr( typeInst->get_name() );51 Expression *expr = new NameExpr( sizeofName( typeInst ) ); 47 52 return expr; 48 53 } else { 49 54 return Mutator::mutate( szeof ); 55 } // if 56 } 57 58 Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) { 59 // alignof( T ) => _alignof_T parameter, which is the alignment of T 60 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( algnof->get_type() ) ) { 61 Expression *expr = new NameExpr( alignofName( typeInst ) ); 62 return expr; 63 } else { 64 return Mutator::mutate( algnof ); 50 65 } // if 51 66 } … … 63 78 return Mutator::mutate( pointer ); 64 79 } 80 81 std::string sizeofName( Type *ty ) { 82 return std::string( "_sizeof_" ) + SymTab::Mangler::mangle( ty, false, false ); 83 } 84 85 std::string alignofName( Type *ty ) { 86 return std::string( "_alignof_" ) + SymTab::Mangler::mangle( ty, false, false ); 87 } 65 88 } // namespace GenPoly 66 89 -
src/GenPoly/ScrubTyVars.h
rcf16f94 r4389966 17 17 #define _SCRUBTYVARS_H 18 18 19 #include <string> 20 19 21 #include "GenPoly.h" 20 22 … … 26 28 public: 27 29 ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {} 28 30 31 /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars` 29 32 template< typename SynTreeClass > 30 33 static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars ); 34 /// Replaces dtypes and ftypes with the appropriate void type, and sizeof expressions of polymorphic types with the proper variable 31 35 template< typename SynTreeClass > 32 36 static SynTreeClass *scrub( SynTreeClass *target ); … … 34 38 virtual Type* mutate( TypeInstType *typeInst ); 35 39 Expression* mutate( SizeofExpr *szeof ); 40 Expression* mutate( AlignofExpr *algnof ); 36 41 virtual Type* mutate( PointerType *pointer ); 37 42 private: … … 54 59 return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) ); 55 60 } 61 62 /// Gets the name of the sizeof parameter for the type 63 std::string sizeofName( Type *ty ); 64 65 /// Gets the name of the alignof parameter for the type 66 std::string alignofName( Type *ty ); 56 67 } // namespace GenPoly 57 68
Note:
See TracChangeset
for help on using the changeset viewer.