Changeset 7527e63 for src/GenPoly/Box.cc
- Timestamp:
- Aug 16, 2016, 3:20:06 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 1f6d4624
- Parents:
- 950f7a7 (diff), 7880579 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r950f7a7 r7527e63 62 62 63 63 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 64 65 /// Abstracts type equality for a list of parameter types66 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 ) ) {}73 74 /// Extracts types from a list of TypeExpr*75 TypeList( const std::list< TypeExpr* >& _params ) : params() {76 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {77 params.push_back( (*param)->get_type()->clone() );78 }79 }80 81 TypeList& operator= ( const TypeList &that ) {82 deleteAll( params );83 84 params.clear();85 cloneAll( that.params, params );86 87 return *this;88 }89 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;102 103 SymTab::Indexer dummy;104 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {105 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;106 }107 return true;108 }109 110 std::list< Type* > params; ///< Instantiation parameters111 };112 113 /// Maps a key and a TypeList to the some value, accounting for scope114 template< typename Key, typename Value >115 class InstantiationMap {116 /// Wraps value for a specific (Key, TypeList) combination117 typedef std::pair< TypeList, Value* > Instantiation;118 /// List of TypeLists paired with their appropriate values119 typedef std::vector< Instantiation > ValueList;120 /// Underlying map type; maps keys to a linear list of corresponding TypeLists and values121 typedef ScopedMap< Key*, ValueList > InnerMap;122 123 InnerMap instantiations; ///< instantiations124 125 public:126 /// Starts a new scope127 void beginScope() { instantiations.beginScope(); }128 129 /// Ends a scope130 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 key137 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;140 }141 }142 // no matching instantiations found143 return 0;144 }145 146 /// Adds a value for a (key, typeList) pair to the current scope147 void insert( Key *key, const std::list< TypeExpr* > ¶ms, Value *value ) {148 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) );149 }150 };151 64 152 65 /// Adds layout-generation functions to polymorphic types … … 191 104 Type *replaceWithConcrete( ApplicationExpr *appExpr, Type *type, bool doClone = true ); 192 105 /// wraps a function application returning a polymorphic type with a new temporary for the out-parameter return value 193 Expression *add PolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg );106 Expression *addDynRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ); 194 107 Expression *applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars ); 195 108 void boxParam( Type *formal, Expression *&arg, const TyVarMap &exprTyVars ); … … 237 150 238 151 std::map< UniqueId, std::string > adapterName; 239 };240 241 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately242 class GenericInstantiator : public DeclMutator {243 /// Map of (generic type, parameter list) pairs to concrete type instantiations244 InstantiationMap< AggregateDecl, AggregateDecl > instantiations;245 /// Namer for concrete types246 UniqueName typeNamer;247 248 public:249 GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}250 251 virtual Type* mutate( StructInstType *inst );252 virtual Type* mutate( UnionInstType *inst );253 254 // virtual Expression* mutate( MemberExpr *memberExpr );255 256 virtual void doBeginScope();257 virtual void doEndScope();258 private:259 /// Wrap instantiation lookup for structs260 StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); }261 /// Wrap instantiation lookup for unions262 UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); }263 /// Wrap instantiation insertion for structs264 void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); }265 /// Wrap instantiation insertion for unions266 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }267 152 }; 268 153 … … 354 239 Pass1 pass1; 355 240 Pass2 pass2; 356 GenericInstantiator instantiator;357 241 PolyGenericCalculator polyCalculator; 358 242 Pass3 pass3; … … 361 245 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 362 246 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 363 instantiator.mutateDeclarationList( translationUnit );364 247 mutateTranslationUnit/*All*/( translationUnit, polyCalculator ); 365 248 mutateTranslationUnit/*All*/( translationUnit, pass3 ); … … 619 502 return 0; 620 503 } 621 504 622 505 /// Returns T if the given declaration is a function with parameters (T*, T) for some TypeInstType T, NULL otherwise 623 506 TypeInstType *isTypeInstPtrValFn( DeclarationWithType *decl ) { … … 637 520 return 0; 638 521 } 639 522 640 523 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise 641 524 TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) { … … 677 560 return 0; 678 561 } 679 562 680 563 /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified, 681 564 /// NULL otherwise … … 772 655 copyOps.beginScope(); 773 656 dtorOps.beginScope(); 774 657 775 658 DeclarationWithType *oldRetval = retval; 776 659 bool oldUseRetval = useRetval; … … 778 661 // process polymorphic return value 779 662 retval = 0; 780 if ( is PolyRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) {663 if ( isDynRet( functionDecl->get_functionType() ) && functionDecl->get_linkage() == LinkageSpec::Cforall ) { 781 664 retval = functionDecl->get_functionType()->get_returnVals().front(); 782 665 … … 889 772 arg++; 890 773 } else { 891 // /xxx - should this be an assertion?774 // xxx - should this be an assertion? 892 775 throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr ); 893 776 } // if … … 902 785 std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); 903 786 std::list< Expression* >::const_iterator fnArg = arg; 904 std::set< std::string > seenTypes; // < names for generic types we've seen787 std::set< std::string > seenTypes; ///< names for generic types we've seen 905 788 906 789 // a polymorphic return type may need to be added to the argument list … … 985 868 } 986 869 987 Expression *Pass1::add PolyRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *polyType, std::list< Expression *>::iterator &arg ) {870 Expression *Pass1::addDynRetParam( ApplicationExpr *appExpr, FunctionType *function, ReferenceToType *dynType, std::list< Expression *>::iterator &arg ) { 988 871 assert( env ); 989 Type *concrete = replaceWithConcrete( appExpr, polyType );872 Type *concrete = replaceWithConcrete( appExpr, dynType ); 990 873 // add out-parameter for return value 991 874 return addRetParam( appExpr, function, concrete, arg ); … … 994 877 Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) { 995 878 Expression *ret = appExpr; 996 if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 879 // if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) { 880 if ( isDynRet( function, tyVars ) ) { 997 881 ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg ); 998 882 } // if … … 1042 926 /// this gets rid of warnings from gcc. 1043 927 void addCast( Expression *&actual, Type *formal, const TyVarMap &tyVars ) { 1044 Type * newType = formal->clone();1045 if ( getFunctionType( newType ) ) {928 if ( getFunctionType( formal ) ) { 929 Type * newType = formal->clone(); 1046 930 newType = ScrubTyVars::scrub( newType, tyVars ); 1047 931 actual = new CastExpr( actual, newType ); … … 1085 969 // actually make the adapter type 1086 970 FunctionType *adapter = adaptee->clone(); 1087 if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) { 971 // if ( ! adapter->get_returnVals().empty() && isPolyType( adapter->get_returnVals().front()->get_type(), tyVars ) ) { 972 if ( isDynRet( adapter, tyVars ) ) { 1088 973 makeRetParm( adapter ); 1089 974 } // if … … 1147 1032 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 1148 1033 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 1149 } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 1034 // } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 1035 } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 1150 1036 // return type T 1151 1037 if ( (*param)->get_name() == "" ) { … … 1394 1280 TyVarMap exprTyVars( (TypeDecl::Kind)-1 ); 1395 1281 makeTyVarMap( function, exprTyVars ); 1396 ReferenceToType * polyRetType = isPolyRet( function);1397 1398 if ( polyRetType ) {1399 ret = add PolyRetParam( appExpr, function, polyRetType, arg );1282 ReferenceToType *dynRetType = isDynRet( function, exprTyVars ); 1283 1284 if ( dynRetType ) { 1285 ret = addDynRetParam( appExpr, function, dynRetType, arg ); 1400 1286 } else if ( needsAdapter( function, scopeTyVars ) ) { 1401 1287 // std::cerr << "needs adapter: "; … … 1407 1293 arg = appExpr->get_args().begin(); 1408 1294 1409 passTypeVars( appExpr, polyRetType, arg, exprTyVars );1295 passTypeVars( appExpr, dynRetType, arg, exprTyVars ); 1410 1296 addInferredParams( appExpr, function, arg, exprTyVars ); 1411 1297 … … 1471 1357 VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) { 1472 1358 // line below cloned from FixFunction.cc 1359 // xxx - functionObj is never added to a list of declarations... 1473 1360 ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, 1474 1361 new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 ); 1475 1362 functionObj->set_mangleName( functionDecl->get_mangleName() ); 1363 functionObj->set_scopeLevel( functionDecl->get_scopeLevel() ); 1476 1364 return new VariableExpr( functionObj ); 1477 1365 } … … 1492 1380 = ParamEntry( assertOp->get_uniqueId(), assertOp->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertOp ) ); 1493 1381 } 1494 1382 1495 1383 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1496 1384 if ( retval && returnStmt->get_expr() ) { … … 1554 1442 DeclarationWithType *assertDtor = findOpForType( formalType, dtorOps, scopedDtorOps ); 1555 1443 if ( ! assertDtor ) throw SemanticError( "No destructor found for ", formalType ); 1556 1444 1557 1445 // add inferred parameters for otype operators to assignment expression 1558 1446 // NOTE: Code here assumes that first four assertions are assign op, ctor, copy ctor, dtor, in that order … … 1568 1456 ++actualIt; 1569 1457 addAssertionFor( assignExpr, *actualIt, assertDtor ); 1570 1571 //DeclarationWithType *actualDecl = asserts.front(); 1572 //assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1573 // = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); 1458 1574 1459 } 1575 1460 } … … 1695 1580 1696 1581 // move polymorphic return type to parameter list 1697 if ( is PolyRet( funcType ) ) {1582 if ( isDynRet( funcType ) ) { 1698 1583 DeclarationWithType *ret = funcType->get_returnVals().front(); 1699 1584 ret->set_type( new PointerType( Type::Qualifiers(), ret->get_type() ) ); … … 1776 1661 } 1777 1662 1778 //////////////////////////////////////// GenericInstantiator //////////////////////////////////////////////////1779 1780 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type1781 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {1782 bool allConcrete = true; // will finish the substitution list even if they're not all concrete1783 1784 // substitute concrete types for given parameters, and incomplete types for placeholders1785 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();1786 std::list< Expression* >::const_iterator param = params.begin();1787 for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {1788 // switch ( (*baseParam)->get_kind() ) {1789 // case TypeDecl::Any: { // any type is a valid substitution here; complete types can be used to instantiate generics1790 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );1791 assert(paramType && "Aggregate parameters should be type expressions");1792 out.push_back( paramType->clone() );1793 // check that the substituted type isn't a type variable itself1794 if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {1795 allConcrete = false;1796 }1797 // break;1798 // }1799 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*]1800 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );1801 // break;1802 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]1803 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );1804 // break;1805 // }1806 }1807 1808 // if any parameters left over, not done1809 if ( baseParam != baseParams.end() ) return false;1810 // // if not enough parameters given, substitute remaining incomplete types for placeholders1811 // for ( ; baseParam != baseParams.end(); ++baseParam ) {1812 // switch ( (*baseParam)->get_kind() ) {1813 // case TypeDecl::Any: // no more substitutions here, fail early1814 // return false;1815 // case TypeDecl::Dtype: // dtype can be consistently replaced with void [only pointers, which become void*]1816 // out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );1817 // break;1818 // case TypeDecl::Ftype: // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]1819 // out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );1820 // break;1821 // }1822 // }1823 1824 return allConcrete;1825 }1826 1827 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out1828 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,1829 std::list< Declaration* >& out ) {1830 // substitute types into new members1831 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );1832 for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {1833 Declaration *newMember = (*member)->clone();1834 subs.apply(newMember);1835 out.push_back( newMember );1836 }1837 }1838 1839 Type* GenericInstantiator::mutate( StructInstType *inst ) {1840 // mutate subtypes1841 Type *mutated = Mutator::mutate( inst );1842 inst = dynamic_cast< StructInstType* >( mutated );1843 if ( ! inst ) return mutated;1844 1845 // exit early if no need for further mutation1846 if ( inst->get_parameters().empty() ) return inst;1847 assert( inst->get_baseParameters() && "Base struct has parameters" );1848 1849 // check if type can be concretely instantiated; put substitutions into typeSubs1850 std::list< TypeExpr* > typeSubs;1851 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {1852 deleteAll( typeSubs );1853 return inst;1854 }1855 1856 // make concrete instantiation of generic type1857 StructDecl *concDecl = lookup( inst, typeSubs );1858 if ( ! concDecl ) {1859 // set concDecl to new type, insert type declaration into statements to add1860 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );1861 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );1862 DeclMutator::addDeclaration( concDecl );1863 insert( inst, typeSubs, concDecl );1864 }1865 StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );1866 newInst->set_baseStruct( concDecl );1867 1868 deleteAll( typeSubs );1869 delete inst;1870 return newInst;1871 }1872 1873 Type* GenericInstantiator::mutate( UnionInstType *inst ) {1874 // mutate subtypes1875 Type *mutated = Mutator::mutate( inst );1876 inst = dynamic_cast< UnionInstType* >( mutated );1877 if ( ! inst ) return mutated;1878 1879 // exit early if no need for further mutation1880 if ( inst->get_parameters().empty() ) return inst;1881 assert( inst->get_baseParameters() && "Base union has parameters" );1882 1883 // check if type can be concretely instantiated; put substitutions into typeSubs1884 std::list< TypeExpr* > typeSubs;1885 if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {1886 deleteAll( typeSubs );1887 return inst;1888 }1889 1890 // make concrete instantiation of generic type1891 UnionDecl *concDecl = lookup( inst, typeSubs );1892 if ( ! concDecl ) {1893 // set concDecl to new type, insert type declaration into statements to add1894 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );1895 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );1896 DeclMutator::addDeclaration( concDecl );1897 insert( inst, typeSubs, concDecl );1898 }1899 UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );1900 newInst->set_baseUnion( concDecl );1901 1902 deleteAll( typeSubs );1903 delete inst;1904 return newInst;1905 }1906 1907 // /// Gets the base struct or union declaration for a member expression; NULL if not applicable1908 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {1909 // // get variable for member aggregate1910 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );1911 // if ( ! varExpr ) return NULL;1912 //1913 // // get object for variable1914 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );1915 // if ( ! objectDecl ) return NULL;1916 //1917 // // get base declaration from object type1918 // Type *objectType = objectDecl->get_type();1919 // StructInstType *structType = dynamic_cast< StructInstType* >( objectType );1920 // if ( structType ) return structType->get_baseStruct();1921 // UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );1922 // if ( unionType ) return unionType->get_baseUnion();1923 //1924 // return NULL;1925 // }1926 //1927 // /// Finds the declaration with the given name, returning decls.end() if none such1928 // std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {1929 // for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {1930 // if ( (*decl)->get_name() == name ) return decl;1931 // }1932 // return decls.end();1933 // }1934 //1935 // Expression* Instantiate::mutate( MemberExpr *memberExpr ) {1936 // // mutate, exiting early if no longer MemberExpr1937 // Expression *expr = Mutator::mutate( memberExpr );1938 // memberExpr = dynamic_cast< MemberExpr* >( expr );1939 // if ( ! memberExpr ) return expr;1940 //1941 // // get declaration of member and base declaration of member, exiting early if not found1942 // AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );1943 // if ( ! memberBase ) return memberExpr;1944 // DeclarationWithType *memberDecl = memberExpr->get_member();1945 // std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );1946 // if ( baseIt == memberBase->get_members().end() ) return memberExpr;1947 // DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );1948 // if ( ! baseDecl ) return memberExpr;1949 //1950 // // check if stated type of the member is not the type of the member's declaration; if so, need a cast1951 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker1952 // SymTab::Indexer dummy;1953 // if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;1954 // else return new CastExpr( memberExpr, memberDecl->get_type() );1955 // }1956 1957 void GenericInstantiator::doBeginScope() {1958 DeclMutator::doBeginScope();1959 instantiations.beginScope();1960 }1961 1962 void GenericInstantiator::doEndScope() {1963 DeclMutator::doEndScope();1964 instantiations.endScope();1965 }1966 1967 1663 ////////////////////////////////////////// PolyGenericCalculator //////////////////////////////////////////////////// 1968 1664 … … 2108 1804 findGeneric( objectType ); // ensure layout for this type is available 2109 1805 1806 // replace member expression with dynamically-computed layout expression 2110 1807 Expression *newMemberExpr = 0; 2111 1808 if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) { … … 2181 1878 bool PolyGenericCalculator::findGeneric( Type *ty ) { 2182 1879 ty = replaceTypeInst( ty, env ); 2183 1880 2184 1881 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 2185 1882 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) {
Note:
See TracChangeset
for help on using the changeset viewer.