source: src/InitTweak/RemoveInit.cc@ 3cfe27f

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since 3cfe27f was cf16f94, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

create temporary return variable for return expressions, remove unnecessary code after temporary-return-variable change, fix missing lvalue qualifiers, change stream operator to |

  • Property mode set to 100644
File size: 4.4 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// RemoveInit.cc --
8//
9// Author : Rob Schluntz
10// 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
16#include "RemoveInit.h"
17#include "SynTree/Declaration.h"
18#include "SynTree/Type.h"
19#include "SynTree/Expression.h"
20#include "SynTree/Statement.h"
21#include "SynTree/Initializer.h"
22#include "SynTree/Mutator.h"
23
24namespace InitTweak {
25 namespace {
26 const std::list<Label> noLabels;
27 }
28
29 class RemoveInit : public Mutator {
30 public:
31 RemoveInit();
32 virtual ObjectDecl * mutate(ObjectDecl *objDecl);
33 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
34
35 virtual Statement * mutate( ReturnStmt * returnStmt );
36
37 virtual CompoundStmt * mutate(CompoundStmt * compoundStmt);
38
39 protected:
40 std::list< Statement* > stmtsToAddBefore;
41 std::list< Statement* > stmtsToAddAfter;
42 void mutateStatementList( std::list< Statement* > &statements );
43
44 std::list<DeclarationWithType*> returnVals;
45 UniqueName tempNamer;
46 std::string funcName;
47 };
48
49 void tweak( std::list< Declaration * > translationUnit ) {
50 RemoveInit remover;
51 mutateAll( translationUnit, remover );
52 }
53
54 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 }
75
76 // in the case where an object has an initializer and a polymorphic type, insert an assignment immediately after the
77 // declaration. This will (seemingly) cause the later phases to do the right thing with the assignment
78 ObjectDecl *RemoveInit::mutate( ObjectDecl *objDecl ) {
79 if (objDecl->get_init() && dynamic_cast<TypeInstType*>(objDecl->get_type())) {
80 if (SingleInit * single = dynamic_cast<SingleInit*>(objDecl->get_init())) {
81 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
82 assign->get_args().push_back( new AddressExpr (new NameExpr( objDecl->get_name() ) ) );
83 assign->get_args().push_back( single->get_value()->clone() );
84 stmtsToAddAfter.push_back(new ExprStmt(noLabels, assign));
85 } // if
86 } // if
87 return objDecl;
88 }
89
90 Statement *RemoveInit::mutate( ReturnStmt *returnStmt ) {
91 // update for multiple return values
92 assert( returnVals.size() == 0 || returnVals.size() == 1 );
93 // hands off if the function returns an lvalue - we don't want to allocate a temporary if a variable's address
94 // is being returned
95 if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue() ) {
96 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
99 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
100 assign->get_args().push_back( new AddressExpr (new NameExpr( newObj->get_name() ) ) );
101 assign->get_args().push_back( returnStmt->get_expr() );
102 stmtsToAddBefore.push_back(new ExprStmt(noLabels, assign));
103
104 returnStmt->set_expr( new VariableExpr( newObj ) );
105 } // if
106 return returnStmt;
107 }
108
109 DeclarationWithType* RemoveInit::mutate( FunctionDecl *functionDecl ) {
110 std::list<DeclarationWithType*> oldReturnVals = returnVals;
111 std::string oldFuncName = funcName;
112
113 FunctionType * type = functionDecl->get_functionType();
114 returnVals = type->get_returnVals();
115 funcName = functionDecl->get_name();
116 DeclarationWithType * decl = Mutator::mutate( functionDecl );
117 returnVals = oldReturnVals;
118 funcName = oldFuncName;
119 return decl;
120 }
121} // namespace InitTweak
122
123// Local Variables: //
124// tab-width: 4 //
125// mode: c++ //
126// compile-command: "make install" //
127// End: //
Note: See TracBrowser for help on using the repository browser.