#pragma once #define VISIT_START( node ) \ __attribute__((unused)) \ const auto & guard = init_guard(); \ call_previsit( node ); \ if( visit_children() ) { \ reset_visit(); \ #define VISIT_END( node ) \ } \ call_postvisit( node ); \ #define MUTATE_START( node ) \ __attribute__((unused)) \ const auto & guard = init_guard(); \ call_premutate( node ); \ if( visit_children() ) { \ reset_visit(); \ #define MUTATE_END( type, node ) \ } \ return call_postmutate< type * >( node ); \ #define VISIT_BODY( node ) \ VISIT_START( node ); \ Visitor::visit( node ); \ VISIT_END( node ); \ #define MUTATE_BODY( type, node ) \ MUTATE_START( node ); \ Mutator::mutate( node ); \ MUTATE_END( type, node ); \ template static inline bool empty( T * ptr ) { return !ptr || ptr->empty(); } typedef std::list< Statement * > StmtList_t; template< typename pass_type > void PassVisitor< pass_type >::visitStatementList( std::list< Statement * > & statements ) { SemanticError errors; StmtList_t* beforeStmts = get_beforeStmts(); StmtList_t* afterStmts = get_afterStmts(); for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) { if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); } try { (*i)->accept( *this ); } catch ( SemanticError &e ) { errors.append( e ); } if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); } } if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); } if ( !errors.isEmpty() ) { throw errors; } } template< typename pass_type > void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) { SemanticError errors; StmtList_t* beforeStmts = get_beforeStmts(); StmtList_t* afterStmts = get_afterStmts(); for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) { if ( !empty( afterStmts ) ) { statements.splice( i, *afterStmts ); } try { *i = (*i)->acceptMutator( *this ); } catch ( SemanticError &e ) { errors.append( e ); } if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); } } if ( !empty( afterStmts ) ) { statements.splice( statements.end(), *afterStmts ); } if ( !errors.isEmpty() ) { throw errors; } } template< typename pass_type > Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) { // don't want statements from outer CompoundStmts to be added to this CompoundStmt ValueGuardPtr< TypeSubstitution * > oldEnv ( get_env_ptr() ); ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); maybeAccept( stmt, *this ); StmtList_t* beforeStmts = get_beforeStmts(); StmtList_t* afterStmts = get_afterStmts(); if( empty(beforeStmts) && empty(afterStmts) ) { return stmt; } CompoundStmt *compound = new CompoundStmt( noLabels ); if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); } compound->get_kids().push_back( stmt ); if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); } return compound; } template< typename pass_type > Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) { // don't want statements from outer CompoundStmts to be added to this CompoundStmt ValueGuardPtr< TypeSubstitution * > oldEnv ( get_env_ptr() ); ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); Statement *newStmt = maybeMutate( stmt, *this ); StmtList_t* beforeStmts = get_beforeStmts(); StmtList_t* afterStmts = get_afterStmts(); if( empty(beforeStmts) && empty(afterStmts) ) { return newStmt; } CompoundStmt *compound = new CompoundStmt( noLabels ); if( !empty(beforeStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *beforeStmts ); } compound->get_kids().push_back( newStmt ); if( !empty(afterStmts) ) { compound->get_kids().splice( compound->get_kids().end(), *afterStmts ); } return compound; } template< typename pass_type > void PassVisitor< pass_type >::visitExpression( Expression * expr ) { if( !expr ) return; auto env_ptr = get_env_ptr(); if ( env_ptr && expr->get_env() ) { *env_ptr = expr->get_env(); } // xxx - should env be cloned (or moved) onto the result of the mutate? expr->accept( *this ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) { if( !expr ) return nullptr; auto env_ptr = get_env_ptr(); if ( env_ptr && expr->get_env() ) { *env_ptr = expr->get_env(); } // xxx - should env be cloned (or moved) onto the result of the mutate? return expr->acceptMutator( *this ); } //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ template< typename pass_type > void PassVisitor< pass_type >::visit( ObjectDecl * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( FunctionDecl * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( StructDecl * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( UnionDecl * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( EnumDecl * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TraitDecl * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TypeDecl * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TypedefDecl * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( AsmDecl * node ) { VISIT_BODY( node ); } //-------------------------------------------------------------------------- // CompoundStmt template< typename pass_type > void PassVisitor< pass_type >::visit( CompoundStmt * node ) { VISIT_START( node ); call_beginScope(); visitStatementList( node->get_kids() ); call_endScope(); VISIT_END( node ); } template< typename pass_type > CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) { MUTATE_START( node ); call_beginScope(); mutateStatementList( node->get_kids() ); call_endScope(); MUTATE_END( CompoundStmt, node ); } //-------------------------------------------------------------------------- // ExprStmt template< typename pass_type > void PassVisitor< pass_type >::visit( ExprStmt * node ) { VISIT_START( node ); call_beginScope(); visitExpression( node->get_expr() ); call_endScope(); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( ExprStmt * node ) { MUTATE_START( node ); node->set_expr( mutateExpression( node->get_expr() ) ); MUTATE_END( Statement, node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( AsmStmt * node ) { VISIT_BODY( node ); } //-------------------------------------------------------------------------- // IfStmt template< typename pass_type > void PassVisitor< pass_type >::visit( IfStmt * node ) { VISIT_START( node ); visitExpression( node->get_condition() ); node->set_thenPart ( visitStatement( node->get_thenPart() ) ); node->set_elsePart ( visitStatement( node->get_elsePart() ) ); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) { MUTATE_START( node ); node->set_condition( mutateExpression( node->get_condition() ) ); node->set_thenPart ( mutateStatement ( node->get_thenPart() ) ); node->set_elsePart ( mutateStatement ( node->get_elsePart() ) ); MUTATE_END( Statement, node ); } //-------------------------------------------------------------------------- // WhileStmt template< typename pass_type > void PassVisitor< pass_type >::visit( WhileStmt * node ) { VISIT_START( node ); visitExpression( node->get_condition() ); node->set_body( visitStatement( node->get_body() ) ); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( WhileStmt * node ) { MUTATE_START( node ); node->set_condition( mutateExpression( node->get_condition() ) ); node->set_body( mutateStatement( node->get_body() ) ); MUTATE_END( Statement, node ); } //-------------------------------------------------------------------------- // WhileStmt template< typename pass_type > void PassVisitor< pass_type >::visit( ForStmt * node ) { VISIT_START( node ); acceptAll( node->get_initialization(), *this ); visitExpression( node->get_condition() ); visitExpression( node->get_increment() ); node->set_body( visitStatement( node->get_body() ) ); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) { MUTATE_START( node ); mutateAll( node->get_initialization(), *this ); node->set_condition( mutateExpression( node->get_condition() ) ); node->set_increment( mutateExpression( node->get_increment() ) ); node->set_body( mutateStatement( node->get_body() ) ); MUTATE_END( Statement, node ); } //-------------------------------------------------------------------------- // SwitchStmt template< typename pass_type > void PassVisitor< pass_type >::visit( SwitchStmt * node ) { VISIT_START( node ); visitExpression( node->get_condition() ); visitStatementList( node->get_statements() ); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) { MUTATE_START( node ); node->set_condition( mutateExpression( node->get_condition() ) ); mutateStatementList( node->get_statements() ); MUTATE_END( Statement, node ); } //-------------------------------------------------------------------------- // SwitchStmt template< typename pass_type > void PassVisitor< pass_type >::visit( CaseStmt * node ) { VISIT_START( node ); visitExpression( node->get_condition() ); visitStatementList( node->get_statements() ); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) { MUTATE_START( node ); node->set_condition( mutateExpression( node->get_condition() ) ); mutateStatementList( node->get_statements() ); MUTATE_END( Statement, node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( BranchStmt * node ) { VISIT_BODY( node ); } //-------------------------------------------------------------------------- // ReturnStmt template< typename pass_type > void PassVisitor< pass_type >::visit( ReturnStmt * node ) { VISIT_START( node ); visitExpression( node->get_expr() ); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) { MUTATE_START( node ); node->set_expr( mutateExpression( node->get_expr() ) ); MUTATE_END( Statement, node ); } //-------------------------------------------------------------------------- // ThrowStmt template< typename pass_type > void PassVisitor< pass_type >::visit( ThrowStmt * node ) { VISIT_BODY( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) { MUTATE_BODY( Statement, node ); } //-------------------------------------------------------------------------- // TryStmt template< typename pass_type > void PassVisitor< pass_type >::visit( TryStmt * node ) { VISIT_START( node ); maybeAccept( node->get_block(), *this ); acceptAll( node->get_catchers(), *this ); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( TryStmt * node ) { MUTATE_START( node ); node->set_block( maybeMutate( node->get_block(), *this ) ); mutateAll( node->get_catchers(), *this ); MUTATE_END( Statement, node ); } //-------------------------------------------------------------------------- // CatchStmt template< typename pass_type > void PassVisitor< pass_type >::visit( CatchStmt * node ) { VISIT_START( node ); node->set_body( visitStatement( node->get_body() ) ); maybeAccept( node->get_decl(), *this ); VISIT_END( node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) { MUTATE_START( node ); node->set_body( mutateStatement( node->get_body() ) ); node->set_decl( maybeMutate( node->get_decl(), *this ) ); MUTATE_END( Statement, node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( FinallyStmt * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( NullStmt * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( DeclStmt * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ApplicationExpr * node ) { VISIT_BODY( node ); } //-------------------------------------------------------------------------- // UntypedExpr template< typename pass_type > void PassVisitor< pass_type >::visit( UntypedExpr * node ) { VISIT_START( node ); for ( auto expr : node->get_args() ) { visitExpression( expr ); } VISIT_END( node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) { MUTATE_START( node ); for ( auto& expr : node->get_args() ) { expr = mutateExpression( expr ); } MUTATE_END( Expression, node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( NameExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( CastExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( AddressExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( LabelAddressExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( MemberExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( VariableExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ConstantExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( SizeofExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( AlignofExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( UntypedOffsetofExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( OffsetofExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( OffsetPackExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( AttrExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( LogicalExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ConditionalExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( CommaExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TypeExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( AsmExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ImplicitCopyCtorExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ConstructorExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( CompoundLiteralExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( UntypedValofExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( RangeExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( UntypedTupleExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TupleExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TupleIndexExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TupleAssignExpr * node ) { VISIT_BODY( node ); } //-------------------------------------------------------------------------- // UntypedExpr template< typename pass_type > void PassVisitor< pass_type >::visit( StmtExpr * node ) { VISIT_START( node ); // don't want statements from outer CompoundStmts to be added to this StmtExpr ValueGuardPtr< TypeSubstitution * > oldEnv ( get_env_ptr() ); ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); Visitor::visit( node ); VISIT_END( node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) { MUTATE_START( node ); // don't want statements from outer CompoundStmts to be added to this StmtExpr ValueGuardPtr< TypeSubstitution * > oldEnv ( get_env_ptr() ); ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() ); ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () ); Mutator::mutate( node ); MUTATE_END( Expression, node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( UniqueExpr * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( VoidType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( BasicType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( PointerType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ArrayType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( FunctionType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( StructInstType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( UnionInstType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( EnumInstType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TraitInstType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TypeInstType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TupleType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( TypeofType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( AttrType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( VarArgsType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ZeroType * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( OneType * node ) { VISIT_BODY( node ); } //-------------------------------------------------------------------------- // UntypedExpr template< typename pass_type > void PassVisitor< pass_type >::visit( SingleInit * node ) { VISIT_START( node ); visitExpression( node->get_value() ); VISIT_END( node ); } template< typename pass_type > Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) { MUTATE_START( node ); node->set_value( mutateExpression( node->get_value() ) ); MUTATE_END( Initializer, node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ListInit * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( ConstructorInit * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( Subrange * node ) { VISIT_BODY( node ); } template< typename pass_type > void PassVisitor< pass_type >::visit( Constant * node ) { VISIT_BODY( node ); } //--------------------------------------------------------------------------------------------------------------- template< typename pass_type > DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) { MUTATE_BODY( DeclarationWithType, node ); } template< typename pass_type > DeclarationWithType * PassVisitor< pass_type >::mutate( FunctionDecl * node ) { MUTATE_BODY( DeclarationWithType, node ); } template< typename pass_type > Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) { MUTATE_BODY( Declaration, node ); } template< typename pass_type > Declaration * PassVisitor< pass_type >::mutate( UnionDecl * node ) { MUTATE_BODY( Declaration, node ); } template< typename pass_type > Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) { MUTATE_BODY( Declaration, node ); } template< typename pass_type > Declaration * PassVisitor< pass_type >::mutate( TraitDecl * node ) { MUTATE_BODY( Declaration, node ); } template< typename pass_type > TypeDecl * PassVisitor< pass_type >::mutate( TypeDecl * node ) { MUTATE_BODY( TypeDecl, node ); } template< typename pass_type > Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) { MUTATE_BODY( Declaration, node ); } template< typename pass_type > AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) { MUTATE_BODY( AsmDecl, node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) { MUTATE_BODY( Statement, node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) { MUTATE_BODY( Statement, node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) { MUTATE_BODY( Statement, node ); } template< typename pass_type > NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) { MUTATE_BODY( NullStmt, node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) { MUTATE_BODY( Statement, node ); } template< typename pass_type > Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) { MUTATE_BODY( Statement, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( CastExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( UntypedMemberExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( ConstantExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( SizeofExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( LogicalExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( ConditionalExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( AsmExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( ImplicitCopyCtorExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( ConstructorExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( UntypedValofExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( RangeExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) { MUTATE_BODY( Expression, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( VoidType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( BasicType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( PointerType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( ArrayType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( FunctionType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( StructInstType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( TypeInstType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( TupleType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( TypeofType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( AttrType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( ZeroType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Type * PassVisitor< pass_type >::mutate( OneType * node ) { MUTATE_BODY( Type, node ); } template< typename pass_type > Initializer * PassVisitor< pass_type >::mutate( ListInit * node ) { MUTATE_BODY( Initializer, node ); } template< typename pass_type > Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) { MUTATE_BODY( Initializer, node ); } template< typename pass_type > Subrange * PassVisitor< pass_type >::mutate( Subrange * node ) { MUTATE_BODY( Subrange, node ); } template< typename pass_type > Constant * PassVisitor< pass_type >::mutate( Constant * node ) { MUTATE_BODY( Constant, node ); }