summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/MicrosoftCXXABI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/MicrosoftCXXABI.cpp')
-rw-r--r--clang/lib/AST/MicrosoftCXXABI.cpp16
1 files changed, 14 insertions, 2 deletions
diff --git a/clang/lib/AST/MicrosoftCXXABI.cpp b/clang/lib/AST/MicrosoftCXXABI.cpp
index ee96e13e4b1..27b3e341c4b 100644
--- a/clang/lib/AST/MicrosoftCXXABI.cpp
+++ b/clang/lib/AST/MicrosoftCXXABI.cpp
@@ -197,8 +197,20 @@ std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
unsigned PtrSize = Target.getPointerWidth(0);
unsigned IntSize = Target.getIntWidth();
uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
- unsigned Align = Ptrs > 0 ? Target.getPointerAlign(0) : Target.getIntAlign();
- Width = llvm::RoundUpToAlignment(Width, Align);
+ unsigned Align;
+
+ // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
+ // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
+ // function memptrs.
+ if (Ptrs + Ints > 1 && Target.getTriple().getArch() == llvm::Triple::x86)
+ Align = 8 * 8;
+ else if (Ptrs)
+ Align = Target.getPointerAlign(0);
+ else
+ Align = Target.getIntAlign();
+
+ if (Target.getTriple().getArch() == llvm::Triple::x86_64)
+ Width = llvm::RoundUpToAlignment(Width, Align);
return std::make_pair(Width, Align);
}
OpenPOWER on IntegriCloud