Changeset 296b2be


Ignore:
Timestamp:
Jun 1, 2017, 1:35:58 PM (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:
5013c62
Parents:
ab904dc
Message:

PassVisitor? now supports features given by PolyMutator?

Location:
src/Common
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • src/Common/PassVisitor.h

    rab904dc r296b2be  
    11#pragma once
     2
     3#include <stack>
    24
    35#include "SynTree/Mutator.h"
     
    1113#include "SynTree/Constant.h"
    1214
    13 //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    14 // Deep magic (a.k.a template meta programming) to make the templated visitor work
    15 // Basically the goal is to make 2 previsit_impl
    16 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
    17 //     'pass.previsit( node )' that compiles will be used for that node for that type
    18 //     This requires that this option only compile for passes that actually define an appropriate visit.
    19 //     SFINAE will make sure the compilation errors in this function don't halt the build.
    20 //     See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE
    21 // 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing.
    22 //     This is needed only to eliminate the need for passes to specify any kind of handlers.
    23 //     The second implementation only works because it has a lower priority. This is due to the bogus last parameter.
    24 //     The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0
    25 //     the first implementation takes priority in regards to overloading.
    26 // Mutator functions work along the same principal
    27 //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    28 // Visit
    29 template<typename pass_type, typename node_type>
    30 static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.previsit( node ), void() ) {
    31         pass.previsit( node );
    32 }
    33 
    34 template<typename pass_type, typename node_type>
    35 static inline void previsit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
    36 
    37 
    38 template<typename pass_type, typename node_type>
    39 static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postvisit( node ), void() ) {
    40         pass.postvisit( node );
    41 }
    42 
    43 template<typename pass_type, typename node_type>
    44 static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
    45 
    46 // Mutate
    47 template<typename pass_type, typename node_type>
    48 static inline auto premutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.premutate( node ), void() ) {
    49         return pass.premutate( node );
    50 }
    51 
    52 template<typename pass_type, typename node_type>
    53 static inline void premutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {}
    54 
    55 
    56 template<typename return_type, typename pass_type, typename node_type>
    57 static inline auto postmutate_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postmutate( node ) ) {
    58         return pass.postmutate( node );
    59 }
    60 
    61 template<typename return_type, typename pass_type, typename node_type>
    62 static inline return_type postmutate_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) { return node; }
     15#include "PassVisitor.proto.h"
    6316
    6417//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    256209
    257210private:
    258         template<typename node_type>
    259         auto call_previsit ( node_type * node )
    260                 -> decltype( previsit_impl ( pass, node, 0 ), void() )
    261         {
    262                 previsit_impl ( pass, node, 0 );
    263         }
    264 
    265         template<typename node_type>
    266         auto call_postvisit( node_type * node )
    267                 -> decltype( postvisit_impl( pass, node, 0 ), void() )
    268         {
    269                 postvisit_impl( pass, node, 0 );
    270         }
    271 
    272         template<typename node_type>
    273         auto call_premutate ( node_type * node )
    274                 -> decltype( premutate_impl( pass, node, 0 ), void() )
    275         {
    276                 premutate_impl( pass, node, 0 );
    277         }
    278 
    279         template<typename return_type, typename node_type>
    280         auto call_postmutate ( node_type * node )
    281                 -> decltype( postmutate_impl<return_type>( pass, node, 0 ) )
    282         {
    283                 return postmutate_impl<return_type>( pass, node, 0 );
    284         }
     211        template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
     212        template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); }
     213
     214        template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); }
     215        template<typename return_type, typename node_type> return_type call_postmutate ( node_type * node ) { return postmutate_impl<return_type>( pass, node, 0 ); }
     216
     217        void call_beginScope() { begin_scope_impl( pass, 0 ); }
     218        void call_endScope  () { end_scope_impl  ( pass, 0 ); }
     219
     220        void mutateStatementList( std::list< Statement* > &statements );
     221        Statement * mutateStatement( Statement * stmt );
     222        Expression * mutateExpression( Expression * expr );
     223
     224private:
     225        TypeSubstitution * env;
     226
     227        std::list< Statement* > stmtsToAdd;
     228        std::list< Statement* > stmtsToAddAfter;
    285229};
    286230
  • src/Common/PassVisitor.impl.h

    rab904dc r296b2be  
    11#pragma once
     2
     3#define MUTATE_START( node )  \
     4        call_premutate( node ); \
     5
     6
     7#define MUTATE_END( type, node )                \
     8        return call_postmutate< type * >( node ); \
     9
    210
    311#define VISIT_BODY( node )    \
     
    614        call_postvisit( node ); \
    715
    8 #define MUTATE_BODY( type, node )                   \
    9         call_premutate( node );                       \
    10         Mutator::mutate( node );                      \
    11         auto ret = call_postmutate< type * >( node ); \
    12         return ret;                                   \
    13 
    14 
    15 
     16
     17#define MUTATE_BODY( type, node ) \
     18        MUTATE_START( node );       \
     19        Mutator::mutate( node );    \
     20        MUTATE_END( type, node );   \
     21
     22template< typename pass_type >
     23void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
     24        SemanticError errors;
     25
     26        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
     27                if ( ! stmtsToAddAfter.empty() ) {
     28                        statements.splice( i, stmtsToAddAfter );
     29                } // if
     30                try {
     31                        *i = (*i)->acceptMutator( *this );
     32                } catch ( SemanticError &e ) {
     33                        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;
     44        }
     45}
     46
     47template< typename pass_type >
     48Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
     49        // 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        stmtsToAdd.clear();
     54        stmtsToAddAfter.clear();
     55
     56        Statement *newStmt = maybeMutate( stmt, *this );
     57        if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) {
     58                CompoundStmt *compound = new CompoundStmt( noLabels );
     59                compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd );
     60                compound->get_kids().push_back( newStmt );
     61                compound->get_kids().splice( compound->get_kids().end(), stmtsToAddAfter );
     62                // doEndScope();
     63                return compound;
     64        } else {
     65                return newStmt;
     66        }
     67}
     68
     69template< typename pass_type >
     70Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
     71        if( !expr ) return nullptr;
     72
     73        if ( expr->get_env() ) {
     74                env = expr->get_env();
     75        }
     76        // xxx - should env be cloned (or moved) onto the result of the mutate?
     77        return expr->acceptMutator( *this );
     78}
     79
     80
     81//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    1682
    1783template< typename pass_type >
     
    66132
    67133template< typename pass_type >
     134CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
     135        MUTATE_START( node );
     136        call_beginScope();
     137
     138        mutateStatementList( node->get_kids() );
     139
     140        call_endScope();
     141        MUTATE_END( CompoundStmt, node );
     142}
     143
     144template< typename pass_type >
    68145void PassVisitor< pass_type >::visit( ExprStmt * node ) {
    69146        VISIT_BODY( node );
     
    71148
    72149template< typename pass_type >
     150Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
     151        MUTATE_START( node );
     152
     153        node->set_expr( mutateExpression( node->get_expr() ) );
     154
     155        MUTATE_END( Statement, node );
     156}
     157
     158template< typename pass_type >
    73159void PassVisitor< pass_type >::visit( AsmStmt * node ) {
    74160        VISIT_BODY( node );
     
    81167
    82168template< typename pass_type >
     169Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
     170        MUTATE_START( node );
     171
     172        node->set_condition( mutateExpression( node->get_condition() ) );
     173        node->set_thenPart ( mutateStatement ( node->get_thenPart()  ) );
     174        node->set_elsePart ( mutateStatement ( node->get_elsePart()  ) );
     175
     176        MUTATE_END( Statement, node );
     177}
     178
     179template< typename pass_type >
    83180void PassVisitor< pass_type >::visit( WhileStmt * node ) {
    84181        VISIT_BODY( node );
     
    86183
    87184template< typename pass_type >
     185Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
     186        MUTATE_START( node );
     187
     188        node->set_condition( mutateExpression( node->get_condition() ) );
     189        node->set_body( mutateStatement( node->get_body() ) );
     190
     191        MUTATE_END( Statement, node );
     192}
     193
     194
     195template< typename pass_type >
    88196void PassVisitor< pass_type >::visit( ForStmt * node ) {
    89197        VISIT_BODY( node );
     
    91199
    92200template< typename pass_type >
     201Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
     202        MUTATE_START( node );
     203
     204        mutateAll( node->get_initialization(), *this );
     205        node->set_condition(  mutateExpression( node->get_condition() ) );
     206        node->set_increment(  mutateExpression( node->get_increment() ) );
     207        node->set_body(  mutateStatement( node->get_body() ) );
     208
     209        MUTATE_END( Statement, node );
     210}
     211
     212template< typename pass_type >
    93213void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
    94214        VISIT_BODY( node );
     
    96216
    97217template< typename pass_type >
     218Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
     219        MUTATE_START( node );
     220       
     221        node->set_condition( mutateExpression( node->get_condition() ) );
     222        mutateStatementList( node->get_statements() );
     223       
     224        MUTATE_END( Statement, node );
     225}
     226
     227template< typename pass_type >
    98228void PassVisitor< pass_type >::visit( CaseStmt * node ) {
    99229        VISIT_BODY( node );
     
    101231
    102232template< typename pass_type >
     233Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
     234        MUTATE_START( node );
     235       
     236        node->set_condition(  mutateExpression( node->get_condition() ) );
     237        mutateStatementList( node->get_statements() );
     238       
     239        MUTATE_END( Statement, node );
     240}
     241
     242template< typename pass_type >
    103243void PassVisitor< pass_type >::visit( BranchStmt * node ) {
    104244        VISIT_BODY( node );
     
    111251
    112252template< typename pass_type >
     253Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
     254        MUTATE_START( node );
     255
     256        node->set_expr( mutateExpression( node->get_expr() ) );
     257
     258        MUTATE_END( Statement, node );
     259}
     260
     261template< typename pass_type >
    113262void PassVisitor< pass_type >::visit( TryStmt * node ) {
    114263        VISIT_BODY( node );
     
    116265
    117266template< typename pass_type >
     267Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
     268        MUTATE_START( node );
     269
     270        node->set_block(  maybeMutate( node->get_block(), *this ) );
     271        mutateAll( node->get_catchers(), *this );
     272       
     273        MUTATE_END( Statement, node );
     274}
     275
     276template< typename pass_type >
    118277void PassVisitor< pass_type >::visit( CatchStmt * node ) {
    119278        VISIT_BODY( node );
     
    121280
    122281template< typename pass_type >
     282Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
     283        MUTATE_START( node );
     284       
     285        node->set_body(  mutateStatement( node->get_body() ) );
     286        node->set_decl(  maybeMutate( node->get_decl(), *this ) );
     287       
     288        MUTATE_END( Statement, node );
     289}
     290
     291template< typename pass_type >
    123292void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
    124293        VISIT_BODY( node );
     
    151320
    152321template< typename pass_type >
     322Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
     323        MUTATE_START( node );
     324
     325        for ( auto& expr : node->get_args() ) {
     326                expr = mutateExpression( expr );
     327        }
     328
     329        MUTATE_END( Expression, node );
     330}
     331
     332template< typename pass_type >
    153333void PassVisitor< pass_type >::visit( NameExpr * node ) {
    154334        VISIT_BODY( node );
     
    301481
    302482template< typename pass_type >
     483Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
     484        MUTATE_START( node );
     485       
     486        // don't want statements from outer CompoundStmts to be added to this StmtExpr
     487        ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd );
     488        ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter );
     489        ValueGuard< TypeSubstitution * > oldEnv( env );
     490
     491        // xxx - not sure if this is needed, along with appropriate reset, but I don't think so...
     492        // ValueGuard< TyVarMap > oldScopeTyVars( scopeTyVars );
     493
     494        stmtsToAdd.clear();
     495        stmtsToAddAfter.clear();
     496        // scopeTyVars.clear();
     497
     498        Mutator::mutate( node );
     499
     500        MUTATE_END( Expression, node );
     501}
     502
     503template< typename pass_type >
    303504void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
    304505        VISIT_BODY( node );
     
    388589void PassVisitor< pass_type >::visit( SingleInit * node ) {
    389590        VISIT_BODY( node );
     591}
     592
     593template< typename pass_type >
     594Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
     595        MUTATE_START( node );
     596
     597        node->set_value( mutateExpression( node->get_value() ) );
     598
     599        MUTATE_END( Initializer, node );
    390600}
    391601
     
    458668
    459669template< typename pass_type >
    460 CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
    461         MUTATE_BODY( CompoundStmt, node );
    462 }
    463 
    464 template< typename pass_type >
    465 Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
    466         MUTATE_BODY( Statement, node );
    467 }
    468 
    469 template< typename pass_type >
    470670Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
    471671        MUTATE_BODY( Statement, node );
     
    473673
    474674template< typename pass_type >
    475 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
    476         MUTATE_BODY( Statement, node );
    477 }
    478 
    479 template< typename pass_type >
    480 Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
    481         MUTATE_BODY( Statement, node );
    482 }
    483 
    484 template< typename pass_type >
    485 Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
    486         MUTATE_BODY( Statement, node );
    487 }
    488 
    489 template< typename pass_type >
    490 Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
    491         MUTATE_BODY( Statement, node );
    492 }
    493 
    494 template< typename pass_type >
    495 Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
    496         MUTATE_BODY( Statement, node );
    497 }
    498 
    499 template< typename pass_type >
    500675Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
    501676        MUTATE_BODY( Statement, node );
     
    503678
    504679template< typename pass_type >
    505 Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
    506         MUTATE_BODY( Statement, node );
    507 }
    508 
    509 template< typename pass_type >
    510 Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
    511         MUTATE_BODY( Statement, node );
    512 }
    513 
    514 template< typename pass_type >
    515 Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
    516         MUTATE_BODY( Statement, node );
    517 }
    518 
    519 template< typename pass_type >
    520680Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
    521681        MUTATE_BODY( Statement, node );
     
    543703
    544704template< typename pass_type >
    545 Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
    546         MUTATE_BODY( Expression, node );
    547 }
    548 
    549 template< typename pass_type >
    550705Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
    551706        MUTATE_BODY( Expression, node );
     
    693848
    694849template< typename pass_type >
    695 Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
    696         MUTATE_BODY( Expression, node );
    697 }
    698 
    699 template< typename pass_type >
    700850Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
    701851        MUTATE_BODY( Expression, node );
     
    780930Type * PassVisitor< pass_type >::mutate( OneType * node ) {
    781931        MUTATE_BODY( Type, node );
    782 }
    783 
    784 template< typename pass_type >
    785 Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
    786         MUTATE_BODY( Initializer, node );
    787932}
    788933
Note: See TracChangeset for help on using the changeset viewer.