From: Argyrios Kyrtzidis Date: Fri, 9 Sep 2011 06:44:21 +0000 (+0000) Subject: Do a lookup for the blocks runtime globals to see if they were declared, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ead363bdd2756efa945108941ab46bbde3bd8bdf;p=clang Do a lookup for the blocks runtime globals to see if they were declared, instead of codegen waiting to consume such a declaration, which won't happen if that decls are coming from a PCH. Fixes rdar://10028656. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139359 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index dbcb7acfee..7ccae08464 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -68,9 +68,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, CFConstantStringClassRef(0), ConstantStringClassRef(0), NSConstantStringType(0), VMContext(M.getContext()), - NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0), NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), - BlockObjectAssignDecl(0), BlockObjectDisposeDecl(0), BlockObjectAssign(0), BlockObjectDispose(0), BlockDescriptorType(0), GenericBlockLiteralType(0) { if (Features.ObjC1) @@ -739,15 +737,6 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { // Ignore declarations, they will be emitted on their first use. if (const FunctionDecl *FD = dyn_cast(Global)) { - if (FD->getIdentifier()) { - StringRef Name = FD->getName(); - if (Name == "_Block_object_assign") { - BlockObjectAssignDecl = FD; - } else if (Name == "_Block_object_dispose") { - BlockObjectDisposeDecl = FD; - } - } - // Forward declarations are emitted lazily on first use. if (!FD->doesThisDeclarationHaveABody()) { if (!FD->doesDeclarationForceExternallyVisibleDefinition()) @@ -768,16 +757,6 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) { const VarDecl *VD = cast(Global); assert(VD->isFileVarDecl() && "Cannot emit local var decl as global."); - if (VD->getIdentifier()) { - StringRef Name = VD->getName(); - if (Name == "_NSConcreteGlobalBlock") { - NSConcreteGlobalBlockDecl = VD; - } else if (Name == "_NSConcreteStackBlock") { - NSConcreteStackBlockDecl = VD; - } - } - - if (VD->isThisDeclarationADefinition() != VarDecl::Definition) return; } @@ -2428,12 +2407,15 @@ llvm::Constant *CodeGenModule::getBlockObjectDispose() { if (BlockObjectDispose) return BlockObjectDispose; - // If we saw an explicit decl, use that. - if (BlockObjectDisposeDecl) { - return BlockObjectDispose = GetAddrOfFunction( - BlockObjectDisposeDecl, - getTypes().GetFunctionType(BlockObjectDisposeDecl)); - } + DeclarationName DName(&Context.Idents.get("_Block_object_dispose")); + DeclContext::lookup_result + Lookup = Context.getTranslationUnitDecl()->lookup(DName); + + // If there is an explicit decl, use that. + if (Lookup.first != Lookup.second) + if (const FunctionDecl *FD = dyn_cast(*Lookup.first)) + return BlockObjectDispose = + GetAddrOfFunction(FD, getTypes().GetFunctionType(FD)); // Otherwise construct the function by hand. llvm::Type *args[] = { Int8PtrTy, Int32Ty }; @@ -2447,12 +2429,15 @@ llvm::Constant *CodeGenModule::getBlockObjectAssign() { if (BlockObjectAssign) return BlockObjectAssign; - // If we saw an explicit decl, use that. - if (BlockObjectAssignDecl) { - return BlockObjectAssign = GetAddrOfFunction( - BlockObjectAssignDecl, - getTypes().GetFunctionType(BlockObjectAssignDecl)); - } + DeclarationName DName(&Context.Idents.get("_Block_object_assign")); + DeclContext::lookup_result + Lookup = Context.getTranslationUnitDecl()->lookup(DName); + + // If there is an explicit decl, use that. + if (Lookup.first != Lookup.second) + if (const FunctionDecl *FD = dyn_cast(*Lookup.first)) + return BlockObjectAssign = + GetAddrOfFunction(FD, getTypes().GetFunctionType(FD)); // Otherwise construct the function by hand. llvm::Type *args[] = { Int8PtrTy, Int8PtrTy, Int32Ty }; @@ -2466,12 +2451,15 @@ llvm::Constant *CodeGenModule::getNSConcreteGlobalBlock() { if (NSConcreteGlobalBlock) return NSConcreteGlobalBlock; - // If we saw an explicit decl, use that. - if (NSConcreteGlobalBlockDecl) { - return NSConcreteGlobalBlock = GetAddrOfGlobalVar( - NSConcreteGlobalBlockDecl, - getTypes().ConvertType(NSConcreteGlobalBlockDecl->getType())); - } + DeclarationName DName(&Context.Idents.get("_NSConcreteGlobalBlock")); + DeclContext::lookup_result + Lookup = Context.getTranslationUnitDecl()->lookup(DName); + + // If there is an explicit decl, use that. + if (Lookup.first != Lookup.second) + if (const VarDecl *VD = dyn_cast(*Lookup.first)) + return NSConcreteGlobalBlock = + GetAddrOfGlobalVar(VD, getTypes().ConvertType(VD->getType())); // Otherwise construct the variable by hand. return NSConcreteGlobalBlock = @@ -2482,12 +2470,15 @@ llvm::Constant *CodeGenModule::getNSConcreteStackBlock() { if (NSConcreteStackBlock) return NSConcreteStackBlock; - // If we saw an explicit decl, use that. - if (NSConcreteStackBlockDecl) { - return NSConcreteStackBlock = GetAddrOfGlobalVar( - NSConcreteStackBlockDecl, - getTypes().ConvertType(NSConcreteStackBlockDecl->getType())); - } + DeclarationName DName(&Context.Idents.get("_NSConcreteStackBlock")); + DeclContext::lookup_result + Lookup = Context.getTranslationUnitDecl()->lookup(DName); + + // If there is an explicit decl, use that. + if (Lookup.first != Lookup.second) + if (const VarDecl *VD = dyn_cast(*Lookup.first)) + return NSConcreteStackBlock = + GetAddrOfGlobalVar(VD, getTypes().ConvertType(VD->getType())); // Otherwise construct the variable by hand. return NSConcreteStackBlock = diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 53c29002f9..3e5de655ab 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -314,13 +314,9 @@ class CodeGenModule : public CodeGenTypeCache { /// @name Cache for Blocks Runtime Globals /// @{ - const VarDecl *NSConcreteGlobalBlockDecl; - const VarDecl *NSConcreteStackBlockDecl; llvm::Constant *NSConcreteGlobalBlock; llvm::Constant *NSConcreteStackBlock; - const FunctionDecl *BlockObjectAssignDecl; - const FunctionDecl *BlockObjectDisposeDecl; llvm::Constant *BlockObjectAssign; llvm::Constant *BlockObjectDispose; diff --git a/test/PCH/block-decl-merging.c b/test/PCH/block-decl-merging.c new file mode 100644 index 0000000000..9612b2e522 --- /dev/null +++ b/test/PCH/block-decl-merging.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks %s -emit-pch -o %t +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks %s -include-pch %t -emit-llvm -o - | \ +// RUN: FileCheck %s + +#ifndef HEADER +#define HEADER + +// CHECK: @_NSConcreteGlobalBlock = extern_weak global +extern void * _NSConcreteStackBlock[32] __attribute__((weak_import)); +// CHECK: @_NSConcreteStackBlock = extern_weak global +extern void * _NSConcreteGlobalBlock[32] __attribute__((weak_import)); +extern void _Block_object_dispose(const void *, const int) __attribute__((weak_import)); +// CHECK: declare extern_weak void @_Block_object_assign +extern void _Block_object_assign(void *, const void *, const int) __attribute__((weak_import)); +// CHECK: declare extern_weak void @_Block_object_dispose + +#else + +void *x = ^(){}; + +void f1(void (^a0)(void)); + +void f0() { + __block int x; + f1(^(void){ x = 1; }); +} + +#endif diff --git a/test/PCH/block-decl-merging.cpp b/test/PCH/block-decl-merging.cpp new file mode 100644 index 0000000000..3c0dac63ae --- /dev/null +++ b/test/PCH/block-decl-merging.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks %s -emit-pch -o %t +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks %s -include-pch %t -emit-llvm -o - | \ +// RUN: FileCheck %s + +#ifndef HEADER +#define HEADER + +extern "C" { +// CHECK: @_NSConcreteGlobalBlock = extern_weak global +extern void * _NSConcreteStackBlock[32] __attribute__((weak_import)); +// CHECK: @_NSConcreteStackBlock = extern_weak global +extern void * _NSConcreteGlobalBlock[32] __attribute__((weak_import)); +extern void _Block_object_dispose(const void *, const int) __attribute__((weak_import)); +// CHECK: declare extern_weak void @_Block_object_assign +extern void _Block_object_assign(void *, const void *, const int) __attribute__((weak_import)); +// CHECK: declare extern_weak void @_Block_object_dispose +} + +#else + +void *x = ^(){}; + +void f1(void (^a0)(void)); + +void f0() { + __block int x; + f1(^(void){ x = 1; }); +} + +#endif