Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/RemoveInit.cc

    rcf16f94 r974906e2  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // RemoveInit.cc -- 
     7// RemoveInit.cc --
    88//
    99// Author           : Rob Schluntz
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec 15 15:37:26 2015
    13 // Update Count     : 15
    14 //
    15 
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Jan 11 14:41:26 2016
     13// Update Count     : 118
     14//
     15
     16#include <stack>
     17#include <list>
    1618#include "RemoveInit.h"
    1719#include "SynTree/Declaration.h"
     
    2123#include "SynTree/Initializer.h"
    2224#include "SynTree/Mutator.h"
     25#include "GenPoly/PolyMutator.h"
    2326
    2427namespace InitTweak {
     
    2629                const std::list<Label> noLabels;
    2730        }
    28        
    29         class RemoveInit : public Mutator {
     31
     32        class RemoveInit : public GenPoly::PolyMutator {
    3033          public:
    3134                RemoveInit();
    32                 virtual ObjectDecl * mutate(ObjectDecl *objDecl);
     35                virtual ObjectDecl * mutate( ObjectDecl *objDecl );
    3336                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    3437
    3538                virtual Statement * mutate( ReturnStmt * returnStmt );
    36                
    37                 virtual CompoundStmt * mutate(CompoundStmt * compoundStmt);
    38                
     39
    3940          protected:
    40                 std::list< Statement* > stmtsToAddBefore;
    41                 std::list< Statement* > stmtsToAddAfter;
    42                 void mutateStatementList( std::list< Statement* > &statements );
    43 
    4441                std::list<DeclarationWithType*> returnVals;
    4542                UniqueName tempNamer;
     
    4744        };
    4845
     46        class CtorDtor : public GenPoly::PolyMutator {
     47          public:
     48                // CtorDtor();
     49
     50                virtual ObjectDecl * mutate( ObjectDecl * );
     51
     52                virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
     53
     54          protected:
     55                typedef std::map< std::string, DeclarationWithType * > MMMMAP;
     56                std::stack< MMMMAP > constructedObjects;
     57
     58                // to be added before block ends - use push_front so order is correct
     59                std::list< Statement * > destructorStmts;
     60        };
     61
    4962        void tweak( std::list< Declaration * > translationUnit ) {
    5063                RemoveInit remover;
     64                CtorDtor ctordtor;
    5165                mutateAll( translationUnit, remover );
     66                mutateAll( translationUnit, ctordtor );
    5267        }
    5368
    5469        RemoveInit::RemoveInit() : tempNamer( "_retVal" ) {}
    55        
    56         void RemoveInit::mutateStatementList( std::list< Statement* > &statements ) {
    57                 for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    58                         if ( ! stmtsToAddAfter.empty() ) {
    59                                 statements.splice( i, stmtsToAddAfter );
    60                         } // if
    61                         *i = (*i)->acceptMutator( *this );
    62                         if ( ! stmtsToAddBefore.empty() ) {
    63                                 statements.splice( i, stmtsToAddBefore );
    64                         } // if
    65                 } // for
    66                 if ( ! stmtsToAddAfter.empty() ) {
    67                         statements.splice( statements.end(), stmtsToAddAfter );
    68                 } // if
    69         }
    70 
    71         CompoundStmt *RemoveInit::mutate(CompoundStmt *compoundStmt) {
    72                 mutateStatementList( compoundStmt->get_kids() );
    73                 return compoundStmt;
    74         }
    7570
    7671        // in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
     
    9590                if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue()  ) {
    9691                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, returnVals.front()->get_type()->clone(), 0 );
    97                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, newObj ) );
    98                        
     92                        stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) );
     93
    9994                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    10095                        assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
    10196                        assign->get_args().push_back( returnStmt->get_expr() );
    102                         stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
     97                        stmtsToAdd.push_back(new ExprStmt(noLabels, assign));
    10398
    10499                        returnStmt->set_expr( new VariableExpr( newObj ) );
     
    110105                std::list<DeclarationWithType*> oldReturnVals = returnVals;
    111106                std::string oldFuncName = funcName;
    112                
     107
    113108                FunctionType * type = functionDecl->get_functionType();
    114109                returnVals = type->get_returnVals();
     
    119114                return decl;
    120115        }
     116
     117        bool tryConstruct( ObjectDecl * objDecl ) {
     118                // xxx - handle designations
     119                return objDecl->get_init() == NULL ||
     120                        ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() );
     121        }
     122
     123        ExprStmt * makeCtorDtorStmt( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
     124                UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
     125                expr->get_args().push_back( new VariableExpr( objDecl ) );
     126                expr->get_args().splice( expr->get_args().end(), args );
     127                return new ExprStmt( noLabels, expr );
     128        }
     129
     130        // InitExpander ctor/dtor being marked as weak symbols
     131        // this is causing a bug - Rodolfo's InitExpander is being constructed and destructed
     132        // with different fields, which causes a segfault
     133
     134        class InitExpander : public Visitor {
     135          public:
     136          InitExpander() {}
     137          // ~InitExpander() {}
     138                virtual void visit( SingleInit * singleInit );
     139                virtual void visit( ListInit * listInit );
     140                std::list< Expression * > argList;
     141        };
     142
     143        void InitExpander::visit( SingleInit * singleInit ) {
     144                argList.push_back( singleInit->get_value()->clone() );
     145        }
     146
     147        void InitExpander::visit( ListInit * listInit ) {
     148                // xxx - for now, assume no nested list inits
     149                std::list<Initializer*>::iterator it = listInit->begin_initializers();
     150                for ( ; it != listInit->end_initializers(); ++it ) {
     151                        (*it)->accept( *this );
     152                }
     153        }
     154
     155        std::list< Expression * > makeInitList( Initializer * init ) {
     156                if ( init ) {
     157                        InitExpander expander;
     158                        // init->accept( expander );
     159                        // std::list< Expression * > l = expander.argList;
     160                        std::list< Expression * > l;
     161                        return l;
     162                } else {
     163                        std::list< Expression * > l;
     164                        return l;
     165                }
     166        }
     167
     168        ObjectDecl * CtorDtor::mutate( ObjectDecl * objDecl ) {
     169                // hands off if designated or if @=
     170                if ( tryConstruct( objDecl ) ) {
     171                        ExprStmt * ctor = makeCtorDtorStmt( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
     172                        ExprStmt * dtor = makeCtorDtorStmt( "^?{}", objDecl, std::list< Expression * >() );
     173
     174                        // set_ctor...
     175                        // need to remember init expression, in case no ctors exist
     176                        // if ctor does exist, want to use ctor stmt instead of init
     177                        objDecl->set_ctor( ctor );
     178                        destructorStmts.push_front( dtor );
     179                }
     180                return objDecl;
     181        }
     182
     183        CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
     184                CompoundStmt * ret = PolyMutator::mutate( compoundStmt );
     185                std::list< Statement * > &statements = ret->get_kids();
     186                if ( ! destructorStmts.empty() ) {
     187                        statements.splice( statements.end(), destructorStmts );
     188                } // if
     189                return ret;
     190        }
     191
     192
     193
    121194} // namespace InitTweak
    122195
Note: See TracChangeset for help on using the changeset viewer.