зеркало из https://github.com/microsoft/clang.git
More codegen support for the copy/dispose helpers for block literals.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66241 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
a4f668f3b7
Коммит
45031c08c6
|
@ -52,16 +52,10 @@ llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl(uint64_t Size) {
|
|||
|
||||
if (BlockHasCopyDispose) {
|
||||
// copy_func_helper_decl
|
||||
// FIXME: implement
|
||||
C = llvm::Constant::getNullValue(PtrToInt8Ty);
|
||||
C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
|
||||
Elts.push_back(C);
|
||||
Elts.push_back(BuildCopyHelper());
|
||||
|
||||
// destroy_func_decl
|
||||
// FIXME: implement
|
||||
C = llvm::Constant::getNullValue(PtrToInt8Ty);
|
||||
C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
|
||||
Elts.push_back(C);
|
||||
Elts.push_back(BuildDestroyHelper());
|
||||
}
|
||||
|
||||
C = llvm::ConstantStruct::get(Elts);
|
||||
|
@ -753,14 +747,98 @@ llvm::Constant *BlockFunction::GenerateDestroyHelperFunction() {
|
|||
return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
|
||||
}
|
||||
|
||||
llvm::Constant *BlockFunction::BuildCopyHelper(int flag) {
|
||||
llvm::Constant *BlockFunction::BuildCopyHelper() {
|
||||
return CodeGenFunction(CGM).GenerateCopyHelperFunction();
|
||||
}
|
||||
|
||||
llvm::Constant *BlockFunction::BuildDestroyHelper(int flag) {
|
||||
llvm::Constant *BlockFunction::BuildDestroyHelper() {
|
||||
return CodeGenFunction(CGM).GenerateDestroyHelperFunction();
|
||||
}
|
||||
|
||||
llvm::Constant *BlockFunction::GeneratebyrefCopyHelperFunction() {
|
||||
QualType R = getContext().VoidTy;
|
||||
|
||||
FunctionArgList Args;
|
||||
// FIXME: This leaks
|
||||
ImplicitParamDecl *Src =
|
||||
ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
|
||||
getContext().getPointerType(getContext().VoidTy));
|
||||
|
||||
Args.push_back(std::make_pair(Src, Src->getType()));
|
||||
|
||||
const CGFunctionInfo &FI =
|
||||
CGM.getTypes().getFunctionInfo(R, Args);
|
||||
|
||||
std::string Name = std::string("__Block_byref_id_object_copy_");
|
||||
CodeGenTypes &Types = CGM.getTypes();
|
||||
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
|
||||
|
||||
llvm::Function *Fn =
|
||||
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
||||
Name,
|
||||
&CGM.getModule());
|
||||
|
||||
IdentifierInfo *II
|
||||
= &CGM.getContext().Idents.get("__Block_byref_id_object_copy_");
|
||||
|
||||
FunctionDecl *FD = FunctionDecl::Create(getContext(),
|
||||
getContext().getTranslationUnitDecl(),
|
||||
SourceLocation(), II, R,
|
||||
FunctionDecl::Static, false,
|
||||
true);
|
||||
CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
|
||||
// EmitStmt(BExpr->getBody());
|
||||
CGF.FinishFunction();
|
||||
|
||||
return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
|
||||
}
|
||||
|
||||
llvm::Constant *BlockFunction::GeneratebyrefDestroyHelperFunction() {
|
||||
QualType R = getContext().VoidTy;
|
||||
|
||||
FunctionArgList Args;
|
||||
// FIXME: This leaks
|
||||
ImplicitParamDecl *Src =
|
||||
ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
|
||||
getContext().getPointerType(getContext().VoidTy));
|
||||
|
||||
Args.push_back(std::make_pair(Src, Src->getType()));
|
||||
|
||||
const CGFunctionInfo &FI =
|
||||
CGM.getTypes().getFunctionInfo(R, Args);
|
||||
|
||||
std::string Name = std::string("__Block_byref_id_object_dispose_");
|
||||
CodeGenTypes &Types = CGM.getTypes();
|
||||
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false);
|
||||
|
||||
llvm::Function *Fn =
|
||||
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
||||
Name,
|
||||
&CGM.getModule());
|
||||
|
||||
IdentifierInfo *II
|
||||
= &CGM.getContext().Idents.get("__Block_byref_id_object_dispose_");
|
||||
|
||||
FunctionDecl *FD = FunctionDecl::Create(getContext(),
|
||||
getContext().getTranslationUnitDecl(),
|
||||
SourceLocation(), II, R,
|
||||
FunctionDecl::Static, false,
|
||||
true);
|
||||
CGF.StartFunction(FD, R, Fn, Args, SourceLocation());
|
||||
// EmitStmt(BExpr->getBody());
|
||||
CGF.FinishFunction();
|
||||
|
||||
return llvm::ConstantExpr::getBitCast(Fn, PtrToInt8Ty);
|
||||
}
|
||||
|
||||
llvm::Constant *BlockFunction::BuildbyrefCopyHelper(int flag) {
|
||||
return CodeGenFunction(CGM).GeneratebyrefCopyHelperFunction();
|
||||
}
|
||||
|
||||
llvm::Constant *BlockFunction::BuildbyrefDestroyHelper(int flag) {
|
||||
return CodeGenFunction(CGM).GeneratebyrefDestroyHelperFunction();
|
||||
}
|
||||
|
||||
llvm::Value *BlockFunction::getBlockObjectDispose() {
|
||||
if (CGM.BlockObjectDispose == 0) {
|
||||
const llvm::FunctionType *FTy;
|
||||
|
|
|
@ -160,8 +160,14 @@ public:
|
|||
llvm::Constant *GenerateCopyHelperFunction();
|
||||
llvm::Constant *GenerateDestroyHelperFunction();
|
||||
|
||||
llvm::Constant *BuildCopyHelper(int flag);
|
||||
llvm::Constant *BuildDestroyHelper(int flag);
|
||||
llvm::Constant *BuildCopyHelper();
|
||||
llvm::Constant *BuildDestroyHelper();
|
||||
|
||||
llvm::Constant *GeneratebyrefCopyHelperFunction();
|
||||
llvm::Constant *GeneratebyrefDestroyHelperFunction();
|
||||
|
||||
llvm::Constant *BuildbyrefCopyHelper(int flag);
|
||||
llvm::Constant *BuildbyrefDestroyHelper(int flag);
|
||||
|
||||
llvm::Value *getBlockObjectDispose();
|
||||
void BuildBlockRelease(const VarDecl &D, llvm::Value *DeclPtr);
|
||||
|
|
|
@ -375,9 +375,9 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
|
|||
llvm::Value *copy_helper = Builder.CreateStructGEP(DeclPtr, 4);
|
||||
llvm::Value *destroy_helper = Builder.CreateStructGEP(DeclPtr, 5);
|
||||
|
||||
Builder.CreateStore(BuildCopyHelper(flag), copy_helper);
|
||||
Builder.CreateStore(BuildbyrefCopyHelper(flag), copy_helper);
|
||||
|
||||
Builder.CreateStore(BuildDestroyHelper(flag), destroy_helper);
|
||||
Builder.CreateStore(BuildbyrefDestroyHelper(flag), destroy_helper);
|
||||
}
|
||||
needsDispose = true;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
// RUN: clang %s -emit-llvm -o %t -fblocks -f__block &&
|
||||
// RUN: grep "_Block_object_dispose" %t | count 4
|
||||
// RUN: grep "__copy_helper_block_" %t | count 2
|
||||
// RUN: grep "__destroy_helper_block_" %t | count 2
|
||||
// RUN: grep "_Block_object_dispose" %t | count 5
|
||||
// RUN: grep "__copy_helper_block_" %t | count 6
|
||||
// RUN: grep "__destroy_helper_block_" %t | count 6
|
||||
// RUN: grep "__Block_byref_id_object_copy_" %t | count 2
|
||||
// RUN: grep "__Block_byref_id_object_dispose_" %t | count 2
|
||||
#include <stdio.h>
|
||||
|
||||
void test1() {
|
||||
|
@ -31,8 +33,9 @@ void test2() {
|
|||
}
|
||||
|
||||
void test3() {
|
||||
__block int k;
|
||||
__block int (^j)(int);
|
||||
^{j=0;}();
|
||||
^{j=0; k=0;}();
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче