Changes in / [53ba273:78885b5]
- Location:
- src
- Files:
-
- 1 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r53ba273 r78885b5 455 455 456 456 void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) { 457 assert( false );457 assert( false && "UntypedOffsetofExpr should not reach code generation" ); 458 458 } 459 459 … … 464 464 output << ", " << mangleName( offsetofExpr->get_member() ); 465 465 output << ")"; 466 } 467 468 void CodeGenerator::visit( OffsetPackExpr *offsetPackExpr ) { 469 assert( false && "OffsetPackExpr should not reach code generation" ); 466 470 } 467 471 -
src/CodeGen/CodeGenerator.h
r53ba273 r78885b5 65 65 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 66 66 virtual void visit( OffsetofExpr *offsetofExpr ); 67 virtual void visit( OffsetPackExpr *offsetPackExpr ); 67 68 virtual void visit( LogicalExpr *logicalExpr ); 68 69 virtual void visit( ConditionalExpr *conditionalExpr ); -
src/GenPoly/Box.cc
r53ba273 r78885b5 30 30 #include "FindFunction.h" 31 31 #include "ScopedMap.h" 32 #include "ScopedSet.h" 32 33 #include "ScrubTyVars.h" 33 34 … … 62 63 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 63 64 64 /// Key for a unique concrete type; generic base type paired with type parameter list 65 struct ConcreteType { 66 ConcreteType() : base(NULL), params() {} 67 68 ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); } 69 70 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 65 /// Abstracts type equality for a list of parameter types 66 struct TypeList { 67 TypeList() : params() {} 68 TypeList( const std::list< Type* > &_params ) : params() { cloneAll(_params, params); } 69 TypeList( std::list< Type* > &&_params ) : params( _params ) {} 70 71 TypeList( const TypeList &that ) : params() { cloneAll(that.params, params); } 72 TypeList( TypeList &&that ) : params( std::move( that.params ) ) {} 71 73 72 74 /// Extracts types from a list of TypeExpr* 73 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base),params() {75 TypeList( const std::list< TypeExpr* >& _params ) : params() { 74 76 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 75 77 params.push_back( (*param)->get_type()->clone() ); … … 77 79 } 78 80 79 ConcreteType& operator= (const ConcreteType& that) {81 TypeList& operator= ( const TypeList &that ) { 80 82 deleteAll( params ); 83 81 84 params.clear(); 82 83 base = that.base;84 85 cloneAll( that.params, params ); 85 86 … … 87 88 } 88 89 89 ~ConcreteType() { deleteAll( params ); } 90 91 bool operator== (const ConcreteType& that) const { 92 if ( base != that.base ) return false; 90 TypeList& operator= ( TypeList &&that ) { 91 deleteAll( params ); 92 93 params = std::move( that.params ); 94 95 return *this; 96 } 97 98 ~TypeList() { deleteAll( params ); } 99 100 bool operator== ( const TypeList& that ) const { 101 if ( params.size() != that.params.size() ) return false; 93 102 94 103 SymTab::Indexer dummy; 95 if ( params.size() != that.params.size() ) return false;96 104 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 97 105 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; … … 100 108 } 101 109 102 AggregateDecl *base; ///< Base generic type103 110 std::list< Type* > params; ///< Instantiation parameters 104 111 }; 105 112 106 /// Maps a concrete typeto the some value, accounting for scope107 template< typename Value >113 /// Maps a key and a TypeList to the some value, accounting for scope 114 template< typename Key, typename Value > 108 115 class InstantiationMap { 109 /// Information about a specific instantiation of a generic type 110 struct Instantiation { 111 ConcreteType key; ///< Instantiation parameters for this type 112 Value *value; ///< Value for this instantiation 113 114 Instantiation() : key(), value(0) {} 115 Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {} 116 }; 117 /// Map of generic types to instantiations of them 118 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope; 119 120 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost 116 /// Wraps value for a specific (Key, TypeList) combination 117 typedef std::pair< TypeList, Value* > Instantiation; 118 /// List of TypeLists paired with their appropriate values 119 typedef std::vector< Instantiation > ValueList; 120 /// Underlying map type; maps keys to a linear list of corresponding TypeLists and values 121 typedef ScopedMap< Key*, ValueList > InnerMap; 122 123 InnerMap instantiations; ///< instantiations 121 124 122 125 public: 123 126 /// Starts a new scope 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 127 void beginScope() { instantiations.beginScope(); } 128 128 129 129 /// Ends a scope 130 void endScope() { 131 scopes.pop_back(); 132 } 133 134 /// Default constructor initializes with one scope 135 InstantiationMap() { beginScope(); } 136 137 // private: 138 /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope. 139 /// Returns NULL on none such. 140 Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) { 141 ConcreteType key(generic, params); 142 // scan scopes from innermost out 143 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) { 144 // skip scope if no instantiations of this generic type 145 typename Scope::const_iterator insts = scope->find( generic ); 146 if ( insts == scope->end() ) continue; 147 // look through instantiations for matches to concrete type 148 for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) { 149 if ( inst->key == key ) return inst->value; 130 void endScope() { instantiations.endScope(); } 131 132 /// Gets the value for the (key, typeList) pair, returns NULL on none such. 133 Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const { 134 TypeList typeList( params ); 135 136 // scan scopes for matches to the key 137 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) { 138 for ( typename ValueList::const_reverse_iterator inst = insts->second.rbegin(); inst != insts->second.rend(); ++inst ) { 139 if ( inst->first == typeList ) return inst->second; 150 140 } 151 141 } 152 // no matching instantiation found142 // no matching instantiations found 153 143 return 0; 154 144 } 155 public: 156 // StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); } 157 // UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); } 158 159 // private: 160 /// Adds a value for a concrete type to the current scope 161 void insert( AggregateDecl *generic, const std::list< TypeExpr* > ¶ms, Value *value ) { 162 ConcreteType key(generic, params); 163 scopes.back()[generic].push_back( Instantiation( key, value ) ); 164 } 165 // public: 166 // void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); } 167 // void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); } 145 146 /// Adds a value for a (key, typeList) pair to the current scope 147 void insert( Key *key, const std::list< TypeExpr* > ¶ms, Value *value ) { 148 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) ); 149 } 168 150 }; 169 151 … … 197 179 virtual void doEndScope(); 198 180 private: 199 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it200 Expression *makeOffsetArray( StructInstType *type );201 181 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 202 182 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); … … 225 205 ObjectDecl *makeTemporary( Type *type ); 226 206 227 std::map< std::string, DeclarationWithType *> assignOps; 228 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 229 ScopedMap< std::string, DeclarationWithType* > adapters; 207 std::map< std::string, DeclarationWithType *> assignOps; ///< Currently known type variable assignment operators 208 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; ///< Currently known assignment operators 209 ScopedMap< std::string, DeclarationWithType* > adapters; ///< Set of adapter functions in the current scope 210 230 211 DeclarationWithType *retval; 231 212 bool useRetval; … … 233 214 }; 234 215 235 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 216 /// * Moves polymorphic returns in function types to pointer-type parameters 217 /// * adds type size and assertion parameters to parameter lists 218 /// * does dynamic calculation of type layouts 236 219 class Pass2 : public PolyMutator { 237 220 public: … … 244 227 virtual Type *mutate( PointerType *pointerType ); 245 228 virtual Type *mutate( FunctionType *funcType ); 229 virtual Expression *mutate( SizeofExpr *sizeofExpr ); 230 virtual Expression *mutate( AlignofExpr *alignofExpr ); 231 virtual Expression *mutate( OffsetofExpr *offsetofExpr ); 232 virtual Expression *mutate( OffsetPackExpr *offsetPackExpr ); 233 234 virtual void doBeginScope(); 235 virtual void doEndScope(); 246 236 private: 247 237 void addAdapters( FunctionType *functionType ); 238 /// Makes a new variable in the current scope with the given name, type & optional initializer 239 ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 ); 240 /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns 241 bool findGeneric( Type *ty ); 242 /// adds type parameters to the layout call; will generate the appropriate parameters if needed 243 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ); 248 244 249 245 std::map< UniqueId, std::string > adapterName; 246 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName 247 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 250 248 }; 251 249 … … 253 251 class GenericInstantiator : public DeclMutator { 254 252 /// Map of (generic type, parameter list) pairs to concrete type instantiations 255 InstantiationMap< AggregateDecl > instantiations;253 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; 256 254 /// Namer for concrete types 257 255 UniqueName typeNamer; … … 348 346 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 349 347 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 350 // instantiateGeneric( translationUnit );351 348 instantiator.mutateDeclarationList( translationUnit ); 352 349 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); … … 653 650 654 651 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 655 // if this is a polymorphicassignment function, put it in the map for this scope652 // if this is a assignment function, put it in the map for this scope 656 653 if ( Type *assignedType = isAssignment( functionDecl ) ) { 657 654 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { … … 743 740 } 744 741 745 Expression *Pass1::makeOffsetArray( StructInstType *ty ) {746 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();747 748 // make a new temporary array749 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );750 std::stringstream lenGen;751 lenGen << baseMembers.size();752 ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );753 ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );754 755 // build initializer list for temporary756 std::list< Initializer* > inits;757 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {758 DeclarationWithType *memberDecl;759 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {760 memberDecl = origMember->clone();761 } else {762 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );763 }764 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) );765 }766 arrayTemp->set_init( new ListInit( inits ) );767 768 // return variable pointing to temporary769 return new VariableExpr( arrayTemp );770 }771 772 742 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 773 743 Type *polyBase = hasPolyBase( parmType, exprTyVars ); … … 782 752 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 783 753 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 784 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 785 arg++; 754 // zero-length arrays are forbidden by C, so don't pass offset for empty struct 755 if ( ! argBaseStructType->get_baseStruct()->get_members().empty() ) { 756 arg = appExpr->get_args().insert( arg, new OffsetPackExpr( argBaseStructType->clone() ) ); 757 arg++; 758 } 786 759 } else { 787 760 throw SemanticError( "Cannot pass non-struct type for generic struct" ); … … 931 904 return; 932 905 } else if ( arg->get_results().front()->get_isLvalue() ) { 933 // VariableExpr and MemberExpr are lvalues 934 arg = new AddressExpr( arg ); 906 // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue) 907 if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) { 908 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) ); 909 } else { 910 arg = new AddressExpr( arg ); 911 } 935 912 } else { 936 913 // use type computed in unification to declare boxed variables … … 1027 1004 } // for 1028 1005 } 1029 1030 1031 1006 1032 1007 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { … … 1428 1403 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin(); 1429 1404 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) { 1430 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype) 1431 1432 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1433 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1434 DeclarationWithType *actualDecl = asserts.front(); 1435 TypeInstType *actualType = isTypeInstAssignment( actualDecl ); 1436 assert( actualType && "First assertion of type with assertions should be assignment operator" ); 1405 // Add appropriate mapping to assignment expression environment 1437 1406 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt ); 1438 1407 assert( formalTypeExpr && "type parameters must be type expressions" ); 1439 1408 Type *formalType = formalTypeExpr->get_type(); 1440 assignExpr->get_env()->add( actualType->get_name(), formalType ); 1441 1409 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType ); 1410 1411 // skip types with no assign op (ftype/dtype) 1412 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; 1413 1414 // find assignment operator for formal type 1442 1415 DeclarationWithType *assertAssign = 0; 1443 1416 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { … … 1453 1426 } 1454 1427 } 1455 1456 1428 1429 // add inferred parameter for field assignment operator to assignment expression 1430 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1431 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1432 DeclarationWithType *actualDecl = asserts.front(); 1457 1433 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1458 1434 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); … … 1587 1563 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1588 1564 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1589 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );1590 1565 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1591 1566 ObjectDecl *sizeParm, *alignParm; … … 1631 1606 ++last; 1632 1607 1633 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 1634 offsetParm = newPtr.clone(); 1635 offsetParm->set_name( offsetofName( polyBase ) ); 1636 last = funcType->get_parameters().insert( last, offsetParm ); 1637 ++last; 1608 if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyBase ) ) { 1609 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array 1610 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) { 1611 offsetParm = newPtr.clone(); 1612 offsetParm->set_name( offsetofName( polyBase ) ); 1613 last = funcType->get_parameters().insert( last, offsetParm ); 1614 ++last; 1615 } 1638 1616 } 1639 1617 1640 1618 seenTypes.insert( sizeName ); 1619 knownLayouts.insert( sizeName ); // make sure that any type information passed into the function is accounted for 1641 1620 } 1642 1621 } … … 1650 1629 scopeTyVars = oldtyVars; 1651 1630 return funcType; 1631 } 1632 1633 ObjectDecl *Pass2::makeVar( const std::string &name, Type *type, Initializer *init ) { 1634 ObjectDecl *newObj = new ObjectDecl( name, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, init ); 1635 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 1636 return newObj; 1637 } 1638 1639 void Pass2::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) { 1640 for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 1641 if ( findGeneric( *param ) ) { 1642 // push size/align vars for a generic parameter back 1643 layoutCall->get_args().push_back( new NameExpr( sizeofName( *param ) ) ); 1644 layoutCall->get_args().push_back( new NameExpr( alignofName( *param ) ) ); 1645 } else { 1646 layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) ); 1647 layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) ); 1648 } 1649 } 1650 } 1651 1652 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list 1653 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) { 1654 bool hasDynamicLayout = false; 1655 1656 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 1657 std::list< Expression* >::const_iterator typeParam = typeParams.begin(); 1658 for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) { 1659 // skip non-otype parameters 1660 if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue; 1661 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam ); 1662 assert( typeExpr && "all otype parameters should be type expressions" ); 1663 1664 Type *type = typeExpr->get_type(); 1665 out.push_back( type ); 1666 if ( isPolyType( type ) ) hasDynamicLayout = true; 1667 } 1668 assert( baseParam == baseParams.end() && typeParam == typeParams.end() ); 1669 1670 return hasDynamicLayout; 1671 } 1672 1673 bool Pass2::findGeneric( Type *ty ) { 1674 if ( dynamic_cast< TypeInstType* >( ty ) ) { 1675 // NOTE this assumes that all type variables will be properly bound, and thus have their layouts in scope 1676 return true; 1677 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) { 1678 // check if this type already has a layout generated for it 1679 std::string sizeName = sizeofName( ty ); 1680 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true; 1681 1682 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1683 std::list< Type* > otypeParams; 1684 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false; 1685 1686 // insert local variables for layout and generate call to layout function 1687 knownLayouts.insert( sizeName ); // done early so as not to interfere with the later addition of parameters to the layout call 1688 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 1689 1690 int n_members = structTy->get_baseStruct()->get_members().size(); 1691 if ( n_members == 0 ) { 1692 // all empty structs have the same layout - size 1, align 1 1693 makeVar( sizeName, layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) ); 1694 makeVar( alignofName( ty ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) ); 1695 // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array 1696 } else { 1697 ObjectDecl *sizeVar = makeVar( sizeName, layoutType ); 1698 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() ); 1699 ObjectDecl *offsetVar = makeVar( offsetofName( ty ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) ); 1700 1701 // generate call to layout function 1702 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + structTy->get_baseStruct()->get_name() ) ); 1703 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 1704 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 1705 layoutCall->get_args().push_back( new VariableExpr( offsetVar ) ); 1706 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 1707 1708 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 1709 } 1710 1711 return true; 1712 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) { 1713 // check if this type already has a layout generated for it 1714 std::string sizeName = sizeofName( ty ); 1715 if ( knownLayouts.find( sizeName ) != knownLayouts.end() ) return true; 1716 1717 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 1718 std::list< Type* > otypeParams; 1719 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false; 1720 1721 // insert local variables for layout and generate call to layout function 1722 knownLayouts.insert( sizeName ); // done early so as not to interfere with the later addition of parameters to the layout call 1723 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 1724 1725 ObjectDecl *sizeVar = makeVar( sizeName, layoutType ); 1726 ObjectDecl *alignVar = makeVar( alignofName( ty ), layoutType->clone() ); 1727 1728 // generate call to layout function 1729 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( "__layoutof_" + unionTy->get_baseUnion()->get_name() ) ); 1730 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 1731 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 1732 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 1733 1734 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 1735 1736 return true; 1737 } 1738 1739 return false; 1740 } 1741 1742 Expression *Pass2::mutate( SizeofExpr *sizeofExpr ) { 1743 Type *ty = sizeofExpr->get_type(); 1744 if ( findGeneric( ty ) ) { 1745 Expression *ret = new NameExpr( sizeofName( ty ) ); 1746 delete sizeofExpr; 1747 return ret; 1748 } 1749 return sizeofExpr; 1750 } 1751 1752 Expression *Pass2::mutate( AlignofExpr *alignofExpr ) { 1753 Type *ty = alignofExpr->get_type(); 1754 if ( findGeneric( ty ) ) { 1755 Expression *ret = new NameExpr( alignofName( ty ) ); 1756 delete alignofExpr; 1757 return ret; 1758 } 1759 return alignofExpr; 1760 } 1761 1762 Expression *Pass2::mutate( OffsetofExpr *offsetofExpr ) { 1763 findGeneric( offsetofExpr->get_type() ); 1764 return offsetofExpr; 1765 } 1766 1767 Expression *Pass2::mutate( OffsetPackExpr *offsetPackExpr ) { 1768 StructInstType *ty = offsetPackExpr->get_type(); 1769 1770 Expression *ret = 0; 1771 if ( findGeneric( ty ) ) { 1772 // pull offset back from generated type information 1773 ret = new NameExpr( offsetofName( ty ) ); 1774 } else { 1775 std::string offsetName = offsetofName( ty ); 1776 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) { 1777 // use the already-generated offsets for this type 1778 ret = new NameExpr( offsetName ); 1779 } else { 1780 knownOffsets.insert( offsetName ); 1781 1782 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members(); 1783 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 1784 1785 // build initializer list for offset array 1786 std::list< Initializer* > inits; 1787 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) { 1788 DeclarationWithType *memberDecl; 1789 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) { 1790 memberDecl = origMember->clone(); 1791 } else { 1792 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 ); 1793 } 1794 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 1795 } 1796 1797 // build the offset array and replace the pack with a reference to it 1798 ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ), 1799 new ListInit( inits ) ); 1800 ret = new VariableExpr( offsetArray ); 1801 } 1802 } 1803 1804 delete offsetPackExpr; 1805 return ret; 1806 } 1807 1808 void Pass2::doBeginScope() { 1809 knownLayouts.beginScope(); 1810 knownOffsets.beginScope(); 1811 } 1812 1813 void Pass2::doEndScope() { 1814 knownLayouts.endScope(); 1815 knownOffsets.beginScope(); 1652 1816 } 1653 1817 -
src/GenPoly/ScopedMap.h
r53ba273 r78885b5 17 17 #define _SCOPEDMAP_H 18 18 19 #include <cassert> 19 20 #include <iterator> 20 21 #include <map> … … 164 165 void endScope() { 165 166 scopes.pop_back(); 167 assert( ! scopes.empty() ); 166 168 } 167 169 … … 188 190 return end(); 189 191 } 190 const_iterator find( const Key &key ) const { return const_iterator( find( key ) ); } 192 const_iterator find( const Key &key ) const { 193 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) ); 194 } 191 195 192 196 /// Finds the given key in the outermost scope inside the given scope where it occurs … … 200 204 return end(); 201 205 } 202 const_iterator findNext( const_iterator &it, const Key &key ) const { return const_iterator( findNext( it, key ) ); } 206 const_iterator findNext( const_iterator &it, const Key &key ) const { 207 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findNext( it, key ) ); 208 } 203 209 204 210 /// Inserts the given key-value pair into the outermost scope … … 208 214 } 209 215 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 210 216 217 Value& operator[] ( const Key &key ) { 218 iterator slot = find( key ); 219 if ( slot != end() ) return slot->second; 220 return insert( key, Value() ).first->second; 221 } 211 222 }; 212 223 } // namespace GenPoly -
src/InitTweak/InitModel.h
r53ba273 r78885b5 75 75 void visit( UntypedOffsetofExpr * ) { throw 0; } 76 76 void visit( OffsetofExpr * ) { throw 0; } 77 void visit( OffsetPackExpr * ) { throw 0; } 77 78 void visit( AttrExpr * ) { throw 0; } 78 79 void visit( LogicalExpr * ) { throw 0; } -
src/ResolvExpr/AlternativeFinder.cc
r53ba273 r78885b5 848 848 } 849 849 850 void AlternativeFinder::visit( OffsetPackExpr *offsetPackExpr ) { 851 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) ); 852 } 853 850 854 void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) { 851 855 // assume no polymorphism -
src/ResolvExpr/AlternativeFinder.h
r53ba273 r78885b5 59 59 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 60 60 virtual void visit( OffsetofExpr *offsetofExpr ); 61 virtual void visit( OffsetPackExpr *offsetPackExpr ); 61 62 virtual void visit( AttrExpr *attrExpr ); 62 63 virtual void visit( LogicalExpr *logicalExpr ); -
src/SymTab/Indexer.cc
r53ba273 r78885b5 344 344 maybeAccept( offsetofExpr->get_type(), *this ); 345 345 maybeAccept( offsetofExpr->get_member(), *this ); 346 } 347 348 void Indexer::visit( OffsetPackExpr *offsetPackExpr ) { 349 acceptAllNewScope( offsetPackExpr->get_results(), *this ); 350 maybeAccept( offsetPackExpr->get_type(), *this ); 346 351 } 347 352 -
src/SymTab/Indexer.h
r53ba273 r78885b5 59 59 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 60 60 virtual void visit( OffsetofExpr *offsetofExpr ); 61 virtual void visit( OffsetPackExpr *offsetPackExpr ); 61 62 virtual void visit( AttrExpr *attrExpr ); 62 63 virtual void visit( LogicalExpr *logicalExpr ); -
src/SynTree/Expression.cc
r53ba273 r78885b5 222 222 } 223 223 224 OffsetPackExpr::OffsetPackExpr( StructInstType *type_, Expression *aname_ ) : Expression( aname_ ), type( type_ ) { 225 add_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) ); 226 } 227 228 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {} 229 230 OffsetPackExpr::~OffsetPackExpr() { delete type; } 231 232 void OffsetPackExpr::print( std::ostream &os, int indent ) const { 233 os << std::string( indent, ' ' ) << "Offset pack expression on "; 234 235 if ( type ) { 236 type->print(os, indent + 2); 237 } else { 238 os << "<NULL>"; 239 } 240 241 os << std::endl; 242 Expression::print( os, indent ); 243 } 244 224 245 AttrExpr::AttrExpr( Expression *attr, Expression *expr_, Expression *_aname ) : 225 246 Expression( _aname ), attr( attr ), expr(expr_), type(0), isType(false) { -
src/SynTree/Expression.h
r53ba273 r78885b5 362 362 }; 363 363 364 /// Expression representing a pack of field-offsets for a generic type 365 class OffsetPackExpr : public Expression { 366 public: 367 OffsetPackExpr( StructInstType *type_, Expression *aname_ = 0 ); 368 OffsetPackExpr( const OffsetPackExpr &other ); 369 virtual ~OffsetPackExpr(); 370 371 StructInstType *get_type() const { return type; } 372 void set_type( StructInstType *newValue ) { type = newValue; } 373 374 virtual OffsetPackExpr *clone() const { return new OffsetPackExpr( *this ); } 375 virtual void accept( Visitor &v ) { v.visit( this ); } 376 virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); } 377 378 virtual void print( std::ostream &os, int indent = 0 ) const; 379 380 private: 381 StructInstType *type; 382 }; 383 364 384 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined) 365 385 class AttrExpr : public Expression { -
src/SynTree/Mutator.cc
r53ba273 r78885b5 274 274 } 275 275 276 Expression *Mutator::mutate( OffsetPackExpr *offsetPackExpr ) { 277 mutateAll( offsetPackExpr->get_results(), *this ); 278 offsetPackExpr->set_type( maybeMutate( offsetPackExpr->get_type(), *this ) ); 279 return offsetPackExpr; 280 } 281 276 282 Expression *Mutator::mutate( AttrExpr *attrExpr ) { 277 283 mutateAll( attrExpr->get_results(), *this ); -
src/SynTree/Mutator.h
r53ba273 r78885b5 67 67 virtual Expression* mutate( UntypedOffsetofExpr *offsetofExpr ); 68 68 virtual Expression* mutate( OffsetofExpr *offsetofExpr ); 69 virtual Expression* mutate( OffsetPackExpr *offsetPackExpr ); 69 70 virtual Expression* mutate( AttrExpr *attrExpr ); 70 71 virtual Expression* mutate( LogicalExpr *logicalExpr ); -
src/SynTree/SynTree.h
r53ba273 r78885b5 72 72 class UntypedOffsetofExpr; 73 73 class OffsetofExpr; 74 class OffsetPackExpr; 74 75 class AttrExpr; 75 76 class LogicalExpr; -
src/SynTree/Visitor.cc
r53ba273 r78885b5 230 230 } 231 231 232 void Visitor::visit( OffsetPackExpr *offsetPackExpr ) { 233 acceptAll( offsetPackExpr->get_results(), *this ); 234 maybeAccept( offsetPackExpr->get_type(), *this ); 235 } 236 232 237 void Visitor::visit( AttrExpr *attrExpr ) { 233 238 acceptAll( attrExpr->get_results(), *this ); -
src/SynTree/Visitor.h
r53ba273 r78885b5 67 67 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 68 68 virtual void visit( OffsetofExpr *offsetofExpr ); 69 virtual void visit( OffsetPackExpr *offsetPackExpr ); 69 70 virtual void visit( AttrExpr *attrExpr ); 70 71 virtual void visit( LogicalExpr *logicalExpr ); -
src/Tuples/FlattenTuple.cc
r53ba273 r78885b5 49 49 void FlattenTuple::CollectArgs::visit( UntypedOffsetofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 50 50 void FlattenTuple::CollectArgs::visit( OffsetofExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 51 void FlattenTuple::CollectArgs::visit( OffsetPackExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 51 52 void FlattenTuple::CollectArgs::visit( AttrExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } 52 53 void FlattenTuple::CollectArgs::visit( LogicalExpr *expr ) { currentArgs.insert( currentArgs.end(), expr ); } -
src/Tuples/FlattenTuple.h
r53ba273 r78885b5 45 45 virtual void visit( UntypedOffsetofExpr * ); 46 46 virtual void visit( OffsetofExpr * ); 47 virtual void visit( OffsetPackExpr * ); 47 48 virtual void visit( AttrExpr * ); 48 49 virtual void visit( LogicalExpr * );
Note: See TracChangeset
for help on using the changeset viewer.