Changes in / [fe5c01d:949934e]


Ignore:
Location:
src
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • src/Common/PassVisitor.h

    rfe5c01d r949934e  
    1212#include "SynTree/Expression.h"
    1313#include "SynTree/Constant.h"
     14#include "SynTree/TypeSubstitution.h"
    1415
    1516#include "PassVisitor.proto.h"
     
    2627//                          stmtsToAddBefore or stmtsToAddAfter respectively.
    2728// | WithShortCircuiting  - provides the ability to skip visiting child nodes; set visit_children to false in pre{visit,mutate} to skip visiting children
    28 // | WithScopes           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
     29// | WithGuards           - provides the ability to save/restore data like a LIFO stack; to save, call GuardValue with the variable to save, the variable
    2930//                          will automatically be restored to its previous value after the corresponding postvisit/postmutate teminates.
    3031//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
     
    3233class PassVisitor final : public Visitor, public Mutator {
    3334public:
    34         PassVisitor() = default;
    3535
    3636        template< typename... Args >
     
    283283
    284284public:
    285         TypeSubstitution * env;
     285        TypeSubstitution * env = nullptr;
    286286};
    287287
     
    295295        std::list< Statement* > stmtsToAddAfter;
    296296};
     297
     298class WithDeclsToAdd {
     299protected:
     300        WithDeclsToAdd() = default;
     301        ~WithDeclsToAdd() = default;
     302
     303public:
     304        std::list< Declaration* > declsToAddBefore;
     305        std::list< Declaration* > declsToAddAfter;
     306};
     307
    297308class WithShortCircuiting {
    298309protected:
     
    304315};
    305316
    306 class WithScopes {
    307 protected:
    308         WithScopes() = default;
    309         ~WithScopes() = default;
     317class WithGuards {
     318protected:
     319        WithGuards() = default;
     320        ~WithGuards() = default;
    310321
    311322public:
     
    318329                }, static_cast< void * >( & val ) );
    319330        }
     331
     332        template< typename T >
     333        void GuardScope( T& val ) {
     334                val.beginScope();
     335                at_cleanup( []( void * val ) {
     336                        static_cast< T * >( val )->endScope();
     337                }, static_cast< void * >( & val ) );
     338        }
     339
     340        template< typename Func >
     341        void GuardAction( Func func ) {
     342                at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr );
     343        }
    320344};
    321345
     
    323347class WithVisitorRef {
    324348protected:
    325         WithVisitorRef() = default;
    326         ~WithVisitorRef() = default;
    327 
    328 public:
    329         PassVisitor<pass_type> * const visitor;
     349        WithVisitorRef() {}
     350        ~WithVisitorRef() {}
     351
     352public:
     353        PassVisitor<pass_type> * const visitor = nullptr;
    330354};
    331355
  • src/Common/PassVisitor.impl.h

    rfe5c01d r949934e  
    6868        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
    6969                // splice in new declarations after previous decl
    70                 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 
     70                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
    7171
    7272                if ( i == decls.end() ) break;
     
    8888        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
    8989                // splice in new declarations after previous decl
    90                 if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); } 
     90                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
    9191
    9292                if ( i == decls.end() ) break;
     
    104104void PassVisitor< pass_type >::handleStatementList( std::list< Statement * > & statements, func_t func ) {
    105105        SemanticError errors;
     106
     107        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     108        ValueGuardPtr< StmtList_t > oldBeforeStmts( get_beforeStmts() );
     109        ValueGuardPtr< StmtList_t > oldAfterStmts ( get_afterStmts () );
     110        ValueGuardPtr< DeclList_t > oldBeforeDecls( get_beforeDecls() );
     111        ValueGuardPtr< DeclList_t > oldAfterDecls ( get_afterDecls () );
    106112
    107113        StmtList_t* beforeStmts = get_beforeStmts();
     
    181187Statement * PassVisitor< pass_type >::visitStatement( Statement * stmt ) {
    182188        return handleStatement( stmt, [this]( Statement * stmt ) {
    183                 maybeAccept( stmt, *this ); 
     189                maybeAccept( stmt, *this );
    184190                return stmt;
    185191        });
     
    212218                expr->accept( *this );
    213219                return expr;
    214         });             
     220        });
    215221}
    216222
     
    565571        VISIT_START( node );
    566572
     573        // maybeAccept( node->get_env(), *this );
     574        maybeAccept( node->get_result(), *this );
     575
    567576        for ( auto expr : node->get_args() ) {
    568577                visitExpression( expr );
     
    575584Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
    576585        MUTATE_START( node );
     586
     587        node->set_env( maybeMutate( node->get_env(), *this ) );
     588        node->set_result( maybeMutate( node->get_result(), *this ) );
    577589
    578590        for ( auto& expr : node->get_args() ) {
  • src/Common/PassVisitor.proto.h

    rfe5c01d r949934e  
    5656// Deep magic (a.k.a template meta programming) to make the templated visitor work
    5757// Basically the goal is to make 2 previsit_impl
    58 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 
     58// 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of
    5959//     'pass.previsit( node )' that compiles will be used for that node for that type
    6060//     This requires that this option only compile for passes that actually define an appropriate visit.
  • src/GenPoly/Box.cc

    rfe5c01d r949934e  
    504504                DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) {
    505505                        if ( functionDecl->get_statements() ) {         // empty routine body ?
     506                                // std::cerr << "mutating function: " << functionDecl->get_mangleName() << std::endl;
    506507                                doBeginScope();
    507508                                scopeTyVars.beginScope();
     
    548549                                retval = oldRetval;
    549550                                doEndScope();
     551                                // std::cerr << "end function: " << functionDecl->get_mangleName() << std::endl;
    550552                        } // if
    551553                        return functionDecl;
     
    11161118
    11171119                Expression *Pass1::mutate( ApplicationExpr *appExpr ) {
    1118                         // std::cerr << "mutate appExpr: ";
     1120                        // std::cerr << "mutate appExpr: " << InitTweak::getFunctionName( appExpr ) << std::endl;
    11191121                        // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    11201122                        //      std::cerr << i->first << " ";
     
    11411143                        ReferenceToType *dynRetType = isDynRet( function, exprTyVars );
    11421144
     1145                        // std::cerr << function << std::endl;
     1146                        // std::cerr << "scopeTyVars: ";
     1147                        // printTyVarMap( std::cerr, scopeTyVars );
     1148                        // std::cerr << "exprTyVars: ";
     1149                        // printTyVarMap( std::cerr, exprTyVars );
     1150                        // std::cerr << "env: " << *env << std::endl;
     1151                        // std::cerr << needsAdapter( function, scopeTyVars ) << ! needsAdapter( function, exprTyVars) << std::endl;
     1152
    11431153                        // NOTE: addDynRetParam needs to know the actual (generated) return type so it can make a temp variable, so pass the result type from the appExpr
    11441154                        // passTypeVars needs to know the program-text return type (i.e. the distinction between _conc_T30 and T3(int))
    11451155                        // concRetType may not be a good name in one or both of these places. A more appropriate name change is welcome.
    11461156                        if ( dynRetType ) {
     1157                                // std::cerr << "dynRetType: " << dynRetType << std::endl;
    11471158                                Type *concRetType = appExpr->get_result()->isVoid() ? nullptr : appExpr->get_result();
    11481159                                ret = addDynRetParam( appExpr, concRetType, arg ); // xxx - used to use dynRetType instead of concRetType
  • src/GenPoly/InstantiateGeneric.cc

    rfe5c01d r949934e  
    2222#include "InstantiateGeneric.h"
    2323
    24 #include "DeclMutator.h"
    2524#include "GenPoly.h"
    2625#include "ScopedSet.h"
    2726#include "ScrubTyVars.h"
    28 #include "PolyMutator.h"
     27
     28#include "Common/PassVisitor.h"
     29#include "Common/ScopedMap.h"
     30#include "Common/UniqueName.h"
     31#include "Common/utility.h"
    2932
    3033#include "ResolvExpr/typeops.h"
     
    3437#include "SynTree/Type.h"
    3538
    36 #include "Common/ScopedMap.h"
    37 #include "Common/UniqueName.h"
    38 #include "Common/utility.h"
     39
     40#include "InitTweak/InitTweak.h"
     41
    3942
    4043namespace GenPoly {
     
    153156        }
    154157
    155         // collect the environments of each TypeInstType so that type variables can be replaced
    156         // xxx - possibly temporary solution. Access to type environments is required in GenericInstantiator, but it needs to be a DeclMutator which does not provide easy access to the type environments.
    157         class EnvFinder final : public GenPoly::PolyMutator {
    158         public:
    159                 using GenPoly::PolyMutator::mutate;
    160                 virtual Type * mutate( TypeInstType * inst ) override {
    161                         if ( env ) envMap[inst] = env;
    162                         return inst;
    163                 }
    164 
    165                 // don't want to associate an environment with TypeInstTypes that occur in function types - this may actually only apply to function types belonging to DeclarationWithTypes (or even just FunctionDecl)?
    166                 virtual Type * mutate( FunctionType * ftype ) override {
    167                         return ftype;
    168                 }
    169                 std::unordered_map< ReferenceToType *, TypeSubstitution * > envMap;
    170         };
    171 
    172158        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    173         class GenericInstantiator final : public DeclMutator {
     159        struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
    174160                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    175161                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
     
    178164                /// Namer for concrete types
    179165                UniqueName typeNamer;
    180                 /// Reference to mapping of environments
    181                 const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap;
    182         public:
    183                 GenericInstantiator( const std::unordered_map< ReferenceToType *, TypeSubstitution * > & envMap ) : DeclMutator(), instantiations(), dtypeStatics(), typeNamer("_conc_"), envMap( envMap ) {}
    184 
    185                 using DeclMutator::mutate;
    186                 virtual Type* mutate( StructInstType *inst ) override;
    187                 virtual Type* mutate( UnionInstType *inst ) override;
    188 
    189                 virtual void doBeginScope() override;
    190                 virtual void doEndScope() override;
     166                /// Should not make use of type environment to replace types of function parameter and return values.
     167                bool inFunctionType = false;
     168                GenericInstantiator() : instantiations(), dtypeStatics(), typeNamer("_conc_") {}
     169
     170                Type* postmutate( StructInstType *inst );
     171                Type* postmutate( UnionInstType *inst );
     172
     173                void premutate( FunctionType * ftype ) {
     174                        GuardValue( inFunctionType );
     175                        inFunctionType = true;
     176                }
     177
     178                void beginScope();
     179                void endScope();
    191180        private:
    192181                /// Wrap instantiation lookup for structs
     
    207196
    208197        void instantiateGeneric( std::list< Declaration* > &translationUnit ) {
    209                 EnvFinder finder;
    210                 mutateAll( translationUnit, finder );
    211                 GenericInstantiator instantiator( finder.envMap );
    212                 instantiator.mutateDeclarationList( translationUnit );
     198                PassVisitor<GenericInstantiator> instantiator;
     199                mutateAll( translationUnit, instantiator );
    213200        }
    214201
     
    306293        Type *GenericInstantiator::replaceWithConcrete( Type *type, bool doClone ) {
    307294                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
    308                         if ( envMap.count( typeInst ) ) {
    309                                 TypeSubstitution * env = envMap.at( typeInst );
     295                        if ( env && ! inFunctionType ) {
    310296                                Type *concrete = env->lookup( typeInst->get_name() );
    311297                                if ( concrete ) {
     
    331317
    332318
    333         Type* GenericInstantiator::mutate( StructInstType *inst ) {
    334                 // mutate subtypes
    335                 Type *mutated = Mutator::mutate( inst );
    336                 inst = dynamic_cast< StructInstType* >( mutated );
    337                 if ( ! inst ) return mutated;
    338 
     319        Type* GenericInstantiator::postmutate( StructInstType *inst ) {
    339320                // exit early if no need for further mutation
    340321                if ( inst->get_parameters().empty() ) return inst;
     
    368349                                substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    369350                                insert( inst, typeSubs, concDecl ); // must insert before recursion
    370                                 concDecl->acceptMutator( *this ); // recursively instantiate members
    371                                 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
     351                                concDecl->acceptMutator( *visitor ); // recursively instantiate members
     352                                declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
    372353                        }
    373354                        StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
     
    388369        }
    389370
    390         Type* GenericInstantiator::mutate( UnionInstType *inst ) {
    391                 // mutate subtypes
    392                 Type *mutated = Mutator::mutate( inst );
    393                 inst = dynamic_cast< UnionInstType* >( mutated );
    394                 if ( ! inst ) return mutated;
    395 
     371        Type* GenericInstantiator::postmutate( UnionInstType *inst ) {
    396372                // exit early if no need for further mutation
    397373                if ( inst->get_parameters().empty() ) return inst;
     
    423399                                substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    424400                                insert( inst, typeSubs, concDecl ); // must insert before recursion
    425                                 concDecl->acceptMutator( *this ); // recursively instantiate members
    426                                 DeclMutator::addDeclaration( concDecl ); // must occur before declaration is added so that member instantiations appear first
     401                                concDecl->acceptMutator( *visitor ); // recursively instantiate members
     402                                declsToAddBefore.push_back( concDecl ); // must occur before declaration is added so that member instantiations appear first
    427403                        }
    428404                        UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
     
    442418        }
    443419
    444         void GenericInstantiator::doBeginScope() {
    445                 DeclMutator::doBeginScope();
     420        void GenericInstantiator::beginScope() {
    446421                instantiations.beginScope();
    447422                dtypeStatics.beginScope();
    448423        }
    449424
    450         void GenericInstantiator::doEndScope() {
    451                 DeclMutator::doEndScope();
     425        void GenericInstantiator::endScope() {
    452426                instantiations.endScope();
    453427                dtypeStatics.endScope();
  • src/InitTweak/GenInit.cc

    rfe5c01d r949934e  
    4444        }
    4545
    46         class ReturnFixer : public WithStmtsToAdd, public WithScopes {
    47           public:
     46        struct ReturnFixer : public WithStmtsToAdd, public WithGuards {
    4847                /// consistently allocates a temporary variable for the return value
    4948                /// of a function so that anything which the resolver decides can be constructed
     
    5958        };
    6059
    61         class CtorDtor final : public GenPoly::PolyMutator {
    62           public:
    63                 typedef GenPoly::PolyMutator Parent;
    64                 using Parent::mutate;
     60        struct CtorDtor : public WithGuards, public WithShortCircuiting  {
    6561                /// create constructor and destructor statements for object declarations.
    6662                /// the actual call statements will be added in after the resolver has run
     
    6965                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
    7066
    71                 virtual DeclarationWithType * mutate( ObjectDecl * ) override;
    72                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override;
     67                void previsit( ObjectDecl * );
     68                void previsit( FunctionDecl *functionDecl );
     69
    7370                // should not traverse into any of these declarations to find objects
    7471                // that need to be constructed or destructed
    75                 virtual Declaration* mutate( StructDecl *aggregateDecl ) override;
    76                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; }
    77                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; }
    78                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; }
    79                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; }
    80                 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; }
    81 
    82                 virtual Type * mutate( FunctionType *funcType ) override { return funcType; }
    83 
    84                 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override;
     72                void previsit( StructDecl *aggregateDecl );
     73                void previsit( UnionDecl *aggregateDecl ) { visit_children = false; }
     74                void previsit( EnumDecl *aggregateDecl ) { visit_children = false; }
     75                void previsit( TraitDecl *aggregateDecl ) { visit_children = false; }
     76                void previsit( TypeDecl *typeDecl ) { visit_children = false; }
     77                void previsit( TypedefDecl *typeDecl ) { visit_children = false; }
     78
     79                void previsit( FunctionType *funcType ) { visit_children = false; }
     80
     81                void previsit( CompoundStmt * compoundStmt );
    8582
    8683          private:
     
    211208
    212209        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
    213                 CtorDtor ctordtor;
    214                 mutateAll( translationUnit, ctordtor );
     210                PassVisitor<CtorDtor> ctordtor;
     211                acceptAll( translationUnit, ctordtor );
    215212        }
    216213
     
    289286        }
    290287
    291         DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
     288        void CtorDtor::previsit( ObjectDecl * objDecl ) {
    292289                handleDWT( objDecl );
    293290                // hands off if @=, extern, builtin, etc.
     
    301298                        objDecl->set_init( genCtorInit( objDecl ) );
    302299                }
    303                 return Parent::mutate( objDecl );
    304         }
    305 
    306         DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
    307                 ValueGuard< bool > oldInFunc = inFunction;
     300        }
     301
     302        void CtorDtor::previsit( FunctionDecl *functionDecl ) {
     303                GuardValue( inFunction );
    308304                inFunction = true;
    309305
    310306                handleDWT( functionDecl );
    311307
    312                 managedTypes.beginScope();
     308                GuardScope( managedTypes );
    313309                // go through assertions and recursively add seen ctor/dtors
    314310                for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
     
    317313                        }
    318314                }
    319                 // parameters should not be constructed and destructed, so don't mutate FunctionType
    320                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    321 
    322                 managedTypes.endScope();
    323                 return functionDecl;
    324         }
    325 
    326         Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
     315
     316                PassVisitor<CtorDtor> newCtorDtor;
     317                newCtorDtor.pass = *this;
     318                maybeAccept( functionDecl->get_statements(), newCtorDtor );
     319                visit_children = false;  // do not try and construct parameters or forall parameters - must happen after maybeAccept
     320        }
     321
     322        void CtorDtor::previsit( StructDecl *aggregateDecl ) {
     323                visit_children = false; // do not try to construct and destruct aggregate members
     324
    327325                // don't construct members, but need to take note if there is a managed member,
    328326                // because that means that this type is also managed
     
    336334                        }
    337335                }
    338                 return aggregateDecl;
    339         }
    340 
    341         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    342                 managedTypes.beginScope();
    343                 CompoundStmt * stmt = Parent::mutate( compoundStmt );
    344                 managedTypes.endScope();
    345                 return stmt;
    346         }
    347 
     336        }
     337
     338        void CtorDtor::previsit( CompoundStmt * compoundStmt ) {
     339                GuardScope( managedTypes );
     340        }
    348341} // namespace InitTweak
    349342
  • src/SymTab/Validate.cc

    rfe5c01d r949934e  
    106106
    107107        /// Fix return types so that every function returns exactly one value
    108         class ReturnTypeFixer {
    109           public:
     108        struct ReturnTypeFixer {
    110109                static void fix( std::list< Declaration * > &translationUnit );
    111110
     
    115114
    116115        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    117         class EnumAndPointerDecay {
    118         public:
     116        struct EnumAndPointerDecay {
    119117                void previsit( EnumDecl *aggregateDecl );
    120118                void previsit( FunctionType *func );
     
    159157        };
    160158
    161         class ReturnChecker : public WithScopes {
    162           public:
     159        struct ReturnChecker : public WithGuards {
    163160                /// Checks that return statements return nothing if their return type is void
    164161                /// and return something if the return type is non-void.
    165162                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
    166           private:
     163
    167164                void previsit( FunctionDecl * functionDecl );
    168165                void previsit( ReturnStmt * returnStmt );
     
    205202        };
    206203
    207         class VerifyCtorDtorAssign {
    208         public:
     204        struct VerifyCtorDtorAssign {
    209205                /// ensure that constructors, destructors, and assignment have at least one
    210206                /// parameter, the first of which must be a pointer, and that ctor/dtors have no
     
    216212
    217213        /// ensure that generic types have the correct number of type arguments
    218         class ValidateGenericParameters {
    219         public:
     214        struct ValidateGenericParameters {
    220215                void previsit( StructInstType * inst );
    221216                void previsit( UnionInstType * inst );
    222217        };
    223218
    224         class ArrayLength {
    225         public:
     219        struct ArrayLength {
    226220                /// for array types without an explicit length, compute the length and store it so that it
    227221                /// is known to the rest of the phases. For example,
     
    236230        };
    237231
    238         class CompoundLiteral final : public GenPoly::DeclMutator {
     232        struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> {
    239233                Type::StorageClasses storageClasses;
    240234
    241                 using GenPoly::DeclMutator::mutate;
    242                 DeclarationWithType * mutate( ObjectDecl *objectDecl ) final;
    243                 Expression *mutate( CompoundLiteralExpr *compLitExpr ) final;
     235                void premutate( ObjectDecl *objectDecl );
     236                Expression * postmutate( CompoundLiteralExpr *compLitExpr );
    244237        };
    245238
     
    248241                LinkReferenceToTypes lrt( doDebug, 0 );
    249242                ForallPointerDecay fpd( 0 );
    250                 CompoundLiteral compoundliteral;
     243                PassVisitor<CompoundLiteral> compoundliteral;
    251244                PassVisitor<ValidateGenericParameters> genericParams;
    252245
     
    263256                Concurrency::implementThreadStarter( translationUnit );
    264257                ReturnChecker::checkFunctionReturns( translationUnit );
    265                 compoundliteral.mutateDeclarationList( translationUnit );
     258                mutateAll( translationUnit, compoundliteral );
    266259                acceptAll( translationUnit, fpd );
    267260                ArrayLength::computeLength( translationUnit );
     
    883876        }
    884877
    885         DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
     878        void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
    886879                storageClasses = objectDecl->get_storageClasses();
    887                 DeclarationWithType * temp = Mutator::mutate( objectDecl );
    888                 return temp;
    889         }
    890 
    891         Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
     880        }
     881
     882        Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
    892883                // transform [storage_class] ... (struct S){ 3, ... };
    893884                // into [storage_class] struct S temp =  { 3, ... };
    894885                static UniqueName indexName( "_compLit" );
    895886
    896                 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, 0, compLitExpr->get_result(), compLitExpr->get_initializer() );
    897                 compLitExpr->set_result( 0 );
    898                 compLitExpr->set_initializer( 0 );
     887                ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
     888                compLitExpr->set_result( nullptr );
     889                compLitExpr->set_initializer( nullptr );
    899890                delete compLitExpr;
    900                 DeclarationWithType * newtempvar = mutate( tempvar );
    901                 addDeclaration( newtempvar );                                   // add modified temporary to current block
    902                 return new VariableExpr( newtempvar );
     891                declsToAddBefore.push_back( tempvar );                                  // add modified temporary to current block
     892                return new VariableExpr( tempvar );
    903893        }
    904894
Note: See TracChangeset for help on using the changeset viewer.