]> granicus.if.org Git - clang/commitdiff
Store the size of the EH stack inside each BreakContinue struct so we know when a...
authorAnders Carlsson <andersca@mac.com>
Sat, 13 Dec 2008 22:52:24 +0000 (22:52 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 13 Dec 2008 22:52:24 +0000 (22:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60998 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGObjC.cpp
lib/CodeGen/CGStmt.cpp
lib/CodeGen/CodeGenFunction.h

index f955782ffdc45a68547674a8546a0ea4b20653fa..0237b96b5199a550711a306077d5e096cf10daaf 100644 (file)
@@ -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());
   
index 1c5cb90cbe34d8ec8a7accea6a30d79b17d3e54a..afce63d41d8f08605b47cfd5d9d2f97ec1da66bf 100644 (file)
@@ -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());
index 5c4246f7c315ca7801a23a0ebd3071f7f3009c40..2959c08a4410d4b88578e92e026e39ebb9739966 100644 (file)
@@ -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;