Ignore:
Timestamp:
Sep 18, 2017, 11:02:23 AM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
6994d8c
Parents:
ed235b6 (diff), 5f782f7 (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/InitTweak/FixInit.cc

    red235b6 r8024bc8  
    7070namespace InitTweak {
    7171        namespace {
    72                 typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;
    7372                typedef std::unordered_map< int, int > UnqCount;
    7473
    75                 class InsertImplicitCalls : public WithTypeSubstitution {
    76                 public:
     74                struct InsertImplicitCalls : public WithTypeSubstitution {
    7775                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
    7876                        /// function calls need their parameters to be copy constructed
    79                         static void insert( std::list< Declaration * > & translationUnit, EnvMap & envMap );
    80 
    81                         InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {}
     77                        static void insert( std::list< Declaration * > & translationUnit );
    8278
    8379                        Expression * postmutate( ApplicationExpr * appExpr );
    84                         void premutate( StmtExpr * stmtExpr );
    85 
    86                         // collects environments for relevant nodes
    87                         EnvMap & envMap;
    8880                };
    8981
    90                 class ResolveCopyCtors final : public SymTab::Indexer {
    91                 public:
     82                struct ResolveCopyCtors final : public WithIndexer, public WithShortCircuiting, public WithTypeSubstitution {
    9283                        /// generate temporary ObjectDecls for each argument and return value of each ImplicitCopyCtorExpr,
    9384                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
    9485                        /// arguments and return value temporaries
    95                         static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount );
    96 
    97                         typedef SymTab::Indexer Parent;
    98                         using Parent::visit;
    99 
    100                         ResolveCopyCtors( const EnvMap & envMap, UnqCount & unqCount ) : envMap( envMap ), unqCount( unqCount ) {}
    101 
    102                         virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override;
    103                         virtual void visit( UniqueExpr * unqExpr ) override;
    104                         virtual void visit( StmtExpr * stmtExpr ) override;
     86                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount );
     87
     88                        ResolveCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ) {}
     89
     90                        void postvisit( ImplicitCopyCtorExpr * impCpCtorExpr );
     91                        void postvisit( StmtExpr * stmtExpr );
     92                        void previsit( UniqueExpr * unqExpr );
     93                        void postvisit( UniqueExpr * unqExpr );
    10594
    10695                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
     
    111100                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    112101
    113                         TypeSubstitution * env;
    114                         const EnvMap & envMap;
    115102                        UnqCount & unqCount; // count the number of times each unique expr ID appears
     103                        std::unordered_set< int > vars;
    116104                };
    117105
     
    238226                };
    239227
    240                 class GenStructMemberCalls final : public SymTab::Indexer {
    241                   public:
    242                         typedef Indexer Parent;
     228                struct GenStructMemberCalls final : public WithGuards, public WithShortCircuiting, public WithIndexer {
    243229                        /// generate default/copy ctor and dtor calls for user-defined struct ctor/dtors
    244230                        /// for any member that is missing a corresponding ctor/dtor call.
     
    246232                        static void generate( std::list< Declaration * > & translationUnit );
    247233
    248                         using Parent::visit;
    249 
    250                         virtual void visit( FunctionDecl * funcDecl ) override;
    251 
    252                         virtual void visit( MemberExpr * memberExpr ) override;
    253                         virtual void visit( ApplicationExpr * appExpr ) override;
     234                        void previsit( FunctionDecl * funcDecl );
     235                        void postvisit( FunctionDecl * funcDecl );
     236
     237                        void previsit( MemberExpr * memberExpr );
     238                        void previsit( ApplicationExpr * appExpr );
    254239
    255240                        SemanticError errors;
     
    295280                InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
    296281
    297                 EnvMap envMap;
    298282                UnqCount unqCount;
    299283
    300                 InsertImplicitCalls::insert( translationUnit, envMap );
    301                 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap, unqCount );
     284                InsertImplicitCalls::insert( translationUnit );
     285                ResolveCopyCtors::resolveImplicitCalls( translationUnit, unqCount );
    302286                InsertDtors::insert( translationUnit );
    303287                FixInit::fixInitializers( translationUnit );
     
    318302
    319303        namespace {
    320                 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) {
    321                         PassVisitor<InsertImplicitCalls> inserter( envMap );
     304                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {
     305                        PassVisitor<InsertImplicitCalls> inserter;
    322306                        mutateAll( translationUnit, inserter );
    323307                }
    324308
    325                 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount ) {
    326                         ResolveCopyCtors resolver( envMap, unqCount );
     309                void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
     310                        PassVisitor<ResolveCopyCtors> resolver( unqCount );
    327311                        acceptAll( translationUnit, resolver );
    328312                }
     
    360344
    361345                void GenStructMemberCalls::generate( std::list< Declaration * > & translationUnit ) {
    362                         GenStructMemberCalls warner;
     346                        PassVisitor<GenStructMemberCalls> warner;
    363347                        acceptAll( translationUnit, warner );
    364348                }
     
    398382                        // wrap each function call so that it is easy to identify nodes that have to be copy constructed
    399383                        ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr );
    400                         // save the type substitution into the envMap so that it is easy to find.
     384                        // Move the type substitution to the new top-level, if it is attached to the appExpr.
    401385                        // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion.
    402386                        // The substitution is needed to obtain the type of temporary variables so that copy constructor
    403                         // calls can be resolved. Normally this is what PolyMutator is for, but the pass that resolves
    404                         // copy constructor calls must be an Indexer. We could alternatively make a PolyIndexer which
    405                         // saves the environment, or compute the types of temporaries here, but it's much simpler to
    406                         // save the environment here, and more cohesive to compute temporary variables and resolve copy
    407                         // constructor calls together.
     387                        // calls can be resolved.
    408388                        assert( env );
    409                         envMap[expr] = env;
     389                        std::swap( expr->env, appExpr->env );
    410390                        return expr;
    411                 }
    412 
    413                 void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) {
    414                         assert( env );
    415                         envMap[stmtExpr] = env;
    416391                }
    417392
     
    431406                        // (VariableExpr and already resolved expression)
    432407                        CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; )
    433                         Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this );
     408                        Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer );
    434409                        assert( resolved );
    435410                        if ( resolved->get_env() ) {
     
    480455                }
    481456
    482                 void ResolveCopyCtors::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     457                void ResolveCopyCtors::postvisit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    483458                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    484                         Parent::visit( impCpCtorExpr );
    485                         env = envMap.at(impCpCtorExpr);
    486                         assert( env );
    487459
    488460                        ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr();
     
    513485                }
    514486
    515                 void ResolveCopyCtors::visit( StmtExpr * stmtExpr ) {
    516                         Parent::visit( stmtExpr );
    517                         env = envMap.at(stmtExpr);
     487                void ResolveCopyCtors::postvisit( StmtExpr * stmtExpr ) {
     488                        assert( env );
    518489                        assert( stmtExpr->get_result() );
    519490                        Type * result = stmtExpr->get_result();
     
    537508                                stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    538509                        } // if
    539 
    540                 }
    541 
    542                 void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) {
    543                         static std::unordered_set< int > vars;
     510                }
     511
     512                void ResolveCopyCtors::previsit( UniqueExpr * unqExpr ) {
    544513                        unqCount[ unqExpr->get_id() ]++;  // count the number of unique expressions for each ID
    545514                        if ( vars.count( unqExpr->get_id() ) ) {
    546515                                // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
     516                                visit_children = false;
     517                        }
     518                }
     519
     520                void ResolveCopyCtors::postvisit( UniqueExpr * unqExpr ) {
     521                        if ( vars.count( unqExpr->get_id() ) ) {
     522                                // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
    547523                                return;
    548524                        }
    549525
    550                         Parent::visit( unqExpr );
    551526                        // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought
    552527                        assert( unqExpr->get_result() );
     
    585560
    586561                        // xxx - update to work with multiple return values
    587                         ObjectDecl * returnDecl = returnDecls.empty() ? NULL : returnDecls.front();
     562                        ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
    588563                        Expression * callExpr = impCpCtorExpr->get_callExpr();
    589564
     
    594569                        tempDecls.clear();
    595570                        returnDecls.clear();
    596                         impCpCtorExpr->set_callExpr( NULL );
    597                         impCpCtorExpr->set_env( NULL );
     571                        impCpCtorExpr->set_callExpr( nullptr );
     572                        std::swap( impCpCtorExpr->env, callExpr->env );
     573                        assert( impCpCtorExpr->env == nullptr );
    598574                        delete impCpCtorExpr;
    599575
     
    978954                }
    979955
    980                 void GenStructMemberCalls::visit( FunctionDecl * funcDecl ) {
    981                         ValueGuard< FunctionDecl * > oldFunction( funcDecl );
    982                         ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled );
    983                         ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit );
    984                         ValueGuard< ObjectDecl * > oldThisParam( thisParam );
    985                         ValueGuard< bool > oldIsCtor( isCtor );
    986                         ValueGuard< StructDecl * > oldStructDecl( structDecl );
     956                void GenStructMemberCalls::previsit( FunctionDecl * funcDecl ) {
     957                        GuardValue( funcDecl );
     958                        GuardValue( unhandled );
     959                        GuardValue( usedUninit );
     960                        GuardValue( thisParam );
     961                        GuardValue( isCtor );
     962                        GuardValue( structDecl );
    987963                        errors = SemanticError();  // clear previous errors
    988964
     
    1010986                                }
    1011987                        }
    1012                         Parent::visit( function );
    1013 
     988                }
     989
     990                void addIds( SymTab::Indexer & indexer, const std::list< DeclarationWithType * > & decls ) {
     991                        for ( auto d : decls ) {
     992                                indexer.addId( d );
     993                        }
     994                }
     995
     996                void addTypes( SymTab::Indexer & indexer, const std::list< TypeDecl * > & tds ) {
     997                        for ( auto td : tds ) {
     998                                indexer.addType( td );
     999                                addIds( indexer, td->assertions );
     1000                        }
     1001                }
     1002
     1003                void GenStructMemberCalls::postvisit( FunctionDecl * funcDecl ) {
    10141004                        // remove the unhandled objects from usedUninit, because a call is inserted
    10151005                        // to handle them - only objects that are later constructed are used uninitialized.
     
    10321022                        if ( ! unhandled.empty() ) {
    10331023                                // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors
    1034                                 enterScope();
    1035                                 maybeAccept( function->get_functionType(), *this );
     1024                                auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this]() { indexer.leaveScope(); } );
     1025                                addTypes( indexer, function->type->forall );
     1026                                addIds( indexer, function->type->returnVals );
     1027                                addIds( indexer, function->type->parameters );
    10361028
    10371029                                // need to iterate through members in reverse in order for
     
    10631055                                                Statement * callStmt = stmt.front();
    10641056
    1065                                                 MutatingResolver resolver( *this );
     1057                                                MutatingResolver resolver( indexer );
    10661058                                                try {
    10671059                                                        callStmt->acceptMutator( resolver );
     
    10771069                                        }
    10781070                                }
    1079                                 leaveScope();
    10801071                        }
    10811072                        if (! errors.isEmpty()) {
     
    11071098                }
    11081099
    1109                 void GenStructMemberCalls::visit( ApplicationExpr * appExpr ) {
    1110                         if ( ! checkWarnings( function ) ) return;
     1100                void GenStructMemberCalls::previsit( ApplicationExpr * appExpr ) {
     1101                        if ( ! checkWarnings( function ) ) {
     1102                                visit_children = false;
     1103                                return;
     1104                        }
    11111105
    11121106                        std::string fname = getFunctionName( appExpr );
     
    11271121                                }
    11281122                        }
    1129                         Parent::visit( appExpr );
    1130                 }
    1131 
    1132                 void GenStructMemberCalls::visit( MemberExpr * memberExpr ) {
    1133                         if ( ! checkWarnings( function ) ) return;
    1134                         if ( ! isCtor ) return;
     1123                }
     1124
     1125                void GenStructMemberCalls::previsit( MemberExpr * memberExpr ) {
     1126                        if ( ! checkWarnings( function ) || ! isCtor ) {
     1127                                visit_children = false;
     1128                                return;
     1129                        }
    11351130
    11361131                        if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
     
    11401135                                }
    11411136                        }
    1142                         Parent::visit( memberExpr );
    11431137                }
    11441138
     
    11611155                        // in generated code. If this changes, add mutate methods for entities with
    11621156                        // scope and call {enter,leave}Scope explicitly.
    1163                         objectDecl->accept( indexer );
     1157                        indexer.addId( objectDecl );
    11641158                        return objectDecl;
    11651159                }
Note: See TracChangeset for help on using the changeset viewer.