Changes in src/GenPoly/BoxNew.cpp [5e0bba5f:61e5d99]
- File:
-
- 1 edited
-
src/GenPoly/BoxNew.cpp (modified) (26 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/BoxNew.cpp
r5e0bba5f r61e5d99 39 39 40 40 namespace { 41 42 /// Common field of several sub-passes of box. 43 struct BoxPass { 44 TypeVarMap scopeTypeVars; 45 BoxPass() : scopeTypeVars( ast::TypeData() ) {} 46 }; 47 48 // TODO: Could this be a common helper somewhere? 49 ast::FunctionType * makeFunctionType( ast::FunctionDecl const * decl ) { 50 ast::FunctionType * type = new ast::FunctionType( 51 decl->type->isVarArgs, decl->type->qualifiers 52 ); 53 for ( auto type_param : decl->type_params ) { 54 type->forall.emplace_back( new ast::TypeInstType( type_param ) ); 55 } 56 for ( auto assertion : decl->assertions ) { 57 type->assertions.emplace_back( new ast::VariableExpr( 58 assertion->location, assertion ) ); 59 } 60 for ( auto param : decl->params ) { 61 type->params.emplace_back( param->get_type() ); 62 } 63 for ( auto retval : decl->returns ) { 64 type->returns.emplace_back( retval->get_type() ); 65 } 66 return type; 67 } 41 68 42 69 // -------------------------------------------------------------------------- … … 332 359 /// * Adds appropriate type variables to the function calls. 333 360 struct CallAdapter final : 361 public BoxPass, 334 362 public ast::WithConstTypeSubstitution, 335 363 public ast::WithGuards, … … 348 376 ast::Expr const * postvisit( ast::AddressExpr const * expr ); 349 377 ast::ReturnStmt const * previsit( ast::ReturnStmt const * stmt ); 378 void previsit( ast::PointerType const * type ); 379 void previsit( ast::FunctionType const * type ); 350 380 351 381 void beginScope(); … … 410 440 CodeLocation const & location, ast::Type const * type ); 411 441 412 TypeVarMap scopeTypeVars;442 /// Set of adapter functions in the current scope. 413 443 ScopedMap< std::string, ast::DeclWithType const * > adapters; 414 444 std::map< ast::ApplicationExpr const *, ast::Expr const * > retVals; … … 523 553 524 554 ast::FunctionDecl const * CallAdapter::previsit( ast::FunctionDecl const * decl ) { 525 // Prevent type declaration information from leaking out. 555 if ( nullptr == decl->stmts ) { 556 // This may keep TypeDecls we don't ever want from sneaking in. 557 // Not visiting child nodes might just be faster. 558 GuardScope( scopeTypeVars ); 559 return decl; 560 } 561 526 562 GuardScope( scopeTypeVars ); 527 528 if ( nullptr == decl->stmts ) {529 return decl;530 }531 532 563 GuardValue( retval ); 533 564 … … 631 662 ptrdiff_t initArgCount = mutExpr->args.size(); 632 663 633 TypeVarMap exprTypeVars ;664 TypeVarMap exprTypeVars = { ast::TypeData() }; 634 665 // TODO: Should this take into account the variables already bound in 635 666 // scopeTypeVars ([ex] remove them from exprTypeVars)? … … 656 687 657 688 assert( typeSubs ); 689 ast::Type const * concRetType = replaceWithConcrete( dynRetType, *typeSubs ); 690 // Used to use dynRetType instead of concRetType; this changed so that 691 // the correct type parameters are passed for return types (it should be 692 // the concrete type's parameters, not the formal type's). 658 693 ast::vector<ast::Expr>::iterator argIt = 659 694 passTypeVars( mutExpr, function ); … … 733 768 } 734 769 return stmt; 770 } 771 772 void CallAdapter::previsit( ast::PointerType const * type ) { 773 GuardScope( scopeTypeVars ); 774 makeTypeVarMap( type, scopeTypeVars ); 775 } 776 777 void CallAdapter::previsit( ast::FunctionType const * type ) { 778 GuardScope( scopeTypeVars ); 779 makeTypeVarMap( type, scopeTypeVars ); 735 780 } 736 781 … … 1382 1427 1383 1428 ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) { 1384 TypeVarMap localTypeVars ;1429 TypeVarMap localTypeVars = { ast::TypeData() }; 1385 1430 makeTypeVarMap( decl, localTypeVars ); 1386 1431 … … 1413 1458 layoutParams.emplace_back( alignParam ); 1414 1459 } 1415 // Assertions should be stored in the main list. 1416 assert( mutParam->assertions.empty() ); 1460 // TODO: These should possibly all be gone. 1461 // More all assertions into parameter list. 1462 for ( ast::ptr<ast::DeclWithType> & assert : mutParam->assertions ) { 1463 // Assertion parameters may not be used in body, 1464 // pass along with unused attribute. 1465 assert.get_and_mutate()->attributes.push_back( 1466 new ast::Attribute( "unused" ) ); 1467 inferredParams.push_back( assert ); 1468 } 1469 mutParam->assertions.clear(); 1417 1470 typeParam = mutParam; 1418 1471 } 1472 // TODO: New version of inner loop. 1419 1473 for ( ast::ptr<ast::DeclWithType> & assert : mutDecl->assertions ) { 1420 1474 // Assertion parameters may not be used in body, … … 1431 1485 spliceBegin( mutDecl->params, layoutParams ); 1432 1486 addAdapters( mutDecl, localTypeVars ); 1433 1434 // Now have to update the type to match the declaration.1435 ast::FunctionType * type = new ast::FunctionType(1436 mutDecl->type->isVarArgs, mutDecl->type->qualifiers );1437 for ( auto type_param : mutDecl->type_params ) {1438 type->forall.emplace_back( new ast::TypeInstType( type_param ) );1439 }1440 for ( auto param : mutDecl->params ) {1441 type->params.emplace_back( param->get_type() );1442 }1443 for ( auto retval : mutDecl->returns ) {1444 type->returns.emplace_back( retval->get_type() );1445 }1446 mutDecl->type = type;1447 1487 1448 1488 return mutDecl; … … 1478 1518 } 1479 1519 } 1520 // TODO: Can this be updated as we go along? 1521 mutDecl->type = makeFunctionType( mutDecl ); 1480 1522 return mutDecl; 1481 1523 } … … 1533 1575 assertf( it != adapters.end(), "Could not correct floating node." ); 1534 1576 return ast::mutate_field( expr, &ast::VariableExpr::var, it->second ); 1577 1535 1578 } 1536 1579 … … 1544 1587 /// * Inserts dynamic calculation of polymorphic type layouts where needed. 1545 1588 struct PolyGenericCalculator final : 1589 public BoxPass, 1546 1590 public ast::WithConstTypeSubstitution, 1547 1591 public ast::WithDeclsToAdd<>, … … 1551 1595 PolyGenericCalculator(); 1552 1596 1597 void previsit( ast::ObjectDecl const * decl ); 1553 1598 void previsit( ast::FunctionDecl const * decl ); 1554 1599 void previsit( ast::TypedefDecl const * decl ); … … 1557 1602 ast::StructDecl const * previsit( ast::StructDecl const * decl ); 1558 1603 ast::UnionDecl const * previsit( ast::UnionDecl const * decl ); 1604 void previsit( ast::PointerType const * type ); 1605 void previsit( ast::FunctionType const * type ); 1559 1606 ast::DeclStmt const * previsit( ast::DeclStmt const * stmt ); 1560 1607 ast::Expr const * postvisit( ast::MemberExpr const * expr ); … … 1588 1635 /// C sizeof(). 1589 1636 ast::Expr const * genSizeof( CodeLocation const &, ast::Type const * ); 1637 1590 1638 /// Enters a new scope for type-variables, 1591 1639 /// adding the type variables from the provided type. 1592 1640 void beginTypeScope( ast::Type const * ); 1593 1594 /// The type variables and polymorphic parameters currently in scope.1595 TypeVarMap scopeTypeVars; 1641 /// Enters a new scope for known layouts and offsets, and queues exit calls. 1642 void beginGenericScope(); 1643 1596 1644 /// Set of generic type layouts known in the current scope, 1597 1645 /// indexed by sizeofName. … … 1604 1652 /// If the argument of an AddressExpr is MemberExpr, it is stored here. 1605 1653 ast::MemberExpr const * addrMember = nullptr; 1654 /// Used to avoid recursing too deep in type declarations. 1655 bool expect_func_type = false; 1606 1656 }; 1607 1657 … … 1625 1675 } 1626 1676 1677 void PolyGenericCalculator::previsit( ast::ObjectDecl const * decl ) { 1678 beginTypeScope( decl->type ); 1679 } 1680 1627 1681 void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) { 1628 GuardScope( *this);1682 beginGenericScope(); 1629 1683 beginTypeScope( decl->type ); 1630 1684 } … … 1642 1696 ast::TypeDecl const * decl ) { 1643 1697 ast::Type const * base = decl->base; 1644 if ( nullptr == base ) return decl;1698 if ( nullptr == base) return decl; 1645 1699 1646 1700 // Add size/align variables for opaque type declarations. … … 1667 1721 alignDecl->accept( *visitor ); 1668 1722 1669 // A little trick to replace this with two declarations.1670 // Adding after makes sure that there is no conflict with adding stmts.1723 // Can't use [makeVar], because it inserts into stmtsToAdd and TypeDecls 1724 // can occur at global scope. 1671 1725 declsToAddAfter.push_back( alignDecl ); 1726 // replace with sizeDecl. 1672 1727 return sizeDecl; 1673 1728 } … … 1687 1742 } 1688 1743 1744 void PolyGenericCalculator::previsit( ast::PointerType const * type ) { 1745 beginTypeScope( type ); 1746 } 1747 1748 void PolyGenericCalculator::previsit( ast::FunctionType const * type ) { 1749 beginTypeScope( type ); 1750 1751 GuardValue( expect_func_type ); 1752 GuardScope( *this ); 1753 1754 // The other functions type we will see in this scope are probably 1755 // function parameters they don't help us with the layout and offsets so 1756 // don't mark them as known in this scope. 1757 expect_func_type = false; 1758 } 1759 1760 //void PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) { 1689 1761 ast::DeclStmt const * PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) { 1690 1762 ast::ObjectDecl const * decl = stmt->decl.as<ast::ObjectDecl>(); … … 1694 1766 1695 1767 // Change initialization of a polymorphic value object to allocate via a 1696 // variable-length-array (alloca cannot be safely used in loops). 1768 // variable-length-array (alloca was previouly used, but it cannot be 1769 // safely used in loops). 1697 1770 ast::ObjectDecl * newBuf = new ast::ObjectDecl( decl->location, 1698 1771 bufNamer.newName(), … … 2175 2248 } 2176 2249 2250 void PolyGenericCalculator::beginGenericScope() { 2251 GuardScope( *this ); 2252 // We expect the first function type see to be the type relating to this 2253 // scope but any further type is probably some unrelated function pointer 2254 // keep track of whrich is the first. 2255 GuardValue( expect_func_type ) = true; 2256 } 2257 2177 2258 // -------------------------------------------------------------------------- 2178 /// Removes unneeded or incorrect type information.2259 /// No common theme found. 2179 2260 /// * Replaces initialization of polymorphic values with alloca. 2180 2261 /// * Replaces declaration of dtype/ftype with appropriate void expression. … … 2182 2263 /// * Strips fields from generic structure declarations. 2183 2264 struct Eraser final : 2265 public BoxPass, 2184 2266 public ast::WithGuards { 2185 2267 void guardTypeVarMap( ast::Type const * type ) { … … 2196 2278 void previsit( ast::PointerType const * type ); 2197 2279 void previsit( ast::FunctionType const * type ); 2198 public:2199 TypeVarMap scopeTypeVars;2200 2280 }; 2201 2281
Note:
See TracChangeset
for help on using the changeset viewer.