diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 071cc314b7d14d..19fb4ae82b89d2 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -92,6 +92,7 @@ LANGOPT(CPlusPlus11 , 1, 0, "C++11") LANGOPT(CPlusPlus14 , 1, 0, "C++14") LANGOPT(CPlusPlus17 , 1, 0, "C++17") LANGOPT(CPlusPlus20 , 1, 0, "C++20") +LANGOPT(CPlusPlus2b , 1, 0, "C++2b") LANGOPT(ObjC , 1, 0, "Objective-C") BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, "Objective-C auto-synthesized properties") diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h index ad7f7510b2348d..f82ce05a636928 100644 --- a/clang/include/clang/Basic/LangStandard.h +++ b/clang/include/clang/Basic/LangStandard.h @@ -49,11 +49,12 @@ enum LangFeatures { CPlusPlus14 = (1 << 7), CPlusPlus17 = (1 << 8), CPlusPlus20 = (1 << 9), - Digraphs = (1 << 10), - GNUMode = (1 << 11), - HexFloat = (1 << 12), - ImplicitInt = (1 << 13), - OpenCL = (1 << 14) + CPlusPlus2b = (1 << 10), + Digraphs = (1 << 11), + GNUMode = (1 << 12), + HexFloat = (1 << 13), + ImplicitInt = (1 << 14), + OpenCL = (1 << 15) }; /// LangStandard - Information about the properties of a particular language @@ -111,6 +112,9 @@ struct LangStandard { /// isCPlusPlus20 - Language is a C++20 variant (or later). bool isCPlusPlus20() const { return Flags & CPlusPlus20; } + /// isCPlusPlus2b - Language is a post-C++20 variant (or later). + bool isCPlusPlus2b() const { return Flags & CPlusPlus2b; } + /// hasDigraphs - Language supports digraphs. bool hasDigraphs() const { return Flags & Digraphs; } diff --git a/clang/include/clang/Basic/LangStandards.def b/clang/include/clang/Basic/LangStandards.def index 7b915c31274654..f086d8a43ccb59 100644 --- a/clang/include/clang/Basic/LangStandards.def +++ b/clang/include/clang/Basic/LangStandards.def @@ -152,6 +152,16 @@ LANGSTANDARD(gnucxx20, "gnu++20", CPlusPlus20 | Digraphs | HexFloat | GNUMode) LANGSTANDARD_ALIAS_DEPR(gnucxx20, "gnu++2a") +LANGSTANDARD(cxx2b, "c++2b", + CXX, "Working draft for ISO C++ 2023 DIS", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 | + CPlusPlus20 | CPlusPlus2b | Digraphs | HexFloat) + +LANGSTANDARD(gnucxx2b, "gnu++2b", + CXX, "Working draft for ISO C++ 2023 DIS with GNU extensions", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 | + CPlusPlus20 | CPlusPlus2b | Digraphs | HexFloat | GNUMode) + // OpenCL LANGSTANDARD(opencl10, "cl1.0", OpenCL, "OpenCL 1.0", diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 1c63ce612be0a2..e31f6aa34b36e9 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2388,6 +2388,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, Opts.CPlusPlus14 = Std.isCPlusPlus14(); Opts.CPlusPlus17 = Std.isCPlusPlus17(); Opts.CPlusPlus20 = Std.isCPlusPlus20(); + Opts.CPlusPlus2b = Std.isCPlusPlus2b(); Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus; diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 86d5e61b71127b..42eed9f6c7b595 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -376,8 +376,11 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__STDC_VERSION__", "199409L"); } else { // -- __cplusplus + // FIXME: Use correct value for C++23. + if (LangOpts.CPlusPlus2b) + Builder.defineMacro("__cplusplus", "202101L"); // [C++20] The integer literal 202002L. - if (LangOpts.CPlusPlus20) + else if (LangOpts.CPlusPlus20) Builder.defineMacro("__cplusplus", "202002L"); // [C++17] The integer literal 201703L. else if (LangOpts.CPlusPlus17) diff --git a/clang/test/Driver/std.cpp b/clang/test/Driver/std.cpp index 52b42ab9bd4fdc..c04221b363d7f0 100644 --- a/clang/test/Driver/std.cpp +++ b/clang/test/Driver/std.cpp @@ -11,7 +11,8 @@ // RUN: not %clang -std=gnu++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Z %s // RUN: not %clang -std=c++2a %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX2A %s // RUN: not %clang -std=gnu++2a %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX2A %s - +// RUN: not %clang -std=c++2b %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX2B %s +// RUN: not %clang -std=gnu++2b %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX2B %s void f(int n) { typeof(n)(); @@ -48,3 +49,8 @@ void f(int n) { // GNUXX2A-NOT: undeclared identifier 'typeof' // GNUXX2A-NOT: undeclared identifier 'decltype' +// CXX2B: undeclared identifier 'typeof' +// CXX2B-NOT: undeclared identifier 'decltype' + +// GNUXX2B-NOT: undeclared identifier 'typeof' +// GNUXX2B-NOT: undeclared identifier 'decltype' diff --git a/clang/test/Driver/unknown-std.cpp b/clang/test/Driver/unknown-std.cpp index 9ce9507567a331..d1722b78499abd 100644 --- a/clang/test/Driver/unknown-std.cpp +++ b/clang/test/Driver/unknown-std.cpp @@ -17,6 +17,8 @@ // CHECK-NEXT: note: use 'gnu++17' for 'ISO C++ 2017 with amendments and GNU extensions' standard // CHECK-NEXT: note: use 'c++20' for 'ISO C++ 2020 DIS' standard // CHECK-NEXT: note: use 'gnu++20' for 'ISO C++ 2020 DIS with GNU extensions' standard +// CHECK-NEXT: note: use 'c++2b' for 'Working draft for ISO C++ 2023 DIS' standard +// CHECK-NEXT: note: use 'gnu++2b' for 'Working draft for ISO C++ 2023 DIS with GNU extensions' standard // CUDA-NEXT: note: use 'cuda' for 'NVIDIA CUDA(tm)' standard // Make sure that no other output is present. diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c index e599d9afb42e38..23c4989c515268 100644 --- a/clang/test/Preprocessor/init.c +++ b/clang/test/Preprocessor/init.c @@ -9,6 +9,15 @@ // BLOCKS:#define __block __attribute__((__blocks__(byref))) // // +// RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++2b -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX2B %s +// +// CXX2B:#define __GNUG__ 4 +// CXX2B:#define __GXX_EXPERIMENTAL_CXX0X__ 1 +// CXX2B:#define __GXX_RTTI 1 +// CXX2B:#define __GXX_WEAK__ 1 +// CXX2B:#define __cplusplus 202101L +// CXX2B:#define __private_extern__ extern +// // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++20 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX2A %s // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=c++2a -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX2A %s // @@ -122,6 +131,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++2b -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX2B %s +// +// GXX2B:#define __GNUG__ 4 +// GXX2B:#define __GXX_WEAK__ 1 +// GXX2B:#define __cplusplus 202101L +// GXX2B:#define __private_extern__ extern +// // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++20 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX2A %s // RUN: %clang_cc1 -x c++ -fgnuc-version=4.2.1 -std=gnu++2a -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX2A %s //