Ignore:
Timestamp:
Nov 13, 2023, 3:43:43 AM (2 years ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
25f2798
Parents:
0030b508 (diff), 2174191 (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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/BoxNew.cpp

    r0030b508 rfc12f05  
    3939
    4040namespace {
    41 
    42 /// Common field of several sub-passes of box.
    43 struct BoxPass {
    44         TypeVarMap scopeTypeVars;
    45         BoxPass() : scopeTypeVars( ast::TypeData() ) {}
    46 };
    47 
    48 // TODO: Could this be a common helper somewhere?
    49 ast::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 }
    6841
    6942// --------------------------------------------------------------------------
     
    359332/// * Adds appropriate type variables to the function calls.
    360333struct CallAdapter final :
    361                 public BoxPass,
    362334                public ast::WithConstTypeSubstitution,
    363335                public ast::WithGuards,
     
    376348        ast::Expr const * postvisit( ast::AddressExpr const * expr );
    377349        ast::ReturnStmt const * previsit( ast::ReturnStmt const * stmt );
    378         void previsit( ast::PointerType const * type );
    379         void previsit( ast::FunctionType const * type );
    380350
    381351        void beginScope();
     
    440410                CodeLocation const & location, ast::Type const * type );
    441411
    442         /// Set of adapter functions in the current scope.
     412        TypeVarMap scopeTypeVars;
    443413        ScopedMap< std::string, ast::DeclWithType const * > adapters;
    444414        std::map< ast::ApplicationExpr const *, ast::Expr const * > retVals;
     
    553523
    554524ast::FunctionDecl const * CallAdapter::previsit( ast::FunctionDecl const * decl ) {
     525        // Prevent type declaration information from leaking out.
     526        GuardScope( scopeTypeVars );
     527
    555528        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 );
    559529                return decl;
    560530        }
    561531
    562         GuardScope( scopeTypeVars );
    563532        GuardValue( retval );
    564533
     
    662631        ptrdiff_t initArgCount = mutExpr->args.size();
    663632
    664         TypeVarMap exprTypeVars = { ast::TypeData() };
     633        TypeVarMap exprTypeVars;
    665634        // TODO: Should this take into account the variables already bound in
    666635        // scopeTypeVars ([ex] remove them from exprTypeVars)?
     
    687656
    688657        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).
    693658        ast::vector<ast::Expr>::iterator argIt =
    694659                passTypeVars( mutExpr, function );
     
    768733        }
    769734        return stmt;
    770 }
    771 
    772 void CallAdapter::previsit( ast::PointerType const * type ) {
    773         GuardScope( scopeTypeVars );
    774         makeTypeVarMap( type, scopeTypeVars );
    775 }
    776 
    777 void CallAdapter::previsit( ast::FunctionType const * type ) {
    778         GuardScope( scopeTypeVars );
    779         makeTypeVarMap( type, scopeTypeVars );
    780735}
    781736
     
    14271382
    14281383ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    1429         TypeVarMap localTypeVars = { ast::TypeData() };
     1384        TypeVarMap localTypeVars;
    14301385        makeTypeVarMap( decl, localTypeVars );
    14311386
     
    14581413                        layoutParams.emplace_back( alignParam );
    14591414                }
    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();
     1415                // Assertions should be stored in the main list.
     1416                assert( mutParam->assertions.empty() );
    14701417                typeParam = mutParam;
    14711418        }
    1472         // TODO: New version of inner loop.
    14731419        for ( ast::ptr<ast::DeclWithType> & assert : mutDecl->assertions ) {
    14741420                // Assertion parameters may not be used in body,
     
    14851431        spliceBegin( mutDecl->params, layoutParams );
    14861432        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;
    14871447
    14881448        return mutDecl;
     
    15181478                }
    15191479        }
    1520         // TODO: Can this be updated as we go along?
    1521         mutDecl->type = makeFunctionType( mutDecl );
    15221480        return mutDecl;
    15231481}
     
    15751533        assertf( it != adapters.end(), "Could not correct floating node." );
    15761534        return ast::mutate_field( expr, &ast::VariableExpr::var, it->second );
    1577 
    15781535}
    15791536
     
    15871544/// * Inserts dynamic calculation of polymorphic type layouts where needed.
    15881545struct PolyGenericCalculator final :
    1589                 public BoxPass,
    15901546                public ast::WithConstTypeSubstitution,
    15911547                public ast::WithDeclsToAdd<>,
     
    15951551        PolyGenericCalculator();
    15961552
    1597         void previsit( ast::ObjectDecl const * decl );
    15981553        void previsit( ast::FunctionDecl const * decl );
    15991554        void previsit( ast::TypedefDecl const * decl );
     
    16021557        ast::StructDecl const * previsit( ast::StructDecl const * decl );
    16031558        ast::UnionDecl const * previsit( ast::UnionDecl const * decl );
    1604         void previsit( ast::PointerType const * type );
    1605         void previsit( ast::FunctionType const * type );
    16061559        ast::DeclStmt const * previsit( ast::DeclStmt const * stmt );
    16071560        ast::Expr const * postvisit( ast::MemberExpr const * expr );
     
    16351588        /// C sizeof().
    16361589        ast::Expr const * genSizeof( CodeLocation const &, ast::Type const * );
    1637 
    16381590        /// Enters a new scope for type-variables,
    16391591        /// adding the type variables from the provided type.
    16401592        void beginTypeScope( ast::Type const * );
    1641         /// Enters a new scope for known layouts and offsets, and queues exit calls.
    1642         void beginGenericScope();
    1643 
     1593
     1594        /// The type variables and polymorphic parameters currently in scope.
     1595        TypeVarMap scopeTypeVars;
    16441596        /// Set of generic type layouts known in the current scope,
    16451597        /// indexed by sizeofName.
     
    16521604        /// If the argument of an AddressExpr is MemberExpr, it is stored here.
    16531605        ast::MemberExpr const * addrMember = nullptr;
    1654         /// Used to avoid recursing too deep in type declarations.
    1655         bool expect_func_type = false;
    16561606};
    16571607
     
    16751625}
    16761626
    1677 void PolyGenericCalculator::previsit( ast::ObjectDecl const * decl ) {
    1678         beginTypeScope( decl->type );
    1679 }
    1680 
    16811627void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) {
    1682         beginGenericScope();
     1628        GuardScope( *this );
    16831629        beginTypeScope( decl->type );
    16841630}
     
    16961642                ast::TypeDecl const * decl ) {
    16971643        ast::Type const * base = decl->base;
    1698         if ( nullptr == base) return decl;
     1644        if ( nullptr == base ) return decl;
    16991645
    17001646        // Add size/align variables for opaque type declarations.
     
    17211667        alignDecl->accept( *visitor );
    17221668
    1723         // Can't use [makeVar], because it inserts into stmtsToAdd and TypeDecls
    1724         // can occur at global scope.
     1669        // A little trick to replace this with two declarations.
     1670        // Adding after makes sure that there is no conflict with adding stmts.
    17251671        declsToAddAfter.push_back( alignDecl );
    1726         // replace with sizeDecl.
    17271672        return sizeDecl;
    17281673}
     
    17421687}
    17431688
    1744 void PolyGenericCalculator::previsit( ast::PointerType const * type ) {
    1745         beginTypeScope( type );
    1746 }
    1747 
    1748 void 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 ) {
    17611689ast::DeclStmt const * PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {
    17621690        ast::ObjectDecl const * decl = stmt->decl.as<ast::ObjectDecl>();
     
    17661694
    17671695        // Change initialization of a polymorphic value object to allocate via a
    1768         // variable-length-array (alloca was previouly used, but it cannot be
    1769         // safely used in loops).
     1696        // variable-length-array (alloca cannot be safely used in loops).
    17701697        ast::ObjectDecl * newBuf = new ast::ObjectDecl( decl->location,
    17711698                bufNamer.newName(),
     
    22482175}
    22492176
    2250 void 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 
    22582177// --------------------------------------------------------------------------
    2259 /// No common theme found.
     2178/// Removes unneeded or incorrect type information.
    22602179/// * Replaces initialization of polymorphic values with alloca.
    22612180/// * Replaces declaration of dtype/ftype with appropriate void expression.
     
    22632182/// * Strips fields from generic structure declarations.
    22642183struct Eraser final :
    2265                 public BoxPass,
    22662184                public ast::WithGuards {
    22672185        void guardTypeVarMap( ast::Type const * type ) {
     
    22782196        void previsit( ast::PointerType const * type );
    22792197        void previsit( ast::FunctionType const * type );
     2198public:
     2199        TypeVarMap scopeTypeVars;
    22802200};
    22812201
Note: See TracChangeset for help on using the changeset viewer.