Changeset 54dd994 for src/InitTweak
- Timestamp:
- Jun 24, 2019, 10:30:47 AM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 84917e2
- Parents:
- 3c6e417 (diff), 9e0a360 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/InitTweak
- Files:
-
- 5 edited
-
FixInit.cc (modified) (1 diff)
-
GenInit.cc (modified) (4 diffs)
-
GenInit.h (modified) (2 diffs)
-
InitTweak.cc (modified) (11 diffs)
-
InitTweak.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r3c6e417 r54dd994 1111 1111 arg2 = new MemberExpr( field, new VariableExpr( params.back() ) ); 1112 1112 } 1113 InitExpander srcParam( arg2 );1113 InitExpander_old srcParam( arg2 ); 1114 1114 // cast away reference type and construct field. 1115 1115 Expression * thisExpr = new CastExpr( new VariableExpr( thisParam ), thisParam->get_type()->stripReferences()->clone() ); -
src/InitTweak/GenInit.cc
r3c6e417 r54dd994 18 18 #include <algorithm> // for any_of 19 19 #include <cassert> // for assert, strict_dynamic_cast, assertf 20 #include <deque> 20 21 #include <iterator> // for back_inserter, inserter, back_inse... 21 22 #include <list> // for _List_iterator, list 22 23 24 #include "AST/Decl.hpp" 25 #include "AST/Init.hpp" 26 #include "AST/Node.hpp" 27 #include "AST/Stmt.hpp" 23 28 #include "CodeGen/OperatorTable.h" 24 29 #include "Common/PassVisitor.h" // for PassVisitor, WithGuards, WithShort... … … 274 279 assertf( objDecl, "genCtorDtor passed null objDecl" ); 275 280 std::list< Statement * > stmts; 276 InitExpander srcParam( maybeClone( arg ) );281 InitExpander_old srcParam( maybeClone( arg ) ); 277 282 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), fname, back_inserter( stmts ), objDecl ); 278 283 assert( stmts.size() <= 1 ); … … 286 291 std::list< Statement * > dtor; 287 292 288 InitExpander srcParam( objDecl->get_init() );289 InitExpander nullParam( (Initializer *)NULL );293 InitExpander_old srcParam( objDecl->get_init() ); 294 InitExpander_old nullParam( (Initializer *)NULL ); 290 295 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 291 296 SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); … … 353 358 GuardScope( managedTypes ); 354 359 } 360 361 ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl ) { 362 // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor for each 363 // constructable object 364 InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr }; 365 366 ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall( 367 srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl ); 368 ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall( 369 nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl, 370 SymTab::LoopBackward ); 371 372 // check that either both ctor and dtor are present, or neither 373 assert( (bool)ctor == (bool)dtor ); 374 375 if ( ctor ) { 376 // need to remember init expression, in case no ctors exist. If ctor does exist, want to 377 // use ctor expression instead of init. 378 ctor.strict_as< ast::ImplicitCtorDtorStmt >(); 379 dtor.strict_as< ast::ImplicitCtorDtorStmt >(); 380 381 return new ast::ConstructorInit{ loc, ctor, dtor, objDecl->init }; 382 } 383 384 return nullptr; 385 } 386 355 387 } // namespace InitTweak 356 388 -
src/InitTweak/GenInit.h
r3c6e417 r54dd994 19 19 #include <string> // for string 20 20 21 #include "AST/Fwd.hpp" 22 #include "Common/CodeLocation.h" 23 #include "GenPoly/ScopedSet.h" // for ScopedSet 21 24 #include "SynTree/SynTree.h" // for Visitor Nodes 22 23 #include "GenPoly/ScopedSet.h" // for ScopedSet24 25 25 26 namespace InitTweak { … … 35 36 /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer 36 37 ConstructorInit * genCtorInit( ObjectDecl * objDecl ); 38 ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl ); 37 39 38 40 class ManagedTypes { -
src/InitTweak/InitTweak.cc
r3c6e417 r54dd994 22 22 23 23 #include "AST/Expr.hpp" 24 #include "AST/Init.hpp" 25 #include "AST/Node.hpp" 26 #include "AST/Pass.hpp" 24 27 #include "AST/Stmt.hpp" 25 28 #include "AST/Type.hpp" … … 84 87 }; 85 88 86 struct InitFlattener : public WithShortCircuiting {89 struct InitFlattener_old : public WithShortCircuiting { 87 90 void previsit( SingleInit * singleInit ) { 88 91 visit_children = false; … … 92 95 }; 93 96 94 } 97 struct InitFlattener_new : public ast::WithShortCircuiting { 98 std::vector< ast::ptr< ast::Expr > > argList; 99 100 void previsit( const ast::SingleInit * singleInit ) { 101 visit_children = false; 102 argList.emplace_back( singleInit->value ); 103 } 104 }; 105 106 } // anonymous namespace 95 107 96 108 std::list< Expression * > makeInitList( Initializer * init ) { 97 PassVisitor<InitFlattener > flattener;109 PassVisitor<InitFlattener_old> flattener; 98 110 maybeAccept( init, flattener ); 99 111 return flattener.pass.argList; … … 112 124 } 113 125 114 class InitExpander::ExpanderImpl { 126 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) { 127 ast::Pass< InitFlattener_new > flattener; 128 maybe_accept( init, flattener ); 129 return std::move( flattener.pass.argList ); 130 } 131 132 class InitExpander_old::ExpanderImpl { 115 133 public: 116 134 virtual ~ExpanderImpl() = default; … … 119 137 }; 120 138 121 class InitImpl : public InitExpander::ExpanderImpl {139 class InitImpl_old : public InitExpander_old::ExpanderImpl { 122 140 public: 123 InitImpl ( Initializer * init ) : init( init ) {}124 virtual ~InitImpl () = default;141 InitImpl_old( Initializer * init ) : init( init ) {} 142 virtual ~InitImpl_old() = default; 125 143 126 144 virtual std::list< Expression * > next( __attribute((unused)) std::list< Expression * > & indices ) { … … 136 154 }; 137 155 138 class ExprImpl : public InitExpander::ExpanderImpl {156 class ExprImpl_old : public InitExpander_old::ExpanderImpl { 139 157 public: 140 ExprImpl ( Expression * expr ) : arg( expr ) {}141 virtual ~ExprImpl () { delete arg; }158 ExprImpl_old( Expression * expr ) : arg( expr ) {} 159 virtual ~ExprImpl_old() { delete arg; } 142 160 143 161 virtual std::list< Expression * > next( std::list< Expression * > & indices ) { … … 163 181 }; 164 182 165 InitExpander ::InitExpander( Initializer * init ) : expander( new InitImpl( init ) ) {}166 167 InitExpander ::InitExpander( Expression * expr ) : expander( new ExprImpl( expr ) ) {}168 169 std::list< Expression * > InitExpander ::operator*() {183 InitExpander_old::InitExpander_old( Initializer * init ) : expander( new InitImpl_old( init ) ) {} 184 185 InitExpander_old::InitExpander_old( Expression * expr ) : expander( new ExprImpl_old( expr ) ) {} 186 187 std::list< Expression * > InitExpander_old::operator*() { 170 188 return cur; 171 189 } 172 190 173 InitExpander & InitExpander::operator++() {191 InitExpander_old & InitExpander_old::operator++() { 174 192 cur = expander->next( indices ); 175 193 return *this; … … 177 195 178 196 // use array indices list to build switch statement 179 void InitExpander ::addArrayIndex( Expression * index, Expression * dimension ) {197 void InitExpander_old::addArrayIndex( Expression * index, Expression * dimension ) { 180 198 indices.push_back( index ); 181 199 indices.push_back( dimension ); 182 200 } 183 201 184 void InitExpander ::clearArrayIndices() {202 void InitExpander_old::clearArrayIndices() { 185 203 deleteAll( indices ); 186 204 indices.clear(); 187 205 } 188 206 189 bool InitExpander ::addReference() {207 bool InitExpander_old::addReference() { 190 208 bool added = false; 191 209 for ( Expression *& expr : cur ) { … … 218 236 219 237 template< typename OutIterator > 220 void build( UntypedExpr * callExpr, InitExpander ::IndexList::iterator idx, InitExpander::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {238 void build( UntypedExpr * callExpr, InitExpander_old::IndexList::iterator idx, InitExpander_old::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) { 221 239 if ( idx == idxEnd ) return; 222 240 Expression * index = *idx++; … … 275 293 // remaining elements. 276 294 // To accomplish this, generate switch statement, consuming all of expander's elements 277 Statement * InitImpl ::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {295 Statement * InitImpl_old::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 278 296 if ( ! init ) return nullptr; 279 297 CompoundStmt * block = new CompoundStmt(); … … 288 306 } 289 307 290 Statement * ExprImpl ::buildListInit( UntypedExpr *, std::list< Expression * > & ) {308 Statement * ExprImpl_old::buildListInit( UntypedExpr *, std::list< Expression * > & ) { 291 309 return nullptr; 292 310 } 293 311 294 Statement * InitExpander ::buildListInit( UntypedExpr * dst ) {312 Statement * InitExpander_old::buildListInit( UntypedExpr * dst ) { 295 313 return expander->buildListInit( dst, indices ); 296 314 } 315 316 class InitExpander_new::ExpanderImpl { 317 public: 318 virtual ~ExpanderImpl() = default; 319 virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0; 320 virtual ast::ptr< ast::Stmt > buildListInit( 321 ast::UntypedExpr * callExpr, IndexList & indices ) = 0; 322 }; 323 324 namespace { 325 template< typename Out > 326 void buildCallExpr( 327 ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension, 328 const ast::Init * init, Out & out 329 ) { 330 const CodeLocation & loc = init->location; 331 332 auto cond = new ast::UntypedExpr{ 333 loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } }; 334 335 std::vector< ast::ptr< ast::Expr > > args = makeInitList( init ); 336 splice( callExpr->args, args ); 337 338 out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } ); 339 340 out.emplace_back( new ast::ExprStmt{ 341 loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } ); 342 } 343 344 template< typename Out > 345 void build( 346 ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices, 347 const ast::Init * init, Out & out 348 ) { 349 if ( indices.empty() ) return; 350 351 unsigned idx = 0; 352 353 const ast::Expr * index = indices[idx++]; 354 assert( idx != indices.size() ); 355 const ast::Expr * dimension = indices[idx++]; 356 357 if ( idx == indices.size() ) { 358 if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) { 359 for ( const ast::Init * init : *listInit ) { 360 buildCallExpr( callExpr, index, dimension, init, out ); 361 } 362 } else { 363 buildCallExpr( callExpr, index, dimension, init, out ); 364 } 365 } else { 366 const CodeLocation & loc = init->location; 367 368 unsigned long cond = 0; 369 auto listInit = dynamic_cast< const ast::ListInit * >( init ); 370 if ( ! listInit ) { SemanticError( loc, "unbalanced list initializers" ); } 371 372 static UniqueName targetLabel( "L__autogen__" ); 373 ast::Label switchLabel{ 374 loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } }; 375 376 std::vector< ast::ptr< ast::Stmt > > branches; 377 for ( const ast::Init * init : *listInit ) { 378 auto condition = ast::ConstantExpr::from_ulong( loc, cond ); 379 ++cond; 380 381 std::vector< ast::ptr< ast::Stmt > > stmts; 382 build( callExpr, indices, init, stmts ); 383 stmts.emplace_back( 384 new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } ); 385 branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } ); 386 } 387 out.emplace_back( new ast::SwitchStmt{ loc, index, std::move( branches ) } ); 388 out.emplace_back( new ast::NullStmt{ loc, { switchLabel } } ); 389 } 390 } 391 392 class InitImpl_new final : public InitExpander_new::ExpanderImpl { 393 ast::ptr< ast::Init > init; 394 public: 395 InitImpl_new( const ast::Init * i ) : init( i ) {} 396 397 std::vector< ast::ptr< ast::Expr > > next( InitExpander_new::IndexList & ) override { 398 return makeInitList( init ); 399 } 400 401 ast::ptr< ast::Stmt > buildListInit( 402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 403 ) override { 404 // If array came with an initializer list, initialize each element. We may have more 405 // initializers than elements of the array; need to check at each index that we have 406 // not exceeded size. We may have fewer initializers than elements in the array; need 407 // to default-construct remaining elements. To accomplish this, generate switch 408 // statement consuming all of expander's elements 409 410 if ( ! init ) return {}; 411 412 std::list< ast::ptr< ast::Stmt > > stmts; 413 build( callExpr, indices, init, stmts ); 414 if ( stmts.empty() ) { 415 return {}; 416 } else { 417 auto block = new ast::CompoundStmt{ init->location, std::move( stmts ) }; 418 init = nullptr; // consumed in creating the list init 419 return block; 420 } 421 } 422 }; 423 424 class ExprImpl_new final : public InitExpander_new::ExpanderImpl { 425 ast::ptr< ast::Expr > arg; 426 public: 427 ExprImpl_new( const ast::Expr * a ) : arg( a ) {} 428 429 std::vector< ast::ptr< ast::Expr > > next( 430 InitExpander_new::IndexList & indices 431 ) override { 432 if ( ! arg ) return {}; 433 434 const CodeLocation & loc = arg->location; 435 const ast::Expr * expr = arg; 436 for ( auto it = indices.rbegin(); it != indices.rend(); ++it ) { 437 // go through indices and layer on subscript exprs ?[?] 438 ++it; 439 expr = new ast::UntypedExpr{ 440 loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } }; 441 } 442 return { expr }; 443 } 444 445 ast::ptr< ast::Stmt > buildListInit( 446 ast::UntypedExpr *, InitExpander_new::IndexList & 447 ) override { 448 return {}; 449 } 450 }; 451 } // anonymous namespace 452 453 InitExpander_new::InitExpander_new( const ast::Init * init ) 454 : expander( new InitImpl_new{ init } ), crnt(), indices() {} 455 456 InitExpander_new::InitExpander_new( const ast::Expr * expr ) 457 : expander( new ExprImpl_new{ expr } ), crnt(), indices() {} 458 459 std::vector< ast::ptr< ast::Expr > > InitExpander_new::operator* () { return crnt; } 460 461 InitExpander_new & InitExpander_new::operator++ () { 462 crnt = expander->next( indices ); 463 return *this; 464 } 465 466 /// builds statement which has the same semantics as a C-style list initializer (for array 467 /// initializers) using callExpr as the base expression to perform initialization 468 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) { 469 return expander->buildListInit( callExpr, indices ); 470 } 471 472 void InitExpander_new::addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ) { 473 indices.emplace_back( index ); 474 indices.emplace_back( dimension ); 475 } 476 477 void InitExpander_new::clearArrayIndices() { indices.clear(); } 478 479 bool InitExpander_new::addReference() { 480 for ( ast::ptr< ast::Expr > & expr : crnt ) { 481 expr = new ast::AddressExpr{ expr }; 482 } 483 return ! crnt.empty(); 484 } 297 485 298 486 Type * getTypeofThis( FunctionType * ftype ) { -
src/InitTweak/InitTweak.h
r3c6e417 r54dd994 44 44 /// transform Initializer into an argument list that can be passed to a call expression 45 45 std::list< Expression * > makeInitList( Initializer * init ); 46 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ); 46 47 47 48 /// True if the resolver should try to construct dwt … … 101 102 bool isConstExpr( Initializer * init ); 102 103 103 class InitExpander {104 class InitExpander_old { 104 105 public: 105 106 // expand by stepping through init to get each list of arguments 106 InitExpander ( Initializer * init );107 InitExpander_old( Initializer * init ); 107 108 108 109 // always expand to expr 109 InitExpander ( Expression * expr );110 InitExpander_old( Expression * expr ); 110 111 111 112 // iterator-like interface 112 113 std::list< Expression * > operator*(); 113 InitExpander & operator++();114 InitExpander_old & operator++(); 114 115 115 116 // builds statement which has the same semantics as a C-style list initializer … … 130 131 IndexList indices; 131 132 }; 133 134 class InitExpander_new { 135 public: 136 using IndexList = std::vector< ast::ptr< ast::Expr > >; 137 class ExpanderImpl; 138 139 private: 140 std::shared_ptr< ExpanderImpl > expander; 141 std::vector< ast::ptr< ast::Expr > > crnt; 142 // invariant: list of size 2N (elements come in pairs [index, dimension]) 143 IndexList indices; 144 145 public: 146 /// Expand by stepping through init to get each list of arguments 147 InitExpander_new( const ast::Init * init ); 148 149 /// Always expand to expression 150 InitExpander_new( const ast::Expr * expr ); 151 152 std::vector< ast::ptr< ast::Expr > > operator* (); 153 InitExpander_new & operator++ (); 154 155 /// builds statement which has the same semantics as a C-style list initializer (for array 156 /// initializers) using callExpr as the base expression to perform initialization. 157 /// Mutates callExpr 158 ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr ); 159 160 void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ); 161 162 void clearArrayIndices(); 163 164 bool addReference(); 165 }; 132 166 } // namespace 133 167
Note:
See TracChangeset
for help on using the changeset viewer.