compnerd updated this revision to Diff 103794.
compnerd added a comment.

This is a step in the right direction.  Although the NSDMI cases and default 
parameter value cases are not yet handled, they break due to tracking of the 
global mangling number tracking, not due to the scheme.


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,63 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -std=c++11 -fblocks -S -o - -emit-llvm %s | FileCheck %s
+
+void (^b)() = ^{
+  static int i = 0;
+};
+
+// CHECK-DAG: @"\01?i@?1??_block_invoke@@YAXPAU__block_literal@@@Z@4HA" ={{.*}} global i32 0
+
+extern int e(void);
+
+void f(void) {
+  static int i = 0;
+  ^{ static int i = e(); }();
+
+// CHECK-DAG: @"\01?i@?1??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+
+  ^{ static int i = e(); }();
+
+// CHECK-DAG: @"\01?i@?1??_block_invoke_2@@YAXPAU__block_literal_2@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+
+  ^{ ^{ static int i = e(); }(); }();
+
+// CHECK-DAG: @"\01?i@?1??_block_invoke_3@@YAXPAU__block_literal_3@@@Z?1??_block_invoke_4@@YAXPAU__block_literal_4@@@Z?1??f@@YAXXZ@4HA" ={{.*}} global i32 0
+}
+
+
+template <typename>
+void g(void) {
+  ^{ static int i = e(); }();
+}
+
+template void g<char>(void);
+
+// CHECK-DAG: @"\01?i@?2??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?2???$g@D@@YAXXZ@4HA" ={{.*}} global i32 0
+
+template void g<int>(void);
+
+// CHECK-DAG: @"\01?i@?2??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?2???$g@H@@YAXXZ@4HA" ={{.*}} global i32 0
+
+inline void h(void) {
+  ^{ static int i = e(); }();
+}
+
+// CHECK-DAG: @"\01?i@?2??_block_invoke_1@@YAXPAU__block_literal_1@@@Z?2??h@@YAXXZ@4HA" ={{.*}} global i32 0
+
+#if 0
+struct s {
+  int i = ^{ static int i = e(); return ++i; }();
+  int j = ^{ static int i = e(); return ++i; }();
+
+  void m(int i = ^{ static int i = e(); return ++i; }(),
+         int j = ^{ static int i = e(); return ++i; }()) {}
+};
+#endif
+
+void j(void) {
+  h();
+#if 0
+  struct s s;
+  s.m();
+#endif
+}
+
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -966,16 +966,25 @@
     }
 
     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);
+      DC = getEffectiveDeclContext(BD);
+      unsigned Discriminator = BD->getBlockManglingNumber();
+      if (!Discriminator)
+        Discriminator = Context.getBlockId(BD, /*Local=*/false);
+      Out << "?_block_invoke";
+      if (Discriminator)
+        Out<< '_' << Discriminator;
       Out << '@';
+      if (const auto *RD = dyn_cast<RecordDecl>(DC))
+        mangleName(RD);
+      else
+        Out << '@';
+      Out << "YAXPAU__block_literal";
+      if (Discriminator)
+        Out<< '_' << Discriminator;
+      Out << "@@@Z";
+      if (isa<RecordDecl>(DC))
+        break;
+      continue;
     } 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

Reply via email to