Changeset f45772e for src


Ignore:
Timestamp:
Oct 8, 2023, 9:14:31 AM (2 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/LinkOnce.cc

    r2261bcc rf45772e  
    1010// Created On       : Thur May 13 10:10:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thur May 13 14:39:00 2021
    13 // Update Count     : 0
     12// Last Modified On : Wed Oct  4 10:52:00 2023
     13// Update Count     : 1
    1414//
    1515
     
    1818#include <algorithm>
    1919
     20#include "AST/Attribute.hpp"
     21#include "AST/Decl.hpp"
     22#include "AST/Expr.hpp"
     23#include "AST/Pass.hpp"
    2024#include "Common/PassVisitor.h"       // for PassVisitor, WithShortCircuiting
    2125
    2226namespace CodeGen {
    2327
    24 static bool is_cfa_linkonce( Attribute const * attr ) {
     28namespace {
     29
     30bool is_cfa_linkonce_old( Attribute const * attr ) {
    2531        return std::string("cfa_linkonce") == attr->name;
    2632}
    2733
    28 static bool is_section_attribute( Attribute const * attr ) {
     34bool is_section_attribute_old( Attribute const * attr ) {
    2935        return std::string("section") == attr->name;
    3036}
     
    3945                std::list< Attribute * > & attributes = decl->attributes;
    4046                // 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 );
    4248                if ( attributes.end() != found ) {
    4349                        // Remove any other sections:
    44                         attributes.remove_if( is_section_attribute );
     50                        attributes.remove_if( is_section_attribute_old );
    4551                        // Iterator to the cfa_linkonce attribute should still be valid.
    4652                        Attribute * attribute = *found;
     
    6369};
    6470
     71bool is_cfa_linkonce( ast::Attribute const * attr ) {
     72        return "cfa_linkonce" == attr->name;
     73}
     74
     75bool is_section_attribute( ast::Attribute const * attr ) {
     76        return "section" == attr->name;
     77}
     78
     79struct 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
    65124void translateLinkOnce( std::list< Declaration *> & translationUnit ) {
    66125        PassVisitor<LinkOnceVisitorCore> translator;
     
    68127}
    69128
     129void translateLinkOnce( ast::TranslationUnit & translationUnit ) {
     130        ast::Pass<LinkOnceCore>::run( translationUnit );
    70131}
     132
     133} // namespace CodeGen
  • src/CodeGen/LinkOnce.h

    r2261bcc rf45772e  
    1010// Created On       : Thur May 13 10:06:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thur May 13 14:38:00 2021
    13 // Update Count     : 0
     12// Last Modified On : Wed Oct  4 10:52:00 2023
     13// Update Count     : 1
    1414//
    1515
     
    2323
    2424class Declaration;
     25namespace ast {
     26        class TranslationUnit;
     27}
    2528
    2629namespace CodeGen {
    2730
    2831void translateLinkOnce( std::list< Declaration *> & translationUnit );
     32void translateLinkOnce( ast::TranslationUnit & translationUnit );
    2933/* Convert the cfa_linkonce attribute on top level declaration into
    3034 * a special section declaration (.gnu.linkonce) so that it may be defined
  • src/GenPoly/BoxNew.cpp

    r2261bcc rf45772e  
    7777};
    7878
    79 // Formally takeOtypeOnly
    8079/// Get all sized type declarations; those that affect a layout function.
    8180ast::vector<ast::TypeDecl> takeSizedParams(
     
    510509                ast::FunctionType const * function,
    511510                TypeVarMap const & typeVars ) {
    512         // TODO
    513         // NOTE: This function previously used isPolyObj, which failed to produce
    514         // the correct thing in some situations. It's not clear to [Rob Schluntz]
    515         // why this wasn't working.
    516 
    517511        // If the return type or a parameter type involved polymorphic types,
    518512        // then the adapter will need to take those polymorphic types as pointers.
     
    587581        ast::FunctionType const * type = decl->type;
    588582        if ( isDynRet( type ) && decl->linkage != ast::Linkage::C ) {
    589                 //retval = type->returns.front();
    590583                retval = decl->returns.front();
    591584
     
    748741ast::Expr const * CallAdapter::postvisit( ast::UntypedExpr const * expr ) {
    749742        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;
    755743                return expr->args.front();
    756744        }
     
    10631051                ast::ptr<ast::Type> newType = ast::deepCopy( param );
    10641052                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 );
    10691053                ast::ObjectDecl * newObj = makeTemporary( location, newType );
    10701054                auto assign = ast::UntypedExpr::createCall( location, "?=?", {
     
    12451229                        }
    12461230                        return new ast::ObjectDecl( location, pNamer.newName(), param );
    1247                 } ), // params
     1231                } ),
    12481232                map_range<ast::vector<ast::DeclWithType>>( adapterType->returns,
    12491233                                [&rNamer, &location]( ast::ptr<ast::Type> const & retval ) {
    12501234                        return new ast::ObjectDecl( location, rNamer.newName(), retval );
    1251                 } ), // returns
     1235                } ),
    12521236                nullptr, // stmts
    1253                 ast::Storage::Classes(), // storage
    1254                 ast::Linkage::C // linkage
    1255                 // attrs
    1256                 // fs
    1257                 // isVarArgs
     1237                {}, // storage
     1238                ast::Linkage::C
    12581239        );
    12591240
     
    13141295        // Returns a polymorphic type.
    13151296        } 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 first
    1318                         // place? - I believe this is done, however, I could remove the
    1319                         // 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                 }
    13251297                ast::UntypedExpr * assign = new ast::UntypedExpr( location,
    13261298                        new ast::NameExpr( location, "?=?" ) );
     
    15461518
    15471519// --------------------------------------------------------------------------
    1548 /// Creates the adapter functions. TODO
     1520/// Modifies declarations to accept implicit parameters.
    15491521/// * Move polymorphic returns in function types to pointer-type parameters.
    15501522/// * 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 );
     1523struct DeclAdapter final {
    15621524        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 );
    15651526private:
    1566         ast::FunctionDecl * addAdapters( ast::FunctionDecl * decl );
    1567 
    1568         std::map<UniqueId, std::string> adapterName;
     1527        void addAdapters( ast::FunctionDecl * decl, TypeVarMap & localTypeVars );
    15691528};
    15701529
    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.
     1531ast::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
     1539ast::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 );
    16221544}
    16231545
    16241546ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    1625         GuardScope( scopeTypeVars );
    1626         makeTypeVarMap( decl, scopeTypeVars );
     1547        TypeVarMap localTypeVars = { ast::TypeData() };
     1548        makeTypeVarMap( decl, localTypeVars );
    16271549
    16281550        auto mutDecl = mutate( decl );
     
    16391561
    16401562        // 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;
    16541565        for ( ast::ptr<ast::TypeDecl> & typeParam : mutDecl->type_params ) {
    16551566                auto mutParam = mutate( typeParam.get() );
    16561567                // Add all size and alignment parameters to parameter list.
    16571568                if ( mutParam->isComplete() ) {
    1658                         //ast::TypeInstType paramType( typeParam->name, typeParam );
    16591569                        ast::TypeInstType paramType( mutParam );
    16601570                        std::string paramName = Mangle::mangleType( &paramType );
    16611571
    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 );
    16731577                }
    16741578                // TODO: These should possibly all be gone.
     
    16961600        // Add size/align for generic parameter types to parameter list.
    16971601        std::set<std::string> seenTypes;
    1698         std::vector<ast::ptr<ast::DeclWithType>> otypeParams;
     1602        ast::vector<ast::DeclWithType> otypeParams;
    16991603        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 );
    17011605                if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    17021606                        continue;
     
    17041608                std::string typeName = Mangle::mangleType( polyType );
    17051609                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 ) );
    17101613                otypeParams.emplace_back( sizeParam );
    17111614
    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 ) );
    17151616                otypeParams.emplace_back( alignParam );
    17161617
     1618                // Zero-length arrays are illegal in C, so empty structs have no
     1619                // offset array.
    17171620                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 );
    17371634
    17381635        return mutDecl;
    17391636}
    17401637
    1741 ast::DeclWithType const * DeclAdapter::postvisit(
     1638ast::FunctionDecl const * DeclAdapter::postvisit(
    17421639                ast::FunctionDecl const * decl ) {
    17431640        ast::FunctionDecl * mutDecl = mutate( decl );
     
    17731670}
    17741671
    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;
     1672void DeclAdapter::addAdapters(
     1673                ast::FunctionDecl * mutDecl, TypeVarMap & localTypeVars ) {
     1674        ast::vector<ast::FunctionType> functions;
    17911675        for ( ast::ptr<ast::DeclWithType> & arg : mutDecl->params ) {
    17921676                ast::Type const * type = arg->get_type();
    1793                 type = findAndReplaceFunction( type, functions, scopeTypeVars, needsAdapter );
     1677                type = findAndReplaceFunction( type, functions, localTypeVars, needsAdapter );
    17941678                arg.get_and_mutate()->set_type( type );
    17951679        }
    17961680        std::set<std::string> adaptersDone;
    17971681        for ( ast::ptr<ast::FunctionType> const & func : functions ) {
    1798                 std::string mangleName = mangleAdapterName( func, scopeTypeVars );
     1682                std::string mangleName = mangleAdapterName( func, localTypeVars );
    17991683                if ( adaptersDone.find( mangleName ) != adaptersDone.end() ) {
    18001684                        continue;
     
    18041688                mutDecl->params.insert( mutDecl->params.begin(), new ast::ObjectDecl(
    18051689                        mutDecl->location, adapterName,
    1806                         new ast::PointerType( makeAdapterType( func, scopeTypeVars ) ),
     1690                        new ast::PointerType( makeAdapterType( func, localTypeVars ) ),
    18071691                        nullptr, {}, {}, nullptr,
    18081692                        { new ast::Attribute( "unused" ) } ) );
    18091693                adaptersDone.insert( adaptersDone.begin(), mangleName );
    18101694        }
    1811         return mutDecl;
    18121695}
    18131696
     
    19261809        /// Namer for VLA (variable length array) buffers.
    19271810        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;
    19301813        /// Used to avoid recursing too deep in type declarations.
    19311814        bool expect_func_type = false;
     
    19591842        beginTypeScope( decl->type );
    19601843
    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.
    19661845        for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {
    19671846                // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
     
    20191898ast::StructDecl const * PolyGenericCalculator::previsit(
    20201899                ast::StructDecl const * decl ) {
    2021         //return strict_dynamic_cast<ast::StructDecl *>( mutateMembers( decl ) );
    20221900        auto mutDecl = mutate( decl );
    20231901        mutateMembers( mutDecl );
     
    20271905ast::UnionDecl const * PolyGenericCalculator::previsit(
    20281906                ast::UnionDecl const * decl ) {
    2029         //return strict_dynamic_cast<ast::UnionDecl *>( mutateMembers( decl ) );
    20301907        auto mutDecl = mutate( decl );
    20311908        mutateMembers( mutDecl );
     
    20881965        auto mutDecl = mutate( decl );
    20891966
    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.
    20931968        erase_if( mutDecl->attributes, matchAndMove );
    20941969
     
    21982073        // the substitution manually. For some reason this is not currently the
    21992074        // 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() );
    22012076        ast::TypeSubstitution sub = genericSubstitution( objectType );
    2202         auto result = sub.apply( memberType );
    2203         memberType = result.node.get(); // .release();
     2077        sub.apply( memberType );
     2078
    22042079        // Not all members of a polymorphic type are themselves of a polymorphic
    22052080        // type; in this cas the member expression should be wrapped and
     
    22172092
    22182093void PolyGenericCalculator::previsit( ast::AddressExpr const * expr ) {
    2219         // Is the argument a MemberExpr before mutating?
    22202094        GuardValue( addrMember ) = expr->arg.as<ast::MemberExpr>();
    22212095}
     
    22332107        // MemberExpr was converted to pointer + offset; and it is not valid C to
    22342108        // 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 );
    22392111}
    22402112
     
    25722444                public BoxPass,
    25732445                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        }
    25762450
    25772451        ast::ObjectDecl const * previsit( ast::ObjectDecl const * decl );
     
    25852459};
    25862460
    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 );
     2461ast::ObjectDecl const * Eraser::previsit( ast::ObjectDecl const * decl ) {
     2462        guardTypeVarMap( decl->type );
    25922463        return scrubAllTypeVars( decl );
    25932464}
    25942465
    2595 ast::ObjectDecl const * Eraser::previsit( ast::ObjectDecl const * decl ) {
    2596         return handleDecl( decl, decl->type );
    2597 }
    2598 
    25992466ast::FunctionDecl const * Eraser::previsit( ast::FunctionDecl const * decl ) {
    2600         return handleDecl( decl, decl->type );
     2467        guardTypeVarMap( decl->type );
     2468        return scrubAllTypeVars( decl );
    26012469}
    26022470
    26032471ast::TypedefDecl const * Eraser::previsit( ast::TypedefDecl const * decl ) {
    2604         return handleDecl( decl, decl->base );
     2472        guardTypeVarMap( decl->base );
     2473        return scrubAllTypeVars( decl );
    26052474}
    26062475
     
    26082477template<typename node_t>
    26092478node_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;
    26162483}
    26172484
     
    26292496
    26302497void Eraser::previsit( ast::PointerType const * type ) {
    2631         GuardScope( scopeTypeVars );
    2632         makeTypeVarMap( type, scopeTypeVars );
     2498        guardTypeVarMap( type );
    26332499}
    26342500
    26352501void Eraser::previsit( ast::FunctionType const * type ) {
    2636         GuardScope( scopeTypeVars );
    2637         makeTypeVarMap( type, scopeTypeVars );
     2502        guardTypeVarMap( type );
    26382503}
    26392504
  • src/GenPoly/InstantiateGeneric.h

    r2261bcc rf45772e  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InstantiateGeneric.h --
     7// InstantiateGeneric.h -- Create concrete instances of generic types.
    88//
    99// Author           : Aaron B. Moss
     
    2424
    2525namespace 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
    3027void instantiateGeneric( std::list< Declaration* > &translationUnit );
    3128void 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
    3234} // namespace GenPoly
    3335
  • src/GenPoly/InstantiateGenericNew.cpp

    r2261bcc rf45772e  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InstantiateGenericNew.cpp --
     7// InstantiateGenericNew.cpp -- Create concrete instances of generic types.
    88//
    99// Author           : Andrew Beach
  • src/Validate/NoIdSymbolTable.hpp

    r2261bcc rf45772e  
    2020namespace Validate {
    2121
    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
    2429// called by the Pass template (lookupId and addId).
    2530class NoIdSymbolTable {
    2631        ast::SymbolTable base;
    2732public:
     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
    2837#       define FORWARD_X( func, types_and_names, just_names ) \
    2938        inline auto func types_and_names -> decltype( base.func just_names ) { \
  • src/main.cc

    r2261bcc rf45772e  
    421421                DUMP( bboxp, std::move( transUnit ) );
    422422                PASS( "Box", GenPoly::box, transUnit );
     423                PASS( "Link-Once", CodeGen::translateLinkOnce, transUnit );
    423424
    424425                translationUnit = convert( std::move( transUnit ) );
    425 
    426                 PASS( "Link-Once", CodeGen::translateLinkOnce, translationUnit );
    427426
    428427                // Code has been lowered to C, now we can start generation.
Note: See TracChangeset for help on using the changeset viewer.