diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index f07b7bbbda97..6edfe4c102e7 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -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 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 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()); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index f797c2c4ffce..32bffa105cfb 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -500,7 +500,8 @@ public: const llvm::StructType *, std::vector *); - llvm::Function *GenerateBlockFunction(const BlockExpr *BExpr, + llvm::Function *GenerateBlockFunction(GlobalDecl GD, + const BlockExpr *BExpr, CGBlockInfo &Info, const Decl *OuterFuncDecl, llvm::DenseMap ldm); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6d94520ffd2b..cc97d86995f2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -231,7 +231,7 @@ llvm::StringRef CodeGenModule::getMangledName(GlobalDecl GD) { else if (const CXXDestructorDecl *D = dyn_cast(ND)) getMangleContext().mangleCXXDtor(D, GD.getDtorType(), Buffer); else if (const BlockDecl *BD = dyn_cast(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) { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index f092697fd480..4fbf34319f5c 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -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); diff --git a/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index 01838f98d450..154153aaebfa 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/lib/CodeGen/Mangle.cpp @@ -40,7 +40,7 @@ MiscNameMangler::MiscNameMangler(MangleContext &C, llvm::SmallVectorImpl &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(DC); if (IdentifierInfo *II = ND->getIdentifier()) Out << II->getName(); + else if (const CXXDestructorDecl *D = dyn_cast(ND)) { + llvm::SmallString<64> Buffer; + Context.mangleCXXDtor(D, GD.getDtorType(), Buffer); + Out << Buffer; + } + else if (const CXXConstructorDecl *D = dyn_cast(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(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 &Res) { MiscNameMangler Mangler(*this, Res); - Mangler.mangleBlock(BD); + Mangler.mangleBlock(GD, BD); } void MangleContext::mangleThunk(const CXXMethodDecl *MD, diff --git a/clang/lib/CodeGen/Mangle.h b/clang/lib/CodeGen/Mangle.h index d10334dcbb34..ec575cc7867f 100644 --- a/clang/lib/CodeGen/Mangle.h +++ b/clang/lib/CodeGen/Mangle.h @@ -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 &); virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, llvm::SmallVectorImpl &); - void mangleBlock(const BlockDecl *BD, llvm::SmallVectorImpl &); + void mangleBlock(GlobalDecl GD, + const BlockDecl *BD, llvm::SmallVectorImpl &); 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); }; diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 3823c9dc20a2..ddf32ece5858 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -402,7 +402,7 @@ void MicrosoftCXXNameMangler::manglePostfix(const DeclContext *DC, if (const BlockDecl *BD = dyn_cast(DC)) { llvm::SmallString<64> Name; - Context.mangleBlock(BD, Name); + Context.mangleBlock(GlobalDecl(), BD, Name); Out << Name << '@'; return manglePostfix(DC->getParent(), NoFunction); } diff --git a/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp b/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp new file mode 100644 index 000000000000..e4389a4eeec8 --- /dev/null +++ b/clang/test/CodeGenCXX/block-in-ctor-dtor.cpp @@ -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_