diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-07-14 00:11:03 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-07-14 00:11:03 +0000 |
| commit | a547eb27fa5ed28b631f5a72f369e68e9c3cca1f (patch) | |
| tree | ea8248c585a5ee4759adfc838899e3f35adfbcff /clang/lib/Analysis | |
| parent | d5bbd856e2a71201d8bf9b0cbcb5339df9bf9f12 (diff) | |
| download | bcm5719-llvm-a547eb27fa5ed28b631f5a72f369e68e9c3cca1f.tar.gz bcm5719-llvm-a547eb27fa5ed28b631f5a72f369e68e9c3cca1f.zip | |
P0305R0: Semantic analysis and code generation for C++17 init-statement for 'if' and 'switch':
if (stmt; condition) { ... }
Patch by Anton Bikineev! Some minor formatting and comment tweets by me.
llvm-svn: 275350
Diffstat (limited to 'clang/lib/Analysis')
| -rw-r--r-- | clang/lib/Analysis/BodyFarm.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Analysis/CFG.cpp | 35 |
2 files changed, 35 insertions, 8 deletions
diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp index 07167014d68..d202a040646 100644 --- a/clang/lib/Analysis/BodyFarm.cpp +++ b/clang/lib/Analysis/BodyFarm.cpp @@ -239,7 +239,8 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { SourceLocation()); // (5) Create the 'if' statement. - IfStmt *If = new (C) IfStmt(C, SourceLocation(), false, nullptr, UO, CS); + IfStmt *If = new (C) IfStmt(C, SourceLocation(), false, nullptr, nullptr, + UO, CS); return If; } @@ -342,9 +343,8 @@ static Stmt *create_OSAtomicCompareAndSwap(ASTContext &C, const FunctionDecl *D) Stmt *Else = M.makeReturn(RetVal); /// Construct the If. - Stmt *If = - new (C) IfStmt(C, SourceLocation(), false, nullptr, Comparison, Body, - SourceLocation(), Else); + Stmt *If = new (C) IfStmt(C, SourceLocation(), false, nullptr, nullptr, + Comparison, Body, SourceLocation(), Else); return If; } diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 2c502cdcf4e..d7a9bdb3d82 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -1,4 +1,4 @@ - //===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===// +//===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -1945,7 +1945,8 @@ CFGBlock *CFGBuilder::VisitCompoundStmt(CompoundStmt *C) { addLocalScopeForStmt(C); } if (!C->body_empty() && !isa<ReturnStmt>(*C->body_rbegin())) { - // If the body ends with a ReturnStmt, the dtors will be added in VisitReturnStmt + // If the body ends with a ReturnStmt, the dtors will be added in + // VisitReturnStmt. addAutomaticObjDtors(ScopePos, scopeBeginPos, C); } @@ -2168,6 +2169,13 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { // won't be restored when traversing AST. SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); + // Create local scope for C++17 if init-stmt if one exists. + if (Stmt *Init = I->getInit()) { + LocalScope::const_iterator BeginScopePos = ScopePos; + addLocalScopeForStmt(Init); + addAutomaticObjDtors(ScopePos, BeginScopePos, I); + } + // Create local scope for possible condition variable. // Store scope position. Add implicit destructor. if (VarDecl *VD = I->getConditionVariable()) { @@ -2268,13 +2276,19 @@ CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { // blocks will be pointed to be "Block". CFGBlock *LastBlock = addStmt(I->getCond()); - // Finally, if the IfStmt contains a condition variable, add it and its + // If the IfStmt contains a condition variable, add it and its // initializer to the CFG. if (const DeclStmt* DS = I->getConditionVariableDeclStmt()) { autoCreateBlock(); LastBlock = addStmt(const_cast<DeclStmt *>(DS)); } + // Finally, if the IfStmt contains a C++17 init-stmt, add it to the CFG. + if (Stmt *Init = I->getInit()) { + autoCreateBlock(); + LastBlock = addStmt(Init); + } + return LastBlock; } @@ -3059,6 +3073,13 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { // won't be restored when traversing AST. SaveAndRestore<LocalScope::const_iterator> save_scope_pos(ScopePos); + // Create local scope for C++17 switch init-stmt if one exists. + if (Stmt *Init = Terminator->getInit()) { + LocalScope::const_iterator BeginScopePos = ScopePos; + addLocalScopeForStmt(Init); + addAutomaticObjDtors(ScopePos, BeginScopePos, Terminator); + } + // Create local scope for possible condition variable. // Store scope position. Add implicit destructor. if (VarDecl *VD = Terminator->getConditionVariable()) { @@ -3138,7 +3159,7 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { Block = SwitchTerminatedBlock; CFGBlock *LastBlock = addStmt(Terminator->getCond()); - // Finally, if the SwitchStmt contains a condition variable, add both the + // If the SwitchStmt contains a condition variable, add both the // SwitchStmt and the condition variable initialization to the CFG. if (VarDecl *VD = Terminator->getConditionVariable()) { if (Expr *Init = VD->getInit()) { @@ -3148,6 +3169,12 @@ CFGBlock *CFGBuilder::VisitSwitchStmt(SwitchStmt *Terminator) { } } + // Finally, if the SwitchStmt contains a C++17 init-stmt, add it to the CFG. + if (Stmt *Init = Terminator->getInit()) { + autoCreateBlock(); + LastBlock = addStmt(Init); + } + return LastBlock; } |

