diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/MicrosoftCXXABI.cpp | 16 |
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); } |