forked from OSchip/llvm-project
Patch to correctly mangle block helper functions
when block literal is declared inside a ctor/dtor. Fixes radr 8096995. llvm-svn: 106700
This commit is contained in:
parent
d8dedee96d
commit
9b5528d278
|
@ -228,7 +228,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
|
|||
// block literal.
|
||||
// __invoke
|
||||
llvm::Function *Fn
|
||||
= CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, CurFuncDecl,
|
||||
= CodeGenFunction(CGM).GenerateBlockFunction(CurGD, BE, Info, CurFuncDecl,
|
||||
LocalDeclMap);
|
||||
BlockHasCopyDispose |= Info.BlockHasCopyDispose;
|
||||
Elts[3] = Fn;
|
||||
|
@ -723,7 +723,7 @@ BlockModule::GetAddrOfGlobalBlock(const BlockExpr *BE, const char * n) {
|
|||
CGBlockInfo Info(n);
|
||||
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
|
||||
llvm::Function *Fn
|
||||
= CodeGenFunction(CGM).GenerateBlockFunction(BE, Info, 0, LocalDeclMap);
|
||||
= CodeGenFunction(CGM).GenerateBlockFunction(GlobalDecl(), BE, Info, 0, LocalDeclMap);
|
||||
assert(Info.BlockSize == BlockLiteralSize
|
||||
&& "no imports allowed for global block");
|
||||
|
||||
|
@ -762,7 +762,7 @@ llvm::Value *CodeGenFunction::LoadBlockStruct() {
|
|||
}
|
||||
|
||||
llvm::Function *
|
||||
CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
|
||||
CodeGenFunction::GenerateBlockFunction(GlobalDecl GD, const BlockExpr *BExpr,
|
||||
CGBlockInfo &Info,
|
||||
const Decl *OuterFuncDecl,
|
||||
llvm::DenseMap<const Decl*, llvm::Value*> ldm) {
|
||||
|
@ -835,7 +835,7 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr,
|
|||
const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic);
|
||||
|
||||
MangleBuffer Name;
|
||||
CGM.getMangledName(Name, BD);
|
||||
CGM.getMangledName(GD, Name, BD);
|
||||
llvm::Function *Fn =
|
||||
llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
|
||||
Name.getString(), &CGM.getModule());
|
||||
|
|
|
@ -500,7 +500,8 @@ public:
|
|||
const llvm::StructType *,
|
||||
std::vector<HelperInfo> *);
|
||||
|
||||
llvm::Function *GenerateBlockFunction(const BlockExpr *BExpr,
|
||||
llvm::Function *GenerateBlockFunction(GlobalDecl GD,
|
||||
const BlockExpr *BExpr,
|
||||
CGBlockInfo &Info,
|
||||
const Decl *OuterFuncDecl,
|
||||
llvm::DenseMap<const Decl*, llvm::Value*> ldm);
|
||||
|
|
|
@ -231,7 +231,7 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
|
|||
else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND))
|
||||
getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Buffer);
|
||||
else if (const BlockDecl *BD = dyn_cast<BlockDecl>(ND))
|
||||
getMangleContext().mangleBlock(BD, Buffer);
|
||||
getMangleContext().mangleBlock(GD, BD, Buffer);
|
||||
else
|
||||
getMangleContext().mangleName(ND, Buffer);
|
||||
|
||||
|
@ -245,8 +245,9 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) {
|
|||
return Str;
|
||||
}
|
||||
|
||||
void CodeGenModule::getMangledName(MangleBuffer &Buffer, const BlockDecl *BD) {
|
||||
getMangleContext().mangleBlock(BD, Buffer.getBuffer());
|
||||
void CodeGenModule::getMangledName(GlobalDecl GD, MangleBuffer &Buffer,
|
||||
const BlockDecl *BD) {
|
||||
getMangleContext().mangleBlock(GD, BD, Buffer.getBuffer());
|
||||
}
|
||||
|
||||
llvm::GlobalValue *CodeGenModule::GetGlobalValue(llvm::StringRef Name) {
|
||||
|
|
|
@ -465,7 +465,7 @@ public:
|
|||
unsigned &CallingConv);
|
||||
|
||||
llvm::StringRef getMangledName(GlobalDecl GD);
|
||||
void getMangledName(MangleBuffer &Buffer, const BlockDecl *BD);
|
||||
void getMangledName(GlobalDecl GD, MangleBuffer &Buffer, const BlockDecl *BD);
|
||||
|
||||
void EmitTentativeDefinition(const VarDecl *D);
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ MiscNameMangler::MiscNameMangler(MangleContext &C,
|
|||
llvm::SmallVectorImpl<char> &Res)
|
||||
: Context(C), Out(Res) { }
|
||||
|
||||
void MiscNameMangler::mangleBlock(const BlockDecl *BD) {
|
||||
void MiscNameMangler::mangleBlock(GlobalDecl GD, const BlockDecl *BD) {
|
||||
// Mangle the context of the block.
|
||||
// FIXME: We currently mimic GCC's mangling scheme, which leaves much to be
|
||||
// desired. Come up with a better mangling scheme.
|
||||
|
@ -55,6 +55,16 @@ void MiscNameMangler::mangleBlock(const BlockDecl *BD) {
|
|||
const NamedDecl *ND = cast<NamedDecl>(DC);
|
||||
if (IdentifierInfo *II = ND->getIdentifier())
|
||||
Out << II->getName();
|
||||
else if (const CXXDestructorDecl *D = dyn_cast<CXXDestructorDecl>(ND)) {
|
||||
llvm::SmallString<64> Buffer;
|
||||
Context.mangleCXXDtor(D, GD.getDtorType(), Buffer);
|
||||
Out << Buffer;
|
||||
}
|
||||
else if (const CXXConstructorDecl *D = dyn_cast<CXXConstructorDecl>(ND)) {
|
||||
llvm::SmallString<64> Buffer;
|
||||
Context.mangleCXXCtor(D, GD.getCtorType(), Buffer);
|
||||
Out << Buffer;
|
||||
}
|
||||
else {
|
||||
// FIXME: We were doing a mangleUnqualifiedName() before, but that's
|
||||
// a private member of a class that will soon itself be private to the
|
||||
|
@ -857,7 +867,7 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
|
|||
if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
|
||||
manglePrefix(DC->getParent(), NoFunction);
|
||||
llvm::SmallString<64> Name;
|
||||
Context.mangleBlock(Block, Name);
|
||||
Context.mangleBlock(GlobalDecl(), Block, Name);
|
||||
Out << Name.size() << Name;
|
||||
return;
|
||||
}
|
||||
|
@ -2180,10 +2190,10 @@ void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
|||
Mangler.mangle(D);
|
||||
}
|
||||
|
||||
void MangleContext::mangleBlock(const BlockDecl *BD,
|
||||
void MangleContext::mangleBlock(GlobalDecl GD, const BlockDecl *BD,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
MiscNameMangler Mangler(*this, Res);
|
||||
Mangler.mangleBlock(BD);
|
||||
Mangler.mangleBlock(GD, BD);
|
||||
}
|
||||
|
||||
void MangleContext::mangleThunk(const CXXMethodDecl *MD,
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#define LLVM_CLANG_CODEGEN_MANGLE_H
|
||||
|
||||
#include "CGCXX.h"
|
||||
#include "GlobalDecl.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
@ -133,7 +134,8 @@ public:
|
|||
llvm::SmallVectorImpl<char> &);
|
||||
virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleBlock(const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
|
||||
void mangleBlock(GlobalDecl GD,
|
||||
const BlockDecl *BD, llvm::SmallVectorImpl<char> &);
|
||||
|
||||
void mangleInitDiscriminator() {
|
||||
Discriminator = 0;
|
||||
|
@ -163,7 +165,7 @@ public:
|
|||
|
||||
llvm::raw_svector_ostream &getStream() { return Out; }
|
||||
|
||||
void mangleBlock(const BlockDecl *BD);
|
||||
void mangleBlock(GlobalDecl GD, const BlockDecl *BD);
|
||||
void mangleObjCMethodName(const ObjCMethodDecl *MD);
|
||||
};
|
||||
|
||||
|
|
|
@ -402,7 +402,7 @@ void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC,
|
|||
|
||||
if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) {
|
||||
llvm::SmallString<64> Name;
|
||||
Context.mangleBlock(BD, Name);
|
||||
Context.mangleBlock(GlobalDecl(), BD, Name);
|
||||
Out << Name << '@';
|
||||
return manglePostfix(DC->getParent(), NoFunction);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
|
||||
|
||||
typedef void (^dispatch_block_t)(void);
|
||||
|
||||
void dispatch_once(dispatch_block_t);
|
||||
|
||||
class Zone {
|
||||
public:
|
||||
Zone();
|
||||
~Zone();
|
||||
};
|
||||
|
||||
Zone::Zone() {
|
||||
dispatch_once(^{});
|
||||
dispatch_once(^{});
|
||||
}
|
||||
|
||||
Zone::~Zone() {
|
||||
dispatch_once(^{});
|
||||
dispatch_once(^{});
|
||||
}
|
||||
|
||||
class X : public virtual Zone {
|
||||
X();
|
||||
~X();
|
||||
};
|
||||
|
||||
X::X() {
|
||||
dispatch_once(^{});
|
||||
dispatch_once(^{});
|
||||
};
|
||||
|
||||
X::~X() {
|
||||
dispatch_once(^{});
|
||||
dispatch_once(^{});
|
||||
};
|
||||
|
||||
|
||||
// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN4ZoneC2Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN4ZoneD2Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN1XC1Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN1XC1Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN1XC2Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN1XC2Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN1XD2Ev_block_invoke_
|
||||
// CHECK: define internal void @___ZN1XD2Ev_block_invoke_
|
Loading…
Reference in New Issue