Use the Itanium ABI for member pointers. Add a missing 'break' statement and a test case
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71972 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index ccd3762..329d6c4 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -475,18 +475,18 @@
// pointer size.
return getTypeInfo(cast<ReferenceType>(T)->getPointeeType());
case Type::MemberPointer: {
- // FIXME: This is not only platform- but also ABI-dependent. We follow
- // the GCC ABI, where pointers to data are one pointer large, pointers to
- // functions two pointers. But if we want to support ABI compatibility with
- // other compilers too, we need to delegate this completely to TargetInfo
- // or some ABI abstraction layer.
+ // FIXME: This is ABI dependent. We use the Itanium C++ ABI.
+ // http://www.codesourcery.com/public/cxx-abi/abi.html#member-pointers
+ // If we ever want to support other ABIs this needs to be abstracted.
+
QualType Pointee = cast<MemberPointerType>(T)->getPointeeType();
- unsigned AS = Pointee.getAddressSpace();
- Width = Target.getPointerWidth(AS);
+ std::pair<uint64_t, unsigned> PtrDiffInfo =
+ getTypeInfo(getPointerDiffType());
+ Width = PtrDiffInfo.first;
if (Pointee->isFunctionType())
Width *= 2;
- Align = Target.getPointerAlign(AS);
- // GCC aligns at single pointer width.
+ Align = PtrDiffInfo.second;
+ break;
}
case Type::Complex: {
// Complex types have the same alignment as their elements, but twice the
diff --git a/test/SemaCXX/member-pointer-size.cpp b/test/SemaCXX/member-pointer-size.cpp
new file mode 100644
index 0000000..f86e72b
--- /dev/null
+++ b/test/SemaCXX/member-pointer-size.cpp
@@ -0,0 +1,15 @@
+// RUN: clang-cc -triple x86_64-unknown-unknown %s -fsyntax-only -verify &&
+// RUN: clang-cc -triple i686-unknown-unknown %s -fsyntax-only -verify
+#include <stddef.h>
+
+struct A;
+
+void f() {
+ int A::*dataMember;
+
+ int (A::*memberFunction)();
+
+ typedef int assert1[sizeof(dataMember) == sizeof(ptrdiff_t) ? 1 : -1];
+ typedef int assert2[sizeof(memberFunction) == sizeof(ptrdiff_t) * 2 ? 1 : -1];
+}
+