Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/BoxNew.cpp

    re14d169 r0bf0b978  
    376376        ast::Expr const * postvisit( ast::AddressExpr const * expr );
    377377        ast::ReturnStmt const * previsit( ast::ReturnStmt const * stmt );
     378        void previsit( ast::PointerType const * type );
     379        void previsit( ast::FunctionType const * type );
    378380
    379381        void beginScope();
     
    384386        // return value.
    385387
    386         /// Passes extra layout arguments for sized polymorphic type parameters.
     388        /// Pass the extra type parameters from polymorphic generic arguments or
     389        /// return types into a function application.
     390        ast::vector<ast::Expr>::iterator passArgTypeVars(
     391                ast::ApplicationExpr * expr, ast::Type const * parmType,
     392                ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,
     393                const TypeVarMap & exprTyVars, std::set<std::string> & seenTypes );
     394        /// Passes extra type parameters into a polymorphic function application.
    387395        ast::vector<ast::Expr>::iterator passTypeVars(
    388396                ast::ApplicationExpr * expr,
    389                 ast::FunctionType const * funcType );
     397                ast::Type const * polyRetType,
     398                ast::FunctionType const * funcType,
     399                const TypeVarMap & exprTyVars );
    390400        /// Wraps a function application with a new temporary for the
    391401        /// out-parameter return value.
     
    551561
    552562ast::FunctionDecl const * CallAdapter::previsit( ast::FunctionDecl const * decl ) {
    553         // Prevent type declaration information from leaking out.
     563        if ( nullptr == decl->stmts ) {
     564                // This may keep TypeDecls we don't ever want from sneaking in.
     565                // Not visiting child nodes might just be faster.
     566                GuardScope( scopeTypeVars );
     567                return decl;
     568        }
     569
    554570        GuardScope( scopeTypeVars );
    555 
    556         if ( nullptr == decl->stmts ) {
    557                 return decl;
    558         }
    559 
    560571        GuardValue( retval );
    561572
     
    684695
    685696        assert( typeSubs );
     697        ast::Type const * concRetType = replaceWithConcrete( dynRetType, *typeSubs );
     698        // Used to use dynRetType instead of concRetType; this changed so that
     699        // the correct type parameters are passed for return types (it should be
     700        // the concrete type's parameters, not the formal type's).
    686701        ast::vector<ast::Expr>::iterator argIt =
    687                 passTypeVars( mutExpr, function );
     702                passTypeVars( mutExpr, concRetType, function, exprTypeVars );
    688703        addInferredParams( mutExpr, argIt, function, exprTypeVars );
    689704
     
    763778}
    764779
     780void CallAdapter::previsit( ast::PointerType const * type ) {
     781        GuardScope( scopeTypeVars );
     782        makeTypeVarMap( type, scopeTypeVars );
     783}
     784
     785void CallAdapter::previsit( ast::FunctionType const * type ) {
     786        GuardScope( scopeTypeVars );
     787        makeTypeVarMap( type, scopeTypeVars );
     788}
     789
    765790void CallAdapter::beginScope() {
    766791        adapters.beginScope();
     
    787812}
    788813
     814// arg is an in/out parameter that matches the return value.
     815ast::vector<ast::Expr>::iterator CallAdapter::passArgTypeVars(
     816                ast::ApplicationExpr * expr, ast::Type const * paramType,
     817                ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,
     818                const TypeVarMap & exprTypeVars, std::set<std::string> & seenTypes ) {
     819        ast::Type const * polyType = isPolyType( paramType, exprTypeVars );
     820        if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
     821                return arg;
     822        }
     823
     824        std::string typeName = Mangle::mangleType( polyType );
     825        if ( seenTypes.count( typeName ) ) return arg;
     826
     827        arg = expr->args.insert( arg,
     828                new ast::SizeofExpr( expr->location, ast::deepCopy( argBaseType ) )
     829        );
     830        arg++;
     831        arg = expr->args.insert( arg,
     832                new ast::AlignofExpr( expr->location, ast::deepCopy( argBaseType ) )
     833        );
     834        arg++;
     835        if ( dynamic_cast<ast::StructInstType const *>( polyType ) ) {
     836                auto argBaseStructType =
     837                                dynamic_cast<ast::StructInstType const *>( argBaseType );
     838                if ( nullptr == argBaseStructType ) {
     839                        SemanticError( expr,
     840                                "Cannot pass non-structure type for generic struct: " );
     841                }
     842
     843                // Zero-length arrays are forbidden by C, so don't pass
     844                // offset for empty structure.
     845                if ( !argBaseStructType->base->members.empty() ) {
     846                        arg = expr->args.insert( arg,
     847                                new ast::OffsetPackExpr(
     848                                        expr->location,
     849                                        ast::deepCopy( argBaseStructType ) )
     850                        );
     851                        arg++;
     852                }
     853        }
     854
     855        seenTypes.insert( typeName );
     856        return arg;
     857}
     858
    789859ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars(
    790860                ast::ApplicationExpr * expr,
    791                 ast::FunctionType const * function ) {
     861                ast::Type const * polyRetType,
     862                ast::FunctionType const * function,
     863                const TypeVarMap & exprTypeVars ) {
    792864        assert( typeSubs );
    793865        ast::vector<ast::Expr>::iterator arg = expr->args.begin();
     
    808880                        new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) );
    809881                arg++;
     882        }
     883
     884        // Add size/align for generic types to parameter list.
     885        if ( !expr->func->result ) return arg;
     886        ast::FunctionType const * funcType = getFunctionType( expr->func->result );
     887        assert( funcType );
     888
     889        // This iterator points at first original argument.
     890        ast::vector<ast::Expr>::const_iterator funcArg;
     891        // Names for generic types we've seen.
     892        std::set<std::string> seenTypes;
     893
     894        // A polymorphic return type may need to be added to the argument list.
     895        if ( polyRetType ) {
     896                assert( typeSubs );
     897                auto concRetType = replaceWithConcrete( polyRetType, *typeSubs );
     898                // TODO: This write-back may not be correct.
     899                arg = passArgTypeVars( expr, polyRetType, concRetType,
     900                                arg, exprTypeVars, seenTypes );
     901                // Skip the return parameter in the argument list.
     902                funcArg = arg + 1;
     903        } else {
     904                funcArg = arg;
     905        }
     906
     907        // TODO:
     908        // I believe this is (starts as) the number of original arguments to the
     909        // function with the args before funcArg all being inserted.
     910        ptrdiff_t argsToPass = std::distance( funcArg, expr->args.cend() );
     911
     912        // Add type information args for presently unseen types in parameter list.
     913        ast::vector<ast::Type>::const_iterator funcParam = funcType->params.begin();
     914        // assert( funcType->params.size() == argsToPass );
     915        for ( ; funcParam != funcType->params.end() && 0 < argsToPass
     916                        ; ++funcParam, --argsToPass ) {
     917                assert( 0 < argsToPass );
     918                assert( argsToPass <= (ptrdiff_t)expr->args.size() );
     919                ptrdiff_t index = expr->args.size() - argsToPass;
     920                ast::Type const * argType = expr->args[index]->result;
     921                if ( nullptr == argType ) continue;
     922                arg = passArgTypeVars( expr, *funcParam, argType,
     923                                arg, exprTypeVars, seenTypes );
    810924        }
    811925        return arg;
     
    14091523}
    14101524
     1525ast::ObjectDecl * makePtr(
     1526                CodeLocation const & location, std::string const & name ) {
     1527        return new ast::ObjectDecl( location, name,
     1528                new ast::PointerType( makeSizeAlignType() ),
     1529                nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr );
     1530}
     1531
    14111532ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    14121533        TypeVarMap localTypeVars = { ast::TypeData() };
     
    14631584        mutDecl->assertions.clear();
    14641585
     1586        // Add size/align for generic parameter types to parameter list.
     1587        std::set<std::string> seenTypes;
     1588        ast::vector<ast::DeclWithType> otypeParams;
     1589        for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) {
     1590                ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars );
     1591                if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
     1592                        continue;
     1593                }
     1594                std::string typeName = Mangle::mangleType( polyType );
     1595                if ( seenTypes.count( typeName ) ) continue;
     1596                seenTypes.insert( typeName );
     1597
     1598                auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) );
     1599                otypeParams.emplace_back( sizeParam );
     1600
     1601                auto alignParam = makeObj( funcParam->location, alignofName( typeName ) );
     1602                otypeParams.emplace_back( alignParam );
     1603
     1604                // Zero-length arrays are illegal in C, so empty structs have no
     1605                // offset array.
     1606                if ( auto * polyStruct =
     1607                                dynamic_cast<ast::StructInstType const *>( polyType ) ;
     1608                                polyStruct && !polyStruct->base->members.empty() ) {
     1609                        auto offsetParam = makePtr( funcParam->location, offsetofName( typeName ) );
     1610                        otypeParams.emplace_back( offsetParam );
     1611                }
     1612        }
     1613
    14651614        // Prepend each argument group. From last group to first. addAdapters
    14661615        // does do the same, it just does it itself and see all other parameters.
    14671616        spliceBegin( mutDecl->params, inferredParams );
     1617        spliceBegin( mutDecl->params, otypeParams );
    14681618        spliceBegin( mutDecl->params, layoutParams );
    14691619        addAdapters( mutDecl, localTypeVars );
     
    15781728        PolyGenericCalculator();
    15791729
     1730        void previsit( ast::ObjectDecl const * decl );
    15801731        void previsit( ast::FunctionDecl const * decl );
    15811732        void previsit( ast::TypedefDecl const * decl );
     
    15841735        ast::StructDecl const * previsit( ast::StructDecl const * decl );
    15851736        ast::UnionDecl const * previsit( ast::UnionDecl const * decl );
     1737        void previsit( ast::PointerType const * type );
     1738        void previsit( ast::FunctionType const * type );
    15861739        ast::DeclStmt const * previsit( ast::DeclStmt const * stmt );
    15871740        ast::Expr const * postvisit( ast::MemberExpr const * expr );
     
    16191772        /// adding the type variables from the provided type.
    16201773        void beginTypeScope( ast::Type const * );
     1774        /// Enters a new scope for known layouts and offsets, and queues exit calls.
     1775        void beginGenericScope();
    16211776
    16221777        /// Set of generic type layouts known in the current scope,
     
    16301785        /// If the argument of an AddressExpr is MemberExpr, it is stored here.
    16311786        ast::MemberExpr const * addrMember = nullptr;
     1787        /// Used to avoid recursing too deep in type declarations.
     1788        bool expect_func_type = false;
    16321789};
    16331790
     
    16511808}
    16521809
     1810void PolyGenericCalculator::previsit( ast::ObjectDecl const * decl ) {
     1811        beginTypeScope( decl->type );
     1812}
     1813
    16531814void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) {
    1654         GuardScope( *this );
     1815        beginGenericScope();
    16551816        beginTypeScope( decl->type );
     1817
     1818        // TODO: Going though dec->params does not work for some reason.
     1819        for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {
     1820                // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
     1821                ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );
     1822                if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
     1823                        knownLayouts.insert( Mangle::mangleType( polyType ) );
     1824                }
     1825        }
    16561826}
    16571827
     
    17141884}
    17151885
     1886void PolyGenericCalculator::previsit( ast::PointerType const * type ) {
     1887        beginTypeScope( type );
     1888}
     1889
     1890void PolyGenericCalculator::previsit( ast::FunctionType const * type ) {
     1891        beginTypeScope( type );
     1892
     1893        GuardValue( expect_func_type );
     1894        GuardScope( *this );
     1895
     1896        // The other functions type we will see in this scope are probably
     1897        // function parameters they don't help us with the layout and offsets so
     1898        // don't mark them as known in this scope.
     1899        expect_func_type = false;
     1900
     1901        // Make sure that any type information passed into the function is
     1902        // accounted for.
     1903        for ( ast::ptr<ast::Type> const & funcParam : type->params ) {
     1904                // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
     1905                ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );
     1906                if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
     1907                        knownLayouts.insert( Mangle::mangleType( polyType ) );
     1908                }
     1909        }
     1910}
     1911
     1912//void PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {
    17161913ast::DeclStmt const * PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {
    17171914        ast::ObjectDecl const * decl = stmt->decl.as<ast::ObjectDecl>();
     
    22032400}
    22042401
     2402void PolyGenericCalculator::beginGenericScope() {
     2403        GuardScope( *this );
     2404        // We expect the first function type see to be the type relating to this
     2405        // scope but any further type is probably some unrelated function pointer
     2406        // keep track of whrich is the first.
     2407        GuardValue( expect_func_type ) = true;
     2408}
     2409
    22052410// --------------------------------------------------------------------------
    2206 /// Removes unneeded or incorrect type information.
     2411/// No common theme found.
    22072412/// * Replaces initialization of polymorphic values with alloca.
    22082413/// * Replaces declaration of dtype/ftype with appropriate void expression.
Note: See TracChangeset for help on using the changeset viewer.