forked from OSchip/llvm-project
Do some blocks cleanup and simplification. Fix a crash, and add a test case.
llvm-svn: 65746
This commit is contained in:
parent
e87da66562
commit
ed5e69fe50
|
@ -107,13 +107,43 @@ llvm::Constant *CodeGenModule::getNSConcreteStackBlock() {
|
|||
return NSConcreteStackBlock;
|
||||
}
|
||||
|
||||
static void CollectBlockDeclRefInfo(const Stmt *S,
|
||||
CodeGenFunction::BlockInfo &Info) {
|
||||
for (Stmt::const_child_iterator I = S->child_begin(), E = S->child_end();
|
||||
I != E; ++I)
|
||||
CollectBlockDeclRefInfo(*I, Info);
|
||||
|
||||
if (const BlockDeclRefExpr *DE = dyn_cast<BlockDeclRefExpr>(S)) {
|
||||
// FIXME: Handle enums.
|
||||
if (isa<FunctionDecl>(DE->getDecl()))
|
||||
return;
|
||||
|
||||
if (DE->isByRef())
|
||||
Info.ByRefDeclRefs.push_back(DE);
|
||||
else
|
||||
Info.ByCopyDeclRefs.push_back(DE);
|
||||
}
|
||||
}
|
||||
|
||||
/// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block
|
||||
/// can be declared as a global variable instead of on the stack.
|
||||
static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info)
|
||||
{
|
||||
return Info.ByRefDeclRefs.empty() && Info.ByCopyDeclRefs.empty();
|
||||
}
|
||||
|
||||
// FIXME: Push most into CGM, passing down a few bits, like current
|
||||
// function name.
|
||||
llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
|
||||
bool insideFunction = false;
|
||||
bool BlockRefDeclList = false;
|
||||
bool BlockByrefDeclList = false;
|
||||
|
||||
std::string Name = CurFn->getName();
|
||||
CodeGenFunction::BlockInfo Info(0, Name.c_str());
|
||||
CollectBlockDeclRefInfo(BE->getBody(), Info);
|
||||
|
||||
// Check if the block can be global.
|
||||
if (CanBlockBeGlobal(Info))
|
||||
return CGM.GetAddrOfGlobalBlock(BE, Name.c_str());
|
||||
|
||||
std::vector<llvm::Constant*> Elts;
|
||||
llvm::Constant *C;
|
||||
llvm::Value *V;
|
||||
|
@ -127,11 +157,6 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
|
|||
|
||||
// __isa
|
||||
C = CGM.getNSConcreteStackBlock();
|
||||
if (!insideFunction ||
|
||||
(!BlockRefDeclList && !BlockByrefDeclList)) {
|
||||
C = CGM.getNSConcreteGlobalBlock();
|
||||
flags |= BLOCK_IS_GLOBAL;
|
||||
}
|
||||
const llvm::PointerType *PtrToInt8Ty
|
||||
= llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
|
||||
C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
|
||||
|
@ -148,11 +173,6 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
|
|||
Elts.push_back(C);
|
||||
|
||||
// __invoke
|
||||
const char *Name = "";
|
||||
if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurFuncDecl))
|
||||
if (ND->getIdentifier())
|
||||
Name = ND->getNameAsCString();
|
||||
BlockInfo Info(0, Name);
|
||||
uint64_t subBlockSize, subBlockAlign;
|
||||
llvm::SmallVector<const Expr *, 8> subBlockDeclRefDecls;
|
||||
llvm::Function *Fn
|
||||
|
|
|
@ -450,9 +450,13 @@ public:
|
|||
return CGM.GetAddrOfConstantCFString(S);
|
||||
}
|
||||
case Expr::BlockExprClass: {
|
||||
BlockExpr *B = cast<BlockExpr>(E);
|
||||
if (!B->hasBlockDeclRefExprs())
|
||||
return cast<llvm::Constant>(CGF->BuildBlockLiteralTmp(B));
|
||||
std::string FunctionName;
|
||||
if (CGF)
|
||||
FunctionName = CGF->CurFn->getName();
|
||||
else
|
||||
FunctionName = "global";
|
||||
|
||||
return CGM.GetAddrOfGlobalBlock(cast<BlockExpr>(E), FunctionName.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -275,6 +275,14 @@ public:
|
|||
/// Name - the name of the function this block was created for, if any
|
||||
const char *Name;
|
||||
|
||||
/// ByCopyDeclRefs - Variables from parent scopes that have been imported
|
||||
/// into this block.
|
||||
llvm::SmallVector<const BlockDeclRefExpr *, 8> ByCopyDeclRefs;
|
||||
|
||||
// ByRefDeclRefs - __block variables from parent scopes that have been
|
||||
// imported into this block.
|
||||
llvm::SmallVector<const BlockDeclRefExpr *, 8> ByRefDeclRefs;
|
||||
|
||||
BlockInfo(const llvm::Type *blt, const char *n)
|
||||
: BlockLiteralTy(blt), Name(n) {}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
// RUN: clang %s -emit-llvm -o %t -fblocks
|
||||
void (^f)(void) = ^{};
|
Loading…
Reference in New Issue