summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-07-02 09:43:11 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-07-02 09:43:11 +0000
commit1023668bc2d625e7bb5c3ee776175d4e031b6e97 (patch)
treefa55010833c591662c72dd250d2c6b7b6e248c1b
parent0912de3216b3b9cfe187816f7d7bc8fc2cb64dc3 (diff)
downloadbcm5719-llvm-1023668bc2d625e7bb5c3ee776175d4e031b6e97.tar.gz
bcm5719-llvm-1023668bc2d625e7bb5c3ee776175d4e031b6e97.zip
[MS ABI] nullptr data member ptrs are mangled differently for classes vs fns
It turns out that nullptr pointers to data members act differently in function templates vs class templates. Class templates use a variable width representation proportional to the number of fields needed to materialize it. Function templates always use a single '0' template parameter. However, using '0' all the time is problematic if the class uses single or multiple inheritance. In those cases, use -1. llvm-svn: 241251
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp18
-rw-r--r--clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp15
-rw-r--r--clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp4
3 files changed, 32 insertions, 5 deletions
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index c50db60abe5..48a8fa541a6 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1215,11 +1215,23 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
return;
}
if (MPT->isMemberDataPointer()) {
- mangleMemberDataPointer(RD, nullptr);
- return;
+ if (isa<ClassTemplateDecl>(TD)) {
+ mangleMemberDataPointer(RD, nullptr);
+ return;
+ }
+ // nullptr data pointers are always represented with a single field
+ // which is initialized with either 0 or -1. Why -1? Well, we need to
+ // distinguish the case where the data member is at offset zero in the
+ // record.
+ // However, we are free to use 0 *if* we would use multiple fields for
+ // non-nullptr member pointers.
+ if (!RD->nullFieldOffsetIsZero()) {
+ mangleIntegerLiteral(llvm::APSInt::get(-1), /*IsBoolean=*/false);
+ return;
+ }
}
}
- Out << "$0A@";
+ mangleIntegerLiteral(llvm::APSInt::getUnsigned(0), /*IsBoolean=*/false);
break;
}
case TemplateArgument::Expression:
diff --git a/clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp b/clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
index e2cbe15dfa9..b01d6099d8f 100644
--- a/clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
+++ b/clang/test/CodeGenCXX/mangle-ms-templates-memptrs-2.cpp
@@ -3,22 +3,37 @@
template <typename T, int (T::*)() = nullptr>
struct J {};
+template <typename T, int T::* = nullptr>
+struct K {};
+
struct __single_inheritance M;
J<M> m;
// CHECK-DAG: @"\01?m@@3U?$J@UM@@$0A@@@A"
+K<M> m2;
+// CHECK-DAG: @"\01?m2@@3U?$K@UM@@$0?0@@A"
+
struct __multiple_inheritance N;
J<N> n;
// CHECK-DAG: @"\01?n@@3U?$J@UN@@$HA@@@A"
+K<N> n2;
+// CHECK-DAG: @"\01?n2@@3U?$K@UN@@$0?0@@A"
+
struct __virtual_inheritance O;
J<O> o;
// CHECK-DAG: @"\01?o@@3U?$J@UO@@$IA@A@@@A"
+K<O> o2;
+// CHECK-DAG: @"\01?o2@@3U?$K@UO@@$FA@?0@@A"
+
struct P;
J<P> p;
// CHECK-DAG: @"\01?p@@3U?$J@UP@@$JA@A@?0@@A"
+K<P> p2;
+// CHECK-DAG: @"\01?p2@@3U?$K@UP@@$GA@A@?0@@A"
+
#pragma pointers_to_members(full_generality, virtual_inheritance)
struct S {
diff --git a/clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp b/clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
index 42237f5b7d4..e710abe97e9 100644
--- a/clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
+++ b/clang/test/CodeGenCXX/mangle-ms-templates-memptrs.cpp
@@ -69,8 +69,8 @@ void ReadFields() {
// them right in class templates.
// CHECK: call {{.*}} @"\01??$ReadField@US@@$0A@@@YAHAAUS@@@Z"
// CHECK: call {{.*}} @"\01??$ReadField@UM@@$0A@@@YAHAAUM@@@Z"
-// CHECK: call {{.*}} @"\01??$ReadField@UV@@$FA@?0@@YAHAAUV@@@Z"
-// CHECK: call {{.*}} @"\01??$ReadField@UU@@$GA@A@?0@@YAHAAUU@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UV@@$0A@@@YAHAAUV@@@Z"
+// CHECK: call {{.*}} @"\01??$ReadField@UU@@$0A@@@YAHAAUU@@@Z"
// Non-polymorphic null data memptr vs first field memptr. MSVC mangles these
// the same.
OpenPOWER on IntegriCloud