Changes in / [c2c6177:452747a]
- Location:
- src
- Files:
-
- 8 edited
-
GenPoly/InstantiateGeneric.cc (modified) (4 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (28 diffs)
-
ResolvExpr/AlternativeFinder.h (modified) (3 diffs)
-
ResolvExpr/TypeEnvironment.cc (modified) (1 diff)
-
ResolvExpr/TypeEnvironment.h (modified) (2 diffs)
-
SymTab/Autogen.h (modified) (6 diffs)
-
SymTab/Validate.cc (modified) (5 diffs)
-
SynTree/Expression.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
rc2c6177 r452747a 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/ResolvExpr/AlternativeFinder.cc
rc2c6177 r452747a 578 578 /// State to iteratively build a match of parameter expressions to arguments 579 579 struct ArgPack { 580 std::size_t parent; ///< Index of parent pack 580 std::size_t parent; ///< Index of parent pack 581 581 std::unique_ptr<Expression> expr; ///< The argument stored here 582 582 Cost cost; ///< The cost of this argument … … 593 593 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 594 594 tupleStart(0), expls() {} 595 596 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 595 596 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 597 597 const OpenVarSet& openVars) 598 : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 598 : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 599 599 openVars(openVars), nextArg(0), tupleStart(0), expls() {} 600 601 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 602 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 603 unsigned tupleStart = 0, Cost cost = Cost::zero, 600 601 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 602 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 603 unsigned tupleStart = 0, Cost cost = Cost::zero, 604 604 std::vector<Alternative>&& expls = std::vector<Alternative>{} ) 605 : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 605 : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 606 606 have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart), 607 607 expls(move(expls)) {} 608 609 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 608 609 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 610 610 OpenVarSet&& openVars, unsigned nextArg, Cost added ) 611 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 612 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 611 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 612 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 613 613 nextArg(nextArg), tupleStart(o.tupleStart), expls() {} 614 614 615 615 616 616 // ArgPack(const ArgPack& o) 617 // : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), env(o.env), 618 // need(o.need), have(o.have), openVars(o.openVars), nextArg(o.nextArg), 617 // : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), env(o.env), 618 // need(o.need), have(o.have), openVars(o.openVars), nextArg(o.nextArg), 619 619 // tupleStart(o.tupleStart), expls(o.expls) {} 620 620 621 621 // ArgPack(ArgPack&&) = default; 622 622 623 623 /// Ends a tuple expression, consolidating the appropriate actuals 624 624 void endTuple( const std::vector<ArgPack>& packs ) { … … 640 640 641 641 /// Instantiates an argument to match a formal, returns false if no results left 642 bool instantiateArgument( Type* formalType, Initializer* initializer, 643 const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results, 642 bool instantiateArgument( Type* formalType, Initializer* initializer, 643 const std::vector< AlternativeFinder >& args, std::vector<ArgPack>& results, 644 644 std::size_t& genStart, const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 645 645 if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) { … … 648 648 for ( Type* type : *tupleType ) { 649 649 // xxx - dropping initializer changes behaviour from previous, but seems correct 650 if ( ! instantiateArgument( 651 type, nullptr, args, results, genStart, indexer, nTuples ) ) 650 if ( ! instantiateArgument( 651 type, nullptr, args, results, genStart, indexer, nTuples ) ) 652 652 return false; 653 653 nTuples = 0; … … 676 676 if ( ! results[i].expls.empty() ) { 677 677 const Alternative& actual = results[i].expls.front(); 678 678 679 679 TypeEnvironment env = results[i].env; 680 680 OpenVarSet openVars = results[i].openVars; … … 682 682 env.addActual( actual.env, openVars ); 683 683 684 std::vector<Alternative> newExpls( 684 std::vector<Alternative> newExpls( 685 685 std::next( results[i].expls.begin() ), results[i].expls.end() ); 686 686 results.emplace_back( 687 i, actual.expr, move(env), copy(results[i].need), 688 copy(results[i].have), move(openVars), results[i].nextArg, nTuples, 687 i, actual.expr, move(env), copy(results[i].need), 688 copy(results[i].have), move(openVars), results[i].nextArg, nTuples, 689 689 Cost::zero, move(newExpls) ); 690 690 691 691 continue; 692 692 } 693 693 694 694 // finish result when out of arguments 695 695 if ( results[i].nextArg >= args.size() ) { 696 ArgPack newResult{ 697 results[i].env, results[i].need, results[i].have, 696 ArgPack newResult{ 697 results[i].env, results[i].need, results[i].have, 698 698 results[i].openVars }; 699 699 newResult.nextArg = results[i].nextArg; … … 715 715 716 716 if ( results[i].tupleStart > 0 && Tuples::isTtype( argType ) ) { 717 // the case where a ttype value is passed directly is special, 717 // the case where a ttype value is passed directly is special, 718 718 // e.g. for argument forwarding purposes 719 // xxx - what if passing multiple arguments, last of which is 719 // xxx - what if passing multiple arguments, last of which is 720 720 // ttype? 721 // xxx - what would happen if unify was changed so that unifying 722 // tuple 723 // types flattened both before unifying lists? then pass in 721 // xxx - what would happen if unify was changed so that unifying 722 // tuple 723 // types flattened both before unifying lists? then pass in 724 724 // TupleType (ttype) below. 725 725 --newResult.tupleStart; … … 732 732 733 733 // check unification for ttype before adding to final 734 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 734 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 735 735 newResult.openVars, indexer ) ) { 736 736 finalResults.push_back( move(newResult) ); 737 737 } 738 738 739 739 continue; 740 740 } … … 755 755 // skip empty tuple arguments by (near-)cloning parent into next gen 756 756 results.emplace_back( 757 results[i], move(env), copy(results[i].need), 757 results[i], move(env), copy(results[i].need), 758 758 copy(results[i].have), move(openVars), j + 1, actual.cost ); 759 759 760 760 continue; 761 761 } … … 769 769 // add new result 770 770 results.emplace_back( 771 i, exploded.front().expr, move(env), copy(results[i].need), 772 copy(results[i].have), move(openVars), results[i].nextArg + 1, 771 i, exploded.front().expr, move(env), copy(results[i].need), 772 copy(results[i].have), move(openVars), results[i].nextArg + 1, 773 773 nTuples, actual.cost, move(newExpls) ); 774 774 } … … 793 793 if ( ! results[i].expls.empty() ) { 794 794 const Alternative& actual = results[i].expls.front(); 795 795 796 796 TypeEnvironment env = results[i].env; 797 797 AssertionSet need = results[i].need, have = results[i].have; … … 808 808 std::cerr << std::endl; 809 809 ) 810 810 811 811 if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) { 812 std::vector<Alternative> newExpls( 812 std::vector<Alternative> newExpls( 813 813 std::next( results[i].expls.begin() ), results[i].expls.end() ); 814 results.emplace_back( 815 i, actual.expr, move(env), move(need), move(have), move(openVars), 814 results.emplace_back( 815 i, actual.expr, move(env), move(need), move(have), move(openVars), 816 816 results[i].nextArg, nTuples, Cost::zero, move(newExpls) );; 817 817 } … … 819 819 continue; 820 820 } 821 821 822 822 // use default initializers if out of arguments 823 823 if ( results[i].nextArg >= args.size() ) { … … 828 828 OpenVarSet openVars = results[i].openVars; 829 829 830 if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 830 if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 831 831 indexer ) ) { 832 832 results.emplace_back( 833 i, cnstExpr, move(env), move(need), move(have), 833 i, cnstExpr, move(env), move(need), move(have), 834 834 move(openVars), results[i].nextArg, nTuples ); 835 835 } … … 849 849 850 850 env.addActual( actual.env, openVars ); 851 851 852 852 // explode argument 853 853 std::vector<Alternative> exploded; … … 856 856 // skip empty tuple arguments by (near-)cloning parent into next gen 857 857 results.emplace_back( 858 results[i], move(env), move(need), move(have), move(openVars), j + 1, 858 results[i], move(env), move(need), move(have), move(openVars), j + 1, 859 859 actual.cost ); 860 860 … … 892 892 // reset for next parameter 893 893 genStart = genEnd; 894 894 895 895 return genEnd != results.size(); 896 896 } 897 897 898 898 template<typename OutputIterator> 899 void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 899 void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 900 900 const std::vector<ArgPack>& results, OutputIterator out ) { 901 901 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); … … 948 948 for ( DeclarationWithType* formal : funcType->get_parameters() ) { 949 949 ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal ); 950 if ( ! instantiateArgument( 950 if ( ! instantiateArgument( 951 951 obj->get_type(), obj->get_init(), args, results, genStart, indexer ) ) 952 952 return; … … 964 964 if ( ! results[i].expls.empty() ) { 965 965 const Alternative& actual = results[i].expls.front(); 966 966 967 967 TypeEnvironment env = results[i].env; 968 968 OpenVarSet openVars = results[i].openVars; … … 970 970 env.addActual( actual.env, openVars ); 971 971 972 std::vector<Alternative> newExpls( 972 std::vector<Alternative> newExpls( 973 973 std::next( results[i].expls.begin() ), results[i].expls.end() ); 974 974 results.emplace_back( 975 i, actual.expr, move(env), copy(results[i].need), 976 copy(results[i].have), move(openVars), results[i].nextArg, 0, 975 i, actual.expr, move(env), copy(results[i].need), 976 copy(results[i].have), move(openVars), results[i].nextArg, 0, 977 977 Cost::zero, move(newExpls) ); 978 978 979 979 continue; 980 980 } … … 1001 1001 if ( exploded.empty() ) { 1002 1002 // skip empty tuple arguments by (near-)cloning parent into next gen 1003 results.emplace_back( 1004 results[i], move(env), copy(results[i].need), 1003 results.emplace_back( 1004 results[i], move(env), copy(results[i].need), 1005 1005 copy(results[i].have), move(openVars), j + 1, actual.cost ); 1006 1006 continue; … … 1015 1015 // add new result 1016 1016 results.emplace_back( 1017 i, exploded.front().expr, move(env), copy(results[i].need), 1018 copy(results[i].have), move(openVars), j + 1, 0, 1017 i, exploded.front().expr, move(env), copy(results[i].need), 1018 copy(results[i].have), move(openVars), j + 1, 0, 1019 1019 actual.cost, move(newExpls) ); 1020 1020 } … … 1147 1147 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( winners ) ); 1148 1148 1149 // function may return struct or union value, in which case we need to add alternatives 1150 // for implicitconversions to each of the anonymous members, must happen after findMinCost 1149 // function may return struct or union value, in which case we need to add alternatives 1150 // for implicitconversions to each of the anonymous members, must happen after findMinCost 1151 1151 // since anon conversions are never the cheapest expression 1152 1152 for ( const Alternative & alt : winners ) { … … 1179 1179 for ( Alternative& alt : finder.alternatives ) { 1180 1180 if ( isLvalue( alt.expr ) ) { 1181 alternatives.push_back( 1181 alternatives.push_back( 1182 1182 Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } ); 1183 1183 } // if … … 1228 1228 1229 1229 AltList candidates; 1230 for ( Alternative & alt : finder.alternatives ) {1230 for ( Alternative & alt : finder.alternatives ) { 1231 1231 AssertionSet needAssertions, haveAssertions; 1232 1232 OpenVarSet openVars; … … 1241 1241 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1242 1242 // unification run for side-effects 1243 unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 1243 unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 1244 1244 haveAssertions, openVars, indexer ); 1245 Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 1245 Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 1246 1246 alt.env ); 1247 PRINT( 1248 std::cerr << "working on cast with result: " << castExpr->result << std::endl; 1249 std::cerr << "and expr type: " << alt.expr->result << std::endl; 1250 std::cerr << "env: " << alt.env << std::endl; 1251 ) 1247 1252 if ( thisCost != Cost::infinity ) { 1253 PRINT( 1254 std::cerr << "has finite cost." << std::endl; 1255 ) 1248 1256 // count one safe conversion for each value that is thrown away 1249 1257 thisCost.incSafe( discardedValues ); 1250 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 1258 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 1251 1259 alt.cost, thisCost ); 1252 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 1260 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 1253 1261 back_inserter( candidates ) ); 1254 1262 } // if … … 1539 1547 void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) { 1540 1548 std::vector< AlternativeFinder > subExprAlternatives; 1541 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 1549 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 1542 1550 back_inserter( subExprAlternatives ) ); 1543 1551 std::vector< AltList > possibilities; 1544 combos( subExprAlternatives.begin(), subExprAlternatives.end(), 1552 combos( subExprAlternatives.begin(), subExprAlternatives.end(), 1545 1553 back_inserter( possibilities ) ); 1546 1554 for ( const AltList& alts : possibilities ) { … … 1550 1558 TypeEnvironment compositeEnv; 1551 1559 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 1552 alternatives.push_back( 1560 alternatives.push_back( 1553 1561 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } ); 1554 1562 } // for -
src/ResolvExpr/AlternativeFinder.h
rc2c6177 r452747a 31 31 32 32 namespace ResolvExpr { 33 classArgPack;34 33 struct ArgPack; 34 35 35 class AlternativeFinder : public Visitor { 36 36 public: … … 38 38 39 39 AlternativeFinder( const AlternativeFinder& o ) 40 : indexer(o.indexer), alternatives(o.alternatives), env(o.env), 40 : indexer(o.indexer), alternatives(o.alternatives), env(o.env), 41 41 targetType(o.targetType) {} 42 42 43 43 AlternativeFinder( AlternativeFinder&& o ) 44 : indexer(o.indexer), alternatives(std::move(o.alternatives)), env(o.env), 44 : indexer(o.indexer), alternatives(std::move(o.alternatives)), env(o.env), 45 45 targetType(o.targetType) {} 46 46 47 47 AlternativeFinder& operator= ( const AlternativeFinder& o ) { 48 48 if (&o == this) return *this; 49 49 50 50 // horrific nasty hack to rebind references... 51 51 alternatives.~AltList(); … … 56 56 AlternativeFinder& operator= ( AlternativeFinder&& o ) { 57 57 if (&o == this) return *this; 58 58 59 59 // horrific nasty hack to rebind references... 60 60 alternatives.~AltList(); -
src/ResolvExpr/TypeEnvironment.cc
rc2c6177 r452747a 212 212 } 213 213 214 std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ) { 215 env.print( out ); 216 return out; 217 } 214 218 } // namespace ResolvExpr 215 219 -
src/ResolvExpr/TypeEnvironment.h
rc2c6177 r452747a 86 86 TypeEnvironment *clone() const { return new TypeEnvironment( *this ); } 87 87 88 /// Iteratively adds the environment of a new actual (with allowWidening = false), 88 /// Iteratively adds the environment of a new actual (with allowWidening = false), 89 89 /// and extracts open variables. 90 90 void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ); … … 114 114 return sub.applyFree( type ); 115 115 } 116 117 std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ); 116 118 } // namespace ResolvExpr 117 119 -
src/SymTab/Autogen.h
rc2c6177 r452747a 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
rc2c6177 r452747a 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 ) ) { -
src/SynTree/Expression.cc
rc2c6177 r452747a 324 324 return makeSub( refType->get_base() ); 325 325 } else if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) { 326 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst-> get_parameters().begin() );326 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->parameters.begin() ); 327 327 } else if ( UnionInstType * aggInst = dynamic_cast< UnionInstType * >( t ) ) { 328 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst-> get_parameters().begin() );328 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->parameters.begin() ); 329 329 } else { 330 330 assertf( false, "makeSub expects struct or union type for aggregate, but got: %s", toString( t ).c_str() );
Note:
See TracChangeset
for help on using the changeset viewer.