Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/BoxNew.cpp

    r1ee0a4da r097c8d0  
    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
Note: See TracChangeset for help on using the changeset viewer.