Changeset 134322e


Ignore:
Timestamp:
Jun 1, 2017, 4:26:50 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
676cc8c
Parents:
3fb9a83
Message:

Refactored PassVisitor? to properly support env and statements to add

Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/Common/PassVisitor.h

    r3fb9a83 r134322e  
    220220        void set_env( TypeSubstitution * env ) { set_env_impl( pass, env, 0); }
    221221
     222        void visitStatementList( std::list< Statement* > &statements );
    222223        void mutateStatementList( std::list< Statement* > &statements );
     224
     225        Statement * visitStatement( Statement * stmt );
    223226        Statement * mutateStatement( Statement * stmt );
     227
     228        void visitExpression( Expression * expr );
    224229        Expression * mutateExpression( Expression * expr );
    225230
    226 private:
    227         TypeSubstitution * env;
    228 
    229         std::list< Statement* > stmtsToAdd;
    230         std::list< Statement* > stmtsToAddAfter;
     231
     232        TypeSubstitution **             get_env_ptr    () { return env_impl             ( pass, 0); }
     233        std::list< Statement* > *       get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); }
     234        std::list< Statement* > *       get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
    231235};
    232236
  • src/Common/PassVisitor.impl.h

    r3fb9a83 r134322e  
    2020        MUTATE_END( type, node );   \
    2121
     22
     23
     24template<typename T>
     25static inline bool empty( T * ptr ) {
     26        return !ptr || ptr->empty();
     27}
     28
     29typedef std::list< Statement * > StmtList_t;
     30
     31template< typename pass_type >
     32void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) {
     33        SemanticError errors;
     34
     35        StmtList_t* beforeStmts = get_beforeStmts();
     36        StmtList_t* afterStmts  = get_afterStmts();
     37
     38        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
     39                if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
     40                try {
     41                        *i = (*i)->accept( *this );
     42                } catch ( SemanticError &e ) {
     43                        errors.append( e );
     44                }
     45                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
     46        }
     47
     48        if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
     49        if ( !errors.isEmpty() ) { throw errors; }
     50}
     51
    2252template< typename pass_type >
    2353void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
    2454        SemanticError errors;
    2555
     56        StmtList_t* beforeStmts = get_beforeStmts();
     57        StmtList_t* afterStmts  = get_afterStmts();
     58
    2659        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    27                 if ( ! stmtsToAddAfter.empty() ) {
    28                         statements.splice( i, stmtsToAddAfter );
    29                 } // if
     60                if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
    3061                try {
    3162                        *i = (*i)->acceptMutator( *this );
    3263                } catch ( SemanticError &e ) {
    3364                        errors.append( e );
    34                 } // try
    35                 if ( ! stmtsToAdd.empty() ) {
    36                         statements.splice( i, stmtsToAdd );
    37                 } // if
    38         } // for
    39         if ( ! stmtsToAddAfter.empty() ) {
    40                 statements.splice( statements.end(), stmtsToAddAfter );
    41         } // if
    42         if ( ! errors.isEmpty() ) {
    43                 throw errors;
     65                }
     66                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
    4467        }
     68
     69        if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); }
     70        if ( !errors.isEmpty() ) { throw errors; }
     71}
     72
     73template< typename pass_type >
     74Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
     75        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     76        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     77        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
     78        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     79
     80        Statement *newStmt = maybeVisit( stmt, *this );
     81
     82        StmtList_t* beforeStmts = get_beforeStmts();
     83        StmtList_t* afterStmts  = get_afterStmts();
     84
     85        if( empty(beforeStmts) && empty(afterStmts) ) { return newStmt; }
     86
     87        CompoundStmt *compound = new CompoundStmt( noLabels );
     88        if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
     89        compound->get_kids().push_back( newStmt );
     90        if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
     91        return compound;
    4592}
    4693
     
    4895Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
    4996        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    50         ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd );
    51         ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter );
    52         ValueGuard< TypeSubstitution * > oldEnv( env );
    53         set_env( env );
    54 
    55         stmtsToAdd.clear();
    56         stmtsToAddAfter.clear();
     97        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     98        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
     99        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    57100
    58101        Statement *newStmt = maybeMutate( stmt, *this );
    59         if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) {
    60                 CompoundStmt *compound = new CompoundStmt( noLabels );
    61                 compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd );
    62                 compound->get_kids().push_back( newStmt );
    63                 compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter );
    64                 // doEndScope();
    65                 return compound;
    66         } else {
    67                 return newStmt;
     102
     103        StmtList_t* beforeStmts = get_beforeStmts();
     104        StmtList_t* afterStmts  = get_afterStmts();
     105
     106        if( empty(beforeStmts) && empty(afterStmts) ) { return newStmt; }
     107
     108        CompoundStmt *compound = new CompoundStmt( noLabels );
     109        if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); }
     110        compound->get_kids().push_back( newStmt );
     111        if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); }
     112        return compound;
     113}
     114
     115
     116
     117template< typename pass_type >
     118void PassVisitor< pass_type >::visitExpression( Expression * expr ) {
     119        if( !expr ) return;
     120
     121        auto env_ptr = get_env_ptr();
     122        if ( env_ptr && expr->get_env() ) {
     123                *env_ptr = expr->get_env();
    68124        }
     125        // xxx - should env be cloned (or moved) onto the result of the mutate?
     126        expr->accept( *this );
    69127}
    70128
     
    73131        if( !expr ) return nullptr;
    74132
    75         if ( expr->get_env() ) {
    76                 env = expr->get_env();
    77                 set_env( env );
     133        auto env_ptr = get_env_ptr();
     134        if ( env_ptr && expr->get_env() ) {
     135                *env_ptr = expr->get_env();
    78136        }
    79137        // xxx - should env be cloned (or moved) onto the result of the mutate?
     
    488546       
    489547        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    490         ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd );
    491         ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter );
    492         ValueGuard< TypeSubstitution * > oldEnv( env );
    493         set_env( env );
    494 
    495         // xxx - not sure if this is needed, along with appropriate reset, but I don't think so...
    496         // ValueGuard< TyVarMap > oldScopeTyVars( scopeTyVars );
    497 
    498         stmtsToAdd.clear();
    499         stmtsToAddAfter.clear();
    500         // scopeTyVars.clear();
     548        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     549        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
     550        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
    501551
    502552        Mutator::mutate( node );
  • src/Common/PassVisitor.proto.h

    r3fb9a83 r134322e  
    7070static inline void end_scope_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) {}
    7171
    72 // Env
    73 template<typename pass_type>
    74 static inline auto set_env_impl( pass_type& pass, TypeSubstitution * env, __attribute__((unused)) int unused ) ->decltype( pass.env, void() ) {
    75         pass.env = env;
    76 }
     72// Fields
     73#define FIELD_PTR( type, name )                                                                                                                  \
     74template<typename pass_type>                                                                                                                     \
     75static inline auto name##_impl( pass_type& pass, __attribute__((unused)) int unused ) ->decltype( &pass.name ) { return &pass.name; }          \
     76                                                                                                                                                 \
     77template<typename pass_type>                                                                                                                     \
     78static inline type * name##_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) { return nullptr;}    \
    7779
    78 template<typename pass_type>
    79 static inline void set_env_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) TypeSubstitution * env, __attribute__((unused)) long unused ) {}
     80FIELD_PTR( TypeSubstitution *, env )
     81FIELD_PTR( std::list< Statement* >, stmtsToAddBefore )
     82FIELD_PTR( std::list< Statement* >, stmtsToAddAfter  )
  • src/Common/utility.h

    r3fb9a83 r134322e  
    244244        ValueGuard(T& inRef) : old(inRef), ref(inRef) {}
    245245        ~ValueGuard() { ref = old; }
     246};
     247
     248template< typename T >
     249struct ValueGuardPtr {
     250        T old;
     251        T* ref;
     252
     253        ValueGuardPtr(T * inRef) : old( inRef ? *inRef : T() ), ref(inRef) {}
     254        ~ValueGuardPtr() { if( ref ) *ref = old; }
     255};
     256
     257template< typename T >
     258struct ValueGuardPtr< std::list< T > > {
     259        std::list< T > old;
     260        std::list< T >* ref;
     261
     262        ValueGuardPtr( std::list< T > * inRef) : old(), ref(inRef) {
     263                if( ref ) { swap( *ref, old ); }
     264        }
     265        ~ValueGuardPtr() { if( ref ) { swap( *ref, old ); } }
    246266};
    247267
  • src/InitTweak/FixInit.cc

    r3fb9a83 r134322e  
    2020#include <unordered_map>
    2121#include <unordered_set>
     22
    2223#include "InitTweak.h"
    2324#include "GenInit.h"
    2425#include "FixInit.h"
    2526#include "FixGlobalInit.h"
     27#include "CodeGen/GenType.h"  // for warning/error messages
     28#include "Common/PassVisitor.h"
     29#include "GenPoly/DeclMutator.h"
     30#include "GenPoly/PolyMutator.h"
    2631#include "ResolvExpr/Resolver.h"
    2732#include "ResolvExpr/typeops.h"
     33#include "SymTab/Autogen.h"
     34#include "SymTab/Indexer.h"
     35#include "SynTree/AddStmtVisitor.h"
     36#include "SynTree/Attribute.h"
    2837#include "SynTree/Declaration.h"
    29 #include "SynTree/Type.h"
    3038#include "SynTree/Expression.h"
    31 #include "SynTree/Attribute.h"
    32 #include "SynTree/Statement.h"
    3339#include "SynTree/Initializer.h"
    3440#include "SynTree/Mutator.h"
    35 #include "SymTab/Indexer.h"
    36 #include "SymTab/Autogen.h"
    37 #include "GenPoly/PolyMutator.h"
    38 #include "GenPoly/DeclMutator.h"
    39 #include "SynTree/AddStmtVisitor.h"
    40 #include "CodeGen/GenType.h"  // for warning/error messages
     41#include "SynTree/Statement.h"
     42#include "SynTree/Type.h"
    4143#include "Tuples/Tuples.h"
    4244
     
    5456                typedef std::unordered_map< int, int > UnqCount;
    5557
    56                 class InsertImplicitCalls final : public GenPoly::PolyMutator {
     58                class InsertImplicitCalls {
    5759                public:
    5860                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
     
    6163
    6264                        InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {}
    63                         typedef GenPoly::PolyMutator Parent;
    64                         using Parent::mutate;
    65                         virtual Expression * mutate( ApplicationExpr * appExpr ) override;
    66                         virtual Expression * mutate( StmtExpr * stmtExpr ) override;
     65
     66                        Expression * postmutate( ApplicationExpr * appExpr );
     67                        void premutate( StmtExpr * stmtExpr );
    6768
    6869                        // collects environments for relevant nodes
    6970                        EnvMap & envMap;
     71                        TypeSubstitution * env; //Magically populated by the PassVisitor
    7072                };
    7173
     
    300302        namespace {
    301303                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) {
    302                         InsertImplicitCalls inserter( envMap );
     304                        PassVisitor<InsertImplicitCalls> inserter( envMap );
    303305                        mutateAll( translationUnit, inserter );
    304306                }
     
    350352                }
    351353
    352                 Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) {
    353                         appExpr = dynamic_cast< ApplicationExpr * >( Parent::mutate( appExpr ) );
     354                Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) {
    354355                        assert( appExpr );
    355356
     
    393394                }
    394395
    395                 Expression * InsertImplicitCalls::mutate( StmtExpr * stmtExpr ) {
     396                void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) {
    396397                        assert( env );
    397398                        envMap[stmtExpr] = env;
    398                         return Parent::mutate( stmtExpr );
    399399                }
    400400
Note: See TracChangeset for help on using the changeset viewer.