]> granicus.if.org Git - clang/commitdiff
This patch fixes couple of bugs for predefined expression
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 14 Nov 2014 23:55:27 +0000 (23:55 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 14 Nov 2014 23:55:27 +0000 (23:55 +0000)
used inside blocks. It fixes a crash in naming code
for __func__ etc. when used in a block declared globally.
It also brings back old naming convention for
predefined expression which was broken. rdar://18961148

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

lib/AST/Mangle.cpp
lib/CodeGen/CGExpr.cpp
test/CodeGen/block-with-perdefinedexpr.c [new file with mode: 0644]
test/CodeGenCXX/predefined-expr-cxx14.cpp

index ae6c5f296d7bfc9233ab860803795df324b00953..53ee442bd84515a583166704f0933810044238fd 100644 (file)
@@ -234,17 +234,19 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD,
     if (isa<BlockDecl>(DC))
       for (; DC && isa<BlockDecl>(DC); DC = DC->getParent())
         (void) getBlockId(cast<BlockDecl>(DC), true);
-    assert(isa<NamedDecl>(DC) && "expected a NamedDecl");
-    const NamedDecl *ND = cast<NamedDecl>(DC);
-    if (!shouldMangleDeclName(ND) && ND->getIdentifier())
-      Stream << ND->getIdentifier()->getName();
-    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
-      // Itanium C++ ABI object. What should we do now? Right now, I'm just
-      // calling the mangleName() method on the MangleContext; is there a
-      // better way?
-      mangleName(ND, Stream);
+    assert((isa<TranslationUnitDecl>(DC) || isa<NamedDecl>(DC)) &&
+           "expected a TranslationUnitDecl or a NamedDecl");
+    if (auto ND = dyn_cast<NamedDecl>(DC)) {
+      if (!shouldMangleDeclName(ND) && ND->getIdentifier())
+        Stream << ND->getIdentifier()->getName();
+      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
+        // Itanium C++ ABI object. What should we do now? Right now, I'm just
+        // calling the mangleName() method on the MangleContext; is there a
+        // better way?
+        mangleName(ND, Stream);
+      }
     }
   }
   Stream.flush();
index 0b8caa1e11a9368c87c95806695b137d9d96c0a0..1a3a61a76dde3b796c2b7ff1788bb32bf194edb1 100644 (file)
@@ -2081,7 +2081,10 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
   StringRef NameItems[] = {
       PredefinedExpr::getIdentTypeName(E->getIdentType()), FnName};
   std::string GVName = llvm::join(NameItems, NameItems + 2, ".");
-
+  if (CurCodeDecl && isa<BlockDecl>(CurCodeDecl)) {
+    auto C = CGM.GetAddrOfConstantCString(FnName, GVName.c_str(), 1);
+    return MakeAddrLValue(C, E->getType());
+  }
   auto C = CGM.GetAddrOfConstantStringFromLiteral(SL, GVName);
   return MakeAddrLValue(C, E->getType());
 }
diff --git a/test/CodeGen/block-with-perdefinedexpr.c b/test/CodeGen/block-with-perdefinedexpr.c
new file mode 100644 (file)
index 0000000..68fdea6
--- /dev/null
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 | FileCheck %s
+// rdar://18961148
+
+void syslog(const char *, ...);
+
+void handler( );
+
+static void (^spd)() = ^()
+{
+ handler( ^(){ syslog("%s", __FUNCTION__); } );
+};
+// CHECK: @__FUNCTION__.spd_block_invoke_2 = private unnamed_addr constant [19 x i8] c"spd_block_invoke_2\00"
+// CHECK: define internal void @spd_block_invoke_2
+// CHECK: @__FUNCTION__.spd_block_invoke_2
index 0b10fe5e022068dc34769c0705494a5cfaae678e..1f035757dea93e09a9c8d0d6410a197b263a5548 100644 (file)
@@ -17,8 +17,8 @@
 // CHECK-DAG: @__func__._ZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEv = private unnamed_addr constant [26 x i8] c"topLevelNamespaceFunction\00"
 // CHECK-DAG: @__PRETTY_FUNCTION__._ZN24ClassInTopLevelNamespace25topLevelNamespaceFunctionEv = private unnamed_addr constant [60 x i8] c"auto *ClassInTopLevelNamespace::topLevelNamespaceFunction()\00"
 
-// CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [41 x i8] c"___ZN16ClassBlockConstrD1Ev_block_invoke\00"
-// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [41 x i8] c"___ZN16ClassBlockConstrC1Ev_block_invoke\00"
+// CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [41 x i8] c"___ZN16ClassBlockConstrD2Ev_block_invoke\00"
+// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [41 x i8] c"___ZN16ClassBlockConstrC2Ev_block_invoke\00"
 
 int printf(const char * _Format, ...);