diff options
author | Anders Carlsson <andersca@mac.com> | 2008-12-13 22:52:24 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-12-13 22:52:24 +0000 |
commit | 6b958f9634d27fecc58f6cc3a56abd4ebe41441d (patch) | |
tree | 4b10bee62641b576fbf3db84d76391eb54977990 /clang/lib/CodeGen | |
parent | 24092271cc470d3f73a46573a678258bb0bfbf77 (diff) | |
download | bcm5719-llvm-6b958f9634d27fecc58f6cc3a56abd4ebe41441d.tar.gz bcm5719-llvm-6b958f9634d27fecc58f6cc3a56abd4ebe41441d.zip |
Store the size of the EH stack inside each BreakContinue struct so we know when a break/continue won't cross a try block.
llvm-svn: 60998
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 16 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 7 |
3 files changed, 16 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index f955782ffdc..0237b96b519 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -492,7 +492,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S) llvm::BasicBlock *LoopEnd = createBasicBlock("loopend"); llvm::BasicBlock *AfterBody = createBasicBlock("afterbody"); - BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody)); + BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody, + ObjCEHStack.size())); EmitStmt(S.getBody()); diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 1c5cb90cbe3..afce63d41d8 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -322,7 +322,8 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) { Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock); // Store the blocks to use for break and continue. - BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader)); + BreakContinueStack.push_back(BreakContinue(ExitBlock, LoopHeader, + ObjCEHStack.size())); // Emit the loop body. EmitBlock(LoopBody); @@ -355,7 +356,8 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S) { llvm::BasicBlock *DoCond = createBasicBlock("do.cond"); // Store the blocks to use for break and continue. - BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond)); + BreakContinueStack.push_back(BreakContinue(AfterDo, DoCond, + ObjCEHStack.size())); // Emit the body of the loop into the block. EmitStmt(S.getBody()); @@ -433,7 +435,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) { ContinueBlock = CondBlock; // Store the blocks to use for break and continue. - BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock)); + BreakContinueStack.push_back(BreakContinue(AfterFor, ContinueBlock, + ObjCEHStack.size())); // If the condition is true, execute the body of the for stmt. EmitStmt(S.getBody()); @@ -510,7 +513,7 @@ void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) { assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!"); // FIXME: Implement break in @try or @catch blocks. - if (!ObjCEHStack.empty()) { + if (ObjCEHStack.size() != BreakContinueStack.back().EHStackSize) { CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block"); return; } @@ -528,7 +531,7 @@ void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) { assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); // FIXME: Implement continue in @try or @catch blocks. - if (!ObjCEHStack.empty()) { + if (ObjCEHStack.size() != BreakContinueStack.back().EHStackSize) { CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block"); return; } @@ -646,7 +649,8 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { llvm::BasicBlock *ContinueBlock = NULL; if (!BreakContinueStack.empty()) ContinueBlock = BreakContinueStack.back().ContinueBlock; - BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock)); + BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock, + ObjCEHStack.size())); // Emit switch body. EmitStmt(S.getBody()); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 5c4246f7c31..2959c08a441 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -148,13 +148,14 @@ private: llvm::DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap; // BreakContinueStack - This keeps track of where break and continue - // statements should jump to. + // statements should jump to, as well as the size of the eh stack. struct BreakContinue { - BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb) - : BreakBlock(bb), ContinueBlock(cb) {} + BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb, size_t ehss) + : BreakBlock(bb), ContinueBlock(cb), EHStackSize(ehss) {} llvm::BasicBlock *BreakBlock; llvm::BasicBlock *ContinueBlock; + size_t EHStackSize; }; llvm::SmallVector<BreakContinue, 8> BreakContinueStack; |