Changeset c1ed2ee for src/InitTweak
- Timestamp:
- Jun 21, 2019, 3:41:36 PM (5 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:
- 8d61d620
- Parents:
- 9af00d23
- Location:
- src/InitTweak
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/InitTweak.cc
r9af00d23 rc1ed2ee 22 22 23 23 #include "AST/Expr.hpp" 24 #include "AST/Init.hpp" 24 25 #include "AST/Node.hpp" 26 #include "AST/Pass.hpp" 25 27 #include "AST/Stmt.hpp" 26 28 #include "AST/Type.hpp" … … 85 87 }; 86 88 87 struct InitFlattener : public WithShortCircuiting {89 struct InitFlattener_old : public WithShortCircuiting { 88 90 void previsit( SingleInit * singleInit ) { 89 91 visit_children = false; … … 93 95 }; 94 96 95 } 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 96 107 97 108 std::list< Expression * > makeInitList( Initializer * init ) { 98 PassVisitor<InitFlattener > flattener;109 PassVisitor<InitFlattener_old> flattener; 99 110 maybeAccept( init, flattener ); 100 111 return flattener.pass.argList; … … 114 125 115 126 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) { 116 #warning unimplmented 117 (void)init; 118 assert(false); 119 return {}; 127 ast::Pass< InitFlattener_new > flattener; 128 maybe_accept( init, flattener ); 129 return std::move( flattener.pass.argList ); 120 130 } 121 131 … … 309 319 virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0; 310 320 virtual ast::ptr< ast::Stmt > buildListInit( 311 constast::UntypedExpr * callExpr, IndexList & indices ) = 0;321 ast::UntypedExpr * callExpr, IndexList & indices ) = 0; 312 322 }; 313 323 314 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 315 392 class InitImpl_new final : public InitExpander_new::ExpanderImpl { 316 393 ast::ptr< ast::Init > init; … … 323 400 324 401 ast::ptr< ast::Stmt > buildListInit( 325 constast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices402 ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices 326 403 ) override { 327 #warning unimplemented 328 (void)callExpr; (void)indices; 329 assert(false); 330 return {}; 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 } 331 421 } 332 422 }; … … 340 430 InitExpander_new::IndexList & indices 341 431 ) override { 342 #warning unimplemented 343 (void)indices; 344 assert(false); 345 return {}; 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 }; 346 443 } 347 444 348 445 ast::ptr< ast::Stmt > buildListInit( 349 constast::UntypedExpr *, InitExpander_new::IndexList &446 ast::UntypedExpr *, InitExpander_new::IndexList & 350 447 ) override { 351 448 return {}; … … 369 466 /// builds statement which has the same semantics as a C-style list initializer (for array 370 467 /// initializers) using callExpr as the base expression to perform initialization 371 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( constast::UntypedExpr * callExpr ) {468 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) { 372 469 return expander->buildListInit( callExpr, indices ); 373 470 } -
src/InitTweak/InitTweak.h
r9af00d23 rc1ed2ee 154 154 155 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 ast::ptr< ast::Stmt > buildListInit( const ast::UntypedExpr * callExpr ); 156 /// initializers) using callExpr as the base expression to perform initialization. 157 /// Mutates callExpr 158 ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr ); 158 159 159 160 void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension );
Note: See TracChangeset
for help on using the changeset viewer.