[PATCH] [-cxx-abi microsoft] Mangle TemplateArgument::Declaration correctly for member pointers and references

David Majnemer david.majnemer at gmail.com
Thu Aug 8 02:59:28 PDT 2013


Hi rnk, cdavis5x,

Member pointers currently show up as FieldDecls which, as far as we
know, aren't mangled.

Instead, the proper way to mangle these when they show up as template
arguments is to turn them into their field offset in byte units and
encode that as a literal.

Incidentally, we also failed to properly mangle declarations that are
template parameters.  We would mangle them the same as non-type,
non-reference declarations. Fun-fact: undname cannot handle these!

http://llvm-reviews.chandlerc.com/D1323

Files:
  lib/AST/MicrosoftMangle.cpp
  test/CodeGenCXX/mangle-ms-templates.cpp
  test/tad.obj

Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -882,9 +882,17 @@
     mangleType(T, SourceRange(), QMM_Escape);
     break;
   }
-  case TemplateArgument::Declaration:
-    mangle(cast<NamedDecl>(TA.getAsDecl()), "$1?");
+  case TemplateArgument::Declaration: {
+    const NamedDecl *ND = cast<NamedDecl>(TA.getAsDecl());
+    if (isa<FieldDecl>(ND)) {
+      llvm::APSInt Offset(/*BitWidth=*/64, /*isUnsigned=*/true);
+      Offset = getASTContext().getFieldOffset(cast<FieldDecl>(ND)) /
+               getASTContext().getCharWidth();
+      mangleIntegerLiteral(Offset, false);
+    } else
+      mangle(ND, TA.isDeclForReferenceParam() ? "$E?" : "$1?");
     break;
+  }
   case TemplateArgument::Integral:
     mangleIntegerLiteral(TA.getAsIntegral(),
                          TA.getIntegralType()->isBooleanType());
Index: test/CodeGenCXX/mangle-ms-templates.cpp
===================================================================
--- test/CodeGenCXX/mangle-ms-templates.cpp
+++ test/CodeGenCXX/mangle-ms-templates.cpp
@@ -161,3 +161,22 @@
 template <decltype(nullptr)> struct S1 {};
 void f(S1<nullptr>) {}
 // CHECK: "\01?f@@YAXU?$S1@$0A@@@@Z"
+
+struct record {
+  int first;
+  int second;
+};
+template <const record &>
+struct type1 {
+};
+extern const record inst;
+void recref(type1<inst>) {}
+// CHECK: "\01?recref@@YAXU?$type1@$E?inst@@3Urecord@@B@@@Z"
+
+template <int record::*>
+struct type2 {
+};
+void memptr1(type2<&record::first>) {}
+// CHECK: "\01?memptr1@@YAXU?$type2@$0A@@@@Z"
+void memptr2(type2<&record::second>) {}
+// CHECK: "\01?memptr2@@YAXU?$type2@$03@@@Z"
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1323.1.patch
Type: text/x-patch
Size: 1715 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130808/f2544efc/attachment.bin>


More information about the cfe-commits mailing list