]> granicus.if.org Git - clang/commitdiff
Patch to correctly mangle block helper functions
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 24 Jun 2010 00:08:06 +0000 (00:08 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 24 Jun 2010 00:08:06 +0000 (00:08 +0000)
when block literal is declared inside a ctor/dtor.
Fixes radr 8096995.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106700 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGBlocks.cpp
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/CodeGenModule.cpp
lib/CodeGen/CodeGenModule.h
lib/CodeGen/Mangle.cpp
lib/CodeGen/Mangle.h
lib/CodeGen/MicrosoftCXXABI.cpp
test/CodeGenCXX/block-in-ctor-dtor.cpp [new file with mode: 0644]

index f07b7bbbda9712bed6889edeca561e63fecdc6bd..6edfe4c102e7718db97561c2eac1eb8d89e68b30 100644 (file)
@@ -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());
index f797c2c4ffce24cbef7c95bcaed2bd3f5e6086f0..32bffa105cfbf20226a4e03c14261c08255eea40 100644 (file)
@@ -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);
index 6d94520ffd2bcd5357d834881c9802c1785a9acd..cc97d86995f266fb083d4666b38938755cc0ebba 100644 (file)
@@ -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) {
index f092697fd480d5bff0d30b0f79a4242648de07dc..4fbf34319f5cf851b9cc587880a374fa96177df3 100644 (file)
@@ -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);
 
index 01838f98d450fb97da566e227b8ad19373cea3fa..154153aaebfa6a98ac5c199c1c19d2c1e16f3b80 100644 (file)
@@ -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,
index d10334dcbb34313d88cc169c806685991e565df3..ec575cc7867fd0c9874fd98c1b82c7aef110d101 100644 (file)
@@ -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);
 };
 
index 3823c9dc20a2cf1e80dc8247bac174e42844049a..ddf32ece5858964b06ebca2e737ffe4f03ea0205 100644 (file)
@@ -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);
   }
diff --git a/test/CodeGenCXX/block-in-ctor-dtor.cpp b/test/CodeGenCXX/block-in-ctor-dtor.cpp
new file mode 100644 (file)
index 0000000..e4389a4
--- /dev/null
@@ -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_