Changeset 7b3f66b for src/InitTweak
- Timestamp:
- May 13, 2016, 1:18:35 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- d668182
- Parents:
- fb24492
- Location:
- src/InitTweak
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cc
rfb24492 r7b3f66b 10 10 // Created On : Mon May 04 15:14:56 2016 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon May 09 11:44:29201612 // Last Modified On : Fri May 13 11:37:30 2016 13 13 // Update Count : 2 14 14 // 15 15 16 16 #include "FixGlobalInit.h" 17 #include " GenInit.h"17 #include "InitTweak.h" 18 18 #include "SynTree/Declaration.h" 19 19 #include "SynTree/Type.h" … … 125 125 std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids(); 126 126 127 if ( objDecl->get_init() == NULL ) return;127 // if ( objDecl->get_init() == NULL ) return; 128 128 if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects 129 129 if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable 130 if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return; 130 131 // C allows you to initialize objects with constant expressions 131 132 // xxx - this is an optimization. Need to first resolve constructors before we decide … … 133 134 // if ( isConstExpr( objDecl->get_init() ) ) return; 134 135 135 // steal initializer from object and attach it to a new temporary 136 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() ); 137 objDecl->set_init( NULL ); 138 initStatements.push_back( new DeclStmt( noLabels, newObj ) ); 136 if ( ArrayType * at = dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) { 137 // xxx - initialize each element of the array 138 } else { 139 // steal initializer from object and attach it to a new temporary 140 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() ); 141 objDecl->set_init( NULL ); 142 initStatements.push_back( new DeclStmt( noLabels, newObj ) ); 139 143 140 // copy construct objDecl using temporary141 UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) );142 init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );143 init->get_args().push_back( new VariableExpr( newObj ) );144 initStatements.push_back( new ExprStmt( noLabels, init ) );144 // copy construct objDecl using temporary 145 UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) ); 146 init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) ); 147 init->get_args().push_back( new VariableExpr( newObj ) ); 148 initStatements.push_back( new ExprStmt( noLabels, init ) ); 145 149 146 // add destructor calls to global destroy function 147 UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) ); 148 destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) ); 149 destroyStatements.push_front( new ExprStmt( noLabels, destroy ) ); 150 // add destructor calls to global destroy function 151 UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) ); 152 destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) ); 153 destroyStatements.push_front( new ExprStmt( noLabels, destroy ) ); 154 } 150 155 } 151 156 -
src/InitTweak/FixInit.cc
rfb24492 r7b3f66b 10 10 // Created On : Wed Jan 13 16:29:30 2016 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon May 09 12:36:02201612 // Last Modified On : Fri May 13 11:44:26 2016 13 13 // Update Count : 30 14 14 // … … 17 17 #include <list> 18 18 #include "FixInit.h" 19 #include "InitTweak.h" 19 20 #include "ResolvExpr/Resolver.h" 20 21 #include "ResolvExpr/typeops.h" … … 27 28 #include "SymTab/Indexer.h" 28 29 #include "GenPoly/PolyMutator.h" 29 #include "GenPoly/GenPoly.h"30 30 31 31 bool ctordtorp = false; … … 398 398 } 399 399 400 bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {401 if ( stmt == NULL ) return false;402 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {403 ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );404 assert( appExpr );405 VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );406 assert( function );407 // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor408 // will call all member dtors, and some members may have a user defined dtor.409 FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );410 assert( funcType );411 return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;412 } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {413 // could also be a compound statement with a loop, in the case of an array414 assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop415 ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );416 assert( forStmt && forStmt->get_body() );417 return isInstrinsicSingleArgCallStmt( forStmt->get_body() );418 } else {419 // should never get here420 assert( false && "encountered unknown call statement" );421 }422 }423 424 400 namespace { 425 401 template<typename Iterator, typename OutputIterator> … … 428 404 // remove if instrinsic destructor statement. Note that this is only called 429 405 // on lists of implicit dtors, so if the user manually calls an intrinsic 430 // dtor then the call will still be generated 406 // dtor then the call must (and will) still be generated since the argument 407 // may contain side effects. 431 408 if ( ! isInstrinsicSingleArgCallStmt( *it ) ) { 432 409 // don't need to call intrinsic dtor, because it does nothing, but -
src/InitTweak/FixInit.h
rfb24492 r7b3f66b 10 10 // Created On : Wed Jan 13 16:29:30 2016 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon May 09 12:08:11201612 // Last Modified On : Fri May 13 11:27:52 2016 13 13 // Update Count : 5 14 14 // … … 28 28 /// and unwrap basic C-style initializers 29 29 void fix( std::list< Declaration * > & translationUnit ); 30 31 /// True if stmt is a call statement where the function called is intrinsic and takes one parameter.32 /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.33 /// Currently has assertions that make it less than fully general.34 bool isInstrinsicSingleArgCallStmt( Statement * expr );35 30 } // namespace 36 31 -
src/InitTweak/GenInit.cc
rfb24492 r7b3f66b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 06 16:11:15201612 // Last Modified On : Fri May 13 11:37:48 2016 13 13 // Update Count : 166 14 14 // … … 17 17 #include <list> 18 18 #include "GenInit.h" 19 #include "InitTweak.h" 19 20 #include "SynTree/Declaration.h" 20 21 #include "SynTree/Type.h" … … 129 130 } 130 131 131 bool tryConstruct( ObjectDecl * objDecl ) {132 // xxx - handle designations133 return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&134 (objDecl->get_init() == NULL ||135 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ));136 }137 132 namespace { 138 139 133 Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) { 140 134 UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) ); … … 142 136 expr->get_args().splice( expr->get_args().end(), args ); 143 137 return expr; 144 }145 146 class InitExpander : public Visitor {147 public:148 InitExpander() {}149 // ~InitExpander() {}150 virtual void visit( SingleInit * singleInit );151 virtual void visit( ListInit * listInit );152 std::list< Expression * > argList;153 };154 155 void InitExpander::visit( SingleInit * singleInit ) {156 argList.push_back( singleInit->get_value()->clone() );157 }158 159 void InitExpander::visit( ListInit * listInit ) {160 // xxx - for now, assume no nested list inits161 std::list<Initializer*>::iterator it = listInit->begin_initializers();162 for ( ; it != listInit->end_initializers(); ++it ) {163 (*it)->accept( *this );164 }165 }166 167 std::list< Expression * > makeInitList( Initializer * init ) {168 InitExpander expander;169 maybeAccept( init, expander );170 return expander.argList;171 138 } 172 139 } … … 179 146 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array 180 147 // TODO: walk initializer and generate appropriate copy ctor if element has initializer 181 std::list< Statement * > ctor; 182 std::list< Statement * > dtor; 183 184 SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) ); 185 SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false ); 186 187 // Currently makeArrayFunction produces a single Statement - a CompoundStmt 188 // which wraps everything that needs to happen. As such, it's technically 189 // possible to use a Statement ** in the above calls, but this is inherently 190 // unsafe, so instead we take the slightly less efficient route, but will be 191 // immediately informed if somehow the above assumption is broken. In this case, 192 // we could always wrap the list of statements at this point with a CompoundStmt, 193 // but it seems reasonable at the moment for this to be done by makeArrayFunction 194 // itself 195 assert( ctor.size() == 1 ); 196 assert( dtor.size() == 1 ); 197 198 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 148 std::list< Expression * > args = makeInitList( objDecl->get_init() ); 149 if ( args.empty() ) { 150 std::list< Statement * > ctor; 151 std::list< Statement * > dtor; 152 153 SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) ); 154 SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false ); 155 156 // Currently makeArrayFunction produces a single Statement - a CompoundStmt 157 // which wraps everything that needs to happen. As such, it's technically 158 // possible to use a Statement ** in the above calls, but this is inherently 159 // unsafe, so instead we take the slightly less efficient route, but will be 160 // immediately informed if somehow the above assumption is broken. In this case, 161 // we could always wrap the list of statements at this point with a CompoundStmt, 162 // but it seems reasonable at the moment for this to be done by makeArrayFunction 163 // itself 164 assert( ctor.size() == 1 ); 165 assert( dtor.size() == 1 ); 166 167 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 168 } else { 169 // array came with an initializer list: initialize each element 170 // may have more initializers than elements in the array - need to check at each index that 171 // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting 172 // computation. 173 // may have fewer initializers than eleemnts in the array - need to default construct 174 // remaining elements. 175 // might be able to merge this with the case above. 176 } 199 177 } else { 200 178 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer -
src/InitTweak/GenInit.h
rfb24492 r7b3f66b 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 06 16:18:22201612 // Last Modified On : Fri May 13 11:27:19 2016 13 13 // Update Count : 3 14 14 // … … 27 27 /// Adds return value temporaries and wraps Initializers in ConstructorInit nodes 28 28 void genInit( std::list< Declaration * > & translationUnit ); 29 /// True if the resolver should try to construct objDecl30 bool tryConstruct( ObjectDecl * objDecl );31 29 } // namespace 32 30 -
src/InitTweak/module.mk
rfb24492 r7b3f66b 11 11 ## Created On : Mon Jun 1 17:49:17 2015 12 12 ## Last Modified By : Rob Schluntz 13 ## Last Modified On : Fri May 06 15:59:27201613 ## Last Modified On : Fri May 13 11:36:24 2016 14 14 ## Update Count : 3 15 15 ############################################################################### … … 17 17 SRC += InitTweak/GenInit.cc \ 18 18 InitTweak/FixInit.cc \ 19 InitTweak/FixGlobalInit.cc 19 InitTweak/FixGlobalInit.cc \ 20 InitTweak/InitTweak.cc 20 21
Note: See TracChangeset
for help on using the changeset viewer.