From fbfb5e6530f805f7edcb6eca18eb76e47433aac5 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 8 Feb 2009 00:16:35 +0000 Subject: [PATCH] When emitting blocks, keep track of which cleanup scope they have. Minor fixes and cleanup. llvm-svn: 64053 --- clang/lib/CodeGen/CGStmt.cpp | 6 ++++++ clang/lib/CodeGen/CodeGenFunction.cpp | 20 +++++++++++++++++++- clang/lib/CodeGen/CodeGenFunction.h | 11 +++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index fc7a7c7f8f1e..19977ec380e5 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -188,6 +188,12 @@ void CodeGenFunction::EmitBlock(llvm::BasicBlock *BB, bool IsFinished) { return; } + // If necessary, associate the block with the cleanup stack size. + if (!CleanupEntries.empty()) { + BlockScopes[BB] = CleanupEntries.size() - 1; + CleanupEntries.back().Blocks.push_back(BB); + } + CurFn->getBasicBlockList().push_back(BB); Builder.SetInsertPoint(BB); } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 838de70218d5..0e0140c9ad77 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -119,7 +119,11 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); - + assert(BlockScopes.empty() && + "did not remove all blocks from block scope map!"); + assert(CleanupEntries.empty() && + "mismatched push/pop in cleanup stack!"); + // Emit function epilog (to return). EmitReturnBlock(); @@ -537,8 +541,22 @@ void CodeGenFunction::EmitCleanupBlock() llvm::BasicBlock *CleanupBlock = CE.CleanupBlock; + std::vector Blocks; + std::swap(Blocks, CE.Blocks); + + std::vector BranchFixups; + std::swap(BranchFixups, CE.BranchFixups); + CleanupEntries.pop_back(); EmitBlock(CleanupBlock); + + // Remove all blocks from the block scope map. + for (size_t i = 0, e = Blocks.size(); i != e; ++i) { + assert(BlockScopes.count(Blocks[i]) && + "Did not find block in scope map!"); + + BlockScopes.erase(Blocks[i]); + } } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 8a0220724e5d..3dbc2c99e716 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -253,11 +253,22 @@ private: explicit CleanupEntry(llvm::BasicBlock *cb) : CleanupBlock(cb) {} + + ~CleanupEntry() { + assert(Blocks.empty() && "Did not empty blocks!"); + assert(BranchFixups.empty() && "Did not empty branch fixups!"); + } + }; /// CleanupEntries - Stack of cleanup entries. llvm::SmallVector CleanupEntries; + typedef llvm::DenseMap BlockScopeMap; + + /// BlockScopes - Map of which "cleanup scope" scope basic blocks have. + BlockScopeMap BlockScopes; + public: CodeGenFunction(CodeGenModule &cgm);