- Timestamp:
- Oct 8, 2023, 9:14:31 AM (2 years ago)
- Branches:
- master
- Children:
- 92211d9
- Parents:
- 2261bcc (diff), 9689e54 (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. - Location:
- src
- Files:
-
- 7 edited
-
CodeGen/LinkOnce.cc (modified) (5 diffs)
-
CodeGen/LinkOnce.h (modified) (2 diffs)
-
GenPoly/BoxNew.cpp (modified) (25 diffs)
-
GenPoly/InstantiateGeneric.h (modified) (2 diffs)
-
GenPoly/InstantiateGenericNew.cpp (modified) (1 diff)
-
Validate/NoIdSymbolTable.hpp (modified) (1 diff)
-
main.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/LinkOnce.cc
r2261bcc rf45772e 10 10 // Created On : Thur May 13 10:10:00 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thur May 13 14:39:00 202113 // Update Count : 012 // Last Modified On : Wed Oct 4 10:52:00 2023 13 // Update Count : 1 14 14 // 15 15 … … 18 18 #include <algorithm> 19 19 20 #include "AST/Attribute.hpp" 21 #include "AST/Decl.hpp" 22 #include "AST/Expr.hpp" 23 #include "AST/Pass.hpp" 20 24 #include "Common/PassVisitor.h" // for PassVisitor, WithShortCircuiting 21 25 22 26 namespace CodeGen { 23 27 24 static bool is_cfa_linkonce( Attribute const * attr ) { 28 namespace { 29 30 bool is_cfa_linkonce_old( Attribute const * attr ) { 25 31 return std::string("cfa_linkonce") == attr->name; 26 32 } 27 33 28 static bool is_section_attribute( Attribute const * attr ) {34 bool is_section_attribute_old( Attribute const * attr ) { 29 35 return std::string("section") == attr->name; 30 36 } … … 39 45 std::list< Attribute * > & attributes = decl->attributes; 40 46 // See if we can find the element: 41 auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce );47 auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce_old ); 42 48 if ( attributes.end() != found ) { 43 49 // Remove any other sections: 44 attributes.remove_if( is_section_attribute );50 attributes.remove_if( is_section_attribute_old ); 45 51 // Iterator to the cfa_linkonce attribute should still be valid. 46 52 Attribute * attribute = *found; … … 63 69 }; 64 70 71 bool is_cfa_linkonce( ast::Attribute const * attr ) { 72 return "cfa_linkonce" == attr->name; 73 } 74 75 bool is_section_attribute( ast::Attribute const * attr ) { 76 return "section" == attr->name; 77 } 78 79 struct LinkOnceCore : public ast::WithShortCircuiting { 80 void previsit( ast::Decl const * ) { 81 visit_children = false; 82 } 83 84 ast::DeclWithType const * postvisit( ast::DeclWithType const * decl ) { 85 // Check to see if we have to mutate, because should be uncommon. 86 { 87 auto & attributes = decl->attributes; 88 auto found = std::find_if( attributes.begin(), attributes.end(), 89 is_cfa_linkonce ); 90 if ( attributes.end() == found ) return decl; 91 } 92 auto mutDecl = mutate( decl ); 93 auto & attributes = mutDecl->attributes; 94 95 // Remove all conflicting section attributes. 96 erase_if( attributes, is_section_attribute ); 97 98 // Get the attribute, and overwrite it as a section attribute. 99 auto found = std::find_if( attributes.begin(), attributes.end(), 100 is_cfa_linkonce ); 101 assert( attributes.end() != found ); 102 ast::Attribute * attribute = found->get_and_mutate(); 103 assert( attribute->params.empty() ); 104 assert( !decl->mangleName.empty() ); 105 106 attribute->name = "section"; 107 attribute->params.push_back( 108 ast::ConstantExpr::from_string( mutDecl->location, 109 ".gnu.linkonce." + decl->mangleName 110 ) 111 ); 112 113 // Unconditionnaly add "visibility(default)" to anything with 114 // .gnu.linkonce visibility is a mess otherwise. 115 attributes.push_back( new ast::Attribute( "visibility", { 116 ast::ConstantExpr::from_string( mutDecl->location, "default" ) 117 } ) ); 118 return mutDecl; 119 } 120 }; 121 122 } // namespace 123 65 124 void translateLinkOnce( std::list< Declaration *> & translationUnit ) { 66 125 PassVisitor<LinkOnceVisitorCore> translator; … … 68 127 } 69 128 129 void translateLinkOnce( ast::TranslationUnit & translationUnit ) { 130 ast::Pass<LinkOnceCore>::run( translationUnit ); 70 131 } 132 133 } // namespace CodeGen -
src/CodeGen/LinkOnce.h
r2261bcc rf45772e 10 10 // Created On : Thur May 13 10:06:00 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thur May 13 14:38:00 202113 // Update Count : 012 // Last Modified On : Wed Oct 4 10:52:00 2023 13 // Update Count : 1 14 14 // 15 15 … … 23 23 24 24 class Declaration; 25 namespace ast { 26 class TranslationUnit; 27 } 25 28 26 29 namespace CodeGen { 27 30 28 31 void translateLinkOnce( std::list< Declaration *> & translationUnit ); 32 void translateLinkOnce( ast::TranslationUnit & translationUnit ); 29 33 /* Convert the cfa_linkonce attribute on top level declaration into 30 34 * a special section declaration (.gnu.linkonce) so that it may be defined -
src/GenPoly/BoxNew.cpp
r2261bcc rf45772e 77 77 }; 78 78 79 // Formally takeOtypeOnly80 79 /// Get all sized type declarations; those that affect a layout function. 81 80 ast::vector<ast::TypeDecl> takeSizedParams( … … 510 509 ast::FunctionType const * function, 511 510 TypeVarMap const & typeVars ) { 512 // TODO513 // NOTE: This function previously used isPolyObj, which failed to produce514 // the correct thing in some situations. It's not clear to [Rob Schluntz]515 // why this wasn't working.516 517 511 // If the return type or a parameter type involved polymorphic types, 518 512 // then the adapter will need to take those polymorphic types as pointers. … … 587 581 ast::FunctionType const * type = decl->type; 588 582 if ( isDynRet( type ) && decl->linkage != ast::Linkage::C ) { 589 //retval = type->returns.front();590 583 retval = decl->returns.front(); 591 584 … … 748 741 ast::Expr const * CallAdapter::postvisit( ast::UntypedExpr const * expr ) { 749 742 if ( isPolyDeref( expr, scopeTypeVars, typeSubs ) ) { 750 // TODO Pretty sure this is just a memory management change.751 // Also, I don't understand what this is doing.752 //ast::Expr const * ret = expr->args.front();753 //expr->args.clear();754 //return ret;755 743 return expr->args.front(); 756 744 } … … 1063 1051 ast::ptr<ast::Type> newType = ast::deepCopy( param ); 1064 1052 if ( typeSubs ) typeSubs->apply( newType ); 1065 // TODO: Is this right? (Why wouldn't it be?)1066 // I think this is to make sure we can write to the temporary.1067 //newType.get_and_mutate()->qt = ast::CV::Qualifiers();1068 //reset_qualifiers( newType );1069 1053 ast::ObjectDecl * newObj = makeTemporary( location, newType ); 1070 1054 auto assign = ast::UntypedExpr::createCall( location, "?=?", { … … 1245 1229 } 1246 1230 return new ast::ObjectDecl( location, pNamer.newName(), param ); 1247 } ), // params1231 } ), 1248 1232 map_range<ast::vector<ast::DeclWithType>>( adapterType->returns, 1249 1233 [&rNamer, &location]( ast::ptr<ast::Type> const & retval ) { 1250 1234 return new ast::ObjectDecl( location, rNamer.newName(), retval ); 1251 } ), // returns1235 } ), 1252 1236 nullptr, // stmts 1253 ast::Storage::Classes(), // storage 1254 ast::Linkage::C // linkage 1255 // attrs 1256 // fs 1257 // isVarArgs 1237 {}, // storage 1238 ast::Linkage::C 1258 1239 ); 1259 1240 … … 1314 1295 // Returns a polymorphic type. 1315 1296 } else if ( isDynType( adaptee->returns.front(), typeVars ) ) { 1316 if ( "" == (*paramDecl)->name ) {1317 // TODO: Is it easier to make sure it has a name in the first1318 // place? - I believe this is done, however, I could remove the1319 // condition and just rename for clarity.1320 assertf( false, "Wasn't expecting to get here." );1321 auto mutParam = paramDecl->get_and_mutate();1322 mutParam->name = "_ret";1323 mutParam->linkage = ast::Linkage::C;1324 }1325 1297 ast::UntypedExpr * assign = new ast::UntypedExpr( location, 1326 1298 new ast::NameExpr( location, "?=?" ) ); … … 1546 1518 1547 1519 // -------------------------------------------------------------------------- 1548 /// Creates the adapter functions. TODO1520 /// Modifies declarations to accept implicit parameters. 1549 1521 /// * Move polymorphic returns in function types to pointer-type parameters. 1550 1522 /// * Adds type size and assertion parameters to parameter lists. 1551 struct DeclAdapter final : 1552 public BoxPass, 1553 public ast::WithGuards { 1554 void handleAggrDecl(); 1555 1556 void previsit( ast::StructDecl const * decl ); 1557 void previsit( ast::UnionDecl const * decl ); 1558 void previsit( ast::TraitDecl const * decl ); 1559 void previsit( ast::TypeDecl const * decl ); 1560 void previsit( ast::PointerType const * type ); 1561 void previsit( ast::FunctionType const * type ); 1523 struct DeclAdapter final { 1562 1524 ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl ); 1563 ast::DeclWithType const * postvisit( ast::FunctionDecl const * decl ); 1564 void previsit( ast::CompoundStmt const * stmt ); 1525 ast::FunctionDecl const * postvisit( ast::FunctionDecl const * decl ); 1565 1526 private: 1566 ast::FunctionDecl * addAdapters( ast::FunctionDecl * decl ); 1567 1568 std::map<UniqueId, std::string> adapterName; 1527 void addAdapters( ast::FunctionDecl * decl, TypeVarMap & localTypeVars ); 1569 1528 }; 1570 1529 1571 // at must point within [dst.begin(), dst.end()]. 1572 template< typename T > 1573 void spliceAt( std::vector< T > & dst, typename std::vector< T >::iterator at, 1574 std::vector< T > & src ) { 1575 std::vector< T > tmp; 1576 tmp.reserve( dst.size() + src.size() ); 1577 typename std::vector< T >::iterator it = dst.begin(); 1578 while ( it != at ) { 1579 assert( it != dst.end() ); 1580 tmp.emplace_back( std::move( *it ) ); 1581 ++it; 1582 } 1583 for ( T & x : src ) { tmp.emplace_back( std::move( x ) ); } 1584 while ( it != dst.end() ) { 1585 tmp.emplace_back( std::move( *it ) ); 1586 ++it; 1587 } 1588 1589 dst.clear(); 1590 src.clear(); 1591 tmp.swap( dst ); 1592 } 1593 1594 void DeclAdapter::previsit( ast::StructDecl const * ) { 1595 // Prevent type vars from leaking into the containing scope. 1596 GuardScope( scopeTypeVars ); 1597 } 1598 1599 void DeclAdapter::previsit( ast::UnionDecl const * ) { 1600 // Prevent type vars from leaking into the containing scope. 1601 GuardScope( scopeTypeVars ); 1602 } 1603 1604 void DeclAdapter::previsit( ast::TraitDecl const * ) { 1605 // Prevent type vars from leaking into the containing scope. 1606 GuardScope( scopeTypeVars ); 1607 } 1608 1609 void DeclAdapter::previsit( ast::TypeDecl const * decl ) { 1610 addToTypeVarMap( decl, scopeTypeVars ); 1611 } 1612 1613 void DeclAdapter::previsit( ast::PointerType const * type ) { 1614 GuardScope( scopeTypeVars ); 1615 makeTypeVarMap( type, scopeTypeVars ); 1616 } 1617 1618 // TODO: I think this code is redundent. 1619 void DeclAdapter::previsit( ast::FunctionType const * type ) { 1620 GuardScope( scopeTypeVars ); 1621 makeTypeVarMap( type, scopeTypeVars ); 1530 // size/align/offset parameters may not be used, so add the unused attribute. 1531 ast::ObjectDecl * makeObj( 1532 CodeLocation const & location, std::string const & name ) { 1533 return new ast::ObjectDecl( location, name, 1534 makeSizeAlignType(), 1535 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr, 1536 { new ast::Attribute( "unused" ) } ); 1537 } 1538 1539 ast::ObjectDecl * makePtr( 1540 CodeLocation const & location, std::string const & name ) { 1541 return new ast::ObjectDecl( location, name, 1542 new ast::PointerType( makeSizeAlignType() ), 1543 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr ); 1622 1544 } 1623 1545 1624 1546 ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) { 1625 GuardScope( scopeTypeVars );1626 makeTypeVarMap( decl, scopeTypeVars );1547 TypeVarMap localTypeVars = { ast::TypeData() }; 1548 makeTypeVarMap( decl, localTypeVars ); 1627 1549 1628 1550 auto mutDecl = mutate( decl ); … … 1639 1561 1640 1562 // Add size/align and assertions for type parameters to parameter list. 1641 std::vector<ast::ptr<ast::DeclWithType>>::iterator last = mutDecl->params.begin(); 1642 std::vector<ast::ptr<ast::DeclWithType>> inferredParams; 1643 // size/align/offset parameters may not be used in body, pass along with unused attribute. 1644 // TODO: These should be created with proper location and name. 1645 // TODO: makeSizeAlign[Out]Type are the same as these types, but they may 1646 // be logically different. 1647 ast::ObjectDecl newObj( mutDecl->location, "", 1648 new ast::BasicType( ast::BasicType::LongUnsignedInt ), 1649 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr, 1650 { new ast::Attribute( "unused" ) } ); 1651 ast::ObjectDecl newPtr( mutDecl->location, "", 1652 new ast::PointerType( new ast::BasicType( ast::BasicType::LongUnsignedInt ) ), 1653 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr ); 1563 ast::vector<ast::DeclWithType> inferredParams; 1564 ast::vector<ast::DeclWithType> layoutParams; 1654 1565 for ( ast::ptr<ast::TypeDecl> & typeParam : mutDecl->type_params ) { 1655 1566 auto mutParam = mutate( typeParam.get() ); 1656 1567 // Add all size and alignment parameters to parameter list. 1657 1568 if ( mutParam->isComplete() ) { 1658 //ast::TypeInstType paramType( typeParam->name, typeParam );1659 1569 ast::TypeInstType paramType( mutParam ); 1660 1570 std::string paramName = Mangle::mangleType( ¶mType ); 1661 1571 1662 ast::ObjectDecl * sizeParam = ast::deepCopy( &newObj ); 1663 sizeParam->location = typeParam->location; 1664 sizeParam->name = sizeofName( paramName ); 1665 last = mutDecl->params.insert( last, sizeParam ); 1666 ++last; 1667 1668 ast::ObjectDecl * alignParam = ast::deepCopy( &newObj ); 1669 alignParam->location = typeParam->location; 1670 alignParam->name = alignofName( paramName ); 1671 last = mutDecl->params.insert( last, alignParam ); 1672 ++last; 1572 auto sizeParam = makeObj( typeParam->location, sizeofName( paramName ) ); 1573 layoutParams.emplace_back( sizeParam ); 1574 1575 auto alignParam = makeObj( typeParam->location, alignofName( paramName ) ); 1576 layoutParams.emplace_back( alignParam ); 1673 1577 } 1674 1578 // TODO: These should possibly all be gone. … … 1696 1600 // Add size/align for generic parameter types to parameter list. 1697 1601 std::set<std::string> seenTypes; 1698 std::vector<ast::ptr<ast::DeclWithType>> otypeParams;1602 ast::vector<ast::DeclWithType> otypeParams; 1699 1603 for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) { 1700 ast::Type const * polyType = isPolyType( funcParam->get_type(), scopeTypeVars );1604 ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars ); 1701 1605 if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) { 1702 1606 continue; … … 1704 1608 std::string typeName = Mangle::mangleType( polyType ); 1705 1609 if ( seenTypes.count( typeName ) ) continue; 1706 1707 ast::ObjectDecl * sizeParam = ast::deepCopy( &newObj ); 1708 sizeParam->location = funcParam->location; 1709 sizeParam->name = sizeofName( typeName ); 1610 seenTypes.insert( typeName ); 1611 1612 auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) ); 1710 1613 otypeParams.emplace_back( sizeParam ); 1711 1614 1712 ast::ObjectDecl * alignParam = ast::deepCopy( &newObj ); 1713 alignParam->location = funcParam->location; 1714 alignParam->name = alignofName( typeName ); 1615 auto alignParam = makeObj( funcParam->location, alignofName( typeName ) ); 1715 1616 otypeParams.emplace_back( alignParam ); 1716 1617 1618 // Zero-length arrays are illegal in C, so empty structs have no 1619 // offset array. 1717 1620 if ( auto * polyStruct = 1718 dynamic_cast<ast::StructInstType const *>( polyType ) ) { 1719 // Zero-length arrays are illegal in C, so empty structs have no 1720 // offset array. 1721 if ( !polyStruct->base->members.empty() ) { 1722 ast::ObjectDecl * offsetParam = ast::deepCopy( &newPtr ); 1723 offsetParam->location = funcParam->location; 1724 offsetParam->name = offsetofName( typeName ); 1725 otypeParams.emplace_back( offsetParam ); 1726 } 1727 } 1728 seenTypes.insert( typeName ); 1729 } 1730 1731 // TODO: A unified way of putting these together might be nice. 1732 // Put the list together: adapters (in helper) otype parameters, 1733 // inferred params., layout params. (done) and finally explicit params. 1734 spliceBegin( inferredParams, otypeParams ); 1735 spliceAt( mutDecl->params, last, inferredParams ); 1736 mutDecl = addAdapters( mutDecl ); 1621 dynamic_cast<ast::StructInstType const *>( polyType ) ; 1622 polyStruct && !polyStruct->base->members.empty() ) { 1623 auto offsetParam = makePtr( funcParam->location, offsetofName( typeName ) ); 1624 otypeParams.emplace_back( offsetParam ); 1625 } 1626 } 1627 1628 // Prepend each argument group. From last group to first. addAdapters 1629 // does do the same, it just does it itself and see all other parameters. 1630 spliceBegin( mutDecl->params, inferredParams ); 1631 spliceBegin( mutDecl->params, otypeParams ); 1632 spliceBegin( mutDecl->params, layoutParams ); 1633 addAdapters( mutDecl, localTypeVars ); 1737 1634 1738 1635 return mutDecl; 1739 1636 } 1740 1637 1741 ast:: DeclWithTypeconst * DeclAdapter::postvisit(1638 ast::FunctionDecl const * DeclAdapter::postvisit( 1742 1639 ast::FunctionDecl const * decl ) { 1743 1640 ast::FunctionDecl * mutDecl = mutate( decl ); … … 1773 1670 } 1774 1671 1775 void DeclAdapter::previsit( ast::CompoundStmt const * ) { 1776 GuardScope( scopeTypeVars ); 1777 // TODO: It is entirely possible the scope doesn't need to spread 1778 // across multiple functions. Otherwise, find a better clear. 1779 std::set<TypeVarMap::key_type> keys; 1780 for ( auto pair : const_cast<TypeVarMap const &>( scopeTypeVars ) ) { 1781 keys.insert( pair.first ); 1782 } 1783 for ( auto key : keys ) { 1784 scopeTypeVars.erase( key ); 1785 } 1786 } 1787 1788 // It actually does mutate in-place, but does the return for consistency. 1789 ast::FunctionDecl * DeclAdapter::addAdapters( ast::FunctionDecl * mutDecl ) { 1790 std::vector<ast::ptr<ast::FunctionType>> functions; 1672 void DeclAdapter::addAdapters( 1673 ast::FunctionDecl * mutDecl, TypeVarMap & localTypeVars ) { 1674 ast::vector<ast::FunctionType> functions; 1791 1675 for ( ast::ptr<ast::DeclWithType> & arg : mutDecl->params ) { 1792 1676 ast::Type const * type = arg->get_type(); 1793 type = findAndReplaceFunction( type, functions, scopeTypeVars, needsAdapter );1677 type = findAndReplaceFunction( type, functions, localTypeVars, needsAdapter ); 1794 1678 arg.get_and_mutate()->set_type( type ); 1795 1679 } 1796 1680 std::set<std::string> adaptersDone; 1797 1681 for ( ast::ptr<ast::FunctionType> const & func : functions ) { 1798 std::string mangleName = mangleAdapterName( func, scopeTypeVars );1682 std::string mangleName = mangleAdapterName( func, localTypeVars ); 1799 1683 if ( adaptersDone.find( mangleName ) != adaptersDone.end() ) { 1800 1684 continue; … … 1804 1688 mutDecl->params.insert( mutDecl->params.begin(), new ast::ObjectDecl( 1805 1689 mutDecl->location, adapterName, 1806 new ast::PointerType( makeAdapterType( func, scopeTypeVars ) ),1690 new ast::PointerType( makeAdapterType( func, localTypeVars ) ), 1807 1691 nullptr, {}, {}, nullptr, 1808 1692 { new ast::Attribute( "unused" ) } ) ); 1809 1693 adaptersDone.insert( adaptersDone.begin(), mangleName ); 1810 1694 } 1811 return mutDecl;1812 1695 } 1813 1696 … … 1926 1809 /// Namer for VLA (variable length array) buffers. 1927 1810 UniqueName bufNamer; 1928 /// AddressExpr argument is MemberExpr? (TODO: What?)1929 ast:: Expr const * addrMember = nullptr;1811 /// If the argument of an AddressExpr is MemberExpr, it is stored here. 1812 ast::MemberExpr const * addrMember = nullptr; 1930 1813 /// Used to avoid recursing too deep in type declarations. 1931 1814 bool expect_func_type = false; … … 1959 1842 beginTypeScope( decl->type ); 1960 1843 1961 // - Tried inserting this code. 1962 // Make sure that any type information passed into the function is 1963 // accounted for. 1964 // TODO: For some reason going through decl->params/->get_type() does 1965 // not work. Possibly something is not getting updated. 1844 // TODO: Going though dec->params does not work for some reason. 1966 1845 for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) { 1967 1846 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )` … … 2019 1898 ast::StructDecl const * PolyGenericCalculator::previsit( 2020 1899 ast::StructDecl const * decl ) { 2021 //return strict_dynamic_cast<ast::StructDecl *>( mutateMembers( decl ) );2022 1900 auto mutDecl = mutate( decl ); 2023 1901 mutateMembers( mutDecl ); … … 2027 1905 ast::UnionDecl const * PolyGenericCalculator::previsit( 2028 1906 ast::UnionDecl const * decl ) { 2029 //return strict_dynamic_cast<ast::UnionDecl *>( mutateMembers( decl ) );2030 1907 auto mutDecl = mutate( decl ); 2031 1908 mutateMembers( mutDecl ); … … 2088 1965 auto mutDecl = mutate( decl ); 2089 1966 2090 //mutDecl->attributes.remove_if( matchAndMove ); 2091 // TODO: This common helper might work, but does not officially support 2092 // side effects. 1967 // Forally, side effects are not safe in this function. But it works. 2093 1968 erase_if( mutDecl->attributes, matchAndMove ); 2094 1969 … … 2198 2073 // the substitution manually. For some reason this is not currently the 2199 2074 // case. This requires more investigation. 2200 ast:: Type const *memberType = deepCopy( expr->member->get_type() );2075 ast::ptr<ast::Type> memberType = deepCopy( expr->member->get_type() ); 2201 2076 ast::TypeSubstitution sub = genericSubstitution( objectType ); 2202 auto result =sub.apply( memberType );2203 memberType = result.node.get(); // .release(); 2077 sub.apply( memberType ); 2078 2204 2079 // Not all members of a polymorphic type are themselves of a polymorphic 2205 2080 // type; in this cas the member expression should be wrapped and … … 2217 2092 2218 2093 void PolyGenericCalculator::previsit( ast::AddressExpr const * expr ) { 2219 // Is the argument a MemberExpr before mutating?2220 2094 GuardValue( addrMember ) = expr->arg.as<ast::MemberExpr>(); 2221 2095 } … … 2233 2107 // MemberExpr was converted to pointer + offset; and it is not valid C to 2234 2108 // take the address of an addition, so stript the address-of. 2235 // TODO: should expr->arg->result be changed to expr->result? 2236 ast::Expr * ret = mutate( expr->arg.get() ); 2237 ret->env = expr->env; 2238 return ret; 2109 // It also preserves the env value. 2110 return ast::mutate_field( expr->arg.get(), &ast::Expr::env, expr->env ); 2239 2111 } 2240 2112 … … 2572 2444 public BoxPass, 2573 2445 public ast::WithGuards { 2574 template<typename decl_t> 2575 decl_t const * handleDecl( decl_t const * decl, ast::Type const * type ); 2446 void guardTypeVarMap( ast::Type const * type ) { 2447 GuardScope( scopeTypeVars ); 2448 makeTypeVarMap( type, scopeTypeVars ); 2449 } 2576 2450 2577 2451 ast::ObjectDecl const * previsit( ast::ObjectDecl const * decl ); … … 2585 2459 }; 2586 2460 2587 template<typename decl_t> 2588 decl_t const * Eraser::handleDecl( 2589 decl_t const * decl, ast::Type const * type ) { 2590 GuardScope( scopeTypeVars ); 2591 makeTypeVarMap( type, scopeTypeVars ); 2461 ast::ObjectDecl const * Eraser::previsit( ast::ObjectDecl const * decl ) { 2462 guardTypeVarMap( decl->type ); 2592 2463 return scrubAllTypeVars( decl ); 2593 2464 } 2594 2465 2595 ast::ObjectDecl const * Eraser::previsit( ast::ObjectDecl const * decl ) {2596 return handleDecl( decl, decl->type );2597 }2598 2599 2466 ast::FunctionDecl const * Eraser::previsit( ast::FunctionDecl const * decl ) { 2600 return handleDecl( decl, decl->type ); 2467 guardTypeVarMap( decl->type ); 2468 return scrubAllTypeVars( decl ); 2601 2469 } 2602 2470 2603 2471 ast::TypedefDecl const * Eraser::previsit( ast::TypedefDecl const * decl ) { 2604 return handleDecl( decl, decl->base ); 2472 guardTypeVarMap( decl->base ); 2473 return scrubAllTypeVars( decl ); 2605 2474 } 2606 2475 … … 2608 2477 template<typename node_t> 2609 2478 node_t const * stripGenericMembers( node_t const * decl ) { 2610 if ( !decl->params.empty() ) { 2611 auto mutDecl = ast::mutate( decl ); 2612 mutDecl->members.clear(); 2613 return mutDecl; 2614 } 2615 return decl; 2479 if ( decl->params.empty() ) return decl; 2480 auto mutDecl = ast::mutate( decl ); 2481 mutDecl->members.clear(); 2482 return mutDecl; 2616 2483 } 2617 2484 … … 2629 2496 2630 2497 void Eraser::previsit( ast::PointerType const * type ) { 2631 GuardScope( scopeTypeVars ); 2632 makeTypeVarMap( type, scopeTypeVars ); 2498 guardTypeVarMap( type ); 2633 2499 } 2634 2500 2635 2501 void Eraser::previsit( ast::FunctionType const * type ) { 2636 GuardScope( scopeTypeVars ); 2637 makeTypeVarMap( type, scopeTypeVars ); 2502 guardTypeVarMap( type ); 2638 2503 } 2639 2504 -
src/GenPoly/InstantiateGeneric.h
r2261bcc rf45772e 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // InstantiateGeneric.h -- 7 // InstantiateGeneric.h -- Create concrete instances of generic types. 8 8 // 9 9 // Author : Aaron B. Moss … … 24 24 25 25 namespace GenPoly { 26 /// Replaces all generic types that have static layout with concrete 27 /// instantiations. Types with concrete values for otype parameters will be 28 /// template-expanded, while dtype and ftype parameters will be replaced by 29 /// the appropriate void type. 26 30 27 void instantiateGeneric( std::list< Declaration* > &translationUnit ); 31 28 void instantiateGeneric( ast::TranslationUnit & translationUnit ); 29 /// Replaces all generic types that have static layout with concrete 30 /// instantiations. Sized types are replaced with the concrete argument types 31 /// while unsized types are erased to a void type. 32 /// This pass can cause designators to ignore the pretty print option. 33 32 34 } // namespace GenPoly 33 35 -
src/GenPoly/InstantiateGenericNew.cpp
r2261bcc rf45772e 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // InstantiateGenericNew.cpp -- 7 // InstantiateGenericNew.cpp -- Create concrete instances of generic types. 8 8 // 9 9 // Author : Andrew Beach -
src/Validate/NoIdSymbolTable.hpp
r2261bcc rf45772e 20 20 namespace Validate { 21 21 22 // A SymbolTable that only has the operations used in the Translate Dimension 23 // pass. More importantly, it doesn't have some methods that should no be 22 // A SymbolTable that only tracks names relevant to Validate passes. 23 // It tracks type names but not identifier names. 24 // Some of the canonicalization that occurs before the resolver 25 // affects how identifier name errors get reported to the user. 26 // The Validate phase needs to chase type names, 27 // but it is too early to try tracking identifier names. 28 // Identifier skipping is acheived by omitting methods that should not be 24 29 // called by the Pass template (lookupId and addId). 25 30 class NoIdSymbolTable { 26 31 ast::SymbolTable base; 27 32 public: 33 // All names that are tracked (now) are eligible for collision validation (now). 34 // (Names that are only tracked later get their collision validation then.) 35 NoIdSymbolTable() : base(ast::SymbolTable::ValidateOnAdd) {} 36 28 37 # define FORWARD_X( func, types_and_names, just_names ) \ 29 38 inline auto func types_and_names -> decltype( base.func just_names ) { \ -
src/main.cc
r2261bcc rf45772e 421 421 DUMP( bboxp, std::move( transUnit ) ); 422 422 PASS( "Box", GenPoly::box, transUnit ); 423 PASS( "Link-Once", CodeGen::translateLinkOnce, transUnit ); 423 424 424 425 translationUnit = convert( std::move( transUnit ) ); 425 426 PASS( "Link-Once", CodeGen::translateLinkOnce, translationUnit );427 426 428 427 // Code has been lowered to C, now we can start generation.
Note:
See TracChangeset
for help on using the changeset viewer.