Index: clang/lib/AST/Expr.cpp =================================================================== --- clang/lib/AST/Expr.cpp +++ clang/lib/AST/Expr.cpp @@ -519,19 +519,23 @@ return ""; } if (auto *BD = dyn_cast(CurrentDecl)) { - std::unique_ptr MC; - MC.reset(Context.createMangleContext()); - SmallString<256> Buffer; - llvm::raw_svector_ostream Out(Buffer); + // For blocks we only emit something if it is enclosed in a function + // For top-level block we'd like to include the name of variable, but we + // don't have it at this point. auto DC = CurrentDecl->getDeclContext(); if (DC->isFileContext()) - MC->mangleGlobalBlock(BD, /*ID*/ nullptr, Out); - else if (const auto *CD = dyn_cast(DC)) - MC->mangleCtorBlock(CD, /*CT*/ Ctor_Complete, BD, Out); - else if (const auto *DD = dyn_cast(DC)) - MC->mangleDtorBlock(DD, /*DT*/ Dtor_Complete, BD, Out); - else - MC->mangleBlock(DC, BD, Out); + return ""; + + SmallString<256> Buffer; + llvm::raw_svector_ostream Out(Buffer); + if (auto *DCFunc = dyn_cast(DC)) { + Out << ComputeName(IT, DCFunc); + Out << "_block_invoke"; + } else { + auto *DCBlock = cast(DC); + // For nested blocks, propagate up to the parent. + Out << ComputeName(IT, DCBlock); + } return Out.str(); } if (const FunctionDecl *FD = dyn_cast(CurrentDecl)) { Index: clang/lib/CodeGen/CGExpr.cpp =================================================================== --- clang/lib/CodeGen/CGExpr.cpp +++ clang/lib/CodeGen/CGExpr.cpp @@ -2319,9 +2319,19 @@ 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()); - return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl); + if (auto *BD = dyn_cast(CurCodeDecl)) { + std::string Name = SL->getString(); + if (!Name.empty()) { + unsigned discriminator = + CGM.getCXXABI().getMangleContext().getBlockId(BD, true); + if (discriminator != 0) + Name += "_" + Twine(discriminator + 1).str(); + auto C = CGM.GetAddrOfConstantCString(Name, GVName.c_str()); + return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl); + } else { + auto C = CGM.GetAddrOfConstantCString(FnName, GVName.c_str()); + return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl); + } } auto C = CGM.GetAddrOfConstantStringFromLiteral(SL, GVName); return MakeAddrLValue(C, E->getType(), AlignmentSource::Decl); Index: clang/test/CodeGen/block-with-perdefinedexpr.cpp =================================================================== --- /dev/null +++ clang/test/CodeGen/block-with-perdefinedexpr.cpp @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - -fblocks -triple x86_64-apple-darwin10 | FileCheck %s + +void bar() { + // CHECK-DAG: @__FUNCTION__.___Z3barv_block_invoke = private unnamed_addr constant [17 x i8] c"bar_block_invoke\00", align 1 + const char * (^block1)() = ^() { + return __FUNCTION__; + }; + // CHECK-DAG: @__FUNCTION__.___Z3barv_block_invoke_2 = private unnamed_addr constant [19 x i8] c"bar_block_invoke_2\00", align 1 + const char * (^block2)() = ^() { + return __FUNCTION__; + }; +} + +void baz() { + // CHECK-DAG: @__PRETTY_FUNCTION__.___Z3bazv_block_invoke = private unnamed_addr constant [24 x i8] c"void baz()_block_invoke\00", align 1 + const char * (^block1)() = ^() { + return __PRETTY_FUNCTION__; + }; + // CHECK-DAG: @__PRETTY_FUNCTION__.___Z3bazv_block_invoke_2 = private unnamed_addr constant [26 x i8] c"void baz()_block_invoke_2\00", align 1 + const char * (^block2)() = ^() { + return __PRETTY_FUNCTION__; + }; +} + +namespace foonamespace { +class Foo { +public: + Foo() { + // CHECK-DAG: @__PRETTY_FUNCTION__.___ZN12foonamespace3FooC2Ev_block_invoke = private unnamed_addr constant [38 x i8] c"foonamespace::Foo::Foo()_block_invoke\00", align 1 + const char * (^block1)() = ^() { + return __PRETTY_FUNCTION__; + }; + // CHECK-DAG: @__PRETTY_FUNCTION__.___ZN12foonamespace3FooC2Ev_block_invoke_2 = private unnamed_addr constant [40 x i8] c"foonamespace::Foo::Foo()_block_invoke_2\00", align 1 + const char * (^block2)() = ^() { + return __PRETTY_FUNCTION__; + }; + // CHECK-DAG: @__func__.___ZN12foonamespace3FooC2Ev_block_invoke_3 = private unnamed_addr constant [19 x i8] c"Foo_block_invoke_3\00", align 1 + const char * (^block3)() = ^() { + return __func__; + }; + bar(); + } + ~Foo() { + // CHECK-DAG: @__func__.___ZN12foonamespace3FooD2Ev_block_invoke = private unnamed_addr constant [18 x i8] c"~Foo_block_invoke\00", align 1 + const char * (^block1)() = ^() { + return __func__; + }; + // CHECK-DAG: @__PRETTY_FUNCTION__.___ZN12foonamespace3FooD2Ev_block_invoke_2 = private unnamed_addr constant [41 x i8] c"foonamespace::Foo::~Foo()_block_invoke_2\00", align 1 + const char * (^block2)() = ^() { + return __PRETTY_FUNCTION__; + }; + } + void bar() { + // CHECK-DAG: @__PRETTY_FUNCTION__.___ZN12foonamespace3Foo3barEv_block_invoke = private unnamed_addr constant [43 x i8] c"void foonamespace::Foo::bar()_block_invoke\00", align 1 + const char * (^block1)() = ^() { + return __PRETTY_FUNCTION__; + }; + // CHECK-DAG: @__PRETTY_FUNCTION__.___ZN12foonamespace3Foo3barEv_block_invoke_2 = private unnamed_addr constant [45 x i8] c"void foonamespace::Foo::bar()_block_invoke_2\00", align 1 + const char * (^block2)() = ^() { + return __PRETTY_FUNCTION__; + }; + // CHECK-DAG: @__func__.___ZN12foonamespace3Foo3barEv_block_invoke_3 = private unnamed_addr constant [19 x i8] c"bar_block_invoke_3\00", align 1 + const char * (^block3)() = ^() { + return __func__; + }; + } +}; +Foo f; +} Index: clang/test/CodeGenCXX/predefined-expr-cxx14.cpp =================================================================== --- clang/test/CodeGenCXX/predefined-expr-cxx14.cpp +++ clang/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"___ZN16ClassBlockConstrD2Ev_block_invoke\00" -// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [41 x i8] c"___ZN16ClassBlockConstrC2Ev_block_invoke\00" +// CHECK-DAG: @__func__.___ZN16ClassBlockConstrD2Ev_block_invoke = private unnamed_addr constant [31 x i8] c"~ClassBlockConstr_block_invoke\00" +// CHECK-DAG: @__func__.___ZN16ClassBlockConstrC2Ev_block_invoke = private unnamed_addr constant [30 x i8] c"ClassBlockConstr_block_invoke\00" int printf(const char * _Format, ...);