diff --git a/clang/include/clang/Basic/TargetCXXABI.h b/clang/include/clang/Basic/TargetCXXABI.h --- a/clang/include/clang/Basic/TargetCXXABI.h +++ b/clang/include/clang/Basic/TargetCXXABI.h @@ -257,57 +257,6 @@ llvm_unreachable("bad ABI kind"); } - /// When is record layout allowed to allocate objects in the tail - /// padding of a base class? - /// - /// This decision cannot be changed without breaking platform ABI - /// compatibility. In ISO C++98, tail padding reuse was only permitted for - /// non-POD base classes, but that restriction was removed retroactively by - /// DR 43, and tail padding reuse is always permitted in all de facto C++ - /// language modes. However, many platforms use a variant of the old C++98 - /// rule for compatibility. - enum TailPaddingUseRules { - /// The tail-padding of a base class is always theoretically - /// available, even if it's POD. - AlwaysUseTailPadding, - - /// Only allocate objects in the tail padding of a base class if - /// the base class is not POD according to the rules of C++ TR1. - UseTailPaddingUnlessPOD03, - - /// Only allocate objects in the tail padding of a base class if - /// the base class is not POD according to the rules of C++11. - UseTailPaddingUnlessPOD11 - }; - TailPaddingUseRules getTailPaddingUseRules() const { - switch (getKind()) { - // To preserve binary compatibility, the generic Itanium ABI has - // permanently locked the definition of POD to the rules of C++ TR1, - // and that trickles down to derived ABIs. - case GenericItanium: - case GenericAArch64: - case GenericARM: - case iOS: - case GenericMIPS: - case XL: - return UseTailPaddingUnlessPOD03; - - // AppleARM64 and WebAssembly use the C++11 POD rules. They do not honor - // the Itanium exception about classes with over-large bitfields. - case AppleARM64: - case Fuchsia: - case WebAssembly: - case WatchOS: - return UseTailPaddingUnlessPOD11; - - // MSVC always allocates fields in the tail-padding of a base class - // subobject, even if they're POD. - case Microsoft: - return AlwaysUseTailPadding; - } - llvm_unreachable("bad ABI kind"); - } - friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) { return left.getKind() == right.getKind(); } diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -945,6 +945,14 @@ virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const = 0; + enum TailPaddingUseRules { + AlwaysUseTailPadding, + UseTailPaddingUnlessPOD03, + UseTailPaddingUnlessPOD11 + }; + virtual TailPaddingUseRules getTailPaddingUseRules() const { + return UseTailPaddingUnlessPOD03; + } /// Return information about target-specific builtins for /// the current primary target, and info about which builtins are non-portable diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -2392,12 +2392,12 @@ /// Does the target C++ ABI require us to skip over the tail-padding /// of the given class (considering it as a base class) when allocating /// objects? -static bool mustSkipTailPadding(TargetCXXABI ABI, const CXXRecordDecl *RD) { - switch (ABI.getTailPaddingUseRules()) { - case TargetCXXABI::AlwaysUseTailPadding: +static bool mustSkipTailPadding(const TargetInfo &TI, const CXXRecordDecl *RD) { + switch (TI.getTailPaddingUseRules()) { + case TargetInfo::AlwaysUseTailPadding: return false; - case TargetCXXABI::UseTailPaddingUnlessPOD03: + case TargetInfo::UseTailPaddingUnlessPOD03: // FIXME: To the extent that this is meant to cover the Itanium ABI // rules, we should implement the restrictions about over-sized // bitfields: @@ -2418,7 +2418,7 @@ // intended. return RD->isPOD(); - case TargetCXXABI::UseTailPaddingUnlessPOD11: + case TargetInfo::UseTailPaddingUnlessPOD11: // This is equivalent to RD->getTypeForDecl().isCXX11PODType(), // but with a lot of abstraction penalty stripped off. This does // assume that these properties are set correctly even in C++98 @@ -3319,7 +3319,7 @@ // tail-padding of base classes. This is ABI-dependent. // FIXME: this should be stored in the record layout. bool skipTailPadding = - mustSkipTailPadding(getTargetInfo().getCXXABI(), RD); + mustSkipTailPadding(getTargetInfo(), RD); // FIXME: This should be done in FinalizeLayout. CharUnits DataSize = diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -13,6 +13,7 @@ #define LLVM_CLANG_LIB_BASIC_TARGETS_OSTARGETS_H #include "Targets.h" +#include "llvm/ADT/Triple.h" namespace clang { namespace targets { @@ -161,6 +162,16 @@ : TargetInfo::UnsignedLongLong) : TargetInfo::getLeastIntTypeByWidth(BitWidth, IsSigned); } + + TargetInfo::TailPaddingUseRules getTailPaddingUseRules() const override { + auto CXXABI = this->getCXXABI().getKind(); + if (CXXABI == TargetCXXABI::iOS) + return TargetInfo::UseTailPaddingUnlessPOD03; + if (CXXABI == TargetCXXABI::WatchOS || + CXXABI == TargetCXXABI::AppleARM64) + return TargetInfo::UseTailPaddingUnlessPOD11; + return TargetInfo::UseTailPaddingUnlessPOD03; + } }; // DragonFlyBSD Target @@ -845,6 +856,11 @@ this->WCharType = TargetInfo::UnsignedShort; this->WIntType = TargetInfo::UnsignedShort; } + TargetInfo::TailPaddingUseRules getTailPaddingUseRules() const override { + if (this->getTriple().isWindowsMSVCEnvironment()) + return TargetInfo::AlwaysUseTailPadding; + return TargetInfo::UseTailPaddingUnlessPOD03; + } }; template @@ -922,6 +938,9 @@ this->MCountName = "__mcount"; this->TheCXXABI.set(TargetCXXABI::Fuchsia); } + TargetInfo::TailPaddingUseRules getTailPaddingUseRules() const override { + return TargetInfo::UseTailPaddingUnlessPOD11; + } }; // WebAssembly target @@ -949,6 +968,9 @@ this->TheCXXABI.set(TargetCXXABI::WebAssembly); this->HasFloat128 = true; } + TargetInfo::TailPaddingUseRules getTailPaddingUseRules() const override { + return TargetInfo::UseTailPaddingUnlessPOD11; + } }; // WASI target