Changes in / [6cc913e:cebfcb8]
- Files:
-
- 1 deleted
- 17 edited
-
doc/proposals/function_type_change.md (deleted)
-
src/AST/Convert.cpp (modified) (7 diffs)
-
src/AST/Decl.hpp (modified) (1 diff)
-
src/AST/ForallSubstitutor.hpp (modified) (2 diffs)
-
src/AST/Pass.impl.hpp (modified) (1 diff)
-
src/AST/SymbolTable.cpp (modified) (3 diffs)
-
src/AST/SymbolTable.hpp (modified) (1 diff)
-
src/AST/Type.cpp (modified) (2 diffs)
-
src/AST/Type.hpp (modified) (1 diff)
-
src/InitTweak/InitTweak.cc (modified) (1 diff)
-
src/ResolvExpr/CandidateFinder.cpp (modified) (3 diffs)
-
src/ResolvExpr/CurrentObject.cc (modified) (2 diffs)
-
src/ResolvExpr/Resolver.cc (modified) (3 diffs)
-
src/ResolvExpr/SatisfyAssertions.cpp (modified) (1 diff)
-
src/ResolvExpr/SpecCost.cc (modified) (1 diff)
-
src/ResolvExpr/Unify.cc (modified) (12 diffs)
-
src/SymTab/Mangler.cc (modified) (1 diff)
-
src/SymTab/Validate.cc (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r6cc913e rcebfcb8 177 177 const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final { 178 178 if ( inCache( node ) ) return nullptr; 179 180 // function decl contains real variables that the type must use.181 // the structural change means function type in and out of decl182 // must be handled **differently** on convert back to old.183 auto ftype = new FunctionType(184 cv(node->type),185 (bool)node->type->isVarArgs186 );187 ftype->returnVals = get<DeclarationWithType>().acceptL(node->returns);188 ftype->parameters = get<DeclarationWithType>().acceptL(node->params);189 190 ftype->forall = get<TypeDecl>().acceptL( node->type->forall );191 192 visitType(node->type, ftype);193 194 179 auto decl = new FunctionDecl( 195 180 node->name, 196 181 Type::StorageClasses( node->storage.val ), 197 182 LinkageSpec::Spec( node->linkage.val ), 198 ftype, 199 //get<FunctionType>().accept1( node->type ), 183 get<FunctionType>().accept1( node->type ), 200 184 {}, 201 185 get<Attribute>().acceptL( node->attributes ), … … 1168 1152 1169 1153 const ast::Type * visit( const ast::FunctionType * node ) override final { 1170 static std::string dummy_paramvar_prefix = "__param_";1171 static std::string dummy_returnvar_prefix = "__retval_";1172 1173 1154 auto ty = new FunctionType { 1174 1155 cv( node ), 1175 1156 (bool)node->isVarArgs 1176 1157 }; 1177 auto returns = get<Type>().acceptL(node->returns); 1178 auto params = get<Type>().acceptL(node->params); 1179 1180 int ret_index = 0; 1181 for (auto t: returns) { 1182 // xxx - LinkageSpec shouldn't matter but needs to be something 1183 ObjectDecl * dummy = new ObjectDecl(dummy_returnvar_prefix + std::to_string(ret_index++), {}, LinkageSpec::C, nullptr, t, nullptr); 1184 ty->returnVals.push_back(dummy); 1185 } 1186 int param_index = 0; 1187 for (auto t: params) { 1188 ObjectDecl * dummy = new ObjectDecl(dummy_paramvar_prefix + std::to_string(param_index++), {}, LinkageSpec::C, nullptr, t, nullptr); 1189 ty->parameters.push_back(dummy); 1190 } 1191 1192 // ty->returnVals = get<DeclarationWithType>().acceptL( node->returns ); 1193 // ty->parameters = get<DeclarationWithType>().acceptL( node->params ); 1158 ty->returnVals = get<DeclarationWithType>().acceptL( node->returns ); 1159 ty->parameters = get<DeclarationWithType>().acceptL( node->params ); 1194 1160 ty->forall = get<TypeDecl>().acceptL( node->forall ); 1195 1161 return visitType( node, ty ); … … 1408 1374 ast::Node * node = nullptr; 1409 1375 /// cache of nodes that might be referenced by readonly<> for de-duplication 1410 /// in case that some nodes are dropped by conversion (due to possible structural change) 1411 /// use smart pointers in cache value to prevent accidental invalidation. 1412 /// at conversion stage, all created nodes are guaranteed to be unique, therefore 1413 /// const_casting out of smart pointers is permitted. 1414 std::unordered_map< const BaseSyntaxNode *, ast::ptr<ast::Node> > cache = {}; 1376 std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {}; 1415 1377 1416 1378 // Local Utilities: … … 1485 1447 auto it = cache.find( old ); 1486 1448 if ( it == cache.end() ) return false; 1487 node = const_cast<ast::Node *>(it->second.get());1449 node = it->second; 1488 1450 return true; 1489 1451 } … … 1524 1486 virtual void visit( const FunctionDecl * old ) override final { 1525 1487 if ( inCache( old ) ) return; 1526 auto paramVars = GET_ACCEPT_V(type->parameters, DeclWithType);1527 auto returnVars = GET_ACCEPT_V(type->returnVals, DeclWithType);1528 auto forall = GET_ACCEPT_V(type->forall, TypeDecl);1529 1530 // function type is now derived from parameter decls instead of storing them1531 auto ftype = new ast::FunctionType((ast::ArgumentFlag)old->type->isVarArgs, cv(old->type));1532 ftype->params.reserve(paramVars.size());1533 ftype->returns.reserve(returnVars.size());1534 1535 for (auto & v: paramVars) {1536 ftype->params.emplace_back(v->get_type());1537 }1538 for (auto & v: returnVars) {1539 ftype->returns.emplace_back(v->get_type());1540 }1541 ftype->forall = std::move(forall);1542 visitType(old->type, ftype);1543 1544 1488 auto decl = new ast::FunctionDecl{ 1545 1489 old->location, 1546 1490 old->name, 1547 // GET_ACCEPT_1(type, FunctionType), 1548 std::move(paramVars), 1549 std::move(returnVars), 1491 GET_ACCEPT_1(type, FunctionType), 1550 1492 {}, 1551 1493 { old->storageClasses.val }, … … 1554 1496 { old->get_funcSpec().val } 1555 1497 }; 1556 1557 decl->type = ftype;1558 1498 cache.emplace( old, decl ); 1559 1560 1499 decl->withExprs = GET_ACCEPT_V(withExprs, Expr); 1561 1500 decl->stmts = GET_ACCEPT_1(statements, CompoundStmt); … … 2576 2515 cv( old ) 2577 2516 }; 2578 auto returnVars = GET_ACCEPT_V(returnVals, DeclWithType); 2579 auto paramVars = GET_ACCEPT_V(parameters, DeclWithType); 2580 // ty->returns = GET_ACCEPT_V( returnVals, DeclWithType ); 2581 // ty->params = GET_ACCEPT_V( parameters, DeclWithType ); 2582 for (auto & v: returnVars) { 2583 ty->returns.emplace_back(v->get_type()); 2584 } 2585 for (auto & v: paramVars) { 2586 ty->params.emplace_back(v->get_type()); 2587 } 2517 ty->returns = GET_ACCEPT_V( returnVals, DeclWithType ); 2518 ty->params = GET_ACCEPT_V( parameters, DeclWithType ); 2588 2519 ty->forall = GET_ACCEPT_V( forall, TypeDecl ); 2589 2520 visitType( old, ty ); -
src/AST/Decl.hpp
r6cc913e rcebfcb8 124 124 class FunctionDecl : public DeclWithType { 125 125 public: 126 std::vector<ptr<DeclWithType>> params;127 std::vector<ptr<DeclWithType>> returns;128 // declared type, derived from parameter declarations129 126 ptr<FunctionType> type; 130 127 ptr<CompoundStmt> stmts; 131 128 std::vector< ptr<Expr> > withExprs; 132 129 133 FunctionDecl( const CodeLocation & loc, const std::string & name, 134 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 130 FunctionDecl( const CodeLocation & loc, const std::string & name, FunctionType * type, 135 131 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 136 132 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}) 137 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),133 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ), 138 134 stmts( stmts ) {} 139 135 -
src/AST/ForallSubstitutor.hpp
r6cc913e rcebfcb8 33 33 } 34 34 35 template<typename node_t >36 std::vector<ptr<node_t>> operator() (const std::vector<ptr<node_t>> & o) {37 std::vector<ptr<node_t>> n;38 n.reserve(o.size());39 for (const node_t * d : o) { n.emplace_back(d->accept(*visitor)); }40 return n;41 }42 43 /*44 45 35 /// Substitute parameter/return type 46 36 std::vector< ptr< DeclWithType > > operator() ( const std::vector< ptr< DeclWithType > > & o ) { … … 58 48 return n; 59 49 } 60 61 */62 50 }; 63 51 -
src/AST/Pass.impl.hpp
r6cc913e rcebfcb8 465 465 __pass::symtab::addId( core, 0, func ); 466 466 VISIT( 467 // parameter declarations are now directly here468 maybe_accept( node, &FunctionDecl::params );469 maybe_accept( node, &FunctionDecl::returns );470 // foralls are still in function type471 467 maybe_accept( node, &FunctionDecl::type ); 472 468 // function body needs to have the same scope as parameters - CompoundStmt will not enter -
src/AST/SymbolTable.cpp
r6cc913e rcebfcb8 335 335 } 336 336 337 /*338 337 void SymbolTable::addFunctionType( const FunctionType * ftype ) { 339 338 addTypes( ftype->forall ); … … 341 340 addIds( ftype->params ); 342 341 } 343 */344 342 345 343 void SymbolTable::lazyInitScope() { … … 370 368 assert( ! params.empty() ); 371 369 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 372 const Type * base = InitTweak::getPointerBase( params.front() );370 const Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 373 371 assert( base ); 374 372 return Mangle::mangle( base ); -
src/AST/SymbolTable.hpp
r6cc913e rcebfcb8 145 145 146 146 /// convenience function for adding all of the declarations in a function type to the indexer 147 //void addFunctionType( const FunctionType * ftype );147 void addFunctionType( const FunctionType * ftype ); 148 148 149 149 private: -
src/AST/Type.cpp
r6cc913e rcebfcb8 102 102 // --- FunctionType 103 103 104 105 104 FunctionType::FunctionType( const FunctionType & o ) 106 105 : ParameterizedType( o.qualifiers, copy( o.attributes ) ), returns(), params(), … … 113 112 114 113 namespace { 115 bool containsTtype( const std::vector<ptr< Type>> & l ) {114 bool containsTtype( const std::vector<ptr<DeclWithType>> & l ) { 116 115 if ( ! l.empty() ) { 117 return Tuples::isTtype( l.back() );116 return Tuples::isTtype( l.back()->get_type() ); 118 117 } 119 118 return false; -
src/AST/Type.hpp
r6cc913e rcebfcb8 302 302 class FunctionType final : public ParameterizedType { 303 303 public: 304 // std::vector<ptr<DeclWithType>> returns; 305 // std::vector<ptr<DeclWithType>> params; 306 307 std::vector<ptr<Type>> returns; 308 std::vector<ptr<Type>> params; 304 std::vector<ptr<DeclWithType>> returns; 305 std::vector<ptr<DeclWithType>> params; 309 306 310 307 /// Does the function accept a variable number of arguments following the arguments specified -
src/InitTweak/InitTweak.cc
r6cc913e rcebfcb8 1026 1026 if ( ftype->params.size() != 2 ) return false; 1027 1027 1028 const ast::Type * t1 = getPointerBase( ftype->params.front() );1028 const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() ); 1029 1029 if ( ! t1 ) return false; 1030 const ast::Type * t2 = ftype->params.back() ;1030 const ast::Type * t2 = ftype->params.back()->get_type(); 1031 1031 1032 1032 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); -
src/ResolvExpr/CandidateFinder.cpp
r6cc913e rcebfcb8 188 188 189 189 // mark conversion cost and also specialization cost of param type 190 //const ast::Type * paramType = (*param)->get_type();190 const ast::Type * paramType = (*param)->get_type(); 191 191 cand->expr = ast::mutate_field_index( 192 192 appExpr, &ast::ApplicationExpr::args, i, 193 193 computeExpressionConversionCost( 194 args[i], *param, symtab, cand->env, convCost ) );195 convCost.decSpec( specCost( *param) );194 args[i], paramType, symtab, cand->env, convCost ) ); 195 convCost.decSpec( specCost( paramType ) ); 196 196 ++param; // can't be in for-loop update because of the continue 197 197 } … … 698 698 if ( targetType && ! targetType->isVoid() && ! funcType->returns.empty() ) { 699 699 // attempt to narrow based on expected target type 700 const ast::Type * returnType = funcType->returns.front() ;700 const ast::Type * returnType = funcType->returns.front()->get_type(); 701 701 if ( ! unify( 702 702 returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab ) … … 712 712 std::size_t genStart = 0; 713 713 714 // xxx - how to handle default arg after change to ftype representation? 715 if (const ast::VariableExpr * varExpr = func->expr.as<ast::VariableExpr>()) { 716 if (const ast::FunctionDecl * funcDecl = varExpr->var.as<ast::FunctionDecl>()) { 717 // function may have default args only if directly calling by name 718 // must use types on candidate however, due to RenameVars substitution 719 auto nParams = funcType->params.size(); 720 721 for (size_t i=0; i<nParams; ++i) { 722 auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>(); 723 if (!instantiateArgument( 724 funcType->params[i], obj->init, args, results, genStart, symtab)) return; 725 } 726 goto endMatch; 727 } 728 } 729 for ( const auto & param : funcType->params ) { 714 for ( const ast::DeclWithType * param : funcType->params ) { 715 auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param ); 730 716 // Try adding the arguments corresponding to the current parameter to the existing 731 717 // matches 732 // no default args for indirect calls733 718 if ( ! instantiateArgument( 734 param, nullptr, args, results, genStart, symtab ) ) return; 735 } 736 737 endMatch: 719 obj->type, obj->init, args, results, genStart, symtab ) ) return; 720 } 721 738 722 if ( funcType->isVarArgs ) { 739 723 // append any unused arguments to vararg pack -
src/ResolvExpr/CurrentObject.cc
r6cc913e rcebfcb8 594 594 class SimpleIterator final : public MemberIterator { 595 595 CodeLocation location; 596 const Type *type = nullptr;596 readonly< Type > type = nullptr; 597 597 public: 598 598 SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {} … … 630 630 class ArrayIterator final : public MemberIterator { 631 631 CodeLocation location; 632 const ArrayType *array = nullptr;633 const Type *base = nullptr;632 readonly< ArrayType > array = nullptr; 633 readonly< Type > base = nullptr; 634 634 size_t index = 0; 635 635 size_t size = 0; -
src/ResolvExpr/Resolver.cc
r6cc913e rcebfcb8 1223 1223 template<typename Iter> 1224 1224 inline bool nextMutex( Iter & it, const Iter & end ) { 1225 while ( it != end && ! (*it)-> is_mutex() ) { ++it; }1225 while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; } 1226 1226 return it != end; 1227 1227 } … … 1638 1638 // Check if the argument matches the parameter type in the current 1639 1639 // scope 1640 //ast::ptr< ast::Type > paramType = (*param)->get_type();1640 ast::ptr< ast::Type > paramType = (*param)->get_type(); 1641 1641 if ( 1642 1642 ! unify( 1643 arg->expr->result, *param, resultEnv, need, have, open,1643 arg->expr->result, paramType, resultEnv, need, have, open, 1644 1644 symtab ) 1645 1645 ) { … … 1648 1648 ss << "candidate function not viable: no known conversion " 1649 1649 "from '"; 1650 ast::print( ss, *param);1650 ast::print( ss, (*param)->get_type() ); 1651 1651 ss << "' to '"; 1652 1652 ast::print( ss, arg->expr->result ); -
src/ResolvExpr/SatisfyAssertions.cpp
r6cc913e rcebfcb8 318 318 if ( ! func ) continue; 319 319 320 for ( const a uto ¶m : func->params ) {321 cost.decSpec( specCost( param ) );320 for ( const ast::DeclWithType * param : func->params ) { 321 cost.decSpec( specCost( param->get_type() ) ); 322 322 } 323 323 -
src/ResolvExpr/SpecCost.cc
r6cc913e rcebfcb8 178 178 void previsit( const ast::FunctionType * fty ) { 179 179 int minCount = std::numeric_limits<int>::max(); 180 updateMinimumPresent( minCount, fty->params, type_deref);181 updateMinimumPresent( minCount, fty->returns, type_deref);180 updateMinimumPresent( minCount, fty->params, decl_type ); 181 updateMinimumPresent( minCount, fty->returns, decl_type ); 182 182 // Add another level to minCount if set. 183 183 count = toNoneOrInc( minCount ); -
src/ResolvExpr/Unify.cc
r6cc913e rcebfcb8 395 395 396 396 template< typename Iterator1, typename Iterator2 > 397 bool unify TypeList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {397 bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 398 398 auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); }; 399 399 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { … … 489 489 || flatOther->isTtype() 490 490 ) { 491 if ( unify TypeList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {492 if ( unify TypeList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {491 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 492 if ( unifyDeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 493 493 494 494 // the original types must be used in mark assertions, since pointer comparisons are used … … 784 784 785 785 /// returns flattened version of `src` 786 static std::vector< ast::ptr< ast:: Type > > flattenList(787 const std::vector< ast::ptr< ast:: Type > > & src, ast::TypeEnvironment & env786 static std::vector< ast::ptr< ast::DeclWithType > > flattenList( 787 const std::vector< ast::ptr< ast::DeclWithType > > & src, ast::TypeEnvironment & env 788 788 ) { 789 std::vector< ast::ptr< ast:: Type > > dst;789 std::vector< ast::ptr< ast::DeclWithType > > dst; 790 790 dst.reserve( src.size() ); 791 for ( const a uto &d : src ) {791 for ( const ast::DeclWithType * d : src ) { 792 792 ast::Pass<TtypeExpander_new> expander{ env }; 793 793 // TtypeExpander pass is impure (may mutate nodes in place) 794 794 // need to make nodes shared to prevent accidental mutation 795 ast::ptr<ast:: Type> dc = d->accept(expander);796 auto types = flatten( dc );795 ast::ptr<ast::DeclWithType> dc = d->accept(expander); 796 auto types = flatten( dc->get_type() ); 797 797 for ( ast::ptr< ast::Type > & t : types ) { 798 798 // outermost const, volatile, _Atomic qualifiers in parameters should not play … … 803 803 // requirements than a non-mutex function 804 804 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 805 dst.emplace_back( t);805 dst.emplace_back( new ast::ObjectDecl{ dc->location, "", t } ); 806 806 } 807 807 } … … 811 811 /// Creates a tuple type based on a list of DeclWithType 812 812 template< typename Iter > 813 static ast::ptr< ast::Type > tupleFrom Types( Iter crnt, Iter end ) {813 static ast::ptr< ast::Type > tupleFromDecls( Iter crnt, Iter end ) { 814 814 std::vector< ast::ptr< ast::Type > > types; 815 815 while ( crnt != end ) { 816 816 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 817 817 // that this results in a flat tuple 818 flatten( *crnt, types );818 flatten( (*crnt)->get_type(), types ); 819 819 820 820 ++crnt; … … 825 825 826 826 template< typename Iter > 827 static bool unify TypeList(827 static bool unifyDeclList( 828 828 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 829 829 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, … … 831 831 ) { 832 832 while ( crnt1 != end1 && crnt2 != end2 ) { 833 const ast::Type * t1 = *crnt1;834 const ast::Type * t2 = *crnt2;833 const ast::Type * t1 = (*crnt1)->get_type(); 834 const ast::Type * t2 = (*crnt2)->get_type(); 835 835 bool isTuple1 = Tuples::isTtype( t1 ); 836 836 bool isTuple2 = Tuples::isTtype( t2 ); … … 840 840 // combine remainder of list2, then unify 841 841 return unifyExact( 842 t1, tupleFrom Types( crnt2, end2 ), env, need, have, open,842 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 843 843 noWiden(), symtab ); 844 844 } else if ( ! isTuple1 && isTuple2 ) { 845 845 // combine remainder of list1, then unify 846 846 return unifyExact( 847 tupleFrom Types( crnt1, end1 ), t2, env, need, have, open,847 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 848 848 noWiden(), symtab ); 849 849 } … … 860 860 if ( crnt1 != end1 ) { 861 861 // try unifying empty tuple with ttype 862 const ast::Type * t1 = *crnt1;862 const ast::Type * t1 = (*crnt1)->get_type(); 863 863 if ( ! Tuples::isTtype( t1 ) ) return false; 864 864 return unifyExact( 865 t1, tupleFrom Types( crnt2, end2 ), env, need, have, open,865 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 866 866 noWiden(), symtab ); 867 867 } else if ( crnt2 != end2 ) { 868 868 // try unifying empty tuple with ttype 869 const ast::Type * t2 = *crnt2;869 const ast::Type * t2 = (*crnt2)->get_type(); 870 870 if ( ! Tuples::isTtype( t2 ) ) return false; 871 871 return unifyExact( 872 tupleFrom Types( crnt1, end1 ), t2, env, need, have, open,872 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 873 873 noWiden(), symtab ); 874 874 } … … 877 877 } 878 878 879 static bool unify TypeList(880 const std::vector< ast::ptr< ast:: Type > > & list1,881 const std::vector< ast::ptr< ast:: Type > > & list2,879 static bool unifyDeclList( 880 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 881 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 882 882 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 883 883 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 884 884 ) { 885 return unify TypeList(885 return unifyDeclList( 886 886 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 887 887 symtab ); … … 928 928 ) return; 929 929 930 if ( ! unify TypeList( params, params2, tenv, need, have, open, symtab ) ) return;931 if ( ! unify TypeList(930 if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return; 931 if ( ! unifyDeclList( 932 932 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 933 933 … … 1232 1232 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) { 1233 1233 if ( func->returns.empty() ) return new ast::VoidType{}; 1234 if ( func->returns.size() == 1 ) return func->returns[0] ;1234 if ( func->returns.size() == 1 ) return func->returns[0]->get_type(); 1235 1235 1236 1236 std::vector<ast::ptr<ast::Type>> tys; 1237 for ( const a uto &decl : func->returns ) {1238 tys.emplace_back( decl );1237 for ( const ast::DeclWithType * decl : func->returns ) { 1238 tys.emplace_back( decl->get_type() ); 1239 1239 } 1240 1240 return new ast::TupleType{ std::move(tys) }; -
src/SymTab/Mangler.cc
r6cc913e rcebfcb8 551 551 GuardValue( inFunctionType ); 552 552 inFunctionType = true; 553 if (functionType->returns.empty()) mangleName << Encoding::void_t; 554 else accept_each( functionType->returns, *visitor ); 553 std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns ); 554 if (returnTypes.empty()) mangleName << Encoding::void_t; 555 else accept_each( returnTypes, *visitor ); 555 556 mangleName << "_"; 556 accept_each( functionType->params, *visitor ); 557 std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params ); 558 accept_each( paramTypes, *visitor ); 557 559 mangleName << "_"; 558 560 } -
src/SymTab/Validate.cc
r6cc913e rcebfcb8 1384 1384 /// Replaces enum types by int, and function/array types in function parameter and return 1385 1385 /// lists by appropriate pointers 1386 /*1387 1386 struct EnumAndPointerDecay_new { 1388 1387 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) { … … 1435 1434 } 1436 1435 }; 1437 */1438 1436 1439 1437 /// expand assertions from a trait instance, performing appropriate type variable substitutions … … 1839 1837 const ast::Type * validateType( 1840 1838 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1841 //ast::Pass< EnumAndPointerDecay_new > epc;1839 ast::Pass< EnumAndPointerDecay_new > epc; 1842 1840 ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab }; 1843 1841 ast::Pass< ForallPointerDecay_new > fpd{ loc }; 1844 1842 1845 return type->accept( lrt )->accept( fpd );1843 return type->accept( epc )->accept( lrt )->accept( fpd ); 1846 1844 } 1847 1845
Note:
See TracChangeset
for help on using the changeset viewer.