Enter the cleanups for a block outside the enclosing
full-expression. Naturally they're inactive before we enter
the block literal expression. This restores the intended
behavior that blocks belong to their enclosing scope.
There's a useful -O0 / compile-time optimization that we're
missing here with activating cleanups following straight-line
code from their inactive beginnings.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144268 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h
index 6e71c1f..69f3355 100644
--- a/lib/CodeGen/CGBlocks.h
+++ b/lib/CodeGen/CGBlocks.h
@@ -23,6 +23,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
+#include "CodeGenFunction.h"
#include "CGBuilder.h"
#include "CGCall.h"
#include "CGValue.h"
@@ -128,13 +129,14 @@
class CGBlockInfo {
public:
/// Name - The name of the block, kindof.
- const char *Name;
+ llvm::StringRef Name;
/// The field index of 'this' within the block, if there is one.
unsigned CXXThisIndex;
class Capture {
uintptr_t Data;
+ EHScopeStack::stable_iterator Cleanup;
public:
bool isIndex() const { return (Data & 1) != 0; }
@@ -144,6 +146,14 @@
assert(isConstant());
return reinterpret_cast<llvm::Value*>(Data);
}
+ EHScopeStack::stable_iterator getCleanup() const {
+ assert(isIndex());
+ return Cleanup;
+ }
+ void setCleanup(EHScopeStack::stable_iterator cleanup) {
+ assert(isIndex());
+ Cleanup = cleanup;
+ }
static Capture makeIndex(unsigned index) {
Capture v;
@@ -158,9 +168,6 @@
}
};
- /// The mapping of allocated indexes within the block.
- llvm::DenseMap<const VarDecl*, Capture> Captures;
-
/// CanBeGlobal - True if the block can be global, i.e. it has
/// no non-constant captures.
bool CanBeGlobal : 1;
@@ -176,22 +183,35 @@
/// because it gets set later in the block-creation process.
mutable bool UsesStret : 1;
+ /// The mapping of allocated indexes within the block.
+ llvm::DenseMap<const VarDecl*, Capture> Captures;
+
+ llvm::AllocaInst *Address;
llvm::StructType *StructureType;
- const BlockExpr *Block;
+ const BlockDecl *Block;
+ const BlockExpr *BlockExpression;
CharUnits BlockSize;
CharUnits BlockAlign;
+ CGBlockInfo *NextBlockInfo;
const Capture &getCapture(const VarDecl *var) const {
- llvm::DenseMap<const VarDecl*, Capture>::const_iterator
+ return const_cast<CGBlockInfo*>(this)->getCapture(var);
+ }
+ Capture &getCapture(const VarDecl *var) {
+ llvm::DenseMap<const VarDecl*, Capture>::iterator
it = Captures.find(var);
assert(it != Captures.end() && "no entry for variable!");
return it->second;
}
- const BlockDecl *getBlockDecl() const { return Block->getBlockDecl(); }
- const BlockExpr *getBlockExpr() const { return Block; }
+ const BlockDecl *getBlockDecl() const { return Block; }
+ const BlockExpr *getBlockExpr() const {
+ assert(BlockExpression);
+ assert(BlockExpression->getBlockDecl() == Block);
+ return BlockExpression;
+ }
- CGBlockInfo(const BlockExpr *blockExpr, const char *Name);
+ CGBlockInfo(const BlockDecl *blockDecl, llvm::StringRef Name);
};
} // end namespace CodeGen