Changeset c13e8dc8 for src/InitTweak/InitTweak.cc
- Timestamp:
- Dec 5, 2017, 2:35:03 PM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- f9feab8
- Parents:
- 9c35431 (diff), 65197c2 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/InitTweak.cc
r9c35431 rc13e8dc8 5 5 #include <memory> // for __shared_ptr 6 6 7 #include "Common/PassVisitor.h" 7 8 #include "Common/SemanticError.h" // for SemanticError 8 9 #include "Common/UniqueName.h" // for UniqueName … … 19 20 #include "SynTree/Expression.h" // for Expression, UntypedExpr, Applicati... 20 21 #include "SynTree/Initializer.h" // for Initializer, ListInit, Designation 21 #include "SynTree/Label.h" // for Label , noLabels22 #include "SynTree/Label.h" // for Label 22 23 #include "SynTree/Statement.h" // for CompoundStmt, ExprStmt, BranchStmt 23 24 #include "SynTree/Type.h" // for FunctionType, ArrayType, PointerType … … 29 30 namespace InitTweak { 30 31 namespace { 31 class HasDesignations : public Visitor { 32 public: 32 struct HasDesignations : public WithShortCircuiting { 33 33 bool hasDesignations = false; 34 virtual void visit( Designation * des ) { 35 if ( ! des->get_designators().empty() ) hasDesignations = true; 36 else Visitor::visit( des ); 34 35 void previsit( BaseSyntaxNode * ) { 36 // short circuit if we already know there are designations 37 if ( hasDesignations ) visit_children = false; 38 } 39 40 void previsit( Designation * des ) { 41 // short circuit if we already know there are designations 42 if ( hasDesignations ) visit_children = false; 43 else if ( ! des->get_designators().empty() ) { 44 hasDesignations = true; 45 visit_children = false; 46 } 37 47 } 38 48 }; 39 49 40 class InitDepthChecker : public Visitor { 41 public: 50 struct InitDepthChecker : public WithGuards { 42 51 bool depthOkay = true; 43 52 Type * type; … … 51 60 maxDepth++; 52 61 } 53 v irtual void visit( ListInit * listInit) {62 void previsit( ListInit * ) { 54 63 curDepth++; 64 GuardAction( [this]() { curDepth--; } ); 55 65 if ( curDepth > maxDepth ) depthOkay = false; 56 Visitor::visit( listInit );57 curDepth--;58 66 } 59 67 }; 60 68 61 class InitFlattener : public Visitor { 62 public: 63 virtual void visit( SingleInit * singleInit ); 64 virtual void visit( ListInit * listInit ); 69 struct InitFlattener : public WithShortCircuiting { 70 void previsit( SingleInit * singleInit ) { 71 visit_children = false; 72 argList.push_back( singleInit->value->clone() ); 73 } 65 74 std::list< Expression * > argList; 66 75 }; 67 76 68 void InitFlattener::visit( SingleInit * singleInit ) {69 argList.push_back( singleInit->get_value()->clone() );70 }71 72 void InitFlattener::visit( ListInit * listInit ) {73 // flatten nested list inits74 std::list<Initializer*>::iterator it = listInit->begin();75 for ( ; it != listInit->end(); ++it ) {76 (*it)->accept( *this );77 }78 }79 77 } 80 78 81 79 std::list< Expression * > makeInitList( Initializer * init ) { 82 InitFlattenerflattener;80 PassVisitor<InitFlattener> flattener; 83 81 maybeAccept( init, flattener ); 84 return flattener. argList;82 return flattener.pass.argList; 85 83 } 86 84 87 85 bool isDesignated( Initializer * init ) { 88 HasDesignationsfinder;86 PassVisitor<HasDesignations> finder; 89 87 maybeAccept( init, finder ); 90 return finder. hasDesignations;88 return finder.pass.hasDesignations; 91 89 } 92 90 93 91 bool checkInitDepth( ObjectDecl * objDecl ) { 94 InitDepthChecker checker( objDecl->get_type());95 maybeAccept( objDecl-> get_init(), checker );96 return checker. depthOkay;92 PassVisitor<InitDepthChecker> checker( objDecl->type ); 93 maybeAccept( objDecl->init, checker ); 94 return checker.pass.depthOkay; 97 95 } 98 96 … … 195 193 callExpr->get_args().splice( callExpr->get_args().end(), args ); 196 194 197 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels,callExpr ), nullptr );195 *out++ = new IfStmt( cond, new ExprStmt( callExpr ), nullptr ); 198 196 199 197 UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) ); 200 198 increment->get_args().push_back( index->clone() ); 201 *out++ = new ExprStmt( noLabels,increment );199 *out++ = new ExprStmt( increment ); 202 200 } 203 201 … … 244 242 std::list< Statement * > stmts; 245 243 build( callExpr, idx, idxEnd, init, back_inserter( stmts ) ); 246 stmts.push_back( new BranchStmt( noLabels,switchLabel, BranchStmt::Break ) );247 CaseStmt * caseStmt = new CaseStmt( noLabels,condition, stmts );244 stmts.push_back( new BranchStmt( switchLabel, BranchStmt::Break ) ); 245 CaseStmt * caseStmt = new CaseStmt( condition, stmts ); 248 246 branches.push_back( caseStmt ); 249 247 } 250 *out++ = new SwitchStmt( noLabels,index->clone(), branches );251 *out++ = new NullStmt( std::list<Label>{ switchLabel } );248 *out++ = new SwitchStmt( index->clone(), branches ); 249 *out++ = new NullStmt( { switchLabel } ); 252 250 } 253 251 } … … 262 260 Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 263 261 if ( ! init ) return nullptr; 264 CompoundStmt * block = new CompoundStmt( noLabels);262 CompoundStmt * block = new CompoundStmt(); 265 263 build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) ); 266 264 if ( block->get_kids().empty() ) { … … 309 307 } 310 308 311 class CallFinder : public Visitor { 312 public: 313 typedef Visitor Parent; 309 struct CallFinder { 314 310 CallFinder( const std::list< std::string > & names ) : names( names ) {} 315 311 316 v irtual voidvisit( ApplicationExpr * appExpr ) {312 void postvisit( ApplicationExpr * appExpr ) { 317 313 handleCallExpr( appExpr ); 318 314 } 319 315 320 v irtual voidvisit( UntypedExpr * untypedExpr ) {316 void postvisit( UntypedExpr * untypedExpr ) { 321 317 handleCallExpr( untypedExpr ); 322 318 } … … 328 324 template< typename CallExpr > 329 325 void handleCallExpr( CallExpr * expr ) { 330 Parent::visit( expr );331 326 std::string fname = getFunctionName( expr ); 332 327 if ( std::find( names.begin(), names.end(), fname ) != names.end() ) { … … 337 332 338 333 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) { 339 static CallFinderfinder( std::list< std::string >{ "?{}", "^?{}" } );340 finder. matches = &matches;334 static PassVisitor<CallFinder> finder( std::list< std::string >{ "?{}", "^?{}" } ); 335 finder.pass.matches = &matches; 341 336 maybeAccept( stmt, finder ); 342 337 } … … 544 539 } 545 540 546 class ConstExprChecker : public Visitor { 547 public: 548 ConstExprChecker() : isConstExpr( true ) {} 549 550 using Visitor::visit; 551 552 virtual void visit( ApplicationExpr * ) { isConstExpr = false; } 553 virtual void visit( UntypedExpr * ) { isConstExpr = false; } 554 virtual void visit( NameExpr * ) { isConstExpr = false; } 555 // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; } 556 virtual void visit( AddressExpr *addressExpr ) { 541 struct ConstExprChecker : public WithShortCircuiting { 542 // most expressions are not const expr 543 void previsit( Expression * ) { isConstExpr = false; visit_children = false; } 544 545 void previsit( AddressExpr *addressExpr ) { 546 visit_children = false; 547 557 548 // address of a variable or member expression is constexpr 558 549 Expression * arg = addressExpr->get_arg(); 559 550 if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false; 560 551 } 561 virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; } 562 virtual void visit( MemberExpr * ) { isConstExpr = false; } 563 virtual void visit( VariableExpr * ) { isConstExpr = false; } 564 // these might be okay? 565 // virtual void visit( SizeofExpr *sizeofExpr ); 566 // virtual void visit( AlignofExpr *alignofExpr ); 567 // virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 568 // virtual void visit( OffsetofExpr *offsetofExpr ); 569 // virtual void visit( OffsetPackExpr *offsetPackExpr ); 570 // virtual void visit( AttrExpr *attrExpr ); 571 // virtual void visit( CommaExpr *commaExpr ); 572 // virtual void visit( LogicalExpr *logicalExpr ); 573 // virtual void visit( ConditionalExpr *conditionalExpr ); 574 virtual void visit( TypeExpr * ) { isConstExpr = false; } 575 virtual void visit( AsmExpr * ) { isConstExpr = false; } 576 virtual void visit( UntypedValofExpr * ) { isConstExpr = false; } 577 virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; } 578 virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; } 579 virtual void visit( TupleExpr * ) { isConstExpr = false; } 580 virtual void visit( TupleAssignExpr * ) { isConstExpr = false; } 581 582 bool isConstExpr; 552 553 // these expressions may be const expr, depending on their children 554 void previsit( SizeofExpr * ) {} 555 void previsit( AlignofExpr * ) {} 556 void previsit( UntypedOffsetofExpr * ) {} 557 void previsit( OffsetofExpr * ) {} 558 void previsit( OffsetPackExpr * ) {} 559 void previsit( AttrExpr * ) {} 560 void previsit( CommaExpr * ) {} 561 void previsit( LogicalExpr * ) {} 562 void previsit( ConditionalExpr * ) {} 563 void previsit( CastExpr * ) {} 564 void previsit( ConstantExpr * ) {} 565 566 bool isConstExpr = true; 583 567 }; 584 568 585 569 bool isConstExpr( Expression * expr ) { 586 570 if ( expr ) { 587 ConstExprCheckerchecker;571 PassVisitor<ConstExprChecker> checker; 588 572 expr->accept( checker ); 589 return checker. isConstExpr;573 return checker.pass.isConstExpr; 590 574 } 591 575 return true; … … 594 578 bool isConstExpr( Initializer * init ) { 595 579 if ( init ) { 596 ConstExprCheckerchecker;580 PassVisitor<ConstExprChecker> checker; 597 581 init->accept( checker ); 598 return checker. isConstExpr;582 return checker.pass.isConstExpr; 599 583 } // if 600 584 // for all intents and purposes, no initializer means const expr
Note: See TracChangeset
for help on using the changeset viewer.