Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -966,16 +966,14 @@ } if (const BlockDecl *BD = dyn_cast(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(DC)) { mangleObjCMethodName(Method); } else if (isa(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 +void g() { + auto p = ^() { + static int i = 0; + return ++i; + }; +} + +template void g(); +template void g(); + +// 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