Changes in src/InitTweak/InitTweak.cc [3351cc0:c5f3c68]
- File:
-
- 1 edited
-
src/InitTweak/InitTweak.cc (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/InitTweak.cc
r3351cc0 rc5f3c68 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 … … 12 13 #include "Parser/LinkageSpec.h" // for Spec, isBuiltin, Intrinsic 13 14 #include "ResolvExpr/typeops.h" // for typesCompatibleIgnoreQualifiers 15 #include "SymTab/Autogen.h" 14 16 #include "SymTab/Indexer.h" // for Indexer 15 17 #include "SynTree/Attribute.h" // for Attribute … … 18 20 #include "SynTree/Expression.h" // for Expression, UntypedExpr, Applicati... 19 21 #include "SynTree/Initializer.h" // for Initializer, ListInit, Designation 20 #include "SynTree/Label.h" // for Label , noLabels22 #include "SynTree/Label.h" // for Label 21 23 #include "SynTree/Statement.h" // for CompoundStmt, ExprStmt, BranchStmt 22 24 #include "SynTree/Type.h" // for FunctionType, ArrayType, PointerType … … 28 30 namespace InitTweak { 29 31 namespace { 30 class HasDesignations : public Visitor { 31 public: 32 struct HasDesignations : public WithShortCircuiting { 32 33 bool hasDesignations = false; 33 virtual void visit( Designation * des ) { 34 if ( ! des->get_designators().empty() ) hasDesignations = true; 35 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 } 36 47 } 37 48 }; 38 49 39 class InitDepthChecker : public Visitor { 40 public: 50 struct InitDepthChecker : public WithGuards { 41 51 bool depthOkay = true; 42 52 Type * type; … … 50 60 maxDepth++; 51 61 } 52 v irtual void visit( ListInit * listInit) {62 void previsit( ListInit * ) { 53 63 curDepth++; 64 GuardAction( [this]() { curDepth--; } ); 54 65 if ( curDepth > maxDepth ) depthOkay = false; 55 Visitor::visit( listInit );56 curDepth--;57 66 } 58 67 }; 59 68 60 class InitFlattener : public Visitor { 61 public: 62 virtual void visit( SingleInit * singleInit ); 63 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 } 64 74 std::list< Expression * > argList; 65 75 }; 66 76 67 void InitFlattener::visit( SingleInit * singleInit ) {68 argList.push_back( singleInit->get_value()->clone() );69 }70 71 void InitFlattener::visit( ListInit * listInit ) {72 // flatten nested list inits73 std::list<Initializer*>::iterator it = listInit->begin();74 for ( ; it != listInit->end(); ++it ) {75 (*it)->accept( *this );76 }77 }78 77 } 79 78 80 79 std::list< Expression * > makeInitList( Initializer * init ) { 81 InitFlattenerflattener;80 PassVisitor<InitFlattener> flattener; 82 81 maybeAccept( init, flattener ); 83 return flattener. argList;82 return flattener.pass.argList; 84 83 } 85 84 86 85 bool isDesignated( Initializer * init ) { 87 HasDesignationsfinder;86 PassVisitor<HasDesignations> finder; 88 87 maybeAccept( init, finder ); 89 return finder. hasDesignations;88 return finder.pass.hasDesignations; 90 89 } 91 90 92 91 bool checkInitDepth( ObjectDecl * objDecl ) { 93 InitDepthChecker checker( objDecl->get_type());94 maybeAccept( objDecl-> get_init(), checker );95 return checker. depthOkay;92 PassVisitor<InitDepthChecker> checker( objDecl->type ); 93 maybeAccept( objDecl->init, checker ); 94 return checker.pass.depthOkay; 96 95 } 97 96 … … 194 193 callExpr->get_args().splice( callExpr->get_args().end(), args ); 195 194 196 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels,callExpr ), nullptr );195 *out++ = new IfStmt( cond, new ExprStmt( callExpr ), nullptr ); 197 196 198 197 UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) ); 199 198 increment->get_args().push_back( index->clone() ); 200 *out++ = new ExprStmt( noLabels,increment );199 *out++ = new ExprStmt( increment ); 201 200 } 202 201 … … 243 242 std::list< Statement * > stmts; 244 243 build( callExpr, idx, idxEnd, init, back_inserter( stmts ) ); 245 stmts.push_back( new BranchStmt( noLabels,switchLabel, BranchStmt::Break ) );246 CaseStmt * caseStmt = new CaseStmt( noLabels,condition, stmts );244 stmts.push_back( new BranchStmt( switchLabel, BranchStmt::Break ) ); 245 CaseStmt * caseStmt = new CaseStmt( condition, stmts ); 247 246 branches.push_back( caseStmt ); 248 247 } 249 *out++ = new SwitchStmt( noLabels,index->clone(), branches );250 *out++ = new NullStmt( std::list<Label>{ switchLabel } );248 *out++ = new SwitchStmt( index->clone(), branches ); 249 *out++ = new NullStmt( { switchLabel } ); 251 250 } 252 251 } … … 261 260 Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 262 261 if ( ! init ) return nullptr; 263 CompoundStmt * block = new CompoundStmt( noLabels);262 CompoundStmt * block = new CompoundStmt(); 264 263 build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) ); 265 264 if ( block->get_kids().empty() ) { … … 308 307 } 309 308 310 class CallFinder : public Visitor { 311 public: 312 typedef Visitor Parent; 309 struct CallFinder { 313 310 CallFinder( const std::list< std::string > & names ) : names( names ) {} 314 311 315 v irtual voidvisit( ApplicationExpr * appExpr ) {312 void postvisit( ApplicationExpr * appExpr ) { 316 313 handleCallExpr( appExpr ); 317 314 } 318 315 319 v irtual voidvisit( UntypedExpr * untypedExpr ) {316 void postvisit( UntypedExpr * untypedExpr ) { 320 317 handleCallExpr( untypedExpr ); 321 318 } … … 327 324 template< typename CallExpr > 328 325 void handleCallExpr( CallExpr * expr ) { 329 Parent::visit( expr );330 326 std::string fname = getFunctionName( expr ); 331 327 if ( std::find( names.begin(), names.end(), fname ) != names.end() ) { … … 336 332 337 333 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) { 338 static CallFinderfinder( std::list< std::string >{ "?{}", "^?{}" } );339 finder. matches = &matches;334 static PassVisitor<CallFinder> finder( std::list< std::string >{ "?{}", "^?{}" } ); 335 finder.pass.matches = &matches; 340 336 maybeAccept( stmt, finder ); 341 337 } … … 524 520 } 525 521 526 class ConstExprChecker : public Visitor { 527 public: 528 ConstExprChecker() : isConstExpr( true ) {} 529 530 using Visitor::visit; 531 532 virtual void visit( ApplicationExpr * ) { isConstExpr = false; } 533 virtual void visit( UntypedExpr * ) { isConstExpr = false; } 534 virtual void visit( NameExpr * ) { isConstExpr = false; } 535 // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; } 536 virtual void visit( AddressExpr *addressExpr ) { 522 ApplicationExpr * createBitwiseAssignment( Expression * dst, Expression * src ) { 523 static FunctionDecl * assign = nullptr; 524 if ( ! assign ) { 525 // temporary? Generate a fake assignment operator to represent bitwise assignments. 526 // This operator could easily exist as a real function, but it's tricky because nothing should resolve to this function. 527 TypeDecl * td = new TypeDecl( "T", noStorageClasses, nullptr, TypeDecl::Dtype, true ); 528 assign = new FunctionDecl( "?=?", noStorageClasses, LinkageSpec::Intrinsic, SymTab::genAssignType( new TypeInstType( noQualifiers, td->name, td ) ), nullptr ); 529 } 530 if ( dynamic_cast< ReferenceType * >( dst->result ) ) { 531 dst = new AddressExpr( dst ); 532 } else { 533 dst = new CastExpr( dst, new ReferenceType( noQualifiers, dst->result->clone() ) ); 534 } 535 if ( dynamic_cast< ReferenceType * >( src->result ) ) { 536 src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) ); 537 } 538 return new ApplicationExpr( VariableExpr::functionPointer( assign ), { dst, src } ); 539 } 540 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 537 548 // address of a variable or member expression is constexpr 538 549 Expression * arg = addressExpr->get_arg(); 539 550 if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false; 540 551 } 541 virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; } 542 virtual void visit( MemberExpr * ) { isConstExpr = false; } 543 virtual void visit( VariableExpr * ) { isConstExpr = false; } 544 // these might be okay? 545 // virtual void visit( SizeofExpr *sizeofExpr ); 546 // virtual void visit( AlignofExpr *alignofExpr ); 547 // virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 548 // virtual void visit( OffsetofExpr *offsetofExpr ); 549 // virtual void visit( OffsetPackExpr *offsetPackExpr ); 550 // virtual void visit( AttrExpr *attrExpr ); 551 // virtual void visit( CommaExpr *commaExpr ); 552 // virtual void visit( LogicalExpr *logicalExpr ); 553 // virtual void visit( ConditionalExpr *conditionalExpr ); 554 virtual void visit( TypeExpr * ) { isConstExpr = false; } 555 virtual void visit( AsmExpr * ) { isConstExpr = false; } 556 virtual void visit( UntypedValofExpr * ) { isConstExpr = false; } 557 virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; } 558 virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; } 559 virtual void visit( TupleExpr * ) { isConstExpr = false; } 560 virtual void visit( TupleAssignExpr * ) { isConstExpr = false; } 561 562 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; 563 567 }; 564 568 565 569 bool isConstExpr( Expression * expr ) { 566 570 if ( expr ) { 567 ConstExprCheckerchecker;571 PassVisitor<ConstExprChecker> checker; 568 572 expr->accept( checker ); 569 return checker. isConstExpr;573 return checker.pass.isConstExpr; 570 574 } 571 575 return true; … … 574 578 bool isConstExpr( Initializer * init ) { 575 579 if ( init ) { 576 ConstExprCheckerchecker;580 PassVisitor<ConstExprChecker> checker; 577 581 init->accept( checker ); 578 return checker. isConstExpr;582 return checker.pass.isConstExpr; 579 583 } // if 580 584 // for all intents and purposes, no initializer means const expr
Note:
See TracChangeset
for help on using the changeset viewer.