- Timestamp:
- Nov 22, 2017, 3:40:12 PM (7 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:
- 7e4c4f4
- Parents:
- 98a249fb
- Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
r98a249fb rb95fe40 27 27 #include "Common/utility.h" // for deleteAll, cloneAll 28 28 #include "GenPoly.h" // for isPolyType, typesPolyCompatible 29 #include "ResolvExpr/typeops.h" 29 30 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 30 31 #include "ScrubTyVars.h" // for ScrubTyVars … … 151 152 return gt; 152 153 } 154 155 /// Add cast to dtype-static member expressions so that type information is not lost in GenericInstantiator 156 struct FixDtypeStatic final { 157 Expression * postmutate( MemberExpr * memberExpr ); 158 159 template<typename AggrInst> 160 Expression * fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ); 161 }; 153 162 154 163 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately … … 198 207 199 208 void instantiateGeneric( std::list< Declaration* > &translationUnit ) { 209 PassVisitor<FixDtypeStatic> fixer; 200 210 PassVisitor<GenericInstantiator> instantiator; 211 212 mutateAll( translationUnit, fixer ); 201 213 mutateAll( translationUnit, instantiator ); 214 } 215 216 bool isDtypeStatic( const std::list< TypeDecl* >& baseParams ) { 217 return std::all_of( baseParams.begin(), baseParams.end(), []( TypeDecl * td ) { return ! td->isComplete(); } ); 202 218 } 203 219 … … 479 495 } 480 496 497 template< typename AggrInst > 498 Expression * FixDtypeStatic::fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ) { 499 // need to cast dtype-static member expressions to their actual type before that type is erased. 500 auto & baseParams = *inst->get_baseParameters(); 501 if ( isDtypeStatic( baseParams ) ) { 502 if ( ! ResolvExpr::typesCompatible( memberExpr->result, memberExpr->member->get_type(), SymTab::Indexer() ) ) { 503 // type of member and type of expression differ, so add cast to actual type 504 return new CastExpr( memberExpr, memberExpr->result->clone() ); 505 } 506 } 507 return memberExpr; 508 } 509 510 Expression * FixDtypeStatic::postmutate( MemberExpr * memberExpr ) { 511 Type * aggrType = memberExpr->aggregate->result; 512 if ( isGenericType( aggrType ) ) { 513 if ( StructInstType * inst = dynamic_cast< StructInstType * >( aggrType ) ) { 514 return fixMemberExpr( inst, memberExpr ); 515 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( aggrType ) ) { 516 return fixMemberExpr( inst, memberExpr ); 517 } 518 } 519 return memberExpr; 520 } 521 481 522 } // namespace GenPoly 482 523 -
src/SymTab/Autogen.h
r98a249fb rb95fe40 56 56 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 57 57 template< typename OutputIterator > 58 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );58 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true ); 59 59 60 60 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 61 61 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 62 62 template< typename OutputIterator > 63 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, bool addCast = false) {63 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) { 64 64 bool isReferenceCtorDtor = false; 65 65 if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { … … 68 68 fname = "?=?"; 69 69 dstParam = new AddressExpr( dstParam ); 70 addCast = false;70 addCast = nullptr; 71 71 isReferenceCtorDtor = true; 72 72 } … … 83 83 // remove lvalue as a qualifier, this can change to 84 84 // type->get_qualifiers() = Type::Qualifiers(); 85 assert( type ); 86 Type * castType = type->clone(); 85 Type * castType = addCast->clone(); 87 86 castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 88 87 // castType->set_lvalue( true ); // xxx - might not need this … … 115 114 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 116 115 template< typename OutputIterator > 117 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {116 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) { 118 117 static UniqueName indexName( "_index" ); 119 118 120 119 // for a flexible array member nothing is done -- user must define own assignment 121 if ( ! array->get_dimension() ) return ; 120 if ( ! array->get_dimension() ) return; 121 122 if ( addCast ) { 123 // peel off array layer from cast 124 ArrayType * at = strict_dynamic_cast< ArrayType * >( addCast ); 125 addCast = at->base; 126 } 122 127 123 128 Expression * begin, * end, * update, * cmp; … … 171 176 172 177 template< typename OutputIterator > 173 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, booladdCast, bool forward ) {178 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) { 174 179 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 175 180 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); … … 191 196 if ( isUnnamedBitfield( obj ) ) return; 192 197 193 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ); 198 Type * addCast = nullptr; 199 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ) ) { 200 assert( dstParam->result ); 201 addCast = dstParam->result; 202 } 194 203 std::list< Statement * > stmts; 195 204 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->type, addCast, forward ); -
src/SymTab/Validate.cc
r98a249fb rb95fe40 124 124 125 125 /// Associates forward declarations of aggregates with their definitions 126 struct LinkReferenceToTypes final : public WithIndexer {126 struct LinkReferenceToTypes final : public WithIndexer, public WithGuards { 127 127 LinkReferenceToTypes( const Indexer *indexer ); 128 128 void postvisit( TypeInstType *typeInst ); … … 137 137 void postvisit( UnionDecl *unionDecl ); 138 138 void postvisit( TraitDecl * traitDecl ); 139 140 void previsit( StructDecl *structDecl ); 141 void previsit( UnionDecl *unionDecl ); 142 143 void renameGenericParams( std::list< TypeDecl * > & params ); 139 144 140 145 private: … … 147 152 ForwardStructsType forwardStructs; 148 153 ForwardUnionsType forwardUnions; 154 /// true if currently in a generic type body, so that type parameter instances can be renamed appropriately 155 bool inGeneric = false; 149 156 }; 150 157 … … 561 568 } 562 569 570 void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) { 571 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g. 572 // forall(otype T) 573 // struct Box { 574 // T x; 575 // }; 576 // forall(otype T) 577 // void f(Box(T) b) { 578 // ... 579 // } 580 // The T in Box and the T in f are different, so internally the naming must reflect that. 581 GuardValue( inGeneric ); 582 inGeneric = ! params.empty(); 583 for ( TypeDecl * td : params ) { 584 td->name = "__" + td->name + "_generic_"; 585 } 586 } 587 588 void LinkReferenceToTypes::previsit( StructDecl * structDecl ) { 589 renameGenericParams( structDecl->parameters ); 590 } 591 592 void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) { 593 renameGenericParams( unionDecl->parameters ); 594 } 595 563 596 void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) { 564 597 // visit struct members first so that the types of self-referencing members are updated properly … … 588 621 589 622 void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) { 623 // ensure generic parameter instances are renamed like the base type 624 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 590 625 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) { 591 626 if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
Note: See TracChangeset
for help on using the changeset viewer.