]> granicus.if.org Git - clang/commitdiff
Finish off mangling locals in block literals.
authorEli Friedman <eli.friedman@gmail.com>
Wed, 10 Jul 2013 01:33:19 +0000 (01:33 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 10 Jul 2013 01:33:19 +0000 (01:33 +0000)
Specifically, handle the case where the block is in a default argument
in a class method.  The mangling here follows what we do for lambdas.

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

lib/AST/ItaniumMangle.cpp
test/CodeGenObjCXX/mangle-blocks.mm

index 2dc44eb35559613182241949de4b709749212b47..76a8bf4ecc4ed45bd5ead6f75fd6ad5f6a762a5d 100644 (file)
@@ -56,6 +56,13 @@ static const DeclContext *getEffectiveDeclContext(const Decl *D) {
             = dyn_cast_or_null<ParmVarDecl>(RD->getLambdaContextDecl()))
         return ContextParam->getDeclContext();
   }
+
+  // Perform the same check for block literals.
+  if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
+    if (ParmVarDecl *ContextParam
+          = dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl()))
+      return ContextParam->getDeclContext();
+  }
   
   const DeclContext *DC = D->getDeclContext();
   if (const CapturedDecl *CD = dyn_cast<CapturedDecl>(DC))
@@ -1334,12 +1341,26 @@ void CXXNameMangler::mangleLocalName(const Decl *D) {
       const NamedDecl *ND = cast<NamedDecl>(D);
       mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/);
     }
+  } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) {
+    // Mangle a block in a default parameter; see above explanation for
+    // lambdas.
+    if (const ParmVarDecl *Parm
+            = dyn_cast_or_null<ParmVarDecl>(BD->getBlockManglingContextDecl())) {
+      if (const FunctionDecl *Func
+            = dyn_cast<FunctionDecl>(Parm->getDeclContext())) {
+        Out << 'd';
+        unsigned Num = Func->getNumParams() - Parm->getFunctionScopeIndex();
+        if (Num > 1)
+          mangleNumber(Num - 2);
+        Out << '_';
+      }
+    }
+
+    mangleUnqualifiedBlock(BD);
   } else {
-    if (const BlockDecl *BD = dyn_cast<BlockDecl>(D))
-      mangleUnqualifiedBlock(BD);
-    else
-      mangleUnqualifiedName(cast<NamedDecl>(D));
+    mangleUnqualifiedName(cast<NamedDecl>(D));
   }
+
   if (const NamedDecl *ND = dyn_cast<NamedDecl>(RD ? RD : D)) {
     unsigned disc;
     if (Context.getNextDiscriminator(ND, disc)) {
index 9630c475bdb9cb86fd3586bcc1e7074c68d7d162..4c85229a0e02e6d3ac003a94817a59e36cdabd64 100644 (file)
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -emit-llvm -fblocks -o - -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s
 
 // CHECK: @_ZGVZZ3foovEUb_E5value = internal global i64 0
+// CHECK: @_ZZZN26externally_visible_statics1S3fooEiEd_Ub_E1k = linkonce_odr global i32 0
 // CHECK: @_ZZ26externally_visible_statics1S1xMUb_E1j = linkonce_odr global i32 0
 // CHECK: @_ZZZN26externally_visible_statics10inlinefuncEvEUb_E1i = linkonce_odr global i32 0
 
@@ -79,10 +80,6 @@ namespace externally_visible_statics {
   void g() {
     inlinefunc();
     S s;
-#if 0
-    // FIXME: We know how to mangle k, but crash trying to mangle the
-    // block itself.
     s.foo();
-#endif
   }
 }