compnerd created this revision. compnerd added a project: clang. When generating the decorated name for a static variable inside a BlockDecl, construct a scope for the block invocation function that homes the parameter. This allows for arbitrary nesting of the blocks even if the variables are shadowed. Furthermore, using this for the name allows for undname to properly undecorated the name for us. It shows up as the synthetic __block_invocation function that the compiler emitted in the local scope.
Repository: rL LLVM https://reviews.llvm.org/D34523 Files: lib/AST/MicrosoftMangle.cpp test/CodeGenCXX/msabi-blocks.cpp Index: test/CodeGenCXX/msabi-blocks.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/msabi-blocks.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -std=c++11 -fblocks -S -emit-llvm -o - %s | FileCheck %s + +auto b = ^() { + static int i = 0; + return ++i; +}; + + +void f() { + auto l = ^() { + static int i = 0; + return ++i; + }; + auto m = ^() { + static int i = 0; + return ++i; + }; + auto n = ^() { + auto o = ^() { + static int i = 0; + return ++i; + }; + }; +} + +template <typename T> +void g() { + auto p = ^() { + static int i = 0; + return ++i; + }; +} + +template void g<char>(); +template void g<int>(); + +// CHECK: @"\01?i@?1??_block_invoke@@YAXPAU__block_literal@@@Z@4HA" = internal +// CHECK: @"\01?i@?1??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?1??f@@YAXXZ@4HA" = internal +// CHECK: @"\01?i@?1??_block_invoke_2@@YAXPAU__block_literal_2@@@Z?1??f@@YAXXZ@4HA" = internal +// CHECK: @"\01?i@?1??_block_invoke_3@@YAXPAU__block_literal_3@@@Z?1??_block_invoke_4@@YAXPAU__block_literal_4@@@Z?1??f@@YAXXZ@4HA" = internal +// CHECK: @"\01?i@?2??_block_invoke_5@@YAXPAU__block_literal_5@@@Z?2???$g@D@@YAXXZ@4HA" = linkonce_odr +// CHECK: @"\01?i@?2??_block_invoke_6@@YAXPAU__block_literal_6@@@Z?2???$g@H@@YAXXZ@4HA" = linkonce_odr Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -966,16 +966,14 @@ } if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = - Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle a local inside this block yet"); - Diags.Report(BD->getLocation(), DiagID); - - // FIXME: This is completely, utterly, wrong; see ItaniumMangle - // for how this should be done. - Out << "__block_invoke" << Context.getBlockId(BD, false); - Out << '@'; + auto Discriminator = Context.getBlockId(BD, false); + Out << "?_block_invoke"; + if (Discriminator) + Out << '_' << Discriminator; + Out << "@@YAXPAU__block_literal"; + if (Discriminator) + Out << '_' << Discriminator; + Out << "@@@Z"; } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) { mangleObjCMethodName(Method); } else if (isa<NamedDecl>(DC)) {
Index: test/CodeGenCXX/msabi-blocks.cpp =================================================================== --- /dev/null +++ test/CodeGenCXX/msabi-blocks.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -std=c++11 -fblocks -S -emit-llvm -o - %s | FileCheck %s + +auto b = ^() { + static int i = 0; + return ++i; +}; + + +void f() { + auto l = ^() { + static int i = 0; + return ++i; + }; + auto m = ^() { + static int i = 0; + return ++i; + }; + auto n = ^() { + auto o = ^() { + static int i = 0; + return ++i; + }; + }; +} + +template <typename T> +void g() { + auto p = ^() { + static int i = 0; + return ++i; + }; +} + +template void g<char>(); +template void g<int>(); + +// CHECK: @"\01?i@?1??_block_invoke@@YAXPAU__block_literal@@@Z@4HA" = internal +// CHECK: @"\01?i@?1??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?1??f@@YAXXZ@4HA" = internal +// CHECK: @"\01?i@?1??_block_invoke_2@@YAXPAU__block_literal_2@@@Z?1??f@@YAXXZ@4HA" = internal +// CHECK: @"\01?i@?1??_block_invoke_3@@YAXPAU__block_literal_3@@@Z?1??_block_invoke_4@@YAXPAU__block_literal_4@@@Z?1??f@@YAXXZ@4HA" = internal +// CHECK: @"\01?i@?2??_block_invoke_5@@YAXPAU__block_literal_5@@@Z?2???$g@D@@YAXXZ@4HA" = linkonce_odr +// CHECK: @"\01?i@?2??_block_invoke_6@@YAXPAU__block_literal_6@@@Z?2???$g@H@@YAXXZ@4HA" = linkonce_odr Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -966,16 +966,14 @@ } if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) { - DiagnosticsEngine &Diags = Context.getDiags(); - unsigned DiagID = - Diags.getCustomDiagID(DiagnosticsEngine::Error, - "cannot mangle a local inside this block yet"); - Diags.Report(BD->getLocation(), DiagID); - - // FIXME: This is completely, utterly, wrong; see ItaniumMangle - // for how this should be done. - Out << "__block_invoke" << Context.getBlockId(BD, false); - Out << '@'; + auto Discriminator = Context.getBlockId(BD, false); + Out << "?_block_invoke"; + if (Discriminator) + Out << '_' << Discriminator; + Out << "@@YAXPAU__block_literal"; + if (Discriminator) + Out << '_' << Discriminator; + Out << "@@@Z"; } else if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(DC)) { mangleObjCMethodName(Method); } else if (isa<NamedDecl>(DC)) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits