]> granicus.if.org Git - clang/commitdiff
CodeGen: correct block mangling in ObjC
authorSaleem Abdulrasool <compnerd@compnerd.org>
Tue, 14 Oct 2014 17:20:18 +0000 (17:20 +0000)
committerSaleem Abdulrasool <compnerd@compnerd.org>
Tue, 14 Oct 2014 17:20:18 +0000 (17:20 +0000)
Mangling for blocks defined within blocks in an ObjectiveC context were also
broken by SVN r219393.  Because the code in mangleName assumed that the code was
either C or C++, we would trigger assertions when trying to mangle the inner
blocks in an ObjectiveC context.

Add a test and use the ObjectiveC specific mangling when dealing with an
ObjectiveC method declaration.

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

lib/AST/Mangle.cpp
test/CodeGenObjC/mangle-blocks.m [new file with mode: 0644]

index fba835451e291fc62756eae14c7b96ba480bd052..b5dbdca9c97621dbc604efdba8c66a198abef7a8 100644 (file)
@@ -135,7 +135,10 @@ void MangleContext::mangleName(const NamedDecl *D, raw_ostream &Out) {
   bool MCXX = shouldMangleCXXName(D);
   const TargetInfo &TI = Context.getTargetInfo();
   if (CC == SOF_OTHER || (MCXX && TI.getCXXABI() == TargetCXXABI::Microsoft)) {
-    mangleCXXName(D, Out);
+    if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
+      mangleObjCMethodName(OMD, Out);
+    else
+      mangleCXXName(D, Out);
     return;
   }
 
@@ -147,6 +150,8 @@ void MangleContext::mangleName(const NamedDecl *D, raw_ostream &Out) {
 
   if (!MCXX)
     Out << D->getIdentifier()->getName();
+  else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D))
+    mangleObjCMethodName(OMD, Out);
   else
     mangleCXXName(D, Out);
 
diff --git a/test/CodeGenObjC/mangle-blocks.m b/test/CodeGenObjC/mangle-blocks.m
new file mode 100644 (file)
index 0000000..f0339c1
--- /dev/null
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple i386-apple-ios -fblocks -emit-llvm -o - %s -Wno-objc-root-class \
+// RUN:   | FileCheck %s
+
+void __assert_rtn(const char *, const char *, int, const char *);
+
+@interface Test
+- (void (^)(void)) mangle;
+@end
+
+@implementation Test
+- (void (^)(void)) mangle {
+  return ^() {
+    void (^b)(void) = ^() {
+      __assert_rtn(__func__, __FILE__, __LINE__, "mangle");
+    };
+  };
+}
+@end
+
+// CHECK: @"__func__.__14-[Test mangle]_block_invoke_2" = private unnamed_addr constant [34 x i8] c"__14-[Test mangle]_block_invoke_2\00", align 1
+// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1
+// CHECK: @.str1 = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
+
+// CHECK: define internal void @"__14-[Test mangle]_block_invoke"(i8* %.block_descriptor)
+
+// CHECK: define internal void @"__14-[Test mangle]_block_invoke_2"(i8* %.block_descriptor){{.*}}{
+// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([34 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8]* @.str1, i32 0, i32 0))
+// CHECK: }
+