From: Fariborz Jahanian Date: Fri, 14 Nov 2014 23:55:27 +0000 (+0000) Subject: This patch fixes couple of bugs for predefined expression X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e0cbdd99a65c1a08ce3cdde30db4bc023006d116;p=clang This patch fixes couple of bugs for predefined expression 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 --- diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp index ae6c5f296d..53ee442bd8 100644 --- a/lib/AST/Mangle.cpp +++ b/lib/AST/Mangle.cpp @@ -234,17 +234,19 @@ void MangleContext::mangleBlock(const DeclContext *DC, const BlockDecl *BD, if (isa(DC)) for (; DC && isa(DC); DC = DC->getParent()) (void) getBlockId(cast(DC), true); - assert(isa(DC) && "expected a NamedDecl"); - const NamedDecl *ND = cast(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(DC) || isa(DC)) && + "expected a TranslationUnitDecl or a NamedDecl"); + if (auto ND = dyn_cast(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(); diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 0b8caa1e11..1a3a61a76d 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -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(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 index 0000000000..68fdea60f3 --- /dev/null +++ b/test/CodeGen/block-with-perdefinedexpr.c @@ -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 diff --git a/test/CodeGenCXX/predefined-expr-cxx14.cpp b/test/CodeGenCXX/predefined-expr-cxx14.cpp index 0b10fe5e02..1f035757de 100644 --- a/test/CodeGenCXX/predefined-expr-cxx14.cpp +++ b/test/CodeGenCXX/predefined-expr-cxx14.cpp @@ -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, ...);