зеркало из https://github.com/microsoft/clang-1.git
Store the size of the EH stack inside each BreakContinue struct so we know when a break/continue won't cross a try block.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60998 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
aaa63a761c
Коммит
e21269bcb7
|
@ -492,7 +492,8 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S)
|
||||||
llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
|
llvm::BasicBlock *LoopEnd = createBasicBlock("loopend");
|
||||||
llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
|
llvm::BasicBlock *AfterBody = createBasicBlock("afterbody");
|
||||||
|
|
||||||
BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody));
|
BreakContinueStack.push_back(BreakContinue(LoopEnd, AfterBody,
|
||||||
|
ObjCEHStack.size()));
|
||||||
|
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,8 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
|
||||||
Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
|
Builder.CreateCondBr(BoolCondVal, LoopBody, ExitBlock);
|
||||||
|
|
||||||
// Store the blocks to use for break and continue.
|
// 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.
|
// Emit the loop body.
|
||||||
EmitBlock(LoopBody);
|
EmitBlock(LoopBody);
|
||||||
|
@ -355,7 +356,8 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
|
||||||
llvm::BasicBlock *DoCond = createBasicBlock("do.cond");
|
llvm::BasicBlock *DoCond = createBasicBlock("do.cond");
|
||||||
|
|
||||||
// Store the blocks to use for break and continue.
|
// 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.
|
// Emit the body of the loop into the block.
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
|
@ -433,7 +435,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
|
||||||
ContinueBlock = CondBlock;
|
ContinueBlock = CondBlock;
|
||||||
|
|
||||||
// Store the blocks to use for break and continue.
|
// 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.
|
// If the condition is true, execute the body of the for stmt.
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
|
@ -510,7 +513,7 @@ void CodeGenFunction::EmitBreakStmt(const BreakStmt &S) {
|
||||||
assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
|
assert(!BreakContinueStack.empty() && "break stmt not in a loop or switch!");
|
||||||
|
|
||||||
// FIXME: Implement break in @try or @catch blocks.
|
// 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");
|
CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +531,7 @@ void CodeGenFunction::EmitContinueStmt(const ContinueStmt &S) {
|
||||||
assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
|
assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
|
||||||
|
|
||||||
// FIXME: Implement continue in @try or @catch blocks.
|
// 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");
|
CGM.ErrorUnsupported(&S, "continue inside an Obj-C exception block");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -646,7 +649,8 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) {
|
||||||
llvm::BasicBlock *ContinueBlock = NULL;
|
llvm::BasicBlock *ContinueBlock = NULL;
|
||||||
if (!BreakContinueStack.empty())
|
if (!BreakContinueStack.empty())
|
||||||
ContinueBlock = BreakContinueStack.back().ContinueBlock;
|
ContinueBlock = BreakContinueStack.back().ContinueBlock;
|
||||||
BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock));
|
BreakContinueStack.push_back(BreakContinue(NextBlock, ContinueBlock,
|
||||||
|
ObjCEHStack.size()));
|
||||||
|
|
||||||
// Emit switch body.
|
// Emit switch body.
|
||||||
EmitStmt(S.getBody());
|
EmitStmt(S.getBody());
|
||||||
|
|
|
@ -148,13 +148,14 @@ private:
|
||||||
llvm::DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
|
llvm::DenseMap<const LabelStmt*, llvm::BasicBlock*> LabelMap;
|
||||||
|
|
||||||
// BreakContinueStack - This keeps track of where break and continue
|
// 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 {
|
struct BreakContinue {
|
||||||
BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb)
|
BreakContinue(llvm::BasicBlock *bb, llvm::BasicBlock *cb, size_t ehss)
|
||||||
: BreakBlock(bb), ContinueBlock(cb) {}
|
: BreakBlock(bb), ContinueBlock(cb), EHStackSize(ehss) {}
|
||||||
|
|
||||||
llvm::BasicBlock *BreakBlock;
|
llvm::BasicBlock *BreakBlock;
|
||||||
llvm::BasicBlock *ContinueBlock;
|
llvm::BasicBlock *ContinueBlock;
|
||||||
|
size_t EHStackSize;
|
||||||
};
|
};
|
||||||
llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
|
llvm::SmallVector<BreakContinue, 8> BreakContinueStack;
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче