Changeset 4e284ea6 for src/GenPoly
- Timestamp:
- Mar 8, 2016, 10:32:47 AM (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:
- e8032b0
- Parents:
- 6635c74
- Location:
- src/GenPoly
- Files:
-
- 2 deleted
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r6635c74 r4e284ea6 14 14 // 15 15 16 #include <algorithm> 17 #include <iterator> 18 #include <list> 19 #include <map> 16 20 #include <set> 17 21 #include <stack> 18 22 #include <string> 19 #include < iterator>20 #include < algorithm>23 #include <utility> 24 #include <vector> 21 25 #include <cassert> 22 26 23 27 #include "Box.h" 24 28 #include "DeclMutator.h" 25 #include "InstantiateGeneric.h"26 29 #include "PolyMutator.h" 27 30 #include "FindFunction.h" … … 32 35 33 36 #include "SynTree/Constant.h" 34 #include "SynTree/ Type.h"37 #include "SynTree/Declaration.h" 35 38 #include "SynTree/Expression.h" 36 39 #include "SynTree/Initializer.h" 40 #include "SynTree/Mutator.h" 37 41 #include "SynTree/Statement.h" 38 #include "SynTree/Mutator.h" 42 #include "SynTree/Type.h" 43 #include "SynTree/TypeSubstitution.h" 39 44 40 45 #include "ResolvExpr/TypeEnvironment.h" … … 42 47 #include "ResolvExpr/typeops.h" 43 48 49 #include "SymTab/Indexer.h" 44 50 #include "SymTab/Mangler.h" 45 51 … … 55 61 56 62 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 63 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); } 71 72 /// Extracts types from a list of TypeExpr* 73 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() { 74 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 75 params.push_back( (*param)->get_type()->clone() ); 76 } 77 } 78 79 ConcreteType& operator= (const ConcreteType& that) { 80 deleteAll( params ); 81 params.clear(); 82 83 base = that.base; 84 cloneAll( that.params, params ); 85 86 return *this; 87 } 88 89 ~ConcreteType() { deleteAll( params ); } 90 91 bool operator== (const ConcreteType& that) const { 92 if ( base != that.base ) return false; 93 94 SymTab::Indexer dummy; 95 if ( params.size() != that.params.size() ) return false; 96 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 97 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; 98 } 99 return true; 100 } 101 102 AggregateDecl *base; ///< Base generic type 103 std::list< Type* > params; ///< Instantiation parameters 104 }; 105 106 /// Maps a concrete type to the some value, accounting for scope 107 template< typename Value > 108 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 121 122 public: 123 /// Starts a new scope 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 128 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; 150 } 151 } 152 // no matching instantiation found 153 return 0; 154 } 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 ); } 168 }; 57 169 58 170 /// Adds layout-generation functions to polymorphic types … … 138 250 }; 139 251 252 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately 253 class GenericInstantiator : public DeclMutator { 254 /// Map of (generic type, parameter list) pairs to concrete type instantiations 255 InstantiationMap< AggregateDecl > instantiations; 256 /// Namer for concrete types 257 UniqueName typeNamer; 258 259 public: 260 GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {} 261 262 virtual Type* mutate( StructInstType *inst ); 263 virtual Type* mutate( UnionInstType *inst ); 264 265 // virtual Expression* mutate( MemberExpr *memberExpr ); 266 267 virtual void doBeginScope(); 268 virtual void doEndScope(); 269 private: 270 /// Wrap instantiation lookup for structs 271 StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); } 272 /// Wrap instantiation lookup for unions 273 UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); } 274 /// Wrap instantiation insertion for structs 275 void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); } 276 /// Wrap instantiation insertion for unions 277 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); } 278 }; 279 140 280 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference; 141 281 /// also fixes offsetof expressions. … … 201 341 Pass1 pass1; 202 342 Pass2 pass2; 343 GenericInstantiator instantiator; 203 344 MemberExprFixer memberFixer; 204 345 Pass3 pass3; 346 205 347 layoutBuilder.mutateDeclarationList( translationUnit ); 206 348 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 207 349 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 208 instantiateGeneric( translationUnit ); 350 // instantiateGeneric( translationUnit ); 351 instantiator.mutateDeclarationList( translationUnit ); 209 352 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 210 353 mutateTranslationUnit/*All*/( translationUnit, pass3 ); … … 1509 1652 } 1510 1653 1654 //////////////////////////////////////// GenericInstantiator ////////////////////////////////////////////////// 1655 1656 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type 1657 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) { 1658 bool allConcrete = true; // will finish the substitution list even if they're not all concrete 1659 1660 // substitute concrete types for given parameters, and incomplete types for placeholders 1661 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 1662 std::list< Expression* >::const_iterator param = params.begin(); 1663 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) { 1664 // switch ( (*baseParam)->get_kind() ) { 1665 // case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics 1666 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 1667 assert(paramType && "Aggregate parameters should be type expressions"); 1668 out.push_back( paramType->clone() ); 1669 // check that the substituted type isn't a type variable itself 1670 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) { 1671 allConcrete = false; 1672 } 1673 // break; 1674 // } 1675 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 1676 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 1677 // break; 1678 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 1679 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 1680 // break; 1681 // } 1682 } 1683 1684 // if any parameters left over, not done 1685 if ( baseParam != baseParams.end() ) return false; 1686 // // if not enough parameters given, substitute remaining incomplete types for placeholders 1687 // for ( ; baseParam != baseParams.end(); ++baseParam ) { 1688 // switch ( (*baseParam)->get_kind() ) { 1689 // case TypeDecl::Any: // no more substitutions here, fail early 1690 // return false; 1691 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*] 1692 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) ); 1693 // break; 1694 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype] 1695 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) ); 1696 // break; 1697 // } 1698 // } 1699 1700 return allConcrete; 1701 } 1702 1703 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out 1704 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs, 1705 std::list< Declaration* >& out ) { 1706 // substitute types into new members 1707 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() ); 1708 for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) { 1709 Declaration *newMember = (*member)->clone(); 1710 subs.apply(newMember); 1711 out.push_back( newMember ); 1712 } 1713 } 1714 1715 Type* GenericInstantiator::mutate( StructInstType *inst ) { 1716 // mutate subtypes 1717 Type *mutated = Mutator::mutate( inst ); 1718 inst = dynamic_cast< StructInstType* >( mutated ); 1719 if ( ! inst ) return mutated; 1720 1721 // exit early if no need for further mutation 1722 if ( inst->get_parameters().empty() ) return inst; 1723 assert( inst->get_baseParameters() && "Base struct has parameters" ); 1724 1725 // check if type can be concretely instantiated; put substitutions into typeSubs 1726 std::list< TypeExpr* > typeSubs; 1727 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 1728 deleteAll( typeSubs ); 1729 return inst; 1730 } 1731 1732 // make concrete instantiation of generic type 1733 StructDecl *concDecl = lookup( inst, typeSubs ); 1734 if ( ! concDecl ) { 1735 // set concDecl to new type, insert type declaration into statements to add 1736 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) ); 1737 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 1738 DeclMutator::addDeclaration( concDecl ); 1739 insert( inst, typeSubs, concDecl ); 1740 } 1741 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() ); 1742 newInst->set_baseStruct( concDecl ); 1743 1744 deleteAll( typeSubs ); 1745 delete inst; 1746 return newInst; 1747 } 1748 1749 Type* GenericInstantiator::mutate( UnionInstType *inst ) { 1750 // mutate subtypes 1751 Type *mutated = Mutator::mutate( inst ); 1752 inst = dynamic_cast< UnionInstType* >( mutated ); 1753 if ( ! inst ) return mutated; 1754 1755 // exit early if no need for further mutation 1756 if ( inst->get_parameters().empty() ) return inst; 1757 assert( inst->get_baseParameters() && "Base union has parameters" ); 1758 1759 // check if type can be concretely instantiated; put substitutions into typeSubs 1760 std::list< TypeExpr* > typeSubs; 1761 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) { 1762 deleteAll( typeSubs ); 1763 return inst; 1764 } 1765 1766 // make concrete instantiation of generic type 1767 UnionDecl *concDecl = lookup( inst, typeSubs ); 1768 if ( ! concDecl ) { 1769 // set concDecl to new type, insert type declaration into statements to add 1770 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) ); 1771 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() ); 1772 DeclMutator::addDeclaration( concDecl ); 1773 insert( inst, typeSubs, concDecl ); 1774 } 1775 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() ); 1776 newInst->set_baseUnion( concDecl ); 1777 1778 deleteAll( typeSubs ); 1779 delete inst; 1780 return newInst; 1781 } 1782 1783 // /// Gets the base struct or union declaration for a member expression; NULL if not applicable 1784 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) { 1785 // // get variable for member aggregate 1786 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() ); 1787 // if ( ! varExpr ) return NULL; 1788 // 1789 // // get object for variable 1790 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() ); 1791 // if ( ! objectDecl ) return NULL; 1792 // 1793 // // get base declaration from object type 1794 // Type *objectType = objectDecl->get_type(); 1795 // StructInstType *structType = dynamic_cast< StructInstType* >( objectType ); 1796 // if ( structType ) return structType->get_baseStruct(); 1797 // UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ); 1798 // if ( unionType ) return unionType->get_baseUnion(); 1799 // 1800 // return NULL; 1801 // } 1802 // 1803 // /// Finds the declaration with the given name, returning decls.end() if none such 1804 // std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) { 1805 // for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) { 1806 // if ( (*decl)->get_name() == name ) return decl; 1807 // } 1808 // return decls.end(); 1809 // } 1810 // 1811 // Expression* Instantiate::mutate( MemberExpr *memberExpr ) { 1812 // // mutate, exiting early if no longer MemberExpr 1813 // Expression *expr = Mutator::mutate( memberExpr ); 1814 // memberExpr = dynamic_cast< MemberExpr* >( expr ); 1815 // if ( ! memberExpr ) return expr; 1816 // 1817 // // get declaration of member and base declaration of member, exiting early if not found 1818 // AggregateDecl *memberBase = getMemberBaseDecl( memberExpr ); 1819 // if ( ! memberBase ) return memberExpr; 1820 // DeclarationWithType *memberDecl = memberExpr->get_member(); 1821 // std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() ); 1822 // if ( baseIt == memberBase->get_members().end() ) return memberExpr; 1823 // DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt ); 1824 // if ( ! baseDecl ) return memberExpr; 1825 // 1826 // // check if stated type of the member is not the type of the member's declaration; if so, need a cast 1827 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker 1828 // SymTab::Indexer dummy; 1829 // if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr; 1830 // else return new CastExpr( memberExpr, memberDecl->get_type() ); 1831 // } 1832 1833 void GenericInstantiator::doBeginScope() { 1834 DeclMutator::doBeginScope(); 1835 instantiations.beginScope(); 1836 } 1837 1838 void GenericInstantiator::doEndScope() { 1839 DeclMutator::doEndScope(); 1840 instantiations.endScope(); 1841 } 1842 1511 1843 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1512 1844 -
src/GenPoly/module.mk
r6635c74 r4e284ea6 23 23 GenPoly/CopyParams.cc \ 24 24 GenPoly/FindFunction.cc \ 25 GenPoly/InstantiateGeneric.cc \26 25 GenPoly/DeclMutator.cc
Note: See TracChangeset
for help on using the changeset viewer.