Changes in src/InitTweak/GenInit.cc [7b3f66b:a0fdbd5]
- File:
-
- 1 edited
-
src/InitTweak/GenInit.cc (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
r7b3f66b ra0fdbd5 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 13 11:37:48201612 // Last Modified On : Thu Apr 28 12:26:47 2016 13 13 // Update Count : 166 14 14 // … … 17 17 #include <list> 18 18 #include "GenInit.h" 19 #include "InitTweak.h"20 19 #include "SynTree/Declaration.h" 21 20 #include "SynTree/Type.h" … … 131 130 132 131 namespace { 132 bool tryConstruct( ObjectDecl * objDecl ) { 133 // xxx - handle designations 134 return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) && 135 (objDecl->get_init() == NULL || 136 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )); 137 } 138 133 139 Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) { 134 140 UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) ); … … 136 142 expr->get_args().splice( expr->get_args().end(), args ); 137 143 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 inits 161 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; 138 171 } 139 172 } … … 146 179 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array 147 180 // TODO: walk initializer and generate appropriate copy ctor if element has initializer 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 } 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() ) ); 177 199 } else { 178 200 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer … … 187 209 objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) ); 188 210 } 211 } else { 212 // xxx - find a way to construct/destruct globals 213 // hack: implicit "static" initialization routine for each struct type? or something similar? 214 // --ties into module system 215 // this can be done by mangling main and replacing it with our own main which calls each 216 // module initialization routine in some decided order (order given in link command?) 217 // and finally calls mangled main 189 218 } 190 219 }
Note:
See TracChangeset
for help on using the changeset viewer.