Changes in src/InitTweak/InitTweak.cc [c5f3c68:3351cc0]
- File:
-
- 1 edited
-
src/InitTweak/InitTweak.cc (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/InitTweak.cc
rc5f3c68 r3351cc0 5 5 #include <memory> // for __shared_ptr 6 6 7 #include "Common/PassVisitor.h"8 7 #include "Common/SemanticError.h" // for SemanticError 9 8 #include "Common/UniqueName.h" // for UniqueName … … 13 12 #include "Parser/LinkageSpec.h" // for Spec, isBuiltin, Intrinsic 14 13 #include "ResolvExpr/typeops.h" // for typesCompatibleIgnoreQualifiers 15 #include "SymTab/Autogen.h"16 14 #include "SymTab/Indexer.h" // for Indexer 17 15 #include "SynTree/Attribute.h" // for Attribute … … 20 18 #include "SynTree/Expression.h" // for Expression, UntypedExpr, Applicati... 21 19 #include "SynTree/Initializer.h" // for Initializer, ListInit, Designation 22 #include "SynTree/Label.h" // for Label 20 #include "SynTree/Label.h" // for Label, noLabels 23 21 #include "SynTree/Statement.h" // for CompoundStmt, ExprStmt, BranchStmt 24 22 #include "SynTree/Type.h" // for FunctionType, ArrayType, PointerType … … 30 28 namespace InitTweak { 31 29 namespace { 32 struct HasDesignations : public WithShortCircuiting { 30 class HasDesignations : public Visitor { 31 public: 33 32 bool hasDesignations = false; 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 } 33 virtual void visit( Designation * des ) { 34 if ( ! des->get_designators().empty() ) hasDesignations = true; 35 else Visitor::visit( des ); 47 36 } 48 37 }; 49 38 50 struct InitDepthChecker : public WithGuards { 39 class InitDepthChecker : public Visitor { 40 public: 51 41 bool depthOkay = true; 52 42 Type * type; … … 60 50 maxDepth++; 61 51 } 62 v oid previsit( ListInit *) {52 virtual void visit( ListInit * listInit ) { 63 53 curDepth++; 64 GuardAction( [this]() { curDepth--; } );65 54 if ( curDepth > maxDepth ) depthOkay = false; 55 Visitor::visit( listInit ); 56 curDepth--; 66 57 } 67 58 }; 68 59 69 struct InitFlattener : public WithShortCircuiting { 70 void previsit( SingleInit * singleInit ) { 71 visit_children = false; 72 argList.push_back( singleInit->value->clone() ); 73 } 60 class InitFlattener : public Visitor { 61 public: 62 virtual void visit( SingleInit * singleInit ); 63 virtual void visit( ListInit * listInit ); 74 64 std::list< Expression * > argList; 75 65 }; 76 66 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 inits 73 std::list<Initializer*>::iterator it = listInit->begin(); 74 for ( ; it != listInit->end(); ++it ) { 75 (*it)->accept( *this ); 76 } 77 } 77 78 } 78 79 79 80 std::list< Expression * > makeInitList( Initializer * init ) { 80 PassVisitor<InitFlattener>flattener;81 InitFlattener flattener; 81 82 maybeAccept( init, flattener ); 82 return flattener. pass.argList;83 return flattener.argList; 83 84 } 84 85 85 86 bool isDesignated( Initializer * init ) { 86 PassVisitor<HasDesignations>finder;87 HasDesignations finder; 87 88 maybeAccept( init, finder ); 88 return finder. pass.hasDesignations;89 return finder.hasDesignations; 89 90 } 90 91 91 92 bool checkInitDepth( ObjectDecl * objDecl ) { 92 PassVisitor<InitDepthChecker> checker( objDecl->type);93 maybeAccept( objDecl-> init, checker );94 return checker. pass.depthOkay;93 InitDepthChecker checker( objDecl->get_type() ); 94 maybeAccept( objDecl->get_init(), checker ); 95 return checker.depthOkay; 95 96 } 96 97 … … 193 194 callExpr->get_args().splice( callExpr->get_args().end(), args ); 194 195 195 *out++ = new IfStmt( cond, new ExprStmt(callExpr ), nullptr );196 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr ); 196 197 197 198 UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) ); 198 199 increment->get_args().push_back( index->clone() ); 199 *out++ = new ExprStmt( increment );200 *out++ = new ExprStmt( noLabels, increment ); 200 201 } 201 202 … … 242 243 std::list< Statement * > stmts; 243 244 build( callExpr, idx, idxEnd, init, back_inserter( stmts ) ); 244 stmts.push_back( new BranchStmt( switchLabel, BranchStmt::Break ) );245 CaseStmt * caseStmt = new CaseStmt( condition, stmts );245 stmts.push_back( new BranchStmt( noLabels, switchLabel, BranchStmt::Break ) ); 246 CaseStmt * caseStmt = new CaseStmt( noLabels, condition, stmts ); 246 247 branches.push_back( caseStmt ); 247 248 } 248 *out++ = new SwitchStmt( index->clone(), branches );249 *out++ = new NullStmt( { switchLabel } );249 *out++ = new SwitchStmt( noLabels, index->clone(), branches ); 250 *out++ = new NullStmt( std::list<Label>{ switchLabel } ); 250 251 } 251 252 } … … 260 261 Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 261 262 if ( ! init ) return nullptr; 262 CompoundStmt * block = new CompoundStmt( );263 CompoundStmt * block = new CompoundStmt( noLabels ); 263 264 build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) ); 264 265 if ( block->get_kids().empty() ) { … … 307 308 } 308 309 309 struct CallFinder { 310 class CallFinder : public Visitor { 311 public: 312 typedef Visitor Parent; 310 313 CallFinder( const std::list< std::string > & names ) : names( names ) {} 311 314 312 v oid postvisit( ApplicationExpr * appExpr ) {315 virtual void visit( ApplicationExpr * appExpr ) { 313 316 handleCallExpr( appExpr ); 314 317 } 315 318 316 v oid postvisit( UntypedExpr * untypedExpr ) {319 virtual void visit( UntypedExpr * untypedExpr ) { 317 320 handleCallExpr( untypedExpr ); 318 321 } … … 324 327 template< typename CallExpr > 325 328 void handleCallExpr( CallExpr * expr ) { 329 Parent::visit( expr ); 326 330 std::string fname = getFunctionName( expr ); 327 331 if ( std::find( names.begin(), names.end(), fname ) != names.end() ) { … … 332 336 333 337 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) { 334 static PassVisitor<CallFinder>finder( std::list< std::string >{ "?{}", "^?{}" } );335 finder. pass.matches = &matches;338 static CallFinder finder( std::list< std::string >{ "?{}", "^?{}" } ); 339 finder.matches = &matches; 336 340 maybeAccept( stmt, finder ); 337 341 } … … 520 524 } 521 525 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 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 ) { 548 537 // address of a variable or member expression is constexpr 549 538 Expression * arg = addressExpr->get_arg(); 550 539 if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false; 551 540 } 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; 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; 567 563 }; 568 564 569 565 bool isConstExpr( Expression * expr ) { 570 566 if ( expr ) { 571 PassVisitor<ConstExprChecker>checker;567 ConstExprChecker checker; 572 568 expr->accept( checker ); 573 return checker. pass.isConstExpr;569 return checker.isConstExpr; 574 570 } 575 571 return true; … … 578 574 bool isConstExpr( Initializer * init ) { 579 575 if ( init ) { 580 PassVisitor<ConstExprChecker>checker;576 ConstExprChecker checker; 581 577 init->accept( checker ); 582 return checker. pass.isConstExpr;578 return checker.isConstExpr; 583 579 } // if 584 580 // for all intents and purposes, no initializer means const expr
Note:
See TracChangeset
for help on using the changeset viewer.