Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/BoxNew.cpp

    r5e0bba5f r61e5d99  
    3939
    4040namespace {
     41
     42/// Common field of several sub-passes of box.
     43struct BoxPass {
     44        TypeVarMap scopeTypeVars;
     45        BoxPass() : scopeTypeVars( ast::TypeData() ) {}
     46};
     47
     48// TODO: Could this be a common helper somewhere?
     49ast::FunctionType * makeFunctionType( ast::FunctionDecl const * decl ) {
     50        ast::FunctionType * type = new ast::FunctionType(
     51                decl->type->isVarArgs, decl->type->qualifiers
     52        );
     53        for ( auto type_param : decl->type_params ) {
     54                type->forall.emplace_back( new ast::TypeInstType( type_param ) );
     55        }
     56        for ( auto assertion : decl->assertions ) {
     57                type->assertions.emplace_back( new ast::VariableExpr(
     58                        assertion->location, assertion ) );
     59        }
     60        for ( auto param : decl->params ) {
     61                type->params.emplace_back( param->get_type() );
     62        }
     63        for ( auto retval : decl->returns ) {
     64                type->returns.emplace_back( retval->get_type() );
     65        }
     66        return type;
     67}
    4168
    4269// --------------------------------------------------------------------------
     
    332359/// * Adds appropriate type variables to the function calls.
    333360struct CallAdapter final :
     361                public BoxPass,
    334362                public ast::WithConstTypeSubstitution,
    335363                public ast::WithGuards,
     
    348376        ast::Expr const * postvisit( ast::AddressExpr const * expr );
    349377        ast::ReturnStmt const * previsit( ast::ReturnStmt const * stmt );
     378        void previsit( ast::PointerType const * type );
     379        void previsit( ast::FunctionType const * type );
    350380
    351381        void beginScope();
     
    410440                CodeLocation const & location, ast::Type const * type );
    411441
    412         TypeVarMap scopeTypeVars;
     442        /// Set of adapter functions in the current scope.
    413443        ScopedMap< std::string, ast::DeclWithType const * > adapters;
    414444        std::map< ast::ApplicationExpr const *, ast::Expr const * > retVals;
     
    523553
    524554ast::FunctionDecl const * CallAdapter::previsit( ast::FunctionDecl const * decl ) {
    525         // Prevent type declaration information from leaking out.
     555        if ( nullptr == decl->stmts ) {
     556                // This may keep TypeDecls we don't ever want from sneaking in.
     557                // Not visiting child nodes might just be faster.
     558                GuardScope( scopeTypeVars );
     559                return decl;
     560        }
     561
    526562        GuardScope( scopeTypeVars );
    527 
    528         if ( nullptr == decl->stmts ) {
    529                 return decl;
    530         }
    531 
    532563        GuardValue( retval );
    533564
     
    631662        ptrdiff_t initArgCount = mutExpr->args.size();
    632663
    633         TypeVarMap exprTypeVars;
     664        TypeVarMap exprTypeVars = { ast::TypeData() };
    634665        // TODO: Should this take into account the variables already bound in
    635666        // scopeTypeVars ([ex] remove them from exprTypeVars)?
     
    656687
    657688        assert( typeSubs );
     689        ast::Type const * concRetType = replaceWithConcrete( dynRetType, *typeSubs );
     690        // Used to use dynRetType instead of concRetType; this changed so that
     691        // the correct type parameters are passed for return types (it should be
     692        // the concrete type's parameters, not the formal type's).
    658693        ast::vector<ast::Expr>::iterator argIt =
    659694                passTypeVars( mutExpr, function );
     
    733768        }
    734769        return stmt;
     770}
     771
     772void CallAdapter::previsit( ast::PointerType const * type ) {
     773        GuardScope( scopeTypeVars );
     774        makeTypeVarMap( type, scopeTypeVars );
     775}
     776
     777void CallAdapter::previsit( ast::FunctionType const * type ) {
     778        GuardScope( scopeTypeVars );
     779        makeTypeVarMap( type, scopeTypeVars );
    735780}
    736781
     
    13821427
    13831428ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    1384         TypeVarMap localTypeVars;
     1429        TypeVarMap localTypeVars = { ast::TypeData() };
    13851430        makeTypeVarMap( decl, localTypeVars );
    13861431
     
    14131458                        layoutParams.emplace_back( alignParam );
    14141459                }
    1415                 // Assertions should be stored in the main list.
    1416                 assert( mutParam->assertions.empty() );
     1460                // TODO: These should possibly all be gone.
     1461                // More all assertions into parameter list.
     1462                for ( ast::ptr<ast::DeclWithType> & assert : mutParam->assertions ) {
     1463                        // Assertion parameters may not be used in body,
     1464                        // pass along with unused attribute.
     1465                        assert.get_and_mutate()->attributes.push_back(
     1466                                new ast::Attribute( "unused" ) );
     1467                        inferredParams.push_back( assert );
     1468                }
     1469                mutParam->assertions.clear();
    14171470                typeParam = mutParam;
    14181471        }
     1472        // TODO: New version of inner loop.
    14191473        for ( ast::ptr<ast::DeclWithType> & assert : mutDecl->assertions ) {
    14201474                // Assertion parameters may not be used in body,
     
    14311485        spliceBegin( mutDecl->params, layoutParams );
    14321486        addAdapters( mutDecl, localTypeVars );
    1433 
    1434         // Now have to update the type to match the declaration.
    1435         ast::FunctionType * type = new ast::FunctionType(
    1436                 mutDecl->type->isVarArgs, mutDecl->type->qualifiers );
    1437         for ( auto type_param : mutDecl->type_params ) {
    1438                 type->forall.emplace_back( new ast::TypeInstType( type_param ) );
    1439         }
    1440         for ( auto param : mutDecl->params ) {
    1441                 type->params.emplace_back( param->get_type() );
    1442         }
    1443         for ( auto retval : mutDecl->returns ) {
    1444                 type->returns.emplace_back( retval->get_type() );
    1445         }
    1446         mutDecl->type = type;
    14471487
    14481488        return mutDecl;
     
    14781518                }
    14791519        }
     1520        // TODO: Can this be updated as we go along?
     1521        mutDecl->type = makeFunctionType( mutDecl );
    14801522        return mutDecl;
    14811523}
     
    15331575        assertf( it != adapters.end(), "Could not correct floating node." );
    15341576        return ast::mutate_field( expr, &ast::VariableExpr::var, it->second );
     1577
    15351578}
    15361579
     
    15441587/// * Inserts dynamic calculation of polymorphic type layouts where needed.
    15451588struct PolyGenericCalculator final :
     1589                public BoxPass,
    15461590                public ast::WithConstTypeSubstitution,
    15471591                public ast::WithDeclsToAdd<>,
     
    15511595        PolyGenericCalculator();
    15521596
     1597        void previsit( ast::ObjectDecl const * decl );
    15531598        void previsit( ast::FunctionDecl const * decl );
    15541599        void previsit( ast::TypedefDecl const * decl );
     
    15571602        ast::StructDecl const * previsit( ast::StructDecl const * decl );
    15581603        ast::UnionDecl const * previsit( ast::UnionDecl const * decl );
     1604        void previsit( ast::PointerType const * type );
     1605        void previsit( ast::FunctionType const * type );
    15591606        ast::DeclStmt const * previsit( ast::DeclStmt const * stmt );
    15601607        ast::Expr const * postvisit( ast::MemberExpr const * expr );
     
    15881635        /// C sizeof().
    15891636        ast::Expr const * genSizeof( CodeLocation const &, ast::Type const * );
     1637
    15901638        /// Enters a new scope for type-variables,
    15911639        /// adding the type variables from the provided type.
    15921640        void beginTypeScope( ast::Type const * );
    1593 
    1594         /// The type variables and polymorphic parameters currently in scope.
    1595         TypeVarMap scopeTypeVars;
     1641        /// Enters a new scope for known layouts and offsets, and queues exit calls.
     1642        void beginGenericScope();
     1643
    15961644        /// Set of generic type layouts known in the current scope,
    15971645        /// indexed by sizeofName.
     
    16041652        /// If the argument of an AddressExpr is MemberExpr, it is stored here.
    16051653        ast::MemberExpr const * addrMember = nullptr;
     1654        /// Used to avoid recursing too deep in type declarations.
     1655        bool expect_func_type = false;
    16061656};
    16071657
     
    16251675}
    16261676
     1677void PolyGenericCalculator::previsit( ast::ObjectDecl const * decl ) {
     1678        beginTypeScope( decl->type );
     1679}
     1680
    16271681void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) {
    1628         GuardScope( *this );
     1682        beginGenericScope();
    16291683        beginTypeScope( decl->type );
    16301684}
     
    16421696                ast::TypeDecl const * decl ) {
    16431697        ast::Type const * base = decl->base;
    1644         if ( nullptr == base ) return decl;
     1698        if ( nullptr == base) return decl;
    16451699
    16461700        // Add size/align variables for opaque type declarations.
     
    16671721        alignDecl->accept( *visitor );
    16681722
    1669         // A little trick to replace this with two declarations.
    1670         // Adding after makes sure that there is no conflict with adding stmts.
     1723        // Can't use [makeVar], because it inserts into stmtsToAdd and TypeDecls
     1724        // can occur at global scope.
    16711725        declsToAddAfter.push_back( alignDecl );
     1726        // replace with sizeDecl.
    16721727        return sizeDecl;
    16731728}
     
    16871742}
    16881743
     1744void PolyGenericCalculator::previsit( ast::PointerType const * type ) {
     1745        beginTypeScope( type );
     1746}
     1747
     1748void PolyGenericCalculator::previsit( ast::FunctionType const * type ) {
     1749        beginTypeScope( type );
     1750
     1751        GuardValue( expect_func_type );
     1752        GuardScope( *this );
     1753
     1754        // The other functions type we will see in this scope are probably
     1755        // function parameters they don't help us with the layout and offsets so
     1756        // don't mark them as known in this scope.
     1757        expect_func_type = false;
     1758}
     1759
     1760//void PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {
    16891761ast::DeclStmt const * PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {
    16901762        ast::ObjectDecl const * decl = stmt->decl.as<ast::ObjectDecl>();
     
    16941766
    16951767        // Change initialization of a polymorphic value object to allocate via a
    1696         // variable-length-array (alloca cannot be safely used in loops).
     1768        // variable-length-array (alloca was previouly used, but it cannot be
     1769        // safely used in loops).
    16971770        ast::ObjectDecl * newBuf = new ast::ObjectDecl( decl->location,
    16981771                bufNamer.newName(),
     
    21752248}
    21762249
     2250void PolyGenericCalculator::beginGenericScope() {
     2251        GuardScope( *this );
     2252        // We expect the first function type see to be the type relating to this
     2253        // scope but any further type is probably some unrelated function pointer
     2254        // keep track of whrich is the first.
     2255        GuardValue( expect_func_type ) = true;
     2256}
     2257
    21772258// --------------------------------------------------------------------------
    2178 /// Removes unneeded or incorrect type information.
     2259/// No common theme found.
    21792260/// * Replaces initialization of polymorphic values with alloca.
    21802261/// * Replaces declaration of dtype/ftype with appropriate void expression.
     
    21822263/// * Strips fields from generic structure declarations.
    21832264struct Eraser final :
     2265                public BoxPass,
    21842266                public ast::WithGuards {
    21852267        void guardTypeVarMap( ast::Type const * type ) {
     
    21962278        void previsit( ast::PointerType const * type );
    21972279        void previsit( ast::FunctionType const * type );
    2198 public:
    2199         TypeVarMap scopeTypeVars;
    22002280};
    22012281
Note: See TracChangeset for help on using the changeset viewer.