Skip to content

Commit 8881837

Browse files
committed
Enumerate Clang abi versions in a separate header file
1 parent e136fb0 commit 8881837

File tree

3 files changed

+149
-151
lines changed

3 files changed

+149
-151
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//===--- ABIVersions.def - Clang ABI Versions Database ----------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file enumerates Clang ABI versions.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
/// @file ABIVersions.def
14+
///
15+
/// In this file, each of the Clang ABI Versions except "latest" is enumerated
16+
/// ABI_VER_MAJOR_MINOR, or ABI_VER_MAJOR macro.
17+
///
18+
/// ABI_VER_MAJOR is used when the minor version is 0 or can be omitted.
19+
///
20+
/// The first argument of ABI_VER_MAJOR_MINOR and ABI_VER_MAJOR is the major
21+
/// version.
22+
///
23+
/// The second argument of ABI_VER_MAJOR_MINOR is the minor version.
24+
25+
#if defined(ABI_VER_MAJOR_MINOR) != defined(ABI_VER_MAJOR)
26+
# error ABI_VER_MAJOR_MINOR and ABI_VER_MAJOR should be defined simultaneously
27+
#endif
28+
29+
#ifndef ABI_VER_MAJOR_MINOR
30+
# define ABI_VER_MAJOR_MINOR(Major, Minor)
31+
#endif
32+
33+
#ifndef ABI_VER_MAJOR
34+
# define ABI_VER_MAJOR(Major)
35+
#endif
36+
37+
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
38+
/// (SVN r257626). This causes <1 x long long> to be passed in an integer
39+
/// register instead of an SSE register on x64_64.
40+
ABI_VER_MAJOR_MINOR(3, 8)
41+
42+
/// Attempt to be ABI-compatible with code generated by Clang 4.0.x
43+
/// (SVN r291814). This causes move operations to be ignored when determining
44+
/// whether a class type can be passed or returned directly.
45+
ABI_VER_MAJOR(4)
46+
47+
/// Attempt to be ABI-compatible with code generated by Clang 6.0.x
48+
/// (SVN r321711). This causes determination of whether a type is
49+
/// standard-layout to ignore collisions between empty base classes and between
50+
/// base classes and member subobjects, which affects whether we reuse base
51+
/// class tail padding in some ABIs.
52+
ABI_VER_MAJOR(6)
53+
54+
/// Attempt to be ABI-compatible with code generated by Clang 7.0.x
55+
/// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be compatible
56+
/// with __alignof (i.e., return the preferred alignment) rather than returning
57+
/// the required alignment.
58+
ABI_VER_MAJOR(7)
59+
60+
/// Attempt to be ABI-compatible with code generated by Clang 9.0.x
61+
/// (SVN r351319). This causes vectors of __int128 to be passed in memory
62+
/// instead of passing in multiple scalar registers on x86_64 on Linux and
63+
/// NetBSD.
64+
ABI_VER_MAJOR(9)
65+
66+
/// Attempt to be ABI-compatible with code generated by Clang 11.0.x
67+
/// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit vector
68+
/// member on the stack instead of using registers, to not properly mangle
69+
/// substitutions for template names in some cases, and to mangle declaration
70+
/// template arguments without a cast to the parameter type even when that can
71+
/// lead to mangling collisions.
72+
ABI_VER_MAJOR(11)
73+
74+
/// Attempt to be ABI-compatible with code generated by Clang 12.0.x
75+
/// (git 8e464dd76bef). This causes clang to mangle lambdas within global-scope
76+
/// inline variables incorrectly.
77+
ABI_VER_MAJOR(12)
78+
79+
/// Attempt to be ABI-compatible with code generated by Clang 14.0.x.
80+
/// This causes clang to:
81+
/// - mangle dependent nested names incorrectly.
82+
/// - make trivial only those defaulted copy constructors with a
83+
/// parameter-type-list equivalent to the parameter-type-list of an implicit
84+
/// declaration.
85+
ABI_VER_MAJOR(14)
86+
87+
/// Attempt to be ABI-compatible with code generated by Clang 15.0.x.
88+
/// This causes clang to:
89+
/// - Reverse the implementation for CWG692, CWG1395 and CWG1432.
90+
/// - pack non-POD members of packed structs.
91+
/// - consider classes with defaulted special member functions non-pod.
92+
ABI_VER_MAJOR(15)
93+
94+
/// Attempt to be ABI-compatible with code generated by Clang 17.0.x.
95+
/// This causes clang to revert some fixes to its implementation of the Itanium
96+
/// name mangling scheme, with the consequence that overloaded function
97+
/// templates are mangled the same if they differ only by:
98+
/// - constraints
99+
/// - whether a non-type template parameter has a deduced type
100+
/// - the parameter list of a template template parameter
101+
ABI_VER_MAJOR(17)
102+
103+
/// Attempt to be ABI-compatible with code generated by Clang 18.0.x.
104+
/// This causes clang to revert some fixes to the mangling of lambdas in the
105+
/// initializers of members of local classes.
106+
ABI_VER_MAJOR(18)
107+
108+
/// Attempt to be ABI-compatible with code generated by Clang 19.0.x.
109+
/// This causes clang to:
110+
/// - Incorrectly mangle the 'base type' substitutions of the CXX construction
111+
/// vtable because it hasn't added 'type' as a substitution.
112+
/// - Skip mangling enclosing class templates of member-like friend function
113+
/// templates.
114+
/// - Ignore empty struct arguments in C++ mode for ARM, instead of passing
115+
/// them as if they had a size of 1 byte.
116+
ABI_VER_MAJOR(19)
117+
118+
/// Attempt to be ABI-compatible with code generated by Clang 20.0.x.
119+
/// This causes clang to:
120+
/// - Incorrectly return C++ records in AVX registers on x86_64.
121+
ABI_VER_MAJOR(20)
122+
123+
/// Conform to the underlying platform's C and C++ ABIs as closely as we can.
124+
// (latest)
125+
126+
#undef ABI_VER_MAJOR_MINOR
127+
#undef ABI_VER_MAJOR

clang/include/clang/Basic/LangOptions.h

Lines changed: 4 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -186,94 +186,10 @@ class LangOptionsBase {
186186

187187
/// Clang versions with different platform ABI conformance.
188188
enum class ClangABI {
189-
/// Attempt to be ABI-compatible with code generated by Clang 3.8.x
190-
/// (SVN r257626). This causes <1 x long long> to be passed in an
191-
/// integer register instead of an SSE register on x64_64.
192-
Ver3_8,
193-
194-
/// Attempt to be ABI-compatible with code generated by Clang 4.0.x
195-
/// (SVN r291814). This causes move operations to be ignored when
196-
/// determining whether a class type can be passed or returned directly.
197-
Ver4,
198-
199-
/// Attempt to be ABI-compatible with code generated by Clang 6.0.x
200-
/// (SVN r321711). This causes determination of whether a type is
201-
/// standard-layout to ignore collisions between empty base classes
202-
/// and between base classes and member subobjects, which affects
203-
/// whether we reuse base class tail padding in some ABIs.
204-
Ver6,
205-
206-
/// Attempt to be ABI-compatible with code generated by Clang 7.0.x
207-
/// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be
208-
/// compatible with __alignof (i.e., return the preferred alignment)
209-
/// rather than returning the required alignment.
210-
Ver7,
211-
212-
/// Attempt to be ABI-compatible with code generated by Clang 9.0.x
213-
/// (SVN r351319). This causes vectors of __int128 to be passed in memory
214-
/// instead of passing in multiple scalar registers on x86_64 on Linux and
215-
/// NetBSD.
216-
Ver9,
217-
218-
/// Attempt to be ABI-compatible with code generated by Clang 11.0.x
219-
/// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit
220-
/// vector member on the stack instead of using registers, to not properly
221-
/// mangle substitutions for template names in some cases, and to mangle
222-
/// declaration template arguments without a cast to the parameter type
223-
/// even when that can lead to mangling collisions.
224-
Ver11,
225-
226-
/// Attempt to be ABI-compatible with code generated by Clang 12.0.x
227-
/// (git 8e464dd76bef). This causes clang to mangle lambdas within
228-
/// global-scope inline variables incorrectly.
229-
Ver12,
230-
231-
/// Attempt to be ABI-compatible with code generated by Clang 14.0.x.
232-
/// This causes clang to:
233-
/// - mangle dependent nested names incorrectly.
234-
/// - make trivial only those defaulted copy constructors with a
235-
/// parameter-type-list equivalent to the parameter-type-list of an
236-
/// implicit declaration.
237-
Ver14,
238-
239-
/// Attempt to be ABI-compatible with code generated by Clang 15.0.x.
240-
/// This causes clang to:
241-
/// - Reverse the implementation for DR692, DR1395 and DR1432.
242-
/// - pack non-POD members of packed structs.
243-
/// - consider classes with defaulted special member functions non-pod.
244-
Ver15,
245-
246-
/// Attempt to be ABI-compatible with code generated by Clang 17.0.x.
247-
/// This causes clang to revert some fixes to its implementation of the
248-
/// Itanium name mangling scheme, with the consequence that overloaded
249-
/// function templates are mangled the same if they differ only by:
250-
/// - constraints
251-
/// - whether a non-type template parameter has a deduced type
252-
/// - the parameter list of a template template parameter
253-
Ver17,
254-
255-
/// Attempt to be ABI-compatible with code generated by Clang 18.0.x.
256-
/// This causes clang to revert some fixes to the mangling of lambdas
257-
/// in the initializers of members of local classes.
258-
Ver18,
259-
260-
/// Attempt to be ABI-compatible with code generated by Clang 19.0.x.
261-
/// This causes clang to:
262-
/// - Incorrectly mangle the 'base type' substitutions of the CXX
263-
/// construction vtable because it hasn't added 'type' as a substitution.
264-
/// - Skip mangling enclosing class templates of member-like friend
265-
/// function templates.
266-
/// - Ignore empty struct arguments in C++ mode for ARM, instead of
267-
/// passing them as if they had a size of 1 byte.
268-
Ver19,
269-
270-
/// Attempt to be ABI-compatible with code generated by Clang 20.0.x.
271-
/// This causes clang to:
272-
/// - Incorrectly return C++ records in AVX registers on x86_64.
273-
Ver20,
274-
275-
/// Conform to the underlying platform's C and C++ ABIs as closely
276-
/// as we can.
189+
#define ABI_VER_MAJOR_MINOR(Major, Minor) Ver##Major##_##Minor,
190+
#define ABI_VER_MAJOR(Major) Ver##Major,
191+
#include "clang/Basic/ABIVersions.def"
192+
277193
Latest
278194
};
279195

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 18 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -3936,45 +3936,16 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
39363936
GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);
39373937

39383938
switch (Opts.getClangABICompat()) {
3939-
case LangOptions::ClangABI::Ver3_8:
3940-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "3.8");
3939+
#define ABI_VER_MAJOR_MINOR(Major, Minor) \
3940+
case LangOptions::ClangABI::Ver##Major##_##Minor: \
3941+
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major "." #Minor); \
39413942
break;
3942-
case LangOptions::ClangABI::Ver4:
3943-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "4.0");
3944-
break;
3945-
case LangOptions::ClangABI::Ver6:
3946-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "6.0");
3947-
break;
3948-
case LangOptions::ClangABI::Ver7:
3949-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "7.0");
3950-
break;
3951-
case LangOptions::ClangABI::Ver9:
3952-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "9.0");
3953-
break;
3954-
case LangOptions::ClangABI::Ver11:
3955-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "11.0");
3956-
break;
3957-
case LangOptions::ClangABI::Ver12:
3958-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "12.0");
3959-
break;
3960-
case LangOptions::ClangABI::Ver14:
3961-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "14.0");
3962-
break;
3963-
case LangOptions::ClangABI::Ver15:
3964-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "15.0");
3965-
break;
3966-
case LangOptions::ClangABI::Ver17:
3967-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0");
3968-
break;
3969-
case LangOptions::ClangABI::Ver18:
3970-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0");
3971-
break;
3972-
case LangOptions::ClangABI::Ver19:
3973-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "19.0");
3974-
break;
3975-
case LangOptions::ClangABI::Ver20:
3976-
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "20.0");
3943+
#define ABI_VER_MAJOR(Major) \
3944+
case LangOptions::ClangABI::Ver##Major: \
3945+
GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major ".0"); \
39773946
break;
3947+
#include "clang/Basic/ABIVersions.def"
3948+
39783949
case LangOptions::ClangABI::Latest:
39793950
break;
39803951
}
@@ -4482,32 +4453,16 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
44824453
!VerParts.second.getAsInteger(10, Minor)
44834454
: VerParts.first.size() == Ver.size() || VerParts.second == "0")) {
44844455
// Got a valid version number.
4485-
if (Major == 3 && Minor <= 8)
4486-
Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8);
4487-
else if (Major <= 4)
4488-
Opts.setClangABICompat(LangOptions::ClangABI::Ver4);
4489-
else if (Major <= 6)
4490-
Opts.setClangABICompat(LangOptions::ClangABI::Ver6);
4491-
else if (Major <= 7)
4492-
Opts.setClangABICompat(LangOptions::ClangABI::Ver7);
4493-
else if (Major <= 9)
4494-
Opts.setClangABICompat(LangOptions::ClangABI::Ver9);
4495-
else if (Major <= 11)
4496-
Opts.setClangABICompat(LangOptions::ClangABI::Ver11);
4497-
else if (Major <= 12)
4498-
Opts.setClangABICompat(LangOptions::ClangABI::Ver12);
4499-
else if (Major <= 14)
4500-
Opts.setClangABICompat(LangOptions::ClangABI::Ver14);
4501-
else if (Major <= 15)
4502-
Opts.setClangABICompat(LangOptions::ClangABI::Ver15);
4503-
else if (Major <= 17)
4504-
Opts.setClangABICompat(LangOptions::ClangABI::Ver17);
4505-
else if (Major <= 18)
4506-
Opts.setClangABICompat(LangOptions::ClangABI::Ver18);
4507-
else if (Major <= 19)
4508-
Opts.setClangABICompat(LangOptions::ClangABI::Ver19);
4509-
else if (Major <= 20)
4510-
Opts.setClangABICompat(LangOptions::ClangABI::Ver20);
4456+
#define ABI_VER_MAJOR_MINOR(Major_, Minor_) \
4457+
if (std::tie(Major, Minor) <= std::tuple(Major_, Minor_)) \
4458+
Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_##_##Minor_); \
4459+
else
4460+
#define ABI_VER_MAJOR(Major_) \
4461+
if (Major <= Major_) \
4462+
Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_); \
4463+
else
4464+
#include "clang/Basic/ABIVersions.def"
4465+
{} // sub-statement of the last else branch
45114466
} else if (Ver != "latest") {
45124467
Diags.Report(diag::err_drv_invalid_value)
45134468
<< A->getAsString(Args) << A->getValue();

0 commit comments

Comments
 (0)