Changeset 490fb92e for src/InitTweak


Ignore:
Timestamp:
Oct 23, 2020, 9:06:16 PM (3 years ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
37b7d95
Parents:
41b8ea4
Message:

move FixInit? to new ast

Location:
src/InitTweak
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    r41b8ea4 r490fb92e  
    3434#include "SynTree/Visitor.h"       // for acceptAll, Visitor
    3535
     36#include "AST/Expr.hpp"
     37#include "AST/Node.hpp"
     38#include "AST/Pass.hpp"
     39
    3640namespace InitTweak {
    3741        class GlobalFixer : public WithShortCircuiting {
     
    5054                FunctionDecl * initFunction;
    5155                FunctionDecl * destroyFunction;
     56        };
     57
     58        class GlobalFixer_new : public ast::WithShortCircuiting {
     59        public:
     60                void previsit (const ast::ObjectDecl *);
     61                void previsit (const ast::FunctionDecl *) { visit_children = false; }
     62                void previsit (const ast::StructDecl *) { visit_children = false; }
     63                void previsit (const ast::UnionDecl *) { visit_children = false; }
     64                void previsit (const ast::EnumDecl *) { visit_children = false; }
     65                void previsit (const ast::TraitDecl *) { visit_children = false; }
     66                void previsit (const ast::TypeDecl *) { visit_children = false; }
     67
     68                std::list< ast::ptr<ast::Stmt> > initStmts;
     69                std::list< ast::ptr<ast::Stmt> > destroyStmts;
    5270        };
    5371
     
    91109        }
    92110
     111        void fixGlobalInit(std::list<ast::ptr<ast::Decl>> & translationUnit, bool inLibrary) {
     112                ast::Pass<GlobalFixer_new> fixer;
     113                accept_all(translationUnit, fixer);
     114
     115                if ( !fixer.core.initStmts.empty() ) {
     116                        std::vector<ast::ptr<ast::Expr>> ctorParams;
     117                        if (inLibrary) ctorParams.emplace_back(ast::ConstantExpr::from_int({}, 200));
     118                        auto initFunction = new ast::FunctionDecl({}, "__global_init__", {}, {}, {}, new ast::CompoundStmt({}, std::move(fixer.core.initStmts)),
     119                                ast::Storage::Static, ast::Linkage::C, {new ast::Attribute("constructor", std::move(ctorParams))});
     120
     121                        translationUnit.emplace_back( initFunction );
     122                } // if
     123
     124                if ( !fixer.core.destroyStmts.empty() ) {
     125                        std::vector<ast::ptr<ast::Expr>> dtorParams;
     126                        if (inLibrary) dtorParams.emplace_back(ast::ConstantExpr::from_int({}, 200));
     127                        auto destroyFunction = new ast::FunctionDecl({}, "__global_destroy__", {}, {}, {}, new ast::CompoundStmt({}, std::move(fixer.core.destroyStmts)),
     128                                ast::Storage::Static, ast::Linkage::C, {new ast::Attribute("destructor", std::move(dtorParams))});
     129
     130                        translationUnit.emplace_back(destroyFunction);
     131                } // if
     132        }
     133
    93134        void GlobalFixer::previsit( ObjectDecl *objDecl ) {
    94135                std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids();
     
    126167        }
    127168
     169        void GlobalFixer_new::previsit(const ast::ObjectDecl * objDecl) {
     170                auto mutDecl = mutate(objDecl);
     171                assertf(mutDecl == objDecl, "Global object decl must be unique");
     172                if ( auto ctorInit = objDecl->init.as<ast::ConstructorInit>() ) {
     173                        // a decision should have been made by the resolver, so ctor and init are not both non-NULL
     174                        assert( ! ctorInit->ctor || ! ctorInit->init );
     175
     176                        const ast::Stmt * dtor = ctorInit->dtor;
     177                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
     178                                // don't need to call intrinsic dtor, because it does nothing, but
     179                                // non-intrinsic dtors must be called
     180                                destroyStmts.push_front( dtor );
     181                                // ctorInit->dtor = nullptr;
     182                        } // if
     183                        if ( const ast::Stmt * ctor = ctorInit->ctor ) {
     184                                initStmts.push_back( ctor );
     185                                mutDecl->init = nullptr;
     186                                // ctorInit->ctor = nullptr;
     187                        } else if ( const ast::Init * init = ctorInit->init ) {
     188                                mutDecl->init = init;
     189                                // ctorInit->init = nullptr;
     190                        } else {
     191                                // no constructor and no initializer, which is okay
     192                                mutDecl->init = nullptr;
     193                        } // if
     194                        // delete ctorInit;
     195                } // if
     196        }
     197
    128198        // only modify global variables
    129199        void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; }
  • src/InitTweak/FixGlobalInit.h

    r41b8ea4 r490fb92e  
    1919#include <string>  // for string
    2020
     21#include <AST/Fwd.hpp>
     22
     23
    2124class Declaration;
    2225
     
    2629        /// function is for library code.
    2730        void fixGlobalInit( std::list< Declaration * > & translationUnit, bool inLibrary );
     31        void fixGlobalInit( std::list< ast::ptr<ast::Decl> > & translationUnit, bool inLibrary );
    2832} // namespace
    2933
  • src/InitTweak/FixInit.cc

    r41b8ea4 r490fb92e  
    219219                };
    220220
    221                 struct SplitExpressions : public WithShortCircuiting, public WithTypeSubstitution, public WithStmtsToAdd {
     221                struct SplitExpressions : public WithShortCircuiting, /*public WithTypeSubstitution, */public WithStmtsToAdd {
    222222                        /// add CompoundStmts around top-level expressions so that temporaries are destroyed in the correct places.
    223223                        static void split( std::list< Declaration * > &translationUnit );
  • src/InitTweak/FixInit.h

    r41b8ea4 r490fb92e  
    1919#include <string>  // for string
    2020
     21#include <AST/Fwd.hpp>
     22
    2123class Declaration;
    2224
     
    2426        /// replace constructor initializers with expression statements and unwrap basic C-style initializers
    2527        void fix( std::list< Declaration * > & translationUnit, bool inLibrary );
     28
     29        void fix( std::list<ast::ptr<ast::Decl>> & translationUnit, bool inLibrary);
    2630} // namespace
    2731
  • src/InitTweak/GenInit.cc

    r41b8ea4 r490fb92e  
    283283                assert( stmts.size() <= 1 );
    284284                return stmts.size() == 1 ? strict_dynamic_cast< ImplicitCtorDtorStmt * >( stmts.front() ) : nullptr;
     285
     286        }
     287
     288        ast::ptr<ast::Stmt> genCtorDtor (const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * objDecl, const ast::Expr * arg) {
     289                assertf(objDecl, "genCtorDtor passed null objDecl");
     290                InitExpander_new srcParam(arg);
     291                return SymTab::genImplicitCall(srcParam, new ast::VariableExpr(loc, objDecl), loc, fname, objDecl);
    285292        }
    286293
  • src/InitTweak/GenInit.h

    r41b8ea4 r490fb92e  
    3333        /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
    3434        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
     35        ast::ptr<ast::Stmt> genCtorDtor (const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * objDecl, const ast::Expr * arg = nullptr);
    3536
    3637        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
  • src/InitTweak/InitTweak.cc

    r41b8ea4 r490fb92e  
    498498        }
    499499
     500        const ast::ObjectDecl * getParamThis(const ast::FunctionDecl * func) {
     501                assertf( func, "getParamThis: nullptr ftype" );
     502                auto & params = func->params;
     503                assertf( ! params.empty(), "getParamThis: ftype with 0 parameters: %s", toString( func ).c_str());
     504                return params.front().strict_as<ast::ObjectDecl>();
     505        }
     506
    500507        bool tryConstruct( DeclarationWithType * dwt ) {
    501508                ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt );
     
    511518        }
    512519
     520        bool tryConstruct( const ast::DeclWithType * dwt ) {
     521                auto objDecl = dynamic_cast< const ast::ObjectDecl * >( dwt );
     522                if ( ! objDecl ) return false;
     523                return (objDecl->init == nullptr ||
     524                                ( objDecl->init != nullptr && objDecl->init->maybeConstructed ))
     525                        && ! objDecl->storage.is_extern
     526                        && isConstructable( objDecl->type );
     527        }
     528
     529        bool isConstructable( const ast::Type * type ) {
     530                return ! dynamic_cast< const ast::VarArgsType * >( type ) && ! dynamic_cast< const ast::ReferenceType * >( type )
     531                && ! dynamic_cast< const ast::FunctionType * >( type ) && ! Tuples::isTtype( type );
     532        }
     533
    513534        struct CallFinder_old {
    514535                CallFinder_old( const std::list< std::string > & names ) : names( names ) {}
     
    536557
    537558        struct CallFinder_new final {
    538                 std::vector< ast::ptr< ast::Expr > > matches;
     559                std::vector< const ast::Expr * > matches;
    539560                const std::vector< std::string > names;
    540561
     
    558579        }
    559580
    560         std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ) {
     581        std::vector< const ast::Expr * > collectCtorDtorCalls( const ast::Stmt * stmt ) {
    561582                ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } };
    562583                maybe_accept( stmt, finder );
     
    696717                template <typename Predicate>
    697718                bool allofCtorDtor( const ast::Stmt * stmt, const Predicate & pred ) {
    698                         std::vector< ast::ptr< ast::Expr > > callExprs = collectCtorDtorCalls( stmt );
     719                        std::vector< const ast::Expr * > callExprs = collectCtorDtorCalls( stmt );
    699720                        return std::all_of( callExprs.begin(), callExprs.end(), pred );
    700721                }
     
    939960        }
    940961
     962        // looks like some other such codegen uses UntypedExpr and does not create fake function. should revisit afterwards
     963        // following passes may accidentally resolve this expression if returned as untyped...
     964        ast::Expr * createBitwiseAssignment (const ast::Expr * dst, const ast::Expr * src) {
     965                static ast::ptr<ast::FunctionDecl> assign = nullptr;
     966                if (!assign) {
     967                        auto td = new ast::TypeDecl({}, "T", {}, nullptr, ast::TypeDecl::Dtype, true);
     968                        assign = new ast::FunctionDecl({}, "?=?", {},
     969                        { new ast::ObjectDecl({}, "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))),
     970                          new ast::ObjectDecl({}, "_src", new ast::TypeInstType("T", td))},
     971                        { new ast::ObjectDecl({}, "_ret", new ast::TypeInstType("T", td))}, nullptr, {}, ast::Linkage::Intrinsic);
     972                }
     973                if (dst->result.as<ast::ReferenceType>()) {
     974                        for (int depth = dst->result->referenceDepth(); depth > 0; depth--) {
     975                                dst = new ast::AddressExpr(dst);
     976                        }
     977                }
     978                else {
     979                        dst = new ast::CastExpr(dst, new ast::ReferenceType(dst->result, {}));
     980                }
     981                if (src->result.as<ast::ReferenceType>()) {
     982                        for (int depth = src->result->referenceDepth(); depth > 0; depth--) {
     983                                src = new ast::AddressExpr(src);
     984                        }
     985                }
     986                return new ast::ApplicationExpr(dst->location, ast::VariableExpr::functionPointer(dst->location, assign), {dst, src});
     987        }
     988
    941989        struct ConstExprChecker : public WithShortCircuiting {
    942990                // most expressions are not const expr
  • src/InitTweak/InitTweak.h

    r41b8ea4 r490fb92e  
    3838        /// returns the first parameter of a constructor/destructor/assignment function
    3939        ObjectDecl * getParamThis( FunctionType * ftype );
     40        const ast::ObjectDecl * getParamThis(const ast::FunctionDecl * func);
    4041
    4142        /// generate a bitwise assignment operation.
    4243        ApplicationExpr * createBitwiseAssignment( Expression * dst, Expression * src );
     44
     45        ast::Expr * createBitwiseAssignment( const ast::Expr * dst, const ast::Expr * src);
    4346
    4447        /// transform Initializer into an argument list that can be passed to a call expression
     
    4851        /// True if the resolver should try to construct dwt
    4952        bool tryConstruct( DeclarationWithType * dwt );
     53        bool tryConstruct( const ast::DeclWithType * dwt );
    5054
    5155        /// True if the type can have a user-defined constructor
    5256        bool isConstructable( Type * t );
     57        bool isConstructable( const ast::Type * t );
    5358
    5459        /// True if the Initializer contains designations
     
    7984        /// get all Ctor/Dtor call expressions from a Statement
    8085        void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches );
    81         std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt );
     86        std::vector< const ast::Expr * > collectCtorDtorCalls( const ast::Stmt * stmt );
    8287
    8388        /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
  • src/InitTweak/module.mk

    r41b8ea4 r490fb92e  
    2323        InitTweak/GenInit.h \
    2424        InitTweak/InitTweak.cc \
    25         InitTweak/InitTweak.h
     25        InitTweak/InitTweak.h \
     26        InitTweak/FixInitNew.cpp
    2627
    2728SRCDEMANGLE += \
Note: See TracChangeset for help on using the changeset viewer.