[clang] Implement gcc_struct attribute on Itanium targets (#71148)
This commit implements gcc_struct attribute with the behavior similar to
one in GCC. Current behavior is as follows:
When ItaniumRecordLayoutBuilder is used, [[gcc_struct]] will locally
cancel the effect of -mms-bitfields on a record. If -mms-bitfields is
not supplied and is not a default behavior on a target, [[gcc_struct]]
will be a no-op. This should provide enough compatibility with GCC.
If C++ ABI is "Microsoft", [[gcc_struct]] will currently always produce
a diagnostic, since support for it is not yet implemented in
MicrosoftRecordLayoutBuilder. Note, however, that all the infrastructure
is ready for the future implementation.
In particular, check for default value of -mms-bitfields is moved from a
driver to ASTContext, since it now non-trivially depends on other
supplied flags. This also, unfortunately, makes it impossible to use
usual argument parsing for `-m{no-,}ms-bitfields`.
The patch doesn't introduce any backwards-incompatible changes, except
for situations when cc1 is called directly with `-mms-bitfields` option.
Work towards #24757
---------
Co-authored-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
44aec0e768
commit
1760effa33
@ -379,6 +379,12 @@ Attribute Changes in Clang
|
||||
multilibs for printf features. Requires cooperation with the libc
|
||||
implementation.
|
||||
|
||||
- On targets with Itanium C++ ABI, Clang now supports ``[[gnu:gcc_struct]]``
|
||||
with the behavior similar to one existing in GCC. In particular, whenever
|
||||
``-mms-bitfields`` command line option is provided (or if Microsoft-compatible
|
||||
structure layout is default on the target), ``[[gnu::gcc_struct]]`` requests
|
||||
the compiler to follow Itanium rules for the layout of an annotated structure.
|
||||
|
||||
Improvements to Clang's diagnostics
|
||||
-----------------------------------
|
||||
- Diagnostics messages now refer to ``structured binding`` instead of ``decomposition``,
|
||||
|
||||
@ -2810,6 +2810,10 @@ public:
|
||||
/// runtime, such as those using the Itanium C++ ABI.
|
||||
CharUnits getExnObjectAlignment() const;
|
||||
|
||||
/// Return whether unannotated records are treated as if they have
|
||||
/// [[gnu::ms_struct]].
|
||||
bool defaultsToMsStruct() const;
|
||||
|
||||
/// Get or compute information about the layout of the specified
|
||||
/// record (struct/union/class) \p D, which indicates its size and field
|
||||
/// position information.
|
||||
|
||||
@ -4387,8 +4387,13 @@ def CFGuard : InheritableAttr, TargetSpecificAttr<TargetWindows> {
|
||||
def MSStruct : InheritableAttr {
|
||||
let Spellings = [GCC<"ms_struct">];
|
||||
let Subjects = SubjectList<[Record]>;
|
||||
let Documentation = [Undocumented];
|
||||
let SimpleHandler = 1;
|
||||
let Documentation = [MSStructDocs];
|
||||
}
|
||||
|
||||
def GCCStruct : InheritableAttr {
|
||||
let Spellings = [GCC<"gcc_struct">];
|
||||
let Subjects = SubjectList<[Record]>;
|
||||
let Documentation = [MSStructDocs]; // Covers this attribute too.
|
||||
}
|
||||
|
||||
def DLLExport : InheritableAttr, TargetSpecificAttr<TargetHasDLLImportExport> {
|
||||
|
||||
@ -9682,3 +9682,24 @@ The following aspects are currently supported:
|
||||
- ``float``: The call has a floating point argument
|
||||
}];
|
||||
}
|
||||
|
||||
def MSStructDocs : Documentation {
|
||||
let Category = DocCatDecl;
|
||||
let Content = [{
|
||||
The ``ms_struct`` and ``gcc_struct`` attributes request the compiler to enter a
|
||||
special record layout compatibility mode which mimics the layout of Microsoft or
|
||||
Itanium C++ ABI respectively. Obviously, if the current C++ ABI matches the
|
||||
requested ABI, the attribute does nothing. However, if it does not, annotated
|
||||
structure or class is laid out in a special compatibility mode, which slightly
|
||||
changes offsets for fields and bit-fields. The intention is to match the layout
|
||||
of the requested ABI for structures which only use C features.
|
||||
|
||||
Note that the default behavior can be controlled by ``-mms-bitfields`` and
|
||||
``-mno-ms-bitfields`` switches and via ``#pragma ms_struct``.
|
||||
|
||||
The primary difference is for bitfields, where the MS variant only packs
|
||||
adjacent fields into the same allocation unit if they have integral types
|
||||
of the same size, while the GCC/Itanium variant packs all fields in a bitfield
|
||||
tightly.
|
||||
}];
|
||||
}
|
||||
|
||||
@ -1040,6 +1040,9 @@ def warn_npot_ms_struct : Warning<
|
||||
"data types with sizes that aren't a power of two">,
|
||||
DefaultError, InGroup<IncompatibleMSStruct>;
|
||||
|
||||
def err_itanium_layout_unimplemented : Error<
|
||||
"Itanium-compatible layout for the Microsoft C++ ABI is not yet supported">;
|
||||
|
||||
// -Wpadded-bitfield
|
||||
def warn_padded_struct_bitfield : Warning<
|
||||
"padding %select{struct|interface|class}0 %1 with %2 "
|
||||
|
||||
@ -104,7 +104,9 @@ LANGOPT(AssumeNothrowExceptionDtor , 1, 0, NotCompatible, "Assume exception obje
|
||||
LANGOPT(TraditionalCPP , 1, 0, NotCompatible, "traditional CPP emulation")
|
||||
LANGOPT(RTTI , 1, 1, NotCompatible, "run-time type information")
|
||||
LANGOPT(RTTIData , 1, 1, NotCompatible, "emit run-time type information data")
|
||||
LANGOPT(MSBitfields , 1, 0, NotCompatible, "Microsoft-compatible structure layout")
|
||||
ENUM_LANGOPT(LayoutCompatibility, LayoutCompatibilityKind, 2,
|
||||
LayoutCompatibilityKind::Default, NotCompatible,
|
||||
"Microsoft-compatible structure layout")
|
||||
LANGOPT(MSVolatile , 1, 0, NotCompatible, "Microsoft-compatible volatile loads and stores")
|
||||
LANGOPT(Freestanding , 1, 0, NotCompatible, "freestanding implementation")
|
||||
LANGOPT(NoBuiltin , 1, 0, NotCompatible, "disable builtin functions")
|
||||
|
||||
@ -421,6 +421,16 @@ public:
|
||||
None,
|
||||
};
|
||||
|
||||
enum class LayoutCompatibilityKind {
|
||||
/// Use default layout rules of the target.
|
||||
Default = 0,
|
||||
/// Use Itanium rules for bit-field layout and fundamental types alignment.
|
||||
Itanium = 1,
|
||||
/// Use Microsoft C++ ABI rules for bit-field layout and fundamental types
|
||||
/// alignment.
|
||||
Microsoft = 2,
|
||||
};
|
||||
|
||||
// Define simple language options (with no accessors).
|
||||
#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
|
||||
unsigned Name : Bits;
|
||||
|
||||
@ -5219,9 +5219,7 @@ def : Joined<["-"], "mmacosx-version-min=">,
|
||||
Visibility<[ClangOption, CC1Option, FC1Option, FlangOption]>,
|
||||
Group<m_Group>, Alias<mmacos_version_min_EQ>;
|
||||
def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">,
|
||||
MarshallingInfoFlag<LangOpts<"MSBitfields">>;
|
||||
HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">;
|
||||
def moutline : Flag<["-"], "moutline">, Group<f_clang_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Enable function outlining (AArch64 only)">;
|
||||
@ -5230,6 +5228,12 @@ def mno_outline : Flag<["-"], "mno-outline">, Group<f_clang_Group>,
|
||||
HelpText<"Disable function outlining (AArch64 only)">;
|
||||
def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>,
|
||||
HelpText<"Do not set the default structure layout to be compatible with the Microsoft compiler standard">;
|
||||
def fms_layout_compatibility_EQ : Joined<["-"], "fms-layout-compatibility=">,
|
||||
Visibility<[CC1Option]>,
|
||||
HelpText<"Structure layout compatibility with Microsoft C++ ABI">,
|
||||
Values<"default,itanium,microsoft">,
|
||||
NormalizedValues<["Default", "Itanium", "Microsoft"]>, NormalizedValuesScope<"LangOptions::LayoutCompatibilityKind">,
|
||||
MarshallingInfoEnum<LangOpts<"LayoutCompatibility">, "Default">;
|
||||
def mskip_rax_setup : Flag<["-"], "mskip-rax-setup">, Group<m_Group>,
|
||||
Visibility<[ClangOption, CC1Option]>,
|
||||
HelpText<"Skip setting up RAX register when passing variable arguments (x86 only)">,
|
||||
|
||||
@ -5244,7 +5244,14 @@ void RecordDecl::completeDefinition() {
|
||||
/// This which can be turned on with an attribute, pragma, or the
|
||||
/// -mms-bitfields command-line option.
|
||||
bool RecordDecl::isMsStruct(const ASTContext &C) const {
|
||||
return hasAttr<MSStructAttr>() || C.getLangOpts().MSBitfields == 1;
|
||||
if (hasAttr<GCCStructAttr>())
|
||||
return false;
|
||||
if (hasAttr<MSStructAttr>())
|
||||
return true;
|
||||
auto LayoutCompatibility = C.getLangOpts().getLayoutCompatibility();
|
||||
if (LayoutCompatibility == LangOptions::LayoutCompatibilityKind::Default)
|
||||
return C.defaultsToMsStruct();
|
||||
return LayoutCompatibility == LangOptions::LayoutCompatibilityKind::Microsoft;
|
||||
}
|
||||
|
||||
void RecordDecl::reorderDecls(const SmallVectorImpl<Decl *> &Decls) {
|
||||
|
||||
@ -2794,6 +2794,13 @@ void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) {
|
||||
UseExternalLayout = Source->layoutRecordType(
|
||||
RD, External.Size, External.Align, External.FieldOffsets,
|
||||
External.BaseOffsets, External.VirtualBaseOffsets);
|
||||
|
||||
if (!RD->isMsStruct(Context)) {
|
||||
auto Location = RD->getLocation();
|
||||
if (Location.isValid())
|
||||
Context.getDiagnostics().Report(Location,
|
||||
diag::err_itanium_layout_unimplemented);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -3358,6 +3365,11 @@ void MicrosoftRecordLayoutBuilder::computeVtorDispSet(
|
||||
}
|
||||
}
|
||||
|
||||
bool ASTContext::defaultsToMsStruct() const {
|
||||
return getTargetInfo().hasMicrosoftRecordLayout() ||
|
||||
getTargetInfo().getTriple().isWindowsGNUEnvironment();
|
||||
}
|
||||
|
||||
/// getASTRecordLayout - Get or compute information about the layout of the
|
||||
/// specified record (struct/union/class), which indicates its size and field
|
||||
/// position information.
|
||||
|
||||
@ -5889,9 +5889,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
||||
if (KernelOrKext && RawTriple.isOSDarwin())
|
||||
CmdArgs.push_back("-fforbid-guard-variables");
|
||||
|
||||
if (Args.hasFlag(options::OPT_mms_bitfields, options::OPT_mno_ms_bitfields,
|
||||
Triple.isWindowsGNUEnvironment())) {
|
||||
CmdArgs.push_back("-mms-bitfields");
|
||||
if (Arg *A = Args.getLastArg(options::OPT_mms_bitfields,
|
||||
options::OPT_mno_ms_bitfields)) {
|
||||
if (A->getOption().matches(options::OPT_mms_bitfields))
|
||||
CmdArgs.push_back("-fms-layout-compatibility=microsoft");
|
||||
else
|
||||
CmdArgs.push_back("-fms-layout-compatibility=itanium");
|
||||
}
|
||||
|
||||
if (Triple.isOSCygMing()) {
|
||||
|
||||
@ -18992,9 +18992,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc,
|
||||
// ABI.
|
||||
bool CStdConstraintViolation =
|
||||
BitfieldIsOverwide && !getLangOpts().CPlusPlus;
|
||||
bool MSBitfieldViolation =
|
||||
Value.ugt(TypeStorageSize) &&
|
||||
(IsMsStruct || Context.getTargetInfo().getCXXABI().isMicrosoft());
|
||||
bool MSBitfieldViolation = Value.ugt(TypeStorageSize) && IsMsStruct;
|
||||
if (CStdConstraintViolation || MSBitfieldViolation) {
|
||||
unsigned DiagWidth =
|
||||
CStdConstraintViolation ? TypeWidth : TypeStorageSize;
|
||||
|
||||
@ -6173,6 +6173,36 @@ static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
D->addAttr(::new (S.Context) MSConstexprAttr(S.Context, AL));
|
||||
}
|
||||
|
||||
static void handleMSStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
if (const auto *First = D->getAttr<GCCStructAttr>()) {
|
||||
S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
|
||||
<< AL << First << 0;
|
||||
S.Diag(First->getLocation(), diag::note_conflicting_attribute);
|
||||
return;
|
||||
}
|
||||
if (const auto *Preexisting = D->getAttr<MSStructAttr>()) {
|
||||
if (Preexisting->isImplicit())
|
||||
D->dropAttr<MSStructAttr>();
|
||||
}
|
||||
|
||||
D->addAttr(::new (S.Context) MSStructAttr(S.Context, AL));
|
||||
}
|
||||
|
||||
static void handleGCCStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
if (const auto *First = D->getAttr<MSStructAttr>()) {
|
||||
if (First->isImplicit()) {
|
||||
D->dropAttr<MSStructAttr>();
|
||||
} else {
|
||||
S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
|
||||
<< AL << First << 0;
|
||||
S.Diag(First->getLocation(), diag::note_conflicting_attribute);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
D->addAttr(::new (S.Context) GCCStructAttr(S.Context, AL));
|
||||
}
|
||||
|
||||
static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
|
||||
SmallVector<StringRef, 4> Tags;
|
||||
for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
|
||||
@ -7983,6 +8013,14 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
|
||||
case ParsedAttr::AT_ModularFormat:
|
||||
handleModularFormat(S, D, AL);
|
||||
break;
|
||||
|
||||
case ParsedAttr::AT_MSStruct:
|
||||
handleMSStructAttr(S, D, AL);
|
||||
break;
|
||||
|
||||
case ParsedAttr::AT_GCCStruct:
|
||||
handleGCCStructAttr(S, D, AL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -7288,20 +7288,27 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
|
||||
CheckCompletedMemberFunction(MD);
|
||||
}
|
||||
|
||||
// ms_struct is a request to use the same ABI rules as MSVC. Check
|
||||
// whether this class uses any C++ features that are implemented
|
||||
// completely differently in MSVC, and if so, emit a diagnostic.
|
||||
// That diagnostic defaults to an error, but we allow projects to
|
||||
// map it down to a warning (or ignore it). It's a fairly common
|
||||
// practice among users of the ms_struct pragma to mass-annotate
|
||||
// headers, sweeping up a bunch of types that the project doesn't
|
||||
// really rely on MSVC-compatible layout for. We must therefore
|
||||
// support "ms_struct except for C++ stuff" as a secondary ABI.
|
||||
// {ms,gcc}_struct is a request to change ABI rules to either follow
|
||||
// Microsoft or Itanium C++ ABI. However, even if these attributes are
|
||||
// present, we do not layout classes following foreign ABI rules, but
|
||||
// instead enter a special "compatibility mode", which only changes
|
||||
// alignments of fundamental types and layout of bit fields.
|
||||
// Check whether this class uses any C++ features that are implemented
|
||||
// completely differently in the requested ABI, and if so, emit a
|
||||
// diagnostic. That diagnostic defaults to an error, but we allow
|
||||
// projects to map it down to a warning (or ignore it). It's a fairly
|
||||
// common practice among users of the ms_struct pragma to
|
||||
// mass-annotate headers, sweeping up a bunch of types that the
|
||||
// project doesn't really rely on MSVC-compatible layout for. We must
|
||||
// therefore support "ms_struct except for C++ stuff" as a secondary
|
||||
// ABI.
|
||||
// Don't emit this diagnostic if the feature was enabled as a
|
||||
// language option (as opposed to via a pragma or attribute), as
|
||||
// the option -mms-bitfields otherwise essentially makes it impossible
|
||||
// to build C++ code, unless this diagnostic is turned off.
|
||||
if (Record->isMsStruct(Context) && !Context.getLangOpts().MSBitfields &&
|
||||
if (Context.getLangOpts().getLayoutCompatibility() ==
|
||||
LangOptions::LayoutCompatibilityKind::Default &&
|
||||
Record->isMsStruct(Context) != Context.defaultsToMsStruct() &&
|
||||
(Record->isPolymorphic() || Record->getNumBases())) {
|
||||
Diag(Record->getLocation(), diag::warn_cxx_ms_struct);
|
||||
}
|
||||
|
||||
6
clang/test/CodeGen/gcc_struct-msvc-todo-1.c
Normal file
6
clang/test/CodeGen/gcc_struct-msvc-todo-1.c
Normal file
@ -0,0 +1,6 @@
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-windows-msvc -verify %s
|
||||
|
||||
// expected-error@+1 {{Itanium-compatible layout for the Microsoft C++ ABI is not yet supported}}
|
||||
struct {
|
||||
int a;
|
||||
} __attribute__((gcc_struct)) t1;
|
||||
6
clang/test/CodeGen/gcc_struct-msvc-todo-2.c
Normal file
6
clang/test/CodeGen/gcc_struct-msvc-todo-2.c
Normal file
@ -0,0 +1,6 @@
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-windows-msvc -fms-layout-compatibility=itanium -verify %s
|
||||
|
||||
// expected-error@+1 {{Itanium-compatible layout for the Microsoft C++ ABI is not yet supported}}
|
||||
struct {
|
||||
int a;
|
||||
} t1;
|
||||
18
clang/test/CodeGen/gcc_struct.c
Normal file
18
clang/test/CodeGen/gcc_struct.c
Normal file
@ -0,0 +1,18 @@
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-linux-gnu %s
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-linux-gnu -fms-layout-compatibility=microsoft %s
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-windows-gnu %s
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-windows-gnu -fms-layout-compatibility=itanium %s
|
||||
|
||||
struct {
|
||||
int a : 24;
|
||||
char b : 8;
|
||||
} __attribute__((gcc_struct)) t1;
|
||||
_Static_assert(sizeof(t1) == 4, "");
|
||||
|
||||
#pragma ms_struct on
|
||||
struct {
|
||||
int a : 24;
|
||||
char b : 8;
|
||||
} __attribute__((gcc_struct)) t2;
|
||||
_Static_assert(sizeof(t2) == 4, "");
|
||||
#pragma ms_struct off
|
||||
@ -1,6 +1,6 @@
|
||||
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -o - %s \
|
||||
// RUN: | FileCheck %s --check-prefix=GNU32
|
||||
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -o - %s -mms-bitfields \
|
||||
// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -o - %s -fms-layout-compatibility=microsoft \
|
||||
// RUN: | FileCheck %s --check-prefix=GNU32
|
||||
// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -o - %s \
|
||||
// RUN: | FileCheck %s --check-prefix=GNU64
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -triple i386-apple-darwin10 -mms-bitfields -emit-llvm %s -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -triple i386-apple-darwin10 -fms-layout-compatibility=microsoft -emit-llvm %s -o - | FileCheck %s
|
||||
|
||||
struct s1 {
|
||||
int f32;
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
// RUN: %clang -### --target=x86_64-linux-gnu %s 2>&1 | FileCheck %s -check-prefix=NO-MSBITFIELDS
|
||||
// RUN: %clang -### --target=x86_64-windows-gnu %s 2>&1 | FileCheck %s -check-prefix=MSBITFIELDS
|
||||
// RUN: %clang -### -mno-ms-bitfields -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MSBITFIELDS
|
||||
// RUN: %clang -### -mms-bitfields -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=NO-MSBITFIELDS
|
||||
// RUN: %clang -### --target=x86_64-linux-gnu %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-LAYOUT
|
||||
// RUN: %clang -### --target=x86_64-windows-gnu %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-LAYOUT
|
||||
// RUN: %clang -### --target=x86_64-windows-msvc %s 2>&1 | FileCheck %s -check-prefix=DEFAULT-LAYOUT
|
||||
// RUN: %clang -### -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MICROSOFT-LAYOUT
|
||||
// RUN: %clang -### -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=ITANIUM-LAYOUT
|
||||
// RUN: %clang -### -mno-ms-bitfields -mms-bitfields %s 2>&1 | FileCheck %s -check-prefix=MICROSOFT-LAYOUT
|
||||
// RUN: %clang -### -mms-bitfields -mno-ms-bitfields %s 2>&1 | FileCheck %s -check-prefix=ITANIUM-LAYOUT
|
||||
|
||||
// MSBITFIELDS: -mms-bitfields
|
||||
// NO-MSBITFIELDS-NOT: -mms-bitfields
|
||||
// DEFAULT-LAYOUT-NOT: -fms-layout-compatibility=itanium
|
||||
// DEFAULT-LAYOUT-NOT: -fms-layout-compatibility=microsoft
|
||||
// MICROSOFT-LAYOUT: -fms-layout-compatibility=microsoft
|
||||
// MICROSOFT-LAYOUT-NOT: -fms-layout-compatibility=itanium
|
||||
// ITANIUM-LAYOUT: -fms-layout-compatibility=itanium
|
||||
// ITANIUM-LAYOUT-NOT: -fms-layout-compatibility=microsoft
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -fdump-record-layouts %s 2>/dev/null \
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple %itanium_abi_triple -fms-layout-compatibility=itanium -fdump-record-layouts %s 2>/dev/null \
|
||||
// RUN: | FileCheck %s
|
||||
|
||||
// On z/OS, a bit-field has single byte alignment. Add aligned(4) on z/OS so the union has
|
||||
|
||||
@ -87,6 +87,7 @@
|
||||
// CHECK-NEXT: FlagEnum (SubjectMatchRule_enum)
|
||||
// CHECK-NEXT: Flatten (SubjectMatchRule_function)
|
||||
// CHECK-NEXT: FunctionReturnThunks (SubjectMatchRule_function)
|
||||
// CHECK-NEXT: GCCStruct (SubjectMatchRule_record)
|
||||
// CHECK-NEXT: GNUInline (SubjectMatchRule_function)
|
||||
// CHECK-NEXT: HIPManaged (SubjectMatchRule_variable)
|
||||
// CHECK-NEXT: HLSLVkLocation (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_field, SubjectMatchRule_function)
|
||||
|
||||
37
clang/test/Sema/gcc_ms_struct.c
Normal file
37
clang/test/Sema/gcc_ms_struct.c
Normal file
@ -0,0 +1,37 @@
|
||||
// RUN: %clang_cc1 -emit-llvm-only -triple x86_64-pc-windows-gnu -verify %s
|
||||
|
||||
struct {
|
||||
int a;
|
||||
}
|
||||
// expected-note@+1 {{conflicting attribute is here}}
|
||||
__attribute__((gcc_struct))
|
||||
// expected-error@+1 {{'ms_struct' and 'gcc_struct' attributes are not compatible}}
|
||||
__attribute__((ms_struct))
|
||||
t1;
|
||||
|
||||
struct {
|
||||
int a;
|
||||
}
|
||||
// expected-note@+1 {{conflicting attribute is here}}
|
||||
__attribute__((ms_struct))
|
||||
// expected-error@+1 {{'gcc_struct' and 'ms_struct' attributes are not compatible}}
|
||||
__attribute__((gcc_struct))
|
||||
t2;
|
||||
|
||||
#pragma ms_struct on
|
||||
struct {
|
||||
int a;
|
||||
}
|
||||
// No diagnostic for an attribute, unambiguously overriding the pragma.
|
||||
__attribute__((gcc_struct))
|
||||
t3;
|
||||
|
||||
struct {
|
||||
int a;
|
||||
}
|
||||
// expected-note@+1 {{conflicting attribute is here}}
|
||||
__attribute__((ms_struct))
|
||||
// expected-error@+1 {{'gcc_struct' and 'ms_struct' attributes are not compatible}}
|
||||
__attribute__((gcc_struct))
|
||||
t4;
|
||||
#pragma ms_struct off
|
||||
@ -1,6 +1,5 @@
|
||||
// RUN: %clang_cc1 -mms-bitfields -fsyntax-only -verify -triple x86_64-apple-darwin9 %s
|
||||
// RUN: %clang_cc1 -mms-bitfields -fsyntax-only -Wms-bitfield-padding -verify=checkms -triple x86_64-apple-darwin9 %s
|
||||
|
||||
// RUN: %clang_cc1 -fms-layout-compatibility=microsoft -fsyntax-only -verify -triple x86_64-apple-darwin9 %s
|
||||
// RUN: %clang_cc1 -fms-layout-compatibility=microsoft -fsyntax-only -Wms-bitfield-padding -verify=checkms -triple x86_64-apple-darwin9 %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
// The -mms-bitfields commandline parameter should behave the same
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
|
||||
// RUN: %clang_cc1 -fsyntax-only -Wms-bitfield-padding -verify -triple armv8 -std=c++23 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -DMS_BITFIELDS -mms-bitfields -verify=msbitfields -triple armv8-apple-macos10.15 -std=c++23 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -DMS_BITFIELDS -fms-layout-compatibility=microsoft -verify=msbitfields -triple armv8-apple-macos10.15 -std=c++23 %s
|
||||
|
||||
// msbitfields-no-diagnostics
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
// RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_WARNING -Wno-error=incompatible-ms-struct -verify -triple i686-apple-darwin9 -std=c++11 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_WARNING -Wno-error=incompatible-ms-struct -verify -triple armv7-apple-darwin9 -std=c++11 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -DTEST_FOR_ERROR -verify -triple armv7-apple-darwin9 -std=c++11 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -DNO_PRAGMA -mms-bitfields -verify -triple armv7-apple-darwin9 -std=c++11 %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -DNO_PRAGMA -fms-layout-compatibility=microsoft -verify -triple armv7-apple-darwin9 -std=c++11 %s
|
||||
|
||||
#ifndef NO_PRAGMA
|
||||
#pragma ms_struct on
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
// RUN: %clang_cc1 -fno-rtti -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -mms-bitfields -verify %s 2>&1
|
||||
// RUN: %clang_cc1 -fno-rtti -triple i686-pc-win32 -fdump-record-layouts -fsyntax-only -fms-layout-compatibility=microsoft -verify %s 2>&1
|
||||
|
||||
struct A {
|
||||
char a : 9; // expected-error{{width of bit-field 'a' (9 bits) exceeds the size of its type (8 bits)}}
|
||||
|
||||
@ -1357,6 +1357,7 @@ static bool isExemptAtStart(StringRef Text) {
|
||||
.Case("Fuchsia", true)
|
||||
.Case("GNUstep", true)
|
||||
.Case("IBOutletCollection", true)
|
||||
.Case("Itanium", true)
|
||||
.Case("Microsoft", true)
|
||||
.Case("Neon", true)
|
||||
.StartsWith("NSInvocation", true) // NSInvocation, NSInvocation's
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user