diff --git a/clang/include/clang/Basic/ABIVersions.def b/clang/include/clang/Basic/ABIVersions.def new file mode 100644 index 0000000000000..f6524bc3bafb9 --- /dev/null +++ b/clang/include/clang/Basic/ABIVersions.def @@ -0,0 +1,135 @@ +//===--- ABIVersions.def - Clang ABI Versions Database ----------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file enumerates Clang ABI versions. +// +//===----------------------------------------------------------------------===// +// +/// @file ABIVersions.def +/// +/// In this file, each of the Clang ABI Versions is enumerated +/// ABI_VER_MAJOR_MINOR, ABI_VER_MAJOR, or ABI_VER_LATEST macro. +/// +/// ABI_VER_MAJOR is used when the minor version is 0 or can be omitted. +/// +/// The first argument of ABI_VER_MAJOR_MINOR and ABI_VER_MAJOR is the major +/// version. +/// +/// The second argument of ABI_VER_MAJOR_MINOR is the minor version. +/// +/// The first argument of ABI_VER_LATEST is an identifier `Latest`. + +#if defined(ABI_VER_MAJOR_MINOR) != defined(ABI_VER_MAJOR) || \ + defined(ABI_VER_MAJOR) != defined(ABI_VER_LATEST) +# error ABI_VER_MAJOR_MINOR, ABI_VER_MAJOR and ABI_VER_LATEST should be defined simultaneously +#endif + +#ifndef ABI_VER_MAJOR_MINOR +# define ABI_VER_MAJOR_MINOR(Major, Minor) +#endif + +#ifndef ABI_VER_MAJOR +# define ABI_VER_MAJOR(Major) +#endif + +#ifndef ABI_VER_LATEST +# define ABI_VER_LATEST(Latest) +#endif + +/// Attempt to be ABI-compatible with code generated by Clang 3.8.x +/// (SVN r257626). This causes <1 x long long> to be passed in an integer +/// register instead of an SSE register on x64_64. +ABI_VER_MAJOR_MINOR(3, 8) + +/// Attempt to be ABI-compatible with code generated by Clang 4.0.x +/// (SVN r291814). This causes move operations to be ignored when determining +/// whether a class type can be passed or returned directly. +ABI_VER_MAJOR(4) + +/// Attempt to be ABI-compatible with code generated by Clang 6.0.x +/// (SVN r321711). This causes determination of whether a type is +/// standard-layout to ignore collisions between empty base classes and between +/// base classes and member subobjects, which affects whether we reuse base +/// class tail padding in some ABIs. +ABI_VER_MAJOR(6) + +/// Attempt to be ABI-compatible with code generated by Clang 7.0.x +/// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be compatible +/// with __alignof (i.e., return the preferred alignment) rather than returning +/// the required alignment. +ABI_VER_MAJOR(7) + +/// Attempt to be ABI-compatible with code generated by Clang 9.0.x +/// (SVN r351319). This causes vectors of __int128 to be passed in memory +/// instead of passing in multiple scalar registers on x86_64 on Linux and +/// NetBSD. +ABI_VER_MAJOR(9) + +/// Attempt to be ABI-compatible with code generated by Clang 11.0.x +/// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit vector +/// member on the stack instead of using registers, to not properly mangle +/// substitutions for template names in some cases, and to mangle declaration +/// template arguments without a cast to the parameter type even when that can +/// lead to mangling collisions. +ABI_VER_MAJOR(11) + +/// Attempt to be ABI-compatible with code generated by Clang 12.0.x +/// (git 8e464dd76bef). This causes clang to mangle lambdas within global-scope +/// inline variables incorrectly. +ABI_VER_MAJOR(12) + +/// Attempt to be ABI-compatible with code generated by Clang 14.0.x. +/// This causes clang to: +/// - mangle dependent nested names incorrectly. +/// - make trivial only those defaulted copy constructors with a +/// parameter-type-list equivalent to the parameter-type-list of an implicit +/// declaration. +ABI_VER_MAJOR(14) + +/// Attempt to be ABI-compatible with code generated by Clang 15.0.x. +/// This causes clang to: +/// - Reverse the implementation for CWG692, CWG1395 and CWG1432. +/// - pack non-POD members of packed structs. +/// - consider classes with defaulted special member functions non-pod. +ABI_VER_MAJOR(15) + +/// Attempt to be ABI-compatible with code generated by Clang 17.0.x. +/// This causes clang to revert some fixes to its implementation of the Itanium +/// name mangling scheme, with the consequence that overloaded function +/// templates are mangled the same if they differ only by: +/// - constraints +/// - whether a non-type template parameter has a deduced type +/// - the parameter list of a template template parameter +ABI_VER_MAJOR(17) + +/// Attempt to be ABI-compatible with code generated by Clang 18.0.x. +/// This causes clang to revert some fixes to the mangling of lambdas in the +/// initializers of members of local classes. +ABI_VER_MAJOR(18) + +/// Attempt to be ABI-compatible with code generated by Clang 19.0.x. +/// This causes clang to: +/// - Incorrectly mangle the 'base type' substitutions of the CXX construction +/// vtable because it hasn't added 'type' as a substitution. +/// - Skip mangling enclosing class templates of member-like friend function +/// templates. +/// - Ignore empty struct arguments in C++ mode for ARM, instead of passing +/// them as if they had a size of 1 byte. +ABI_VER_MAJOR(19) + +/// Attempt to be ABI-compatible with code generated by Clang 20.0.x. +/// This causes clang to: +/// - Incorrectly return C++ records in AVX registers on x86_64. +ABI_VER_MAJOR(20) + +/// Conform to the underlying platform's C and C++ ABIs as closely as we can. +ABI_VER_LATEST(Latest) + +#undef ABI_VER_MAJOR_MINOR +#undef ABI_VER_MAJOR +#undef ABI_VER_LATEST diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index 0407897359b5e..569584bcc2297 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -186,95 +186,10 @@ class LangOptionsBase { /// Clang versions with different platform ABI conformance. enum class ClangABI { - /// Attempt to be ABI-compatible with code generated by Clang 3.8.x - /// (SVN r257626). This causes <1 x long long> to be passed in an - /// integer register instead of an SSE register on x64_64. - Ver3_8, - - /// Attempt to be ABI-compatible with code generated by Clang 4.0.x - /// (SVN r291814). This causes move operations to be ignored when - /// determining whether a class type can be passed or returned directly. - Ver4, - - /// Attempt to be ABI-compatible with code generated by Clang 6.0.x - /// (SVN r321711). This causes determination of whether a type is - /// standard-layout to ignore collisions between empty base classes - /// and between base classes and member subobjects, which affects - /// whether we reuse base class tail padding in some ABIs. - Ver6, - - /// Attempt to be ABI-compatible with code generated by Clang 7.0.x - /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be - /// compatible with __alignof (i.e., return the preferred alignment) - /// rather than returning the required alignment. - Ver7, - - /// Attempt to be ABI-compatible with code generated by Clang 9.0.x - /// (SVN r351319). This causes vectors of __int128 to be passed in memory - /// instead of passing in multiple scalar registers on x86_64 on Linux and - /// NetBSD. - Ver9, - - /// Attempt to be ABI-compatible with code generated by Clang 11.0.x - /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit - /// vector member on the stack instead of using registers, to not properly - /// mangle substitutions for template names in some cases, and to mangle - /// declaration template arguments without a cast to the parameter type - /// even when that can lead to mangling collisions. - Ver11, - - /// Attempt to be ABI-compatible with code generated by Clang 12.0.x - /// (git 8e464dd76bef). This causes clang to mangle lambdas within - /// global-scope inline variables incorrectly. - Ver12, - - /// Attempt to be ABI-compatible with code generated by Clang 14.0.x. - /// This causes clang to: - /// - mangle dependent nested names incorrectly. - /// - make trivial only those defaulted copy constructors with a - /// parameter-type-list equivalent to the parameter-type-list of an - /// implicit declaration. - Ver14, - - /// Attempt to be ABI-compatible with code generated by Clang 15.0.x. - /// This causes clang to: - /// - Reverse the implementation for DR692, DR1395 and DR1432. - /// - pack non-POD members of packed structs. - /// - consider classes with defaulted special member functions non-pod. - Ver15, - - /// Attempt to be ABI-compatible with code generated by Clang 17.0.x. - /// This causes clang to revert some fixes to its implementation of the - /// Itanium name mangling scheme, with the consequence that overloaded - /// function templates are mangled the same if they differ only by: - /// - constraints - /// - whether a non-type template parameter has a deduced type - /// - the parameter list of a template template parameter - Ver17, - - /// Attempt to be ABI-compatible with code generated by Clang 18.0.x. - /// This causes clang to revert some fixes to the mangling of lambdas - /// in the initializers of members of local classes. - Ver18, - - /// Attempt to be ABI-compatible with code generated by Clang 19.0.x. - /// This causes clang to: - /// - Incorrectly mangle the 'base type' substitutions of the CXX - /// construction vtable because it hasn't added 'type' as a substitution. - /// - Skip mangling enclosing class templates of member-like friend - /// function templates. - /// - Ignore empty struct arguments in C++ mode for ARM, instead of - /// passing them as if they had a size of 1 byte. - Ver19, - - /// Attempt to be ABI-compatible with code generated by Clang 20.0.x. - /// This causes clang to: - /// - Incorrectly return C++ records in AVX registers on x86_64. - Ver20, - - /// Conform to the underlying platform's C and C++ ABIs as closely - /// as we can. - Latest +#define ABI_VER_MAJOR_MINOR(Major, Minor) Ver##Major##_##Minor, +#define ABI_VER_MAJOR(Major) Ver##Major, +#define ABI_VER_LATEST(Latest) Latest +#include "clang/Basic/ABIVersions.def" }; enum class CoreFoundationABI { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 9f77e621a5e68..ccc3154d20968 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3936,47 +3936,18 @@ void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F); switch (Opts.getClangABICompat()) { - case LangOptions::ClangABI::Ver3_8: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "3.8"); +#define ABI_VER_MAJOR_MINOR(Major, Minor) \ + case LangOptions::ClangABI::Ver##Major##_##Minor: \ + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major "." #Minor); \ break; - case LangOptions::ClangABI::Ver4: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "4.0"); +#define ABI_VER_MAJOR(Major) \ + case LangOptions::ClangABI::Ver##Major: \ + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major ".0"); \ break; - case LangOptions::ClangABI::Ver6: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "6.0"); - break; - case LangOptions::ClangABI::Ver7: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "7.0"); - break; - case LangOptions::ClangABI::Ver9: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "9.0"); - break; - case LangOptions::ClangABI::Ver11: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "11.0"); - break; - case LangOptions::ClangABI::Ver12: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "12.0"); - break; - case LangOptions::ClangABI::Ver14: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "14.0"); - break; - case LangOptions::ClangABI::Ver15: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "15.0"); - break; - case LangOptions::ClangABI::Ver17: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0"); - break; - case LangOptions::ClangABI::Ver18: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0"); - break; - case LangOptions::ClangABI::Ver19: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "19.0"); - break; - case LangOptions::ClangABI::Ver20: - GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "20.0"); - break; - case LangOptions::ClangABI::Latest: +#define ABI_VER_LATEST(Latest) \ + case LangOptions::ClangABI::Latest: \ break; +#include "clang/Basic/ABIVersions.def" } if (Opts.getSignReturnAddressScope() == @@ -4482,32 +4453,18 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, !VerParts.second.getAsInteger(10, Minor) : VerParts.first.size() == Ver.size() || VerParts.second == "0")) { // Got a valid version number. - if (Major == 3 && Minor <= 8) - Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8); - else if (Major <= 4) - Opts.setClangABICompat(LangOptions::ClangABI::Ver4); - else if (Major <= 6) - Opts.setClangABICompat(LangOptions::ClangABI::Ver6); - else if (Major <= 7) - Opts.setClangABICompat(LangOptions::ClangABI::Ver7); - else if (Major <= 9) - Opts.setClangABICompat(LangOptions::ClangABI::Ver9); - else if (Major <= 11) - Opts.setClangABICompat(LangOptions::ClangABI::Ver11); - else if (Major <= 12) - Opts.setClangABICompat(LangOptions::ClangABI::Ver12); - else if (Major <= 14) - Opts.setClangABICompat(LangOptions::ClangABI::Ver14); - else if (Major <= 15) - Opts.setClangABICompat(LangOptions::ClangABI::Ver15); - else if (Major <= 17) - Opts.setClangABICompat(LangOptions::ClangABI::Ver17); - else if (Major <= 18) - Opts.setClangABICompat(LangOptions::ClangABI::Ver18); - else if (Major <= 19) - Opts.setClangABICompat(LangOptions::ClangABI::Ver19); - else if (Major <= 20) - Opts.setClangABICompat(LangOptions::ClangABI::Ver20); +#define ABI_VER_MAJOR_MINOR(Major_, Minor_) \ + if (std::tie(Major, Minor) <= std::tuple(Major_, Minor_)) \ + Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_##_##Minor_); \ + else +#define ABI_VER_MAJOR(Major_) \ + if (Major <= Major_) \ + Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_); \ + else +#define ABI_VER_LATEST(Latest) \ + { /* Equivalent to latest version - do nothing */ \ + } +#include "clang/Basic/ABIVersions.def" } else if (Ver != "latest") { Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << A->getValue();