Changes in / [6065b3aa:49c9773]


Ignore:
Files:
8 added
8 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified doc/working/exception/impl/except.c

    r6065b3aa r49c9773  
    9797                                        //is way more expansive than we might like
    9898                                        //The information we have is :
    99                                         //  - The GR (???)
     99                                        //  - The GR (Series of registers)
     100                                        //    GR1=GP Global Pointer of frame ref by context
    100101                                        //  - The instruction pointer
    101102                                        //  - The instruction pointer info (???)
    102                                         //  - The CFA (???)
     103                                        //  - The CFA (Canonical Frame Address)
    103104                                        //  - The BSP (Probably the base stack pointer)
    104105
  • TabularUnified doc/working/exception/impl/main.c

    r6065b3aa r49c9773  
    3333//libcfa but there is one problem left, see the exception table
    3434//for details
     35__attribute__((noinline))
    3536void try( void (*try_block)(), void (*catch_block)() )
    3637{
     
    129130        raii_t a = { "Main dtor" };
    130131
    131         foo();
     132        for (unsigned int i = 0 ; i < 100000000 ; ++i) foo();
    132133
    133134        printf("End of program reached\n");
  • TabularUnified src/Common/PassVisitor.h

    r6065b3aa r49c9773  
    11#pragma once
    22
     3#include <stack>
     4
     5#include "SynTree/Mutator.h"
    36#include "SynTree/Visitor.h"
    47
    5 //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    6 //Deep magic (a.k.a template meta programming) to make the templated visitor work
    7 //Basically the goal is to make 2 previsit_impl
    8 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
    9 //     'pass.previsit( node )' that compiles will be used for that node for that type
    10 //     This requires that this option only compile for passes that actually define an appropriate visit.
    11 //     SFINAE will make sure the compilation errors in this function don't halt the build.
    12 //     See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE
    13 // 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing.
    14 //     This is needed only to eliminate the need for passes to specify any kind of handlers.
    15 //     The second implementation only works because it has a lower priority. This is due to the bogus last parameter.
    16 //     The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0
    17 //     the first implementation takes priority in regards to overloading.
    18 //-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    19 template<typename pass_type, typename node_type>
    20 static inline auto previsit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.previsit( node ), void() ) {
    21         pass.previsit( node );
    22 }
    23 
    24 template<typename pass_type, typename node_type>
    25 static inline void previsit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {
    26         //Do nothing
    27 }
    28 
    29 
    30 template<typename pass_type, typename node_type>
    31 static inline auto postvisit_impl( pass_type& pass, node_type * node, __attribute__((unused)) int unused ) ->decltype( pass.postvisit( node ), void() ) {
    32         pass.postvisit( node );
    33 }
    34 
    35 template<typename pass_type, typename node_type>
    36 static inline auto postvisit_impl( __attribute__((unused)) pass_type& pass, node_type * node, __attribute__((unused)) long unused ) {
    37         //Do nothing
    38 }
     8#include "SynTree/Initializer.h"
     9#include "SynTree/Statement.h"
     10#include "SynTree/Type.h"
     11#include "SynTree/Declaration.h"
     12#include "SynTree/Expression.h"
     13#include "SynTree/Constant.h"
     14
     15#include "PassVisitor.proto.h"
    3916
    4017//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    4421//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    4522template< typename pass_type >
    46 class PassVisitor final : public Visitor {
     23class PassVisitor final : public Visitor, public Mutator {
    4724public:
    4825        PassVisitor() = default;
    4926
    5027        template< typename... Args >
    51         PassVisitor(Args &&... args) 
     28        PassVisitor(Args &&... args)
    5229                : pass( std::forward<Args>( args )... )
    5330        {}
    5431
    5532        virtual ~PassVisitor() = default;
    56 private:
     33
    5734        pass_type pass;
    58 
    59 public:
    6035
    6136        virtual void visit( ObjectDecl *objectDecl ) override final;
     
    145120        virtual void visit( Constant *constant ) override final;
    146121
     122        virtual DeclarationWithType* mutate( ObjectDecl *objectDecl ) override final;
     123        virtual DeclarationWithType* mutate( FunctionDecl *functionDecl ) override final;
     124        virtual Declaration* mutate( StructDecl *aggregateDecl ) override final;
     125        virtual Declaration* mutate( UnionDecl *aggregateDecl ) override final;
     126        virtual Declaration* mutate( EnumDecl *aggregateDecl ) override final;
     127        virtual Declaration* mutate( TraitDecl *aggregateDecl ) override final;
     128        virtual TypeDecl* mutate( TypeDecl *typeDecl ) override final;
     129        virtual Declaration* mutate( TypedefDecl *typeDecl ) override final;
     130        virtual AsmDecl* mutate( AsmDecl *asmDecl ) override final;
     131
     132        virtual CompoundStmt* mutate( CompoundStmt *compoundStmt ) override final;
     133        virtual Statement* mutate( ExprStmt *exprStmt ) override final;
     134        virtual Statement* mutate( AsmStmt *asmStmt ) override final;
     135        virtual Statement* mutate( IfStmt *ifStmt ) override final;
     136        virtual Statement* mutate( WhileStmt *whileStmt ) override final;
     137        virtual Statement* mutate( ForStmt *forStmt ) override final;
     138        virtual Statement* mutate( SwitchStmt *switchStmt ) override final;
     139        virtual Statement* mutate( CaseStmt *caseStmt ) override final;
     140        virtual Statement* mutate( BranchStmt *branchStmt ) override final;
     141        virtual Statement* mutate( ReturnStmt *returnStmt ) override final;
     142        virtual Statement* mutate( TryStmt *returnStmt ) override final;
     143        virtual Statement* mutate( CatchStmt *catchStmt ) override final;
     144        virtual Statement* mutate( FinallyStmt *catchStmt ) override final;
     145        virtual NullStmt* mutate( NullStmt *nullStmt ) override final;
     146        virtual Statement* mutate( DeclStmt *declStmt ) override final;
     147        virtual Statement* mutate( ImplicitCtorDtorStmt *impCtorDtorStmt ) override final;
     148
     149        virtual Expression* mutate( ApplicationExpr *applicationExpr ) override final;
     150        virtual Expression* mutate( UntypedExpr *untypedExpr ) override final;
     151        virtual Expression* mutate( NameExpr *nameExpr ) override final;
     152        virtual Expression* mutate( AddressExpr *castExpr ) override final;
     153        virtual Expression* mutate( LabelAddressExpr *labAddressExpr ) override final;
     154        virtual Expression* mutate( CastExpr *castExpr ) override final;
     155        virtual Expression* mutate( UntypedMemberExpr *memberExpr ) override final;
     156        virtual Expression* mutate( MemberExpr *memberExpr ) override final;
     157        virtual Expression* mutate( VariableExpr *variableExpr ) override final;
     158        virtual Expression* mutate( ConstantExpr *constantExpr ) override final;
     159        virtual Expression* mutate( SizeofExpr *sizeofExpr ) override final;
     160        virtual Expression* mutate( AlignofExpr *alignofExpr ) override final;
     161        virtual Expression* mutate( UntypedOffsetofExpr *offsetofExpr ) override final;
     162        virtual Expression* mutate( OffsetofExpr *offsetofExpr ) override final;
     163        virtual Expression* mutate( OffsetPackExpr *offsetPackExpr ) override final;
     164        virtual Expression* mutate( AttrExpr *attrExpr ) override final;
     165        virtual Expression* mutate( LogicalExpr *logicalExpr ) override final;
     166        virtual Expression* mutate( ConditionalExpr *conditionalExpr ) override final;
     167        virtual Expression* mutate( CommaExpr *commaExpr ) override final;
     168        virtual Expression* mutate( TypeExpr *typeExpr ) override final;
     169        virtual Expression* mutate( AsmExpr *asmExpr ) override final;
     170        virtual Expression* mutate( ImplicitCopyCtorExpr *impCpCtorExpr ) override final;
     171        virtual Expression* mutate( ConstructorExpr *ctorExpr ) override final;
     172        virtual Expression* mutate( CompoundLiteralExpr *compLitExpr ) override final;
     173        virtual Expression* mutate( UntypedValofExpr *valofExpr ) override final;
     174        virtual Expression* mutate( RangeExpr *rangeExpr ) override final;
     175        virtual Expression* mutate( UntypedTupleExpr *tupleExpr ) override final;
     176        virtual Expression* mutate( TupleExpr *tupleExpr ) override final;
     177        virtual Expression* mutate( TupleIndexExpr *tupleExpr ) override final;
     178        virtual Expression* mutate( MemberTupleExpr *tupleExpr ) override final;
     179        virtual Expression* mutate( TupleAssignExpr *assignExpr ) override final;
     180        virtual Expression* mutate( StmtExpr * stmtExpr ) override final;
     181        virtual Expression* mutate( UniqueExpr * uniqueExpr ) override final;
     182
     183        virtual Type* mutate( VoidType *basicType ) override final;
     184        virtual Type* mutate( BasicType *basicType ) override final;
     185        virtual Type* mutate( PointerType *pointerType ) override final;
     186        virtual Type* mutate( ArrayType *arrayType ) override final;
     187        virtual Type* mutate( FunctionType *functionType ) override final;
     188        virtual Type* mutate( StructInstType *aggregateUseType ) override final;
     189        virtual Type* mutate( UnionInstType *aggregateUseType ) override final;
     190        virtual Type* mutate( EnumInstType *aggregateUseType ) override final;
     191        virtual Type* mutate( TraitInstType *aggregateUseType ) override final;
     192        virtual Type* mutate( TypeInstType *aggregateUseType ) override final;
     193        virtual Type* mutate( TupleType *tupleType ) override final;
     194        virtual Type* mutate( TypeofType *typeofType ) override final;
     195        virtual Type* mutate( AttrType *attrType ) override final;
     196        virtual Type* mutate( VarArgsType *varArgsType ) override final;
     197        virtual Type* mutate( ZeroType *zeroType ) override final;
     198        virtual Type* mutate( OneType *oneType ) override final;
     199
     200        virtual Initializer* mutate( SingleInit *singleInit ) override final;
     201        virtual Initializer* mutate( ListInit *listInit ) override final;
     202        virtual Initializer* mutate( ConstructorInit *ctorInit ) override final;
     203
     204        virtual Subrange *mutate( Subrange *subrange ) override final;
     205
     206        virtual Constant *mutate( Constant *constant ) override final;
     207
    147208private:
    148         template<typename node_type>
    149         auto call_previsit ( node_type * node )
    150                 -> decltype( previsit_impl ( pass, node, 0 ), void() )
    151         {
    152                 previsit_impl ( pass, node, 0 );
    153         }
    154 
    155         template<typename node_type>
    156         auto call_postvisit( node_type * node )
    157                 -> decltype( postvisit_impl( pass, node, 0 ), void() )
    158         {
    159                 postvisit_impl( pass, node, 0 );
    160         }
     209        template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
     210        template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); }
     211
     212        template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); }
     213        template<typename return_type, typename node_type> return_type call_postmutate ( node_type * node ) { return postmutate_impl<return_type>( pass, node, 0 ); }
     214
     215        void call_beginScope() { begin_scope_impl( pass, 0 ); }
     216        void call_endScope  () { end_scope_impl  ( pass, 0 ); }
     217
     218        void set_env( TypeSubstitution * env ) { set_env_impl( pass, env, 0); }
     219
     220        void visitStatementList( std::list< Statement* > &statements );
     221        void mutateStatementList( std::list< Statement* > &statements );
     222
     223        Statement * visitStatement( Statement * stmt );
     224        Statement * mutateStatement( Statement * stmt );
     225
     226        void visitExpression( Expression * expr );
     227        Expression * mutateExpression( Expression * expr );
     228
     229
     230        TypeSubstitution **             get_env_ptr    () { return env_impl             ( pass, 0); }
     231        std::list< Statement* > *       get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); }
     232        std::list< Statement* > *       get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
    161233};
    162234
  • TabularUnified src/Common/PassVisitor.impl.h

    r6065b3aa r49c9773  
    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 )    \
     
    715
    816
    9 template< typename pass_type >
    10 void PassVisitor< pass_type>::visit( ObjectDecl * node ) {
    11         VISIT_BODY( node );
    12 }
    13 
    14 template< typename pass_type >
    15 void PassVisitor< pass_type>::visit( FunctionDecl * node ) {
    16         VISIT_BODY( node );
    17 }
    18 
    19 template< typename pass_type >
    20 void PassVisitor< pass_type>::visit( StructDecl * node ) {
    21         VISIT_BODY( node );
    22 }
    23 
    24 template< typename pass_type >
    25 void PassVisitor< pass_type>::visit( UnionDecl * node ) {
    26         VISIT_BODY( node );
    27 }
    28 
    29 template< typename pass_type >
    30 void PassVisitor< pass_type>::visit( EnumDecl * node ) {
    31         VISIT_BODY( node );
    32 }
    33 
    34 template< typename pass_type >
    35 void PassVisitor< pass_type>::visit( TraitDecl * node ) {
    36         VISIT_BODY( node );
    37 }
    38 
    39 template< typename pass_type >
    40 void PassVisitor< pass_type>::visit( TypeDecl * node ) {
    41         VISIT_BODY( node );
    42 }
    43 
    44 template< typename pass_type >
    45 void PassVisitor< pass_type>::visit( TypedefDecl * node ) {
    46         VISIT_BODY( node );
    47 }
    48 
    49 template< typename pass_type >
    50 void PassVisitor< pass_type>::visit( AsmDecl * node ) {
    51         VISIT_BODY( node );
    52 }
    53 
    54 template< typename pass_type >
    55 void PassVisitor< pass_type>::visit( CompoundStmt * node ) {
    56         VISIT_BODY( node );
    57 }
    58 
    59 template< typename pass_type >
    60 void PassVisitor< pass_type>::visit( ExprStmt * node ) {
    61         VISIT_BODY( node );
    62 }
    63 
    64 template< typename pass_type >
    65 void PassVisitor< pass_type>::visit( AsmStmt * node ) {
    66         VISIT_BODY( node );
    67 }
    68 
    69 template< typename pass_type >
    70 void PassVisitor< pass_type>::visit( IfStmt * node ) {
    71         VISIT_BODY( node );
    72 }
    73 
    74 template< typename pass_type >
    75 void PassVisitor< pass_type>::visit( WhileStmt * node ) {
    76         VISIT_BODY( node );
    77 }
    78 
    79 template< typename pass_type >
    80 void PassVisitor< pass_type>::visit( ForStmt * node ) {
    81         VISIT_BODY( node );
    82 }
    83 
    84 template< typename pass_type >
    85 void PassVisitor< pass_type>::visit( SwitchStmt * node ) {
    86         VISIT_BODY( node );
    87 }
    88 
    89 template< typename pass_type >
    90 void PassVisitor< pass_type>::visit( CaseStmt * node ) {
    91         VISIT_BODY( node );
    92 }
    93 
    94 template< typename pass_type >
    95 void PassVisitor< pass_type>::visit( BranchStmt * node ) {
    96         VISIT_BODY( node );
    97 }
    98 
    99 template< typename pass_type >
    100 void PassVisitor< pass_type>::visit( ReturnStmt * node ) {
    101         VISIT_BODY( node );
    102 }
    103 
    104 template< typename pass_type >
    105 void PassVisitor< pass_type>::visit( TryStmt * node ) {
    106         VISIT_BODY( node );
    107 }
    108 
    109 template< typename pass_type >
    110 void PassVisitor< pass_type>::visit( CatchStmt * node ) {
    111         VISIT_BODY( node );
    112 }
    113 
    114 template< typename pass_type >
    115 void PassVisitor< pass_type>::visit( FinallyStmt * node ) {
    116         VISIT_BODY( node );
    117 }
    118 
    119 template< typename pass_type >
    120 void PassVisitor< pass_type>::visit( NullStmt * node ) {
    121         VISIT_BODY( node );
    122 }
    123 
    124 template< typename pass_type >
    125 void PassVisitor< pass_type>::visit( DeclStmt * node ) {
    126         VISIT_BODY( node );
    127 }
    128 
    129 template< typename pass_type >
    130 void PassVisitor< pass_type>::visit( ImplicitCtorDtorStmt * node ) {
    131         VISIT_BODY( node );
    132 }
    133 
    134 template< typename pass_type >
    135 void PassVisitor< pass_type>::visit( ApplicationExpr * node ) {
    136         VISIT_BODY( node );
    137 }
    138 
    139 template< typename pass_type >
    140 void PassVisitor< pass_type>::visit( UntypedExpr * node ) {
    141         VISIT_BODY( node );
    142 }
    143 
    144 template< typename pass_type >
    145 void PassVisitor< pass_type>::visit( NameExpr * node ) {
    146         VISIT_BODY( node );
    147 }
    148 
    149 template< typename pass_type >
    150 void PassVisitor< pass_type>::visit( CastExpr * node ) {
    151         VISIT_BODY( node );
    152 }
    153 
    154 template< typename pass_type >
    155 void PassVisitor< pass_type>::visit( AddressExpr * node ) {
    156         VISIT_BODY( node );
    157 }
    158 
    159 template< typename pass_type >
    160 void PassVisitor< pass_type>::visit( LabelAddressExpr * node ) {
    161         VISIT_BODY( node );
    162 }
    163 
    164 template< typename pass_type >
    165 void PassVisitor< pass_type>::visit( UntypedMemberExpr * node ) {
    166         VISIT_BODY( node );
    167 }
    168 
    169 template< typename pass_type >
    170 void PassVisitor< pass_type>::visit( MemberExpr * node ) {
    171         VISIT_BODY( node );
    172 }
    173 
    174 template< typename pass_type >
    175 void PassVisitor< pass_type>::visit( VariableExpr * node ) {
    176         VISIT_BODY( node );
    177 }
    178 
    179 template< typename pass_type >
    180 void PassVisitor< pass_type>::visit( ConstantExpr * node ) {
    181         VISIT_BODY( node );
    182 }
    183 
    184 template< typename pass_type >
    185 void PassVisitor< pass_type>::visit( SizeofExpr * node ) {
    186         VISIT_BODY( node );
    187 }
    188 
    189 template< typename pass_type >
    190 void PassVisitor< pass_type>::visit( AlignofExpr * node ) {
    191         VISIT_BODY( node );
    192 }
    193 
    194 template< typename pass_type >
    195 void PassVisitor< pass_type>::visit( UntypedOffsetofExpr * node ) {
    196         VISIT_BODY( node );
    197 }
    198 
    199 template< typename pass_type >
    200 void PassVisitor< pass_type>::visit( OffsetofExpr * node ) {
    201         VISIT_BODY( node );
    202 }
    203 
    204 template< typename pass_type >
    205 void PassVisitor< pass_type>::visit( OffsetPackExpr * node ) {
    206         VISIT_BODY( node );
    207 }
    208 
    209 template< typename pass_type >
    210 void PassVisitor< pass_type>::visit( AttrExpr * node ) {
    211         VISIT_BODY( node );
    212 }
    213 
    214 template< typename pass_type >
    215 void PassVisitor< pass_type>::visit( LogicalExpr * node ) {
    216         VISIT_BODY( node );
    217 }
    218 
    219 template< typename pass_type >
    220 void PassVisitor< pass_type>::visit( ConditionalExpr * node ) {
    221         VISIT_BODY( node );
    222 }
    223 
    224 template< typename pass_type >
    225 void PassVisitor< pass_type>::visit( CommaExpr * node ) {
    226         VISIT_BODY( node );
    227 }
    228 
    229 template< typename pass_type >
    230 void PassVisitor< pass_type>::visit( TypeExpr * node ) {
    231         VISIT_BODY( node );
    232 }
    233 
    234 template< typename pass_type >
    235 void PassVisitor< pass_type>::visit( AsmExpr * node ) {
    236         VISIT_BODY( node );
    237 }
    238 
    239 template< typename pass_type >
    240 void PassVisitor< pass_type>::visit( ImplicitCopyCtorExpr * node ) {
    241         VISIT_BODY( node );
    242 }
    243 
    244 template< typename pass_type >
    245 void PassVisitor< pass_type>::visit( ConstructorExpr * node ) {
    246         VISIT_BODY( node );
    247 }
    248 
    249 template< typename pass_type >
    250 void PassVisitor< pass_type>::visit( CompoundLiteralExpr * node ) {
    251         VISIT_BODY( node );
    252 }
    253 
    254 template< typename pass_type >
    255 void PassVisitor< pass_type>::visit( UntypedValofExpr * node ) {
    256         VISIT_BODY( node );
    257 }
    258 
    259 template< typename pass_type >
    260 void PassVisitor< pass_type>::visit( RangeExpr * node ) {
    261         VISIT_BODY( node );
    262 }
    263 
    264 template< typename pass_type >
    265 void PassVisitor< pass_type>::visit( UntypedTupleExpr * node ) {
    266         VISIT_BODY( node );
    267 }
    268 
    269 template< typename pass_type >
    270 void PassVisitor< pass_type>::visit( TupleExpr * node ) {
    271         VISIT_BODY( node );
    272 }
    273 
    274 template< typename pass_type >
    275 void PassVisitor< pass_type>::visit( TupleIndexExpr * node ) {
    276         VISIT_BODY( node );
    277 }
    278 
    279 template< typename pass_type >
    280 void PassVisitor< pass_type>::visit( MemberTupleExpr * node ) {
    281         VISIT_BODY( node );
    282 }
    283 
    284 template< typename pass_type >
    285 void PassVisitor< pass_type>::visit( TupleAssignExpr * node ) {
    286         VISIT_BODY( node );
    287 }
    288 
    289 template< typename pass_type >
    290 void PassVisitor< pass_type>::visit( StmtExpr * node ) {
    291         VISIT_BODY( node );
    292 }
    293 
    294 template< typename pass_type >
    295 void PassVisitor< pass_type>::visit( UniqueExpr * node ) {
    296         VISIT_BODY( node );
    297 }
    298 
    299 template< typename pass_type >
    300 void PassVisitor< pass_type>::visit( VoidType * node ) {
    301         VISIT_BODY( node );
    302 }
    303 
    304 template< typename pass_type >
    305 void PassVisitor< pass_type>::visit( BasicType * node ) {
    306         VISIT_BODY( node );
    307 }
    308 
    309 template< typename pass_type >
    310 void PassVisitor< pass_type>::visit( PointerType * node ) {
    311         VISIT_BODY( node );
    312 }
    313 
    314 template< typename pass_type >
    315 void PassVisitor< pass_type>::visit( ArrayType * node ) {
    316         VISIT_BODY( node );
    317 }
    318 
    319 template< typename pass_type >
    320 void PassVisitor< pass_type>::visit( FunctionType * node ) {
    321         VISIT_BODY( node );
    322 }
    323 
    324 template< typename pass_type >
    325 void PassVisitor< pass_type>::visit( StructInstType * node ) {
    326         VISIT_BODY( node );
    327 }
    328 
    329 template< typename pass_type >
    330 void PassVisitor< pass_type>::visit( UnionInstType * node ) {
    331         VISIT_BODY( node );
    332 }
    333 
    334 template< typename pass_type >
    335 void PassVisitor< pass_type>::visit( EnumInstType * node ) {
    336         VISIT_BODY( node );
    337 }
    338 
    339 template< typename pass_type >
    340 void PassVisitor< pass_type>::visit( TraitInstType * node ) {
    341         VISIT_BODY( node );
    342 }
    343 
    344 template< typename pass_type >
    345 void PassVisitor< pass_type>::visit( TypeInstType * node ) {
    346         VISIT_BODY( node );
    347 }
    348 
    349 template< typename pass_type >
    350 void PassVisitor< pass_type>::visit( TupleType * node ) {
    351         VISIT_BODY( node );
    352 }
    353 
    354 template< typename pass_type >
    355 void PassVisitor< pass_type>::visit( TypeofType * node ) {
    356         VISIT_BODY( node );
    357 }
    358 
    359 template< typename pass_type >
    360 void PassVisitor< pass_type>::visit( AttrType * node ) {
    361         VISIT_BODY( node );
    362 }
    363 
    364 template< typename pass_type >
    365 void PassVisitor< pass_type>::visit( VarArgsType * node ) {
    366         VISIT_BODY( node );
    367 }
    368 
    369 template< typename pass_type >
    370 void PassVisitor< pass_type>::visit( ZeroType * node ) {
    371         VISIT_BODY( node );
    372 }
    373 
    374 template< typename pass_type >
    375 void PassVisitor< pass_type>::visit( OneType * node ) {
    376         VISIT_BODY( node );
    377 }
    378 
    379 template< typename pass_type >
    380 void PassVisitor< pass_type>::visit( SingleInit * node ) {
    381         VISIT_BODY( node );
    382 }
    383 
    384 template< typename pass_type >
    385 void PassVisitor< pass_type>::visit( ListInit * node ) {
    386         VISIT_BODY( node );
    387 }
    388 
    389 template< typename pass_type >
    390 void PassVisitor< pass_type>::visit( ConstructorInit * node ) {
    391         VISIT_BODY( node );
    392 }
    393 
    394 template< typename pass_type >
    395 void PassVisitor< pass_type>::visit( Subrange * node ) {
    396         VISIT_BODY( node );
    397 }
    398 
    399 template< typename pass_type >
    400 void PassVisitor< pass_type>::visit( Constant * node ) {
    401         VISIT_BODY( node );
    402 }
     17#define MUTATE_BODY( type, node ) \
     18        MUTATE_START( node );       \
     19        Mutator::mutate( node );    \
     20        MUTATE_END( type, node );   \
     21
     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
     52template< typename pass_type >
     53void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
     54        SemanticError errors;
     55
     56        StmtList_t* beforeStmts = get_beforeStmts();
     57        StmtList_t* afterStmts  = get_afterStmts();
     58
     59        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
     60                if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); }
     61                try {
     62                        *i = (*i)->acceptMutator( *this );
     63                } catch ( SemanticError &e ) {
     64                        errors.append( e );
     65                }
     66                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
     67        }
     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;
     92}
     93
     94template< typename pass_type >
     95Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
     96        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     97        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     98        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
     99        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     100
     101        Statement *newStmt = maybeMutate( stmt, *this );
     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();
     124        }
     125        // xxx - should env be cloned (or moved) onto the result of the mutate?
     126        expr->accept( *this );
     127}
     128
     129template< typename pass_type >
     130Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
     131        if( !expr ) return nullptr;
     132
     133        auto env_ptr = get_env_ptr();
     134        if ( env_ptr && expr->get_env() ) {
     135                *env_ptr = expr->get_env();
     136        }
     137        // xxx - should env be cloned (or moved) onto the result of the mutate?
     138        return expr->acceptMutator( *this );
     139}
     140
     141
     142//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     143
     144template< typename pass_type >
     145void PassVisitor< pass_type >::visit( ObjectDecl * node ) {
     146        VISIT_BODY( node );
     147}
     148
     149template< typename pass_type >
     150void PassVisitor< pass_type >::visit( FunctionDecl * node ) {
     151        VISIT_BODY( node );
     152}
     153
     154template< typename pass_type >
     155void PassVisitor< pass_type >::visit( StructDecl * node ) {
     156        VISIT_BODY( node );
     157}
     158
     159template< typename pass_type >
     160void PassVisitor< pass_type >::visit( UnionDecl * node ) {
     161        VISIT_BODY( node );
     162}
     163
     164template< typename pass_type >
     165void PassVisitor< pass_type >::visit( EnumDecl * node ) {
     166        VISIT_BODY( node );
     167}
     168
     169template< typename pass_type >
     170void PassVisitor< pass_type >::visit( TraitDecl * node ) {
     171        VISIT_BODY( node );
     172}
     173
     174template< typename pass_type >
     175void PassVisitor< pass_type >::visit( TypeDecl * node ) {
     176        VISIT_BODY( node );
     177}
     178
     179template< typename pass_type >
     180void PassVisitor< pass_type >::visit( TypedefDecl * node ) {
     181        VISIT_BODY( node );
     182}
     183
     184template< typename pass_type >
     185void PassVisitor< pass_type >::visit( AsmDecl * node ) {
     186        VISIT_BODY( node );
     187}
     188
     189template< typename pass_type >
     190void PassVisitor< pass_type >::visit( CompoundStmt * node ) {
     191        VISIT_BODY( node );
     192}
     193
     194template< typename pass_type >
     195CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
     196        MUTATE_START( node );
     197        call_beginScope();
     198
     199        mutateStatementList( node->get_kids() );
     200
     201        call_endScope();
     202        MUTATE_END( CompoundStmt, node );
     203}
     204
     205template< typename pass_type >
     206void PassVisitor< pass_type >::visit( ExprStmt * node ) {
     207        VISIT_BODY( node );
     208}
     209
     210template< typename pass_type >
     211Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) {
     212        MUTATE_START( node );
     213
     214        node->set_expr( mutateExpression( node->get_expr() ) );
     215
     216        MUTATE_END( Statement, node );
     217}
     218
     219template< typename pass_type >
     220void PassVisitor< pass_type >::visit( AsmStmt * node ) {
     221        VISIT_BODY( node );
     222}
     223
     224template< typename pass_type >
     225void PassVisitor< pass_type >::visit( IfStmt * node ) {
     226        VISIT_BODY( node );
     227}
     228
     229template< typename pass_type >
     230Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
     231        MUTATE_START( node );
     232
     233        node->set_condition( mutateExpression( node->get_condition() ) );
     234        node->set_thenPart ( mutateStatement ( node->get_thenPart()  ) );
     235        node->set_elsePart ( mutateStatement ( node->get_elsePart()  ) );
     236
     237        MUTATE_END( Statement, node );
     238}
     239
     240template< typename pass_type >
     241void PassVisitor< pass_type >::visit( WhileStmt * node ) {
     242        VISIT_BODY( node );
     243}
     244
     245template< typename pass_type >
     246Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) {
     247        MUTATE_START( node );
     248
     249        node->set_condition( mutateExpression( node->get_condition() ) );
     250        node->set_body( mutateStatement( node->get_body() ) );
     251
     252        MUTATE_END( Statement, node );
     253}
     254
     255
     256template< typename pass_type >
     257void PassVisitor< pass_type >::visit( ForStmt * node ) {
     258        VISIT_BODY( node );
     259}
     260
     261template< typename pass_type >
     262Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
     263        MUTATE_START( node );
     264
     265        mutateAll( node->get_initialization(), *this );
     266        node->set_condition(  mutateExpression( node->get_condition() ) );
     267        node->set_increment(  mutateExpression( node->get_increment() ) );
     268        node->set_body(  mutateStatement( node->get_body() ) );
     269
     270        MUTATE_END( Statement, node );
     271}
     272
     273template< typename pass_type >
     274void PassVisitor< pass_type >::visit( SwitchStmt * node ) {
     275        VISIT_BODY( node );
     276}
     277
     278template< typename pass_type >
     279Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
     280        MUTATE_START( node );
     281       
     282        node->set_condition( mutateExpression( node->get_condition() ) );
     283        mutateStatementList( node->get_statements() );
     284       
     285        MUTATE_END( Statement, node );
     286}
     287
     288template< typename pass_type >
     289void PassVisitor< pass_type >::visit( CaseStmt * node ) {
     290        VISIT_BODY( node );
     291}
     292
     293template< typename pass_type >
     294Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
     295        MUTATE_START( node );
     296       
     297        node->set_condition(  mutateExpression( node->get_condition() ) );
     298        mutateStatementList( node->get_statements() );
     299       
     300        MUTATE_END( Statement, node );
     301}
     302
     303template< typename pass_type >
     304void PassVisitor< pass_type >::visit( BranchStmt * node ) {
     305        VISIT_BODY( node );
     306}
     307
     308template< typename pass_type >
     309void PassVisitor< pass_type >::visit( ReturnStmt * node ) {
     310        VISIT_BODY( node );
     311}
     312
     313template< typename pass_type >
     314Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
     315        MUTATE_START( node );
     316
     317        node->set_expr( mutateExpression( node->get_expr() ) );
     318
     319        MUTATE_END( Statement, node );
     320}
     321
     322template< typename pass_type >
     323void PassVisitor< pass_type >::visit( TryStmt * node ) {
     324        VISIT_BODY( node );
     325}
     326
     327template< typename pass_type >
     328Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) {
     329        MUTATE_START( node );
     330
     331        node->set_block(  maybeMutate( node->get_block(), *this ) );
     332        mutateAll( node->get_catchers(), *this );
     333       
     334        MUTATE_END( Statement, node );
     335}
     336
     337template< typename pass_type >
     338void PassVisitor< pass_type >::visit( CatchStmt * node ) {
     339        VISIT_BODY( node );
     340}
     341
     342template< typename pass_type >
     343Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
     344        MUTATE_START( node );
     345       
     346        node->set_body(  mutateStatement( node->get_body() ) );
     347        node->set_decl(  maybeMutate( node->get_decl(), *this ) );
     348       
     349        MUTATE_END( Statement, node );
     350}
     351
     352template< typename pass_type >
     353void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
     354        VISIT_BODY( node );
     355}
     356
     357template< typename pass_type >
     358void PassVisitor< pass_type >::visit( NullStmt * node ) {
     359        VISIT_BODY( node );
     360}
     361
     362template< typename pass_type >
     363void PassVisitor< pass_type >::visit( DeclStmt * node ) {
     364        VISIT_BODY( node );
     365}
     366
     367template< typename pass_type >
     368void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
     369        VISIT_BODY( node );
     370}
     371
     372template< typename pass_type >
     373void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
     374        VISIT_BODY( node );
     375}
     376
     377template< typename pass_type >
     378void PassVisitor< pass_type >::visit( UntypedExpr * node ) {
     379        VISIT_BODY( node );
     380}
     381
     382template< typename pass_type >
     383Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
     384        MUTATE_START( node );
     385
     386        for ( auto& expr : node->get_args() ) {
     387                expr = mutateExpression( expr );
     388        }
     389
     390        MUTATE_END( Expression, node );
     391}
     392
     393template< typename pass_type >
     394void PassVisitor< pass_type >::visit( NameExpr * node ) {
     395        VISIT_BODY( node );
     396}
     397
     398template< typename pass_type >
     399void PassVisitor< pass_type >::visit( CastExpr * node ) {
     400        VISIT_BODY( node );
     401}
     402
     403template< typename pass_type >
     404void PassVisitor< pass_type >::visit( AddressExpr * node ) {
     405        VISIT_BODY( node );
     406}
     407
     408template< typename pass_type >
     409void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) {
     410        VISIT_BODY( node );
     411}
     412
     413template< typename pass_type >
     414void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
     415        VISIT_BODY( node );
     416}
     417
     418template< typename pass_type >
     419void PassVisitor< pass_type >::visit( MemberExpr * node ) {
     420        VISIT_BODY( node );
     421}
     422
     423template< typename pass_type >
     424void PassVisitor< pass_type >::visit( VariableExpr * node ) {
     425        VISIT_BODY( node );
     426}
     427
     428template< typename pass_type >
     429void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
     430        VISIT_BODY( node );
     431}
     432
     433template< typename pass_type >
     434void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
     435        VISIT_BODY( node );
     436}
     437
     438template< typename pass_type >
     439void PassVisitor< pass_type >::visit( AlignofExpr * node ) {
     440        VISIT_BODY( node );
     441}
     442
     443template< typename pass_type >
     444void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) {
     445        VISIT_BODY( node );
     446}
     447
     448template< typename pass_type >
     449void PassVisitor< pass_type >::visit( OffsetofExpr * node ) {
     450        VISIT_BODY( node );
     451}
     452
     453template< typename pass_type >
     454void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) {
     455        VISIT_BODY( node );
     456}
     457
     458template< typename pass_type >
     459void PassVisitor< pass_type >::visit( AttrExpr * node ) {
     460        VISIT_BODY( node );
     461}
     462
     463template< typename pass_type >
     464void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
     465        VISIT_BODY( node );
     466}
     467
     468template< typename pass_type >
     469void PassVisitor< pass_type >::visit( ConditionalExpr * node ) {
     470        VISIT_BODY( node );
     471}
     472
     473template< typename pass_type >
     474void PassVisitor< pass_type >::visit( CommaExpr * node ) {
     475        VISIT_BODY( node );
     476}
     477
     478template< typename pass_type >
     479void PassVisitor< pass_type >::visit( TypeExpr * node ) {
     480        VISIT_BODY( node );
     481}
     482
     483template< typename pass_type >
     484void PassVisitor< pass_type >::visit( AsmExpr * node ) {
     485        VISIT_BODY( node );
     486}
     487
     488template< typename pass_type >
     489void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) {
     490        VISIT_BODY( node );
     491}
     492
     493template< typename pass_type >
     494void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
     495        VISIT_BODY( node );
     496}
     497
     498template< typename pass_type >
     499void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) {
     500        VISIT_BODY( node );
     501}
     502
     503template< typename pass_type >
     504void PassVisitor< pass_type >::visit( UntypedValofExpr * node ) {
     505        VISIT_BODY( node );
     506}
     507
     508template< typename pass_type >
     509void PassVisitor< pass_type >::visit( RangeExpr * node ) {
     510        VISIT_BODY( node );
     511}
     512
     513template< typename pass_type >
     514void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) {
     515        VISIT_BODY( node );
     516}
     517
     518template< typename pass_type >
     519void PassVisitor< pass_type >::visit( TupleExpr * node ) {
     520        VISIT_BODY( node );
     521}
     522
     523template< typename pass_type >
     524void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) {
     525        VISIT_BODY( node );
     526}
     527
     528template< typename pass_type >
     529void PassVisitor< pass_type >::visit( MemberTupleExpr * node ) {
     530        VISIT_BODY( node );
     531}
     532
     533template< typename pass_type >
     534void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) {
     535        VISIT_BODY( node );
     536}
     537
     538template< typename pass_type >
     539void PassVisitor< pass_type >::visit( StmtExpr * node ) {
     540        VISIT_BODY( node );
     541}
     542
     543template< typename pass_type >
     544Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
     545        MUTATE_START( node );
     546       
     547        // don't want statements from outer CompoundStmts to be added to this StmtExpr
     548        ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     549        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
     550        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     551
     552        Mutator::mutate( node );
     553
     554        MUTATE_END( Expression, node );
     555}
     556
     557template< typename pass_type >
     558void PassVisitor< pass_type >::visit( UniqueExpr * node ) {
     559        VISIT_BODY( node );
     560}
     561
     562template< typename pass_type >
     563void PassVisitor< pass_type >::visit( VoidType * node ) {
     564        VISIT_BODY( node );
     565}
     566
     567template< typename pass_type >
     568void PassVisitor< pass_type >::visit( BasicType * node ) {
     569        VISIT_BODY( node );
     570}
     571
     572template< typename pass_type >
     573void PassVisitor< pass_type >::visit( PointerType * node ) {
     574        VISIT_BODY( node );
     575}
     576
     577template< typename pass_type >
     578void PassVisitor< pass_type >::visit( ArrayType * node ) {
     579        VISIT_BODY( node );
     580}
     581
     582template< typename pass_type >
     583void PassVisitor< pass_type >::visit( FunctionType * node ) {
     584        VISIT_BODY( node );
     585}
     586
     587template< typename pass_type >
     588void PassVisitor< pass_type >::visit( StructInstType * node ) {
     589        VISIT_BODY( node );
     590}
     591
     592template< typename pass_type >
     593void PassVisitor< pass_type >::visit( UnionInstType * node ) {
     594        VISIT_BODY( node );
     595}
     596
     597template< typename pass_type >
     598void PassVisitor< pass_type >::visit( EnumInstType * node ) {
     599        VISIT_BODY( node );
     600}
     601
     602template< typename pass_type >
     603void PassVisitor< pass_type >::visit( TraitInstType * node ) {
     604        VISIT_BODY( node );
     605}
     606
     607template< typename pass_type >
     608void PassVisitor< pass_type >::visit( TypeInstType * node ) {
     609        VISIT_BODY( node );
     610}
     611
     612template< typename pass_type >
     613void PassVisitor< pass_type >::visit( TupleType * node ) {
     614        VISIT_BODY( node );
     615}
     616
     617template< typename pass_type >
     618void PassVisitor< pass_type >::visit( TypeofType * node ) {
     619        VISIT_BODY( node );
     620}
     621
     622template< typename pass_type >
     623void PassVisitor< pass_type >::visit( AttrType * node ) {
     624        VISIT_BODY( node );
     625}
     626
     627template< typename pass_type >
     628void PassVisitor< pass_type >::visit( VarArgsType * node ) {
     629        VISIT_BODY( node );
     630}
     631
     632template< typename pass_type >
     633void PassVisitor< pass_type >::visit( ZeroType * node ) {
     634        VISIT_BODY( node );
     635}
     636
     637template< typename pass_type >
     638void PassVisitor< pass_type >::visit( OneType * node ) {
     639        VISIT_BODY( node );
     640}
     641
     642template< typename pass_type >
     643void PassVisitor< pass_type >::visit( SingleInit * node ) {
     644        VISIT_BODY( node );
     645}
     646
     647template< typename pass_type >
     648Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
     649        MUTATE_START( node );
     650
     651        node->set_value( mutateExpression( node->get_value() ) );
     652
     653        MUTATE_END( Initializer, node );
     654}
     655
     656template< typename pass_type >
     657void PassVisitor< pass_type >::visit( ListInit * node ) {
     658        VISIT_BODY( node );
     659}
     660
     661template< typename pass_type >
     662void PassVisitor< pass_type >::visit( ConstructorInit * node ) {
     663        VISIT_BODY( node );
     664}
     665
     666template< typename pass_type >
     667void PassVisitor< pass_type >::visit( Subrange * node ) {
     668        VISIT_BODY( node );
     669}
     670
     671template< typename pass_type >
     672void PassVisitor< pass_type >::visit( Constant * node ) {
     673        VISIT_BODY( node );
     674}
     675
     676//---------------------------------------------------------------------------------------------------------------
     677
     678template< typename pass_type >
     679DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
     680        MUTATE_BODY( DeclarationWithType, node );
     681}
     682
     683template< typename pass_type >
     684DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) {
     685        MUTATE_BODY( DeclarationWithType, node );
     686}
     687
     688template< typename pass_type >
     689Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
     690        MUTATE_BODY( Declaration, node );
     691}
     692
     693template< typename pass_type >
     694Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) {
     695        MUTATE_BODY( Declaration, node );
     696}
     697
     698template< typename pass_type >
     699Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
     700        MUTATE_BODY( Declaration, node );
     701}
     702
     703template< typename pass_type >
     704Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) {
     705        MUTATE_BODY( Declaration, node );
     706}
     707
     708template< typename pass_type >
     709TypeDecl * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
     710        MUTATE_BODY( TypeDecl, node );
     711}
     712
     713template< typename pass_type >
     714Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
     715        MUTATE_BODY( Declaration, node );
     716}
     717
     718template< typename pass_type >
     719AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
     720        MUTATE_BODY( AsmDecl, node );
     721}
     722
     723template< typename pass_type >
     724Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
     725        MUTATE_BODY( Statement, node );
     726}
     727
     728template< typename pass_type >
     729Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
     730        MUTATE_BODY( Statement, node );
     731}
     732
     733template< typename pass_type >
     734Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
     735        MUTATE_BODY( Statement, node );
     736}
     737
     738template< typename pass_type >
     739NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
     740        MUTATE_BODY( NullStmt, node );
     741}
     742
     743template< typename pass_type >
     744Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
     745        MUTATE_BODY( Statement, node );
     746}
     747
     748template< typename pass_type >
     749Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
     750        MUTATE_BODY( Statement, node );
     751}
     752
     753template< typename pass_type >
     754Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
     755        MUTATE_BODY( Expression, node );
     756}
     757
     758template< typename pass_type >
     759Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
     760        MUTATE_BODY( Expression, node );
     761}
     762
     763template< typename pass_type >
     764Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
     765        MUTATE_BODY( Expression, node );
     766}
     767
     768template< typename pass_type >
     769Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
     770        MUTATE_BODY( Expression, node );
     771}
     772
     773template< typename pass_type >
     774Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) {
     775        MUTATE_BODY( Expression, node );
     776}
     777
     778template< typename pass_type >
     779Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) {
     780        MUTATE_BODY( Expression, node );
     781}
     782
     783template< typename pass_type >
     784Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
     785        MUTATE_BODY( Expression, node );
     786}
     787
     788template< typename pass_type >
     789Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
     790        MUTATE_BODY( Expression, node );
     791}
     792
     793template< typename pass_type >
     794Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) {
     795        MUTATE_BODY( Expression, node );
     796}
     797
     798template< typename pass_type >
     799Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) {
     800        MUTATE_BODY( Expression, node );
     801}
     802
     803template< typename pass_type >
     804Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
     805        MUTATE_BODY( Expression, node );
     806}
     807
     808template< typename pass_type >
     809Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
     810        MUTATE_BODY( Expression, node );
     811}
     812
     813template< typename pass_type >
     814Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
     815        MUTATE_BODY( Expression, node );
     816}
     817
     818template< typename pass_type >
     819Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
     820        MUTATE_BODY( Expression, node );
     821}
     822
     823template< typename pass_type >
     824Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
     825        MUTATE_BODY( Expression, node );
     826}
     827
     828template< typename pass_type >
     829Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) {
     830        MUTATE_BODY( Expression, node );
     831}
     832
     833template< typename pass_type >
     834Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) {
     835        MUTATE_BODY( Expression, node );
     836}
     837
     838template< typename pass_type >
     839Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
     840        MUTATE_BODY( Expression, node );
     841}
     842
     843template< typename pass_type >
     844Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
     845        MUTATE_BODY( Expression, node );
     846}
     847
     848template< typename pass_type >
     849Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) {
     850        MUTATE_BODY( Expression, node );
     851}
     852
     853template< typename pass_type >
     854Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) {
     855        MUTATE_BODY( Expression, node );
     856}
     857
     858template< typename pass_type >
     859Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) {
     860        MUTATE_BODY( Expression, node );
     861}
     862
     863template< typename pass_type >
     864Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
     865        MUTATE_BODY( Expression, node );
     866}
     867
     868template< typename pass_type >
     869Expression * PassVisitor< pass_type >::mutate( UntypedValofExpr * node ) {
     870        MUTATE_BODY( Expression, node );
     871}
     872
     873template< typename pass_type >
     874Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) {
     875        MUTATE_BODY( Expression, node );
     876}
     877
     878template< typename pass_type >
     879Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
     880        MUTATE_BODY( Expression, node );
     881}
     882
     883template< typename pass_type >
     884Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
     885        MUTATE_BODY( Expression, node );
     886}
     887
     888template< typename pass_type >
     889Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
     890        MUTATE_BODY( Expression, node );
     891}
     892
     893template< typename pass_type >
     894Expression * PassVisitor< pass_type >::mutate( MemberTupleExpr * node ) {
     895        MUTATE_BODY( Expression, node );
     896}
     897
     898template< typename pass_type >
     899Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
     900        MUTATE_BODY( Expression, node );
     901}
     902
     903template< typename pass_type >
     904Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
     905        MUTATE_BODY( Expression, node );
     906}
     907
     908template< typename pass_type >
     909Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
     910        MUTATE_BODY( Type, node );
     911}
     912
     913template< typename pass_type >
     914Type * PassVisitor< pass_type >::mutate( BasicType * node ) {
     915        MUTATE_BODY( Type, node );
     916}
     917
     918template< typename pass_type >
     919Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
     920        MUTATE_BODY( Type, node );
     921}
     922
     923template< typename pass_type >
     924Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
     925        MUTATE_BODY( Type, node );
     926}
     927
     928template< typename pass_type >
     929Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
     930        MUTATE_BODY( Type, node );
     931}
     932
     933template< typename pass_type >
     934Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
     935        MUTATE_BODY( Type, node );
     936}
     937
     938template< typename pass_type >
     939Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
     940        MUTATE_BODY( Type, node );
     941}
     942
     943template< typename pass_type >
     944Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
     945        MUTATE_BODY( Type, node );
     946}
     947
     948template< typename pass_type >
     949Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
     950        MUTATE_BODY( Type, node );
     951}
     952
     953template< typename pass_type >
     954Type * PassVisitor< pass_type >::mutate( TypeInstType * node ) {
     955        MUTATE_BODY( Type, node );
     956}
     957
     958template< typename pass_type >
     959Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
     960        MUTATE_BODY( Type, node );
     961}
     962
     963template< typename pass_type >
     964Type * PassVisitor< pass_type >::mutate( TypeofType * node ) {
     965        MUTATE_BODY( Type, node );
     966}
     967
     968template< typename pass_type >
     969Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
     970        MUTATE_BODY( Type, node );
     971}
     972
     973template< typename pass_type >
     974Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
     975        MUTATE_BODY( Type, node );
     976}
     977
     978template< typename pass_type >
     979Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
     980        MUTATE_BODY( Type, node );
     981}
     982
     983template< typename pass_type >
     984Type * PassVisitor< pass_type >::mutate( OneType * node ) {
     985        MUTATE_BODY( Type, node );
     986}
     987
     988template< typename pass_type >
     989Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) {
     990        MUTATE_BODY( Initializer, node );
     991}
     992
     993template< typename pass_type >
     994Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
     995        MUTATE_BODY( Initializer, node );
     996}
     997
     998template< typename pass_type >
     999Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
     1000        MUTATE_BODY( Subrange, node );
     1001}
     1002
     1003template< typename pass_type >
     1004Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
     1005        MUTATE_BODY( Constant, node );
     1006}
  • TabularUnified src/Common/utility.h

    r6065b3aa r49c9773  
    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
  • TabularUnified src/InitTweak/FixInit.cc

    r6065b3aa r49c9773  
    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
     
    190192                };
    191193
    192                 class FixInit final : public GenPoly::PolyMutator {
     194                class FixInit {
    193195                  public:
    194196                        /// expand each object declaration to use its constructor after it is declared.
    195197                        static void fixInitializers( std::list< Declaration * > &translationUnit );
    196198
    197                         typedef GenPoly::PolyMutator Parent;
    198                         using Parent::mutate;
    199                         virtual DeclarationWithType * mutate( ObjectDecl *objDecl ) override;
     199                        DeclarationWithType * postmutate( ObjectDecl *objDecl );
    200200
    201201                        std::list< Declaration * > staticDtorDecls;
     202                        std::list< Statement * > stmtsToAddAfter; // found by PassVisitor
    202203                };
    203204
     
    300301        namespace {
    301302                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) {
    302                         InsertImplicitCalls inserter( envMap );
     303                        PassVisitor<InsertImplicitCalls> inserter( envMap );
    303304                        mutateAll( translationUnit, inserter );
    304305                }
     
    310311
    311312                void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) {
    312                         FixInit fixer;
     313                        PassVisitor<FixInit> fixer;
    313314
    314315                        // can't use mutateAll, because need to insert declarations at top-level
     
    318319                                try {
    319320                                        *i = maybeMutate( *i, fixer );
    320                                         translationUnit.splice( i, fixer.staticDtorDecls );
     321                                        translationUnit.splice( i, fixer.pass.staticDtorDecls );
    321322                                } catch( SemanticError &e ) {
    322323                                        e.set_location( (*i)->location );
     
    350351                }
    351352
    352                 Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) {
    353                         appExpr = dynamic_cast< ApplicationExpr * >( Parent::mutate( appExpr ) );
     353                Expression * InsertImplicitCalls::postmutate( ApplicationExpr * appExpr ) {
    354354                        assert( appExpr );
    355355
     
    393393                }
    394394
    395                 Expression * InsertImplicitCalls::mutate( StmtExpr * stmtExpr ) {
     395                void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) {
    396396                        assert( env );
    397397                        envMap[stmtExpr] = env;
    398                         return Parent::mutate( stmtExpr );
    399398                }
    400399
     
    696695                }
    697696
    698                 DeclarationWithType *FixInit::mutate( ObjectDecl *objDecl ) {
    699                         // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors when the init
    700                         // is removed from the ObjectDecl
    701                         objDecl = dynamic_cast< ObjectDecl * >( Parent::mutate( objDecl ) );
     697                DeclarationWithType *FixInit::postmutate( ObjectDecl *objDecl ) {
     698                        // since this removes the init field from objDecl, it must occur after children are mutated (i.e. postmutate)
    702699                        if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
    703700                                // a decision should have been made by the resolver, so ctor and init are not both non-NULL
  • TabularUnified src/Tuples/TupleExpansion.cc

    r6065b3aa r49c9773  
    1818#include <cassert>
    1919#include "Tuples.h"
     20#include "Common/PassVisitor.h"
     21#include "Common/ScopedMap.h"
    2022#include "GenPoly/DeclMutator.h"
     23#include "InitTweak/GenInit.h"
     24#include "InitTweak/InitTweak.h"
     25#include "ResolvExpr/typeops.h"
     26#include "SymTab/Mangler.h"
     27#include "SynTree/Declaration.h"
     28#include "SynTree/Expression.h"
     29#include "SynTree/Initializer.h"
    2130#include "SynTree/Mutator.h"
    2231#include "SynTree/Statement.h"
    23 #include "SynTree/Declaration.h"
    2432#include "SynTree/Type.h"
    25 #include "SynTree/Expression.h"
    26 #include "SynTree/Initializer.h"
    27 #include "SymTab/Mangler.h"
    28 #include "Common/ScopedMap.h"
    29 #include "ResolvExpr/typeops.h"
    30 #include "InitTweak/GenInit.h"
    31 #include "InitTweak/InitTweak.h"
    3233
    3334namespace Tuples {
     
    8283                };
    8384
    84                 class TupleIndexExpander final : public Mutator {
    85                 public:
    86                         typedef Mutator Parent;
    87                         using Parent::mutate;
    88 
    89                         virtual Expression * mutate( TupleIndexExpr * tupleExpr ) override;
     85                class TupleIndexExpander {
     86                public:
     87                        Expression * postmutate( TupleIndexExpr * tupleExpr );
    9088                };
    9189
     
    116114                replacer.mutateDeclarationList( translationUnit );
    117115
    118                 TupleIndexExpander idxExpander;
     116                PassVisitor<TupleIndexExpander> idxExpander;
    119117                mutateAll( translationUnit, idxExpander );
    120118
     
    250248        }
    251249
    252         Expression * TupleIndexExpander::mutate( TupleIndexExpr * tupleExpr ) {
    253                 Expression * tuple = maybeMutate( tupleExpr->get_tuple(), *this );
     250        Expression * TupleIndexExpander::postmutate( TupleIndexExpr * tupleExpr ) {
     251                Expression * tuple = tupleExpr->get_tuple();
    254252                assert( tuple );
    255253                tupleExpr->set_tuple( nullptr );
  • TabularUnified src/tests/test.py

    r6065b3aa r49c9773  
    253253        # for each test to run
    254254        try :
    255                 results = pool.map_async(partial(run_test_worker, generate=generate, dry_run=dry_run, debug=debug), tests, chunksize = 1 ).get(3600)
     255                results = pool.map_async(partial(run_test_worker, generate=generate, dry_run=dry_run, debug=debug), tests, chunksize = 1 ).get(7200)
    256256        except KeyboardInterrupt:
    257257                pool.terminate()
Note: See TracChangeset for help on using the changeset viewer.