Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/BoxNew.cpp

    r097c8d0 r1ee0a4da  
    7777};
    7878
     79// Formally takeOtypeOnly
    7980/// Get all sized type declarations; those that affect a layout function.
    8081ast::vector<ast::TypeDecl> takeSizedParams(
     
    509510                ast::FunctionType const * function,
    510511                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
    511517        // If the return type or a parameter type involved polymorphic types,
    512518        // then the adapter will need to take those polymorphic types as pointers.
     
    581587        ast::FunctionType const * type = decl->type;
    582588        if ( isDynRet( type ) && decl->linkage != ast::Linkage::C ) {
     589                //retval = type->returns.front();
    583590                retval = decl->returns.front();
    584591
     
    741748ast::Expr const * CallAdapter::postvisit( ast::UntypedExpr const * expr ) {
    742749        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;
    743755                return expr->args.front();
    744756        }
     
    10511063                ast::ptr<ast::Type> newType = ast::deepCopy( param );
    10521064                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 );
    10531069                ast::ObjectDecl * newObj = makeTemporary( location, newType );
    10541070                auto assign = ast::UntypedExpr::createCall( location, "?=?", {
     
    12291245                        }
    12301246                        return new ast::ObjectDecl( location, pNamer.newName(), param );
    1231                 } ),
     1247                } ), // params
    12321248                map_range<ast::vector<ast::DeclWithType>>( adapterType->returns,
    12331249                                [&rNamer, &location]( ast::ptr<ast::Type> const & retval ) {
    12341250                        return new ast::ObjectDecl( location, rNamer.newName(), retval );
    1235                 } ),
     1251                } ), // returns
    12361252                nullptr, // stmts
    1237                 {}, // storage
    1238                 ast::Linkage::C
     1253                ast::Storage::Classes(), // storage
     1254                ast::Linkage::C // linkage
     1255                // attrs
     1256                // fs
     1257                // isVarArgs
    12391258        );
    12401259
     
    12951314        // Returns a polymorphic type.
    12961315        } 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                }
    12971325                ast::UntypedExpr * assign = new ast::UntypedExpr( location,
    12981326                        new ast::NameExpr( location, "?=?" ) );
     
    15181546
    15191547// --------------------------------------------------------------------------
    1520 /// Modifies declarations to accept implicit parameters.
     1548/// Creates the adapter functions. TODO
    15211549/// * Move polymorphic returns in function types to pointer-type parameters.
    15221550/// * Adds type size and assertion parameters to parameter lists.
    1523 struct DeclAdapter final {
     1551struct 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 );
    15241562        ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl );
    1525         ast::FunctionDecl const * postvisit( ast::FunctionDecl const * decl );
     1563        ast::DeclWithType const * postvisit( ast::FunctionDecl const * decl );
     1564        void previsit( ast::CompoundStmt const * stmt );
    15261565private:
    1527         void addAdapters( ast::FunctionDecl * decl, TypeVarMap & localTypeVars );
     1566        ast::FunctionDecl * addAdapters( ast::FunctionDecl * decl );
     1567
     1568        std::map<UniqueId, std::string> adapterName;
    15281569};
    15291570
    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 );
     1571// at must point within [dst.begin(), dst.end()].
     1572template< typename T >
     1573void 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
     1594void DeclAdapter::previsit( ast::StructDecl const * ) {
     1595        // Prevent type vars from leaking into the containing scope.
     1596        GuardScope( scopeTypeVars );
     1597}
     1598
     1599void DeclAdapter::previsit( ast::UnionDecl const * ) {
     1600        // Prevent type vars from leaking into the containing scope.
     1601        GuardScope( scopeTypeVars );
     1602}
     1603
     1604void DeclAdapter::previsit( ast::TraitDecl const * ) {
     1605        // Prevent type vars from leaking into the containing scope.
     1606        GuardScope( scopeTypeVars );
     1607}
     1608
     1609void DeclAdapter::previsit( ast::TypeDecl const * decl ) {
     1610        addToTypeVarMap( decl, scopeTypeVars );
     1611}
     1612
     1613void DeclAdapter::previsit( ast::PointerType const * type ) {
     1614        GuardScope( scopeTypeVars );
     1615        makeTypeVarMap( type, scopeTypeVars );
     1616}
     1617
     1618// TODO: I think this code is redundent.
     1619void DeclAdapter::previsit( ast::FunctionType const * type ) {
     1620        GuardScope( scopeTypeVars );
     1621        makeTypeVarMap( type, scopeTypeVars );
    15441622}
    15451623
    15461624ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    1547         TypeVarMap localTypeVars = { ast::TypeData() };
    1548         makeTypeVarMap( decl, localTypeVars );
     1625        GuardScope( scopeTypeVars );
     1626        makeTypeVarMap( decl, scopeTypeVars );
    15491627
    15501628        auto mutDecl = mutate( decl );
     
    15611639
    15621640        // Add size/align and assertions for type parameters to parameter list.
    1563         ast::vector<ast::DeclWithType> inferredParams;
    1564         ast::vector<ast::DeclWithType> layoutParams;
     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 );
    15651654        for ( ast::ptr<ast::TypeDecl> & typeParam : mutDecl->type_params ) {
    15661655                auto mutParam = mutate( typeParam.get() );
    15671656                // Add all size and alignment parameters to parameter list.
    15681657                if ( mutParam->isComplete() ) {
     1658                        //ast::TypeInstType paramType( typeParam->name, typeParam );
    15691659                        ast::TypeInstType paramType( mutParam );
    15701660                        std::string paramName = Mangle::mangleType( &paramType );
    15711661
    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 );
     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;
    15771673                }
    15781674                // TODO: These should possibly all be gone.
     
    16001696        // Add size/align for generic parameter types to parameter list.
    16011697        std::set<std::string> seenTypes;
    1602         ast::vector<ast::DeclWithType> otypeParams;
     1698        std::vector<ast::ptr<ast::DeclWithType>> otypeParams;
    16031699        for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) {
    1604                 ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars );
     1700                ast::Type const * polyType = isPolyType( funcParam->get_type(), scopeTypeVars );
    16051701                if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    16061702                        continue;
     
    16081704                std::string typeName = Mangle::mangleType( polyType );
    16091705                if ( seenTypes.count( typeName ) ) continue;
     1706
     1707                ast::ObjectDecl * sizeParam = ast::deepCopy( &newObj );
     1708                sizeParam->location = funcParam->location;
     1709                sizeParam->name = sizeofName( typeName );
     1710                otypeParams.emplace_back( sizeParam );
     1711
     1712                ast::ObjectDecl * alignParam = ast::deepCopy( &newObj );
     1713                alignParam->location = funcParam->location;
     1714                alignParam->name = alignofName( typeName );
     1715                otypeParams.emplace_back( alignParam );
     1716
     1717                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                }
    16101728                seenTypes.insert( typeName );
    1611 
    1612                 auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) );
    1613                 otypeParams.emplace_back( sizeParam );
    1614 
    1615                 auto alignParam = makeObj( funcParam->location, alignofName( typeName ) );
    1616                 otypeParams.emplace_back( alignParam );
    1617 
    1618                 // Zero-length arrays are illegal in C, so empty structs have no
    1619                 // offset array.
    1620                 if ( auto * polyStruct =
    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 );
     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 );
    16341737
    16351738        return mutDecl;
    16361739}
    16371740
    1638 ast::FunctionDecl const * DeclAdapter::postvisit(
     1741ast::DeclWithType const * DeclAdapter::postvisit(
    16391742                ast::FunctionDecl const * decl ) {
    16401743        ast::FunctionDecl * mutDecl = mutate( decl );
     
    16701773}
    16711774
    1672 void DeclAdapter::addAdapters(
    1673                 ast::FunctionDecl * mutDecl, TypeVarMap & localTypeVars ) {
    1674         ast::vector<ast::FunctionType> functions;
     1775void 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.
     1789ast::FunctionDecl * DeclAdapter::addAdapters( ast::FunctionDecl * mutDecl ) {
     1790        std::vector<ast::ptr<ast::FunctionType>> functions;
    16751791        for ( ast::ptr<ast::DeclWithType> & arg : mutDecl->params ) {
    16761792                ast::Type const * type = arg->get_type();
    1677                 type = findAndReplaceFunction( type, functions, localTypeVars, needsAdapter );
     1793                type = findAndReplaceFunction( type, functions, scopeTypeVars, needsAdapter );
    16781794                arg.get_and_mutate()->set_type( type );
    16791795        }
    16801796        std::set<std::string> adaptersDone;
    16811797        for ( ast::ptr<ast::FunctionType> const & func : functions ) {
    1682                 std::string mangleName = mangleAdapterName( func, localTypeVars );
     1798                std::string mangleName = mangleAdapterName( func, scopeTypeVars );
    16831799                if ( adaptersDone.find( mangleName ) != adaptersDone.end() ) {
    16841800                        continue;
     
    16881804                mutDecl->params.insert( mutDecl->params.begin(), new ast::ObjectDecl(
    16891805                        mutDecl->location, adapterName,
    1690                         new ast::PointerType( makeAdapterType( func, localTypeVars ) ),
     1806                        new ast::PointerType( makeAdapterType( func, scopeTypeVars ) ),
    16911807                        nullptr, {}, {}, nullptr,
    16921808                        { new ast::Attribute( "unused" ) } ) );
    16931809                adaptersDone.insert( adaptersDone.begin(), mangleName );
    16941810        }
     1811        return mutDecl;
    16951812}
    16961813
     
    18091926        /// Namer for VLA (variable length array) buffers.
    18101927        UniqueName bufNamer;
    1811         /// If the argument of an AddressExpr is MemberExpr, it is stored here.
    1812         ast::MemberExpr const * addrMember = nullptr;
     1928        /// AddressExpr argument is MemberExpr? (TODO: What?)
     1929        ast::Expr const * addrMember = nullptr;
    18131930        /// Used to avoid recursing too deep in type declarations.
    18141931        bool expect_func_type = false;
     
    18421959        beginTypeScope( decl->type );
    18431960
    1844         // TODO: Going though dec->params does not work for some reason.
     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.
    18451966        for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {
    18461967                // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
     
    18982019ast::StructDecl const * PolyGenericCalculator::previsit(
    18992020                ast::StructDecl const * decl ) {
     2021        //return strict_dynamic_cast<ast::StructDecl *>( mutateMembers( decl ) );
    19002022        auto mutDecl = mutate( decl );
    19012023        mutateMembers( mutDecl );
     
    19052027ast::UnionDecl const * PolyGenericCalculator::previsit(
    19062028                ast::UnionDecl const * decl ) {
     2029        //return strict_dynamic_cast<ast::UnionDecl *>( mutateMembers( decl ) );
    19072030        auto mutDecl = mutate( decl );
    19082031        mutateMembers( mutDecl );
     
    19652088        auto mutDecl = mutate( decl );
    19662089
    1967         // Forally, side effects are not safe in this function. But it works.
     2090        //mutDecl->attributes.remove_if( matchAndMove );
     2091        // TODO: This common helper might work, but does not officially support
     2092        // side effects.
    19682093        erase_if( mutDecl->attributes, matchAndMove );
    19692094
     
    20732198        // the substitution manually. For some reason this is not currently the
    20742199        // case. This requires more investigation.
    2075         ast::ptr<ast::Type> memberType = deepCopy( expr->member->get_type() );
     2200        ast::Type const * memberType = deepCopy( expr->member->get_type() );
    20762201        ast::TypeSubstitution sub = genericSubstitution( objectType );
    2077         sub.apply( memberType );
    2078 
     2202        auto result = sub.apply( memberType );
     2203        memberType = result.node.get(); // .release();
    20792204        // Not all members of a polymorphic type are themselves of a polymorphic
    20802205        // type; in this cas the member expression should be wrapped and
     
    20922217
    20932218void PolyGenericCalculator::previsit( ast::AddressExpr const * expr ) {
     2219        // Is the argument a MemberExpr before mutating?
    20942220        GuardValue( addrMember ) = expr->arg.as<ast::MemberExpr>();
    20952221}
     
    21072233        // MemberExpr was converted to pointer + offset; and it is not valid C to
    21082234        // take the address of an addition, so stript the address-of.
    2109         // It also preserves the env value.
    2110         return ast::mutate_field( expr->arg.get(), &ast::Expr::env, expr->env );
     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;
    21112239}
    21122240
     
    24442572                public BoxPass,
    24452573                public ast::WithGuards {
    2446         void guardTypeVarMap( ast::Type const * type ) {
    2447                 GuardScope( scopeTypeVars );
    2448                 makeTypeVarMap( type, scopeTypeVars );
    2449         }
     2574        template<typename decl_t>
     2575        decl_t const * handleDecl( decl_t const * decl, ast::Type const * type );
    24502576
    24512577        ast::ObjectDecl const * previsit( ast::ObjectDecl const * decl );
     
    24592585};
    24602586
     2587template<typename decl_t>
     2588decl_t const * Eraser::handleDecl(
     2589                decl_t const * decl, ast::Type const * type ) {
     2590        GuardScope( scopeTypeVars );
     2591        makeTypeVarMap( type, scopeTypeVars );
     2592        return scrubAllTypeVars( decl );
     2593}
     2594
    24612595ast::ObjectDecl const * Eraser::previsit( ast::ObjectDecl const * decl ) {
    2462         guardTypeVarMap( decl->type );
    2463         return scrubAllTypeVars( decl );
     2596        return handleDecl( decl, decl->type );
    24642597}
    24652598
    24662599ast::FunctionDecl const * Eraser::previsit( ast::FunctionDecl const * decl ) {
    2467         guardTypeVarMap( decl->type );
    2468         return scrubAllTypeVars( decl );
     2600        return handleDecl( decl, decl->type );
    24692601}
    24702602
    24712603ast::TypedefDecl const * Eraser::previsit( ast::TypedefDecl const * decl ) {
    2472         guardTypeVarMap( decl->base );
    2473         return scrubAllTypeVars( decl );
     2604        return handleDecl( decl, decl->base );
    24742605}
    24752606
     
    24772608template<typename node_t>
    24782609node_t const * stripGenericMembers( node_t const * decl ) {
    2479         if ( decl->params.empty() ) return decl;
    2480         auto mutDecl = ast::mutate( decl );
    2481         mutDecl->members.clear();
    2482         return mutDecl;
     2610        if ( !decl->params.empty() ) {
     2611                auto mutDecl = ast::mutate( decl );
     2612                mutDecl->members.clear();
     2613                return mutDecl;
     2614        }
     2615        return decl;
    24832616}
    24842617
     
    24962629
    24972630void Eraser::previsit( ast::PointerType const * type ) {
    2498         guardTypeVarMap( type );
     2631        GuardScope( scopeTypeVars );
     2632        makeTypeVarMap( type, scopeTypeVars );
    24992633}
    25002634
    25012635void Eraser::previsit( ast::FunctionType const * type ) {
    2502         guardTypeVarMap( type );
     2636        GuardScope( scopeTypeVars );
     2637        makeTypeVarMap( type, scopeTypeVars );
    25032638}
    25042639
Note: See TracChangeset for help on using the changeset viewer.