[Clang] Add flags and lang option for C++2d (#203992)
This adds diagnostic groups, command-line options, a language option,
and various other things required to support `-std=c++2d`. I haven’t
touched e.g. clang-tidy or clang-format, as I’m not really familiar w/
either. This is only meant to add the most necessary parts to support
C++29 mode.
I grepped for `CPlusPlus26`/`C++26`/`C++2c` and updated all places I
could find where we need to handle every language mode in some way or
another.
This patch is roughly based on b763d6a4ed.
This commit is contained in:
parent
5de2fb5112
commit
1381ef49fc
26 changed files with 97 additions and 18 deletions
|
|
@ -226,6 +226,14 @@ Language Selection and Mode Options
|
|||
|
||||
Working draft for C++2c with GNU extensions
|
||||
|
||||
| ``c++2d``
|
||||
|
||||
Working draft for C++2d
|
||||
|
||||
| ``gnu++2d``
|
||||
|
||||
Working draft for C++2d with GNU extensions
|
||||
|
||||
The default C++ language standard is ``gnu++17``.
|
||||
|
||||
Supported values for the OpenCL language are:
|
||||
|
|
|
|||
|
|
@ -231,6 +231,8 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
|
|||
|
||||
#### C++2d Feature Support
|
||||
|
||||
- Added compiler flags `-std=c++2d` and `-std=gnu++2d` for experimental C++2d implementation work.
|
||||
|
||||
- Clang now supports [P3733R1](https://wg21.link/p3733r1>) More named universal character escapes.
|
||||
The change is applied as a DR to all C++ language modes. (#GH203944)
|
||||
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the
|
|||
|
||||
### C++ Language Changes
|
||||
|
||||
#### C++2d Feature Support
|
||||
|
||||
#### C++2c Feature Support
|
||||
|
||||
#### C++23 Feature Support
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ specific section:
|
|||
- :ref:`Objective-C Language <objc>`: ObjC 1, ObjC 2, ObjC 2.1, plus
|
||||
variants depending on base language.
|
||||
- :ref:`C++ Language <cxx>`: C++98, C++03, C++11, C++14, C++17, C++20, C++23,
|
||||
and C++26.
|
||||
C++26, and C++29.
|
||||
- :ref:`Objective C++ Language <objcxx>`
|
||||
- :ref:`OpenCL Kernel Language <opencl>`: OpenCL C 1.0, 1.1, 1.2, 2.0, 3.0,
|
||||
and C++ for OpenCL 1.0 and 2021.
|
||||
|
|
|
|||
|
|
@ -244,6 +244,7 @@ multiclass CXX17Compat<string message, bit ext_warn = true> : CXXCompat<message,
|
|||
multiclass CXX20Compat<string message, bit ext_warn = true> : CXXCompat<message, 20, ext_warn>;
|
||||
multiclass CXX23Compat<string message, bit ext_warn = true> : CXXCompat<message, 23, ext_warn>;
|
||||
multiclass CXX26Compat<string message, bit ext_warn = true> : CXXCompat<message, 26, ext_warn, "2c">;
|
||||
multiclass CXX29Compat<string message, bit ext_warn = true> : CXXCompat<message, 29, ext_warn, "2d">;
|
||||
|
||||
// Definitions for Diagnostics.
|
||||
include "DiagnosticASTKinds.td"
|
||||
|
|
|
|||
|
|
@ -412,6 +412,9 @@ def CXXPre26CompatPedantic :
|
|||
DiagGroup<"pre-c++26-compat-pedantic", [CXXPre26Compat]>;
|
||||
def : DiagGroup<"pre-c++2c-compat", [CXXPre26Compat]>;
|
||||
def : DiagGroup<"pre-c++2c-compat-pedantic", [CXXPre26CompatPedantic]>;
|
||||
def CXXPre29Compat : DiagGroup<"pre-c++2d-compat">;
|
||||
def CXXPre29CompatPedantic :
|
||||
DiagGroup<"pre-c++2d-compat-pedantic", [CXXPre29Compat]>;
|
||||
|
||||
def CXX98CompatBindToTemporaryCopy :
|
||||
DiagGroup<"c++98-compat-bind-to-temporary-copy">;
|
||||
|
|
@ -1580,6 +1583,10 @@ def CXX23 : DiagGroup<"c++23-extensions", [CXX23AttrsOnLambda]>;
|
|||
// earlier C++ versions.
|
||||
def CXX26 : DiagGroup<"c++26-extensions">;
|
||||
|
||||
// A warning group for warnings about using C++29 features as extensions in
|
||||
// earlier C++ versions.
|
||||
def CXX29 : DiagGroup<"c++2d-extensions">;
|
||||
|
||||
def : DiagGroup<"c++0x-extensions", [CXX11]>;
|
||||
def : DiagGroup<"c++1y-extensions", [CXX14]>;
|
||||
def : DiagGroup<"c++1z-extensions", [CXX17]>;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ LANGOPT(CPlusPlus17 , 1, 0, NotCompatible, "C++17")
|
|||
LANGOPT(CPlusPlus20 , 1, 0, NotCompatible, "C++20")
|
||||
LANGOPT(CPlusPlus23 , 1, 0, NotCompatible, "C++23")
|
||||
LANGOPT(CPlusPlus26 , 1, 0, NotCompatible, "C++26")
|
||||
LANGOPT(CPlusPlus29 , 1, 0, NotCompatible, "C++29")
|
||||
LANGOPT(ObjC , 1, 0, NotCompatible, "Objective-C")
|
||||
LANGOPT(ObjCDefaultSynthProperties , 1, 0, Benign,
|
||||
"Objective-C auto-synthesized properties")
|
||||
|
|
|
|||
|
|
@ -59,11 +59,12 @@ enum LangFeatures {
|
|||
CPlusPlus20 = (1 << 10),
|
||||
CPlusPlus23 = (1 << 11),
|
||||
CPlusPlus26 = (1 << 12),
|
||||
Digraphs = (1 << 13),
|
||||
GNUMode = (1 << 14),
|
||||
HexFloat = (1 << 15),
|
||||
OpenCL = (1 << 16),
|
||||
HLSL = (1 << 17)
|
||||
CPlusPlus29 = (1 << 13),
|
||||
Digraphs = (1 << 14),
|
||||
GNUMode = (1 << 15),
|
||||
HexFloat = (1 << 16),
|
||||
OpenCL = (1 << 17),
|
||||
HLSL = (1 << 18)
|
||||
};
|
||||
|
||||
/// LangStandard - Information about the properties of a particular language
|
||||
|
|
@ -133,6 +134,9 @@ public:
|
|||
/// isCPlusPlus26 - Language is a post-C++26 variant (or later).
|
||||
bool isCPlusPlus26() const { return Flags & CPlusPlus26; }
|
||||
|
||||
/// isCPlusPlus29 - Language is a post-C++29 variant (or later).
|
||||
bool isCPlusPlus29() const { return Flags & CPlusPlus29; }
|
||||
|
||||
/// hasDigraphs - Language supports digraphs.
|
||||
bool hasDigraphs() const { return Flags & Digraphs; }
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,8 @@ LANGSTANDARD(c2y, "c2y",
|
|||
LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | HexFloat, 202400)
|
||||
LANGSTANDARD(gnu2y, "gnu2y",
|
||||
C, "Working Draft for ISO C2y with GNU extensions",
|
||||
LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | GNUMode | HexFloat, 202400)
|
||||
LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | GNUMode
|
||||
| HexFloat, 202400)
|
||||
// TODO: Add the iso9899:202y alias once ISO publishes the standard.
|
||||
|
||||
// C++ modes
|
||||
|
|
@ -191,6 +192,19 @@ LANGSTANDARD(gnucxx26, "gnu++2c",
|
|||
CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat | GNUMode, 202400)
|
||||
LANGSTANDARD_ALIAS(gnucxx26, "gnu++26")
|
||||
|
||||
// FIXME: Use correct version code for C++29 once published.
|
||||
// TODO: Add LANGSTANDARD_ALIAS() for "c++29" once C++29 is ratified.
|
||||
LANGSTANDARD(cxx29, "c++2d",
|
||||
CXX, "Working draft for C++2d",
|
||||
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
|
||||
CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | CPlusPlus29 | Digraphs | HexFloat, 202700)
|
||||
|
||||
// TODO: Add LANGSTANDARD_ALIAS() for "gnu++29" once C++29 is ratified.
|
||||
LANGSTANDARD(gnucxx29, "gnu++2d",
|
||||
CXX, "Working draft for C++2d with GNU extensions",
|
||||
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
|
||||
CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | CPlusPlus29 | Digraphs | HexFloat | GNUMode, 202700)
|
||||
|
||||
// OpenCL
|
||||
LANGSTANDARD(opencl10, "cl1.0",
|
||||
OpenCL, "OpenCL 1.0",
|
||||
|
|
|
|||
|
|
@ -634,6 +634,7 @@ defvar cpp17 = LangOpts<"CPlusPlus17">;
|
|||
defvar cpp20 = LangOpts<"CPlusPlus20">;
|
||||
defvar cpp23 = LangOpts<"CPlusPlus23">;
|
||||
defvar cpp26 = LangOpts<"CPlusPlus26">;
|
||||
defvar cpp29 = LangOpts<"CPlusPlus29">;
|
||||
defvar c99 = LangOpts<"C99">;
|
||||
defvar c23 = LangOpts<"C23">;
|
||||
defvar lang_std = LangOpts<"LangStd">;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ TESTLANGUAGE_CXX(CXX, 17, c++17, 4)
|
|||
TESTLANGUAGE_CXX(CXX, 20, c++20, 5)
|
||||
TESTLANGUAGE_CXX(CXX, 23, c++23, 6)
|
||||
TESTLANGUAGE_CXX(CXX, 26, c++26, 7)
|
||||
TESTLANGUAGE_CXX(CXX, 29, c++2d, 8)
|
||||
|
||||
#undef TESTLANGUAGE_CXX
|
||||
#undef TESTLANGUAGE_C
|
||||
|
|
|
|||
|
|
@ -902,6 +902,8 @@ unsigned DiagnosticIDs::getCXXCompatDiagId(const LangOptions &LangOpts,
|
|||
assert(CompatDiagId < std::size(Diags) && "Invalid compat diag id");
|
||||
|
||||
unsigned StdVer = [&] {
|
||||
if (LangOpts.CPlusPlus29)
|
||||
return 2029;
|
||||
if (LangOpts.CPlusPlus26)
|
||||
return 2026;
|
||||
if (LangOpts.CPlusPlus23)
|
||||
|
|
|
|||
|
|
@ -124,6 +124,7 @@ void LangOptions::setLangDefaults(LangOptions &Opts, Language Lang,
|
|||
Opts.CPlusPlus20 = Std.isCPlusPlus20();
|
||||
Opts.CPlusPlus23 = Std.isCPlusPlus23();
|
||||
Opts.CPlusPlus26 = Std.isCPlusPlus26();
|
||||
Opts.CPlusPlus29 = Std.isCPlusPlus29();
|
||||
Opts.GNUMode = Std.isGNUMode();
|
||||
Opts.GNUCVersion = 0;
|
||||
Opts.HexFloats = Std.hasHexFloats();
|
||||
|
|
@ -277,7 +278,9 @@ std::optional<uint32_t> LangOptions::getCPlusPlusLangStd() const {
|
|||
return std::nullopt;
|
||||
|
||||
LangStandard::Kind Std;
|
||||
if (CPlusPlus26)
|
||||
if (CPlusPlus29)
|
||||
Std = LangStandard::lang_cxx29;
|
||||
else if (CPlusPlus26)
|
||||
Std = LangStandard::lang_cxx26;
|
||||
else if (CPlusPlus23)
|
||||
Std = LangStandard::lang_cxx23;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
|
|||
.Case("cplusplus20", LangOpts.CPlusPlus20)
|
||||
.Case("cplusplus23", LangOpts.CPlusPlus23)
|
||||
.Case("cplusplus26", LangOpts.CPlusPlus26)
|
||||
.Case("cplusplus29", LangOpts.CPlusPlus29)
|
||||
.Case("c99", LangOpts.C99)
|
||||
.Case("c11", LangOpts.C11)
|
||||
.Case("c17", LangOpts.C17)
|
||||
|
|
|
|||
|
|
@ -228,7 +228,10 @@ static void addVisualCDefines(const LangOptions &Opts, MacroBuilder &Builder) {
|
|||
Builder.defineMacro("_HAS_CHAR16_T_LANGUAGE_SUPPORT", Twine(1));
|
||||
|
||||
if (Opts.isCompatibleWithMSVC(LangOptions::MSVC2015)) {
|
||||
if (Opts.CPlusPlus26)
|
||||
if (Opts.CPlusPlus29)
|
||||
// TODO update to the proper value.
|
||||
Builder.defineMacro("_MSVC_LANG", "202700L");
|
||||
else if (Opts.CPlusPlus26)
|
||||
// TODO update to the proper value.
|
||||
Builder.defineMacro("_MSVC_LANG", "202400L");
|
||||
else if (Opts.CPlusPlus23)
|
||||
|
|
|
|||
|
|
@ -150,6 +150,8 @@ static llvm::ManagedStatic<IndexErrorCategory> Category;
|
|||
static std::string getLangDescription(const LangOptions &LO) {
|
||||
if (!LO.CPlusPlus)
|
||||
return "non-C++";
|
||||
if (LO.CPlusPlus29)
|
||||
return "C++29";
|
||||
if (LO.CPlusPlus26)
|
||||
return "C++26";
|
||||
if (LO.CPlusPlus23)
|
||||
|
|
|
|||
|
|
@ -1671,7 +1671,7 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
|
|||
(Std->containsValue("c++20") || Std->containsValue("c++2a") ||
|
||||
Std->containsValue("c++23") || Std->containsValue("c++2b") ||
|
||||
Std->containsValue("c++26") || Std->containsValue("c++2c") ||
|
||||
Std->containsValue("c++latest"));
|
||||
Std->containsValue("c++2d") || Std->containsValue("c++latest"));
|
||||
|
||||
// Process -fmodule-header{=} flags.
|
||||
if (Arg *A = Args.getLastArg(options::OPT_fmodule_header_EQ,
|
||||
|
|
|
|||
|
|
@ -7690,9 +7690,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
// TransferableCommand::tryParseStdArg() in
|
||||
// lib/Tooling/InterpolatingCompilationDatabase.cpp
|
||||
// to match.
|
||||
// TODO add c++23 and c++26 when MSVC supports it.
|
||||
// TODO add c++23, c++26, c++29 when MSVC supports
|
||||
// it.
|
||||
.Case("c++23preview", "-std=c++23")
|
||||
.Case("c++latest", "-std=c++26")
|
||||
.Case("c++latest", "-std=c++2d")
|
||||
.Default("");
|
||||
if (IsSYCL) {
|
||||
const LangStandard *LangStd =
|
||||
|
|
@ -7782,7 +7783,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
Std->containsValue("c++23") || Std->containsValue("gnu++23") ||
|
||||
Std->containsValue("c++23preview") || Std->containsValue("c++2c") ||
|
||||
Std->containsValue("gnu++2c") || Std->containsValue("c++26") ||
|
||||
Std->containsValue("gnu++26") || Std->containsValue("c++latest") ||
|
||||
Std->containsValue("gnu++26") || Std->containsValue("c++2d") ||
|
||||
Std->containsValue("gnu++2d") || Std->containsValue("c++latest") ||
|
||||
Std->containsValue("gnu++latest"));
|
||||
bool HaveModules =
|
||||
RenderModulesOptions(C, D, Args, Input, Output, HaveCxx20, CmdArgs);
|
||||
|
|
|
|||
|
|
@ -148,9 +148,9 @@ static LangStandard::Kind latestLangStandardC() {
|
|||
// flag in clang-CL mode.
|
||||
static LangStandard::Kind latestLangStandardCXX() {
|
||||
// FIXME: Have a single source of truth for the mapping from
|
||||
// c++latest --> c++26 that's shared by the driver code
|
||||
// c++latest --> c++29 that's shared by the driver code
|
||||
// (clang/lib/Driver/ToolChains/Clang.cpp) and this file.
|
||||
return LangStandard::lang_cxx26;
|
||||
return LangStandard::lang_cxx29;
|
||||
}
|
||||
|
||||
// A CompileCommand that can be applied to another file.
|
||||
|
|
|
|||
|
|
@ -625,7 +625,7 @@
|
|||
// STDCXX23PREVIEW: -std=c++23
|
||||
|
||||
// RUN: %clang_cl -fmsc-version=1900 -TP -std:c++latest -### -- %s 2>&1 | FileCheck -check-prefix=STDCXXLATEST %s
|
||||
// STDCXXLATEST: -std=c++26
|
||||
// STDCXXLATEST: -std=c++2d
|
||||
|
||||
// RUN: env CL="/Gy" %clang_cl -### -- %s 2>&1 | FileCheck -check-prefix=ENV-CL %s
|
||||
// ENV-CL: "-ffunction-sections"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
// CHECK-NEXT: note: use 'gnu++23' for 'ISO C++ 2023 DIS with GNU extensions' standard
|
||||
// CHECK-NEXT: note: use 'c++2c' or 'c++26' for 'Working draft for C++2c' standard
|
||||
// CHECK-NEXT: note: use 'gnu++2c' or 'gnu++26' for 'Working draft for C++2c with GNU extensions' standard
|
||||
// CHECK-NEXT: note: use 'c++2d' for 'Working draft for C++2d' standard
|
||||
// CHECK-NEXT: note: use 'gnu++2d' for 'Working draft for C++2d with GNU extensions' standard
|
||||
|
||||
// Make sure that no other output is present.
|
||||
// CHECK-NOT: {{^.+$}}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,15 @@
|
|||
// BLOCKS:#define __BLOCKS__ 1
|
||||
// BLOCKS:#define __block __attribute__((__blocks__(byref)))
|
||||
//
|
||||
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++2d -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX29 %s
|
||||
//
|
||||
// CXX29:#define __GNUG__ 4
|
||||
// CXX29:#define __GXX_EXPERIMENTAL_CXX0X__ 1
|
||||
// CXX29:#define __GXX_RTTI 1
|
||||
// CXX29:#define __GXX_WEAK__ 1
|
||||
// CXX29:#define __cplusplus 202700L
|
||||
// CXX29:#define __private_extern__ extern
|
||||
//
|
||||
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++26 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX26 %s
|
||||
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++2c -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX26 %s
|
||||
//
|
||||
|
|
@ -214,6 +223,13 @@
|
|||
// RUN: %clang_cc1 -ffreestanding -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix FREESTANDING %s
|
||||
// FREESTANDING:#define __STDC_HOSTED__ 0
|
||||
//
|
||||
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++2d -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX29 %s
|
||||
//
|
||||
// GXX29:#define __GNUG__ 4
|
||||
// GXX29:#define __GXX_WEAK__ 1
|
||||
// GXX29:#define __cplusplus 202700L
|
||||
// GXX29:#define __private_extern__ extern
|
||||
//
|
||||
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++26 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX26 %s
|
||||
// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++2c -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX26 %s
|
||||
//
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@ TEST(LangOptsTest, CppStdLang) {
|
|||
EXPECT_EQ(opts.getCPlusPlusLangStd(), 202302);
|
||||
opts.CPlusPlus26 = 1;
|
||||
EXPECT_EQ(opts.getCPlusPlusLangStd(), 202400);
|
||||
opts.CPlusPlus29 = 1;
|
||||
EXPECT_EQ(opts.getCPlusPlusLangStd(), 202700);
|
||||
|
||||
EXPECT_FALSE(opts.getCLangStd());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ improve the quality of clang by self-testing. Some examples:
|
|||
</ul>
|
||||
</li>
|
||||
|
||||
<li><b>Continue work on C++20, C++23, C++2c, and C23 support</b>:
|
||||
<li><b>Continue work on C++20, C++23, C++2c, C++2d, and C23 support</b>:
|
||||
There are still several C++20 features to complete, and work has begun on
|
||||
supporting the latest language standards. Please see the
|
||||
<a href="cxx_status.html">C++ status report page</a> to find out what is
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
</tr>
|
||||
<tr>
|
||||
<td><a href="#cxx29">C++2d</a></td>
|
||||
<td></td>
|
||||
<td><tt>-std=c++2d</tt></td>
|
||||
<td class="partial" align="center">Partial</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
|
@ -98,6 +98,8 @@ and so on, to track known bugs with Clang's language conformance.</p>
|
|||
<p>Clang has support for some of the features of the C++ standard following
|
||||
C++2c, informally referred to as C++2d.</p>
|
||||
|
||||
<p>You can use Clang in C++2d mode with the <code>-std=c++2d</code> option.</p>
|
||||
|
||||
<details open>
|
||||
<summary>List of features and minimum Clang version with support</summary>
|
||||
<table width="689" border="1" cellspacing="0">
|
||||
|
|
|
|||
|
|
@ -186,6 +186,9 @@ def availability(issue):
|
|||
elif status.endswith(' c++26'):
|
||||
status = status[:-6]
|
||||
avail_suffix = ' (C++26 onwards)'
|
||||
elif status.endswith(' c++29'):
|
||||
status = status[:-6]
|
||||
avail_suffix = ' (C++29 onwards)'
|
||||
if status == 'unknown':
|
||||
avail = 'Unknown'
|
||||
avail_style = 'unknown'
|
||||
|
|
|
|||
Loading…
Reference in a new issue