]> granicus.if.org Git - clang/commitdiff
Change mangling of objects inside block literals.
authorEli Friedman <eli.friedman@gmail.com>
Mon, 24 Jun 2013 20:24:19 +0000 (20:24 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Mon, 24 Jun 2013 20:24:19 +0000 (20:24 +0000)
This changes the mangling of local static variables/etc. inside blocks
to do something simple and sane.  This avoids depending on the way we mangle
blocks, which isn't really appropriate here.

John, please take a look at this to make sure the mangling I chose is sane.

Fixes <rdar://problem/14074423>.

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

lib/AST/ItaniumMangle.cpp
test/CXX/expr/expr.prim/expr.prim.lambda/blocks-irgen.mm
test/CodeGenObjCXX/mangle-blocks.mm

index 7102bf349b209a2322a6fa44d86d5ddbc9efa7e1..cf1e5126d3c1fc6a8dd34874f59b032709eec88e 100644 (file)
@@ -1416,12 +1416,15 @@ void CXXNameMangler::manglePrefix(const DeclContext *DC, bool NoFunction) {
     return;
 
   if (const BlockDecl *Block = dyn_cast<BlockDecl>(DC)) {
-    manglePrefix(getEffectiveParentContext(DC), NoFunction);    
-    SmallString<64> Name;
-    llvm::raw_svector_ostream NameStream(Name);
-    Context.mangleBlock(Block, NameStream);
-    NameStream.flush();
-    Out << Name.size() << Name;
+    // The symbol we're adding a prefix for isn't externally
+    // visible; make up something sane.
+    // FIXME: This isn't always true!
+    SmallString<16> BlockPrefix;
+    BlockPrefix += "__block_prefix_internal";
+    unsigned Number = Context.getBlockId(Block, false);
+    if (Number > 1)
+      BlockPrefix += llvm::utostr_32(Number - 2);
+    Out << BlockPrefix.size() << BlockPrefix;
     return;
   } else if (isa<CapturedDecl>(DC)) {
     // Skip CapturedDecl context.
index 9f9867106930beb77582680d214c5400982b76ae..cb2bf75f2207be4ed01ec53396ce492bef10b78f 100644 (file)
@@ -14,7 +14,7 @@ namespace PR12746 {
   }
 
   // CHECK: define internal zeroext i1 @___ZN7PR127462f1EPi_block_invoke
-  // CHECK: call zeroext i1 @"_ZNK7PR127462f132___ZN7PR127462f1EPi_block_invoke3$_0clEv"
+  // CHECK: call zeroext i1 @"_ZNK23__block_prefix_internal3$_0clEv"
 
   bool f2(int *x) {
     auto outer = [&]() -> bool {
index 892c8afedebfdf87af7733780103960f2a0c61df..20cc7b485441acba1ca09ba94a2559039e3e39a7 100644 (file)
@@ -1,12 +1,13 @@
 // RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s
 
-// CHECK: @_ZGVN3foo22___Z3foov_block_invoke5valueE = internal global i64 0
+// CHECK: @_ZGVN23__block_prefix_internal5valueE = internal global i64 0
+// CHECK: @_ZN24__block_prefix_internal35namebE = internal global i8*
 
 int f();
 
 void foo() {
   // CHECK: define internal i32 @___Z3foov_block_invoke
-  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN3foo22___Z3foov_block_invoke5valueE
+  // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVN23__block_prefix_internal5valueE
   (void)^(int x) { 
     static int value = f();
     return x + value;
@@ -24,7 +25,7 @@ int i = ^(int x) { return x;}(i);
 - (void)method { 
   // CHECK: define internal signext i8 @"__11-[A method]_block_invoke"
   (void)^(int x) {
-    // CHECK: @"_ZN11-[A method]28__11-[A method]_block_invoke4nameE"
+    // CHECK: @_ZN24__block_prefix_internal04nameE
     static const char *name = "hello";
     return name[x];
   };
@@ -42,9 +43,20 @@ namespace N {
   // CHECK: define internal signext i8 @___Z3fooi_block_invoke
   void bar() {
     (void)^(int x) { 
-      // CHECK: @_ZN1N3bar26___ZN1N3barEv_block_invoke4nameE
+      // CHECK: @_ZN24__block_prefix_internal14nameE
       static const char *name = "hello";
       return name[x];
     };
   }
 }
+
+class C {
+  C();
+};
+C::C() {
+  (void)^(int x) { 
+    // CHECK: @_ZN24__block_prefix_internal35namebE
+    static const char *nameb = "hello";
+    return nameb[x];
+  };
+}