Changes in src/GenPoly/BoxNew.cpp [e14d169:0bf0b978]
- File:
-
- 1 edited
-
src/GenPoly/BoxNew.cpp (modified) (16 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/BoxNew.cpp
re14d169 r0bf0b978 376 376 ast::Expr const * postvisit( ast::AddressExpr const * expr ); 377 377 ast::ReturnStmt const * previsit( ast::ReturnStmt const * stmt ); 378 void previsit( ast::PointerType const * type ); 379 void previsit( ast::FunctionType const * type ); 378 380 379 381 void beginScope(); … … 384 386 // return value. 385 387 386 /// Passes extra layout arguments for sized polymorphic type parameters. 388 /// Pass the extra type parameters from polymorphic generic arguments or 389 /// return types into a function application. 390 ast::vector<ast::Expr>::iterator passArgTypeVars( 391 ast::ApplicationExpr * expr, ast::Type const * parmType, 392 ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg, 393 const TypeVarMap & exprTyVars, std::set<std::string> & seenTypes ); 394 /// Passes extra type parameters into a polymorphic function application. 387 395 ast::vector<ast::Expr>::iterator passTypeVars( 388 396 ast::ApplicationExpr * expr, 389 ast::FunctionType const * funcType ); 397 ast::Type const * polyRetType, 398 ast::FunctionType const * funcType, 399 const TypeVarMap & exprTyVars ); 390 400 /// Wraps a function application with a new temporary for the 391 401 /// out-parameter return value. … … 551 561 552 562 ast::FunctionDecl const * CallAdapter::previsit( ast::FunctionDecl const * decl ) { 553 // Prevent type declaration information from leaking out. 563 if ( nullptr == decl->stmts ) { 564 // This may keep TypeDecls we don't ever want from sneaking in. 565 // Not visiting child nodes might just be faster. 566 GuardScope( scopeTypeVars ); 567 return decl; 568 } 569 554 570 GuardScope( scopeTypeVars ); 555 556 if ( nullptr == decl->stmts ) {557 return decl;558 }559 560 571 GuardValue( retval ); 561 572 … … 684 695 685 696 assert( typeSubs ); 697 ast::Type const * concRetType = replaceWithConcrete( dynRetType, *typeSubs ); 698 // Used to use dynRetType instead of concRetType; this changed so that 699 // the correct type parameters are passed for return types (it should be 700 // the concrete type's parameters, not the formal type's). 686 701 ast::vector<ast::Expr>::iterator argIt = 687 passTypeVars( mutExpr, function);702 passTypeVars( mutExpr, concRetType, function, exprTypeVars ); 688 703 addInferredParams( mutExpr, argIt, function, exprTypeVars ); 689 704 … … 763 778 } 764 779 780 void CallAdapter::previsit( ast::PointerType const * type ) { 781 GuardScope( scopeTypeVars ); 782 makeTypeVarMap( type, scopeTypeVars ); 783 } 784 785 void CallAdapter::previsit( ast::FunctionType const * type ) { 786 GuardScope( scopeTypeVars ); 787 makeTypeVarMap( type, scopeTypeVars ); 788 } 789 765 790 void CallAdapter::beginScope() { 766 791 adapters.beginScope(); … … 787 812 } 788 813 814 // arg is an in/out parameter that matches the return value. 815 ast::vector<ast::Expr>::iterator CallAdapter::passArgTypeVars( 816 ast::ApplicationExpr * expr, ast::Type const * paramType, 817 ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg, 818 const TypeVarMap & exprTypeVars, std::set<std::string> & seenTypes ) { 819 ast::Type const * polyType = isPolyType( paramType, exprTypeVars ); 820 if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) { 821 return arg; 822 } 823 824 std::string typeName = Mangle::mangleType( polyType ); 825 if ( seenTypes.count( typeName ) ) return arg; 826 827 arg = expr->args.insert( arg, 828 new ast::SizeofExpr( expr->location, ast::deepCopy( argBaseType ) ) 829 ); 830 arg++; 831 arg = expr->args.insert( arg, 832 new ast::AlignofExpr( expr->location, ast::deepCopy( argBaseType ) ) 833 ); 834 arg++; 835 if ( dynamic_cast<ast::StructInstType const *>( polyType ) ) { 836 auto argBaseStructType = 837 dynamic_cast<ast::StructInstType const *>( argBaseType ); 838 if ( nullptr == argBaseStructType ) { 839 SemanticError( expr, 840 "Cannot pass non-structure type for generic struct: " ); 841 } 842 843 // Zero-length arrays are forbidden by C, so don't pass 844 // offset for empty structure. 845 if ( !argBaseStructType->base->members.empty() ) { 846 arg = expr->args.insert( arg, 847 new ast::OffsetPackExpr( 848 expr->location, 849 ast::deepCopy( argBaseStructType ) ) 850 ); 851 arg++; 852 } 853 } 854 855 seenTypes.insert( typeName ); 856 return arg; 857 } 858 789 859 ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars( 790 860 ast::ApplicationExpr * expr, 791 ast::FunctionType const * function ) { 861 ast::Type const * polyRetType, 862 ast::FunctionType const * function, 863 const TypeVarMap & exprTypeVars ) { 792 864 assert( typeSubs ); 793 865 ast::vector<ast::Expr>::iterator arg = expr->args.begin(); … … 808 880 new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) ); 809 881 arg++; 882 } 883 884 // Add size/align for generic types to parameter list. 885 if ( !expr->func->result ) return arg; 886 ast::FunctionType const * funcType = getFunctionType( expr->func->result ); 887 assert( funcType ); 888 889 // This iterator points at first original argument. 890 ast::vector<ast::Expr>::const_iterator funcArg; 891 // Names for generic types we've seen. 892 std::set<std::string> seenTypes; 893 894 // A polymorphic return type may need to be added to the argument list. 895 if ( polyRetType ) { 896 assert( typeSubs ); 897 auto concRetType = replaceWithConcrete( polyRetType, *typeSubs ); 898 // TODO: This write-back may not be correct. 899 arg = passArgTypeVars( expr, polyRetType, concRetType, 900 arg, exprTypeVars, seenTypes ); 901 // Skip the return parameter in the argument list. 902 funcArg = arg + 1; 903 } else { 904 funcArg = arg; 905 } 906 907 // TODO: 908 // I believe this is (starts as) the number of original arguments to the 909 // function with the args before funcArg all being inserted. 910 ptrdiff_t argsToPass = std::distance( funcArg, expr->args.cend() ); 911 912 // Add type information args for presently unseen types in parameter list. 913 ast::vector<ast::Type>::const_iterator funcParam = funcType->params.begin(); 914 // assert( funcType->params.size() == argsToPass ); 915 for ( ; funcParam != funcType->params.end() && 0 < argsToPass 916 ; ++funcParam, --argsToPass ) { 917 assert( 0 < argsToPass ); 918 assert( argsToPass <= (ptrdiff_t)expr->args.size() ); 919 ptrdiff_t index = expr->args.size() - argsToPass; 920 ast::Type const * argType = expr->args[index]->result; 921 if ( nullptr == argType ) continue; 922 arg = passArgTypeVars( expr, *funcParam, argType, 923 arg, exprTypeVars, seenTypes ); 810 924 } 811 925 return arg; … … 1409 1523 } 1410 1524 1525 ast::ObjectDecl * makePtr( 1526 CodeLocation const & location, std::string const & name ) { 1527 return new ast::ObjectDecl( location, name, 1528 new ast::PointerType( makeSizeAlignType() ), 1529 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr ); 1530 } 1531 1411 1532 ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) { 1412 1533 TypeVarMap localTypeVars = { ast::TypeData() }; … … 1463 1584 mutDecl->assertions.clear(); 1464 1585 1586 // Add size/align for generic parameter types to parameter list. 1587 std::set<std::string> seenTypes; 1588 ast::vector<ast::DeclWithType> otypeParams; 1589 for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) { 1590 ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars ); 1591 if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) { 1592 continue; 1593 } 1594 std::string typeName = Mangle::mangleType( polyType ); 1595 if ( seenTypes.count( typeName ) ) continue; 1596 seenTypes.insert( typeName ); 1597 1598 auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) ); 1599 otypeParams.emplace_back( sizeParam ); 1600 1601 auto alignParam = makeObj( funcParam->location, alignofName( typeName ) ); 1602 otypeParams.emplace_back( alignParam ); 1603 1604 // Zero-length arrays are illegal in C, so empty structs have no 1605 // offset array. 1606 if ( auto * polyStruct = 1607 dynamic_cast<ast::StructInstType const *>( polyType ) ; 1608 polyStruct && !polyStruct->base->members.empty() ) { 1609 auto offsetParam = makePtr( funcParam->location, offsetofName( typeName ) ); 1610 otypeParams.emplace_back( offsetParam ); 1611 } 1612 } 1613 1465 1614 // Prepend each argument group. From last group to first. addAdapters 1466 1615 // does do the same, it just does it itself and see all other parameters. 1467 1616 spliceBegin( mutDecl->params, inferredParams ); 1617 spliceBegin( mutDecl->params, otypeParams ); 1468 1618 spliceBegin( mutDecl->params, layoutParams ); 1469 1619 addAdapters( mutDecl, localTypeVars ); … … 1578 1728 PolyGenericCalculator(); 1579 1729 1730 void previsit( ast::ObjectDecl const * decl ); 1580 1731 void previsit( ast::FunctionDecl const * decl ); 1581 1732 void previsit( ast::TypedefDecl const * decl ); … … 1584 1735 ast::StructDecl const * previsit( ast::StructDecl const * decl ); 1585 1736 ast::UnionDecl const * previsit( ast::UnionDecl const * decl ); 1737 void previsit( ast::PointerType const * type ); 1738 void previsit( ast::FunctionType const * type ); 1586 1739 ast::DeclStmt const * previsit( ast::DeclStmt const * stmt ); 1587 1740 ast::Expr const * postvisit( ast::MemberExpr const * expr ); … … 1619 1772 /// adding the type variables from the provided type. 1620 1773 void beginTypeScope( ast::Type const * ); 1774 /// Enters a new scope for known layouts and offsets, and queues exit calls. 1775 void beginGenericScope(); 1621 1776 1622 1777 /// Set of generic type layouts known in the current scope, … … 1630 1785 /// If the argument of an AddressExpr is MemberExpr, it is stored here. 1631 1786 ast::MemberExpr const * addrMember = nullptr; 1787 /// Used to avoid recursing too deep in type declarations. 1788 bool expect_func_type = false; 1632 1789 }; 1633 1790 … … 1651 1808 } 1652 1809 1810 void PolyGenericCalculator::previsit( ast::ObjectDecl const * decl ) { 1811 beginTypeScope( decl->type ); 1812 } 1813 1653 1814 void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) { 1654 GuardScope( *this);1815 beginGenericScope(); 1655 1816 beginTypeScope( decl->type ); 1817 1818 // TODO: Going though dec->params does not work for some reason. 1819 for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) { 1820 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )` 1821 ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars ); 1822 if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) { 1823 knownLayouts.insert( Mangle::mangleType( polyType ) ); 1824 } 1825 } 1656 1826 } 1657 1827 … … 1714 1884 } 1715 1885 1886 void PolyGenericCalculator::previsit( ast::PointerType const * type ) { 1887 beginTypeScope( type ); 1888 } 1889 1890 void PolyGenericCalculator::previsit( ast::FunctionType const * type ) { 1891 beginTypeScope( type ); 1892 1893 GuardValue( expect_func_type ); 1894 GuardScope( *this ); 1895 1896 // The other functions type we will see in this scope are probably 1897 // function parameters they don't help us with the layout and offsets so 1898 // don't mark them as known in this scope. 1899 expect_func_type = false; 1900 1901 // Make sure that any type information passed into the function is 1902 // accounted for. 1903 for ( ast::ptr<ast::Type> const & funcParam : type->params ) { 1904 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )` 1905 ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars ); 1906 if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) { 1907 knownLayouts.insert( Mangle::mangleType( polyType ) ); 1908 } 1909 } 1910 } 1911 1912 //void PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) { 1716 1913 ast::DeclStmt const * PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) { 1717 1914 ast::ObjectDecl const * decl = stmt->decl.as<ast::ObjectDecl>(); … … 2203 2400 } 2204 2401 2402 void PolyGenericCalculator::beginGenericScope() { 2403 GuardScope( *this ); 2404 // We expect the first function type see to be the type relating to this 2405 // scope but any further type is probably some unrelated function pointer 2406 // keep track of whrich is the first. 2407 GuardValue( expect_func_type ) = true; 2408 } 2409 2205 2410 // -------------------------------------------------------------------------- 2206 /// Removes unneeded or incorrect type information.2411 /// No common theme found. 2207 2412 /// * Replaces initialization of polymorphic values with alloca. 2208 2413 /// * Replaces declaration of dtype/ftype with appropriate void expression.
Note:
See TracChangeset
for help on using the changeset viewer.