[clang] [clang][Basic] Add helper APIs to get language version codes from LangOptions (PR #163348)
Michael Buch via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 15 02:11:18 PDT 2025
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/163348
>From 375a56e2def366b838a79042b2c11e08dfbd8a4c Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 13 Oct 2025 23:59:16 +0100
Subject: [PATCH 1/5] [clang][Basic] Add helper APIs to get language version
codes from LangOptions
---
clang/include/clang/Basic/LangOptions.h | 31 +++++++++++++++++
clang/lib/Basic/LangOptions.cpp | 46 +++++++++++++++++++++++++
clang/lib/Frontend/InitPreprocessor.cpp | 37 +++-----------------
clang/unittests/Basic/CMakeLists.txt | 1 +
4 files changed, 82 insertions(+), 33 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 41595ec2a060d..940e79634ccd5 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -184,6 +184,28 @@ class LangOptionsBase {
HLSL_202y = 2029,
};
+ /// C language version codes as defined by the standard.
+ enum CLangStd : uint32_t {
+ // FIXME: Use correct value for C2y.
+ C_2y = 202400,
+ C_23 = 202311,
+ C_17 = 201710,
+ C_11 = 201112,
+ C_99 = 199901,
+ };
+
+ /// C++ language version codes as defined by the standard.
+ enum CPlusPlusLangStd : uint32_t {
+ // FIXME: Use correct value for C++26.
+ CPP_26 = 202400,
+ CPP_23 = 202302,
+ CPP_20 = 202002,
+ CPP_17 = 201703,
+ CPP_14 = 201402,
+ CPP_11 = 201103,
+ CPP_03 = 199711,
+ };
+
/// Clang versions with different platform ABI conformance.
enum class ClangABI {
#define ABI_VER_MAJOR_MINOR(Major, Minor) Ver##Major##_##Minor,
@@ -756,6 +778,15 @@ class LangOptions : public LangOptionsBase {
bool isTargetDevice() const {
return OpenMPIsTargetDevice || CUDAIsDevice || SYCLIsDevice;
}
+
+ /// Returns the most applicable C standard-compliant language version code.
+ /// If none could be determined, returns \ref std::nullopt.
+ std::optional<CLangStd> GetCLangStd() const;
+
+ /// Returns the most applicable C++ standard-compliant language
+ /// version code.
+ /// If none could be determined, returns \ref std::nullopt.
+ std::optional<CPlusPlusLangStd> GetCPlusPlusLangStd() const;
};
/// Floating point control options
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index f034514466d3f..6745427e2c223 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -243,3 +243,49 @@ LLVM_DUMP_METHOD void FPOptionsOverride::dump() {
#include "clang/Basic/FPOptions.def"
llvm::errs() << "\n";
}
+
+std::optional<clang::LangOptionsBase::CPlusPlusLangStd>
+LangOptions::GetCPlusPlusLangStd() const {
+ if (!CPlusPlus)
+ return std::nullopt;
+
+ if (CPlusPlus26)
+ return clang::LangOptionsBase::CPP_26;
+
+ if (CPlusPlus23)
+ return clang::LangOptionsBase::CPP_23;
+
+ if (CPlusPlus20)
+ return clang::LangOptionsBase::CPP_20;
+
+ if (CPlusPlus17)
+ return clang::LangOptionsBase::CPP_17;
+
+ if (CPlusPlus14)
+ return clang::LangOptionsBase::CPP_14;
+
+ if (CPlusPlus11)
+ return clang::LangOptionsBase::CPP_11;
+
+ return clang::LangOptionsBase::CPP_03;
+}
+
+std::optional<clang::LangOptionsBase::CLangStd>
+LangOptions::GetCLangStd() const {
+ if (C2y)
+ return clang::LangOptionsBase::C_2y;
+
+ if (C23)
+ return clang::LangOptionsBase::C_23;
+
+ if (C17)
+ return clang::LangOptionsBase::C_17;
+
+ if (C11)
+ return clang::LangOptionsBase::C_11;
+
+ if (C99)
+ return clang::LangOptionsBase::C_99;
+
+ return std::nullopt;
+}
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index b899fb9c6494a..27bc4cf7108cc 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -459,43 +459,14 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
// value is, are implementation-defined.
// (Removed in C++20.)
if (!LangOpts.CPlusPlus) {
- if (LangOpts.C2y)
- Builder.defineMacro("__STDC_VERSION__", "202400L");
- else if (LangOpts.C23)
- Builder.defineMacro("__STDC_VERSION__", "202311L");
- else if (LangOpts.C17)
- Builder.defineMacro("__STDC_VERSION__", "201710L");
- else if (LangOpts.C11)
- Builder.defineMacro("__STDC_VERSION__", "201112L");
- else if (LangOpts.C99)
- Builder.defineMacro("__STDC_VERSION__", "199901L");
+ if (auto LangStd = LangOpts.GetCLangStd())
+ Builder.defineMacro("__STDC_VERSION__", Twine(*LangStd) + "L");
else if (!LangOpts.GNUMode && LangOpts.Digraphs)
Builder.defineMacro("__STDC_VERSION__", "199409L");
} else {
// -- __cplusplus
- if (LangOpts.CPlusPlus26)
- // FIXME: Use correct value for C++26.
- Builder.defineMacro("__cplusplus", "202400L");
- else if (LangOpts.CPlusPlus23)
- Builder.defineMacro("__cplusplus", "202302L");
- // [C++20] The integer literal 202002L.
- else if (LangOpts.CPlusPlus20)
- Builder.defineMacro("__cplusplus", "202002L");
- // [C++17] The integer literal 201703L.
- else if (LangOpts.CPlusPlus17)
- Builder.defineMacro("__cplusplus", "201703L");
- // [C++14] The name __cplusplus is defined to the value 201402L when
- // compiling a C++ translation unit.
- else if (LangOpts.CPlusPlus14)
- Builder.defineMacro("__cplusplus", "201402L");
- // [C++11] The name __cplusplus is defined to the value 201103L when
- // compiling a C++ translation unit.
- else if (LangOpts.CPlusPlus11)
- Builder.defineMacro("__cplusplus", "201103L");
- // [C++03] The name __cplusplus is defined to the value 199711L when
- // compiling a C++ translation unit.
- else
- Builder.defineMacro("__cplusplus", "199711L");
+ Builder.defineMacro("__cplusplus",
+ Twine(*LangOpts.GetCPlusPlusLangStd()) + "L");
// -- __STDCPP_DEFAULT_NEW_ALIGNMENT__
// [C++17] An integer literal of type std::size_t whose value is the
diff --git a/clang/unittests/Basic/CMakeLists.txt b/clang/unittests/Basic/CMakeLists.txt
index 8c8baa57b64e7..f20c8db00a595 100644
--- a/clang/unittests/Basic/CMakeLists.txt
+++ b/clang/unittests/Basic/CMakeLists.txt
@@ -6,6 +6,7 @@ add_distinct_clang_unittest(BasicTests
DiagnosticTest.cpp
FileEntryTest.cpp
FileManagerTest.cpp
+ LangOptionsTest.cpp
LineOffsetMappingTest.cpp
OffloadArchTest.cpp
SanitizersTest.cpp
>From 1c64d14e7b418c1b039b3b8a5a554cfccf63d6a3 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 14 Oct 2025 11:51:08 +0100
Subject: [PATCH 2/5] fixup! add test file
---
clang/unittests/Basic/LangOptionsTest.cpp | 55 +++++++++++++++++++++++
1 file changed, 55 insertions(+)
create mode 100644 clang/unittests/Basic/LangOptionsTest.cpp
diff --git a/clang/unittests/Basic/LangOptionsTest.cpp b/clang/unittests/Basic/LangOptionsTest.cpp
new file mode 100644
index 0000000000000..37ba4f19aa4bd
--- /dev/null
+++ b/clang/unittests/Basic/LangOptionsTest.cpp
@@ -0,0 +1,55 @@
+//===- unittests/Basic/LangOptionsTest.cpp --------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/LangOptions.h"
+#include "clang/Testing/CommandLineArgs.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+TEST(LangOptsTest, CStdLang) {
+ LangOptions opts;
+ EXPECT_FALSE(opts.GetCLangStd());
+ opts.C99 = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_99);
+ opts.C11 = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_11);
+ opts.C17 = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_17);
+ opts.C23 = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_23);
+ opts.C2y = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_2y);
+
+ EXPECT_FALSE(opts.GetCPlusPlusLangStd());
+}
+
+TEST(LangOptsTest, CppStdLang) {
+ LangOptions opts;
+ EXPECT_FALSE(opts.GetCPlusPlusLangStd());
+ opts.CPlusPlus = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_03);
+ opts.CPlusPlus11 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_11);
+ opts.CPlusPlus14 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_14);
+ opts.CPlusPlus17 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_17);
+ opts.CPlusPlus20 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_20);
+ opts.CPlusPlus23 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_23);
+ opts.CPlusPlus26 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_26);
+
+ EXPECT_FALSE(opts.GetCLangStd());
+}
+}
>From 79150a3781592adc2b56c3082752f96af671730c Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 14 Oct 2025 11:51:21 +0100
Subject: [PATCH 3/5] fixup! clang-format
---
clang/unittests/Basic/LangOptionsTest.cpp | 69 +++++++++++++----------
1 file changed, 38 insertions(+), 31 deletions(-)
diff --git a/clang/unittests/Basic/LangOptionsTest.cpp b/clang/unittests/Basic/LangOptionsTest.cpp
index 37ba4f19aa4bd..5abb2cd8498e6 100644
--- a/clang/unittests/Basic/LangOptionsTest.cpp
+++ b/clang/unittests/Basic/LangOptionsTest.cpp
@@ -16,40 +16,47 @@ using namespace clang;
namespace {
TEST(LangOptsTest, CStdLang) {
- LangOptions opts;
- EXPECT_FALSE(opts.GetCLangStd());
- opts.C99 = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_99);
- opts.C11 = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_11);
- opts.C17 = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_17);
- opts.C23 = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_23);
- opts.C2y = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_2y);
+ LangOptions opts;
+ EXPECT_FALSE(opts.GetCLangStd());
+ opts.C99 = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_99);
+ opts.C11 = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_11);
+ opts.C17 = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_17);
+ opts.C23 = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_23);
+ opts.C2y = 1;
+ EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_2y);
- EXPECT_FALSE(opts.GetCPlusPlusLangStd());
+ EXPECT_FALSE(opts.GetCPlusPlusLangStd());
}
TEST(LangOptsTest, CppStdLang) {
- LangOptions opts;
- EXPECT_FALSE(opts.GetCPlusPlusLangStd());
- opts.CPlusPlus = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_03);
- opts.CPlusPlus11 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_11);
- opts.CPlusPlus14 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_14);
- opts.CPlusPlus17 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_17);
- opts.CPlusPlus20 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_20);
- opts.CPlusPlus23 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_23);
- opts.CPlusPlus26 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(), clang::LangOptionsBase::CPlusPlusLangStd::CPP_26);
+ LangOptions opts;
+ EXPECT_FALSE(opts.GetCPlusPlusLangStd());
+ opts.CPlusPlus = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ clang::LangOptionsBase::CPlusPlusLangStd::CPP_03);
+ opts.CPlusPlus11 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ clang::LangOptionsBase::CPlusPlusLangStd::CPP_11);
+ opts.CPlusPlus14 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ clang::LangOptionsBase::CPlusPlusLangStd::CPP_14);
+ opts.CPlusPlus17 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ clang::LangOptionsBase::CPlusPlusLangStd::CPP_17);
+ opts.CPlusPlus20 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ clang::LangOptionsBase::CPlusPlusLangStd::CPP_20);
+ opts.CPlusPlus23 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ clang::LangOptionsBase::CPlusPlusLangStd::CPP_23);
+ opts.CPlusPlus26 = 1;
+ EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ clang::LangOptionsBase::CPlusPlusLangStd::CPP_26);
- EXPECT_FALSE(opts.GetCLangStd());
-}
+ EXPECT_FALSE(opts.GetCLangStd());
}
+} // namespace
>From ab03eae2db6c0fa83ccbbfd3eb727bc93d746895 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Tue, 14 Oct 2025 12:15:17 +0100
Subject: [PATCH 4/5] fixup! lower-case function names
---
clang/include/clang/Basic/LangOptions.h | 4 +--
clang/lib/Basic/LangOptions.cpp | 4 +--
clang/lib/Frontend/InitPreprocessor.cpp | 4 +--
clang/unittests/Basic/LangOptionsTest.cpp | 32 +++++++++++------------
4 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 940e79634ccd5..e4d08b599f6be 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -781,12 +781,12 @@ class LangOptions : public LangOptionsBase {
/// Returns the most applicable C standard-compliant language version code.
/// If none could be determined, returns \ref std::nullopt.
- std::optional<CLangStd> GetCLangStd() const;
+ std::optional<CLangStd> getCLangStd() const;
/// Returns the most applicable C++ standard-compliant language
/// version code.
/// If none could be determined, returns \ref std::nullopt.
- std::optional<CPlusPlusLangStd> GetCPlusPlusLangStd() const;
+ std::optional<CPlusPlusLangStd> getCPlusPlusLangStd() const;
};
/// Floating point control options
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index 6745427e2c223..0961004f93d4b 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -245,7 +245,7 @@ LLVM_DUMP_METHOD void FPOptionsOverride::dump() {
}
std::optional<clang::LangOptionsBase::CPlusPlusLangStd>
-LangOptions::GetCPlusPlusLangStd() const {
+LangOptions::getCPlusPlusLangStd() const {
if (!CPlusPlus)
return std::nullopt;
@@ -271,7 +271,7 @@ LangOptions::GetCPlusPlusLangStd() const {
}
std::optional<clang::LangOptionsBase::CLangStd>
-LangOptions::GetCLangStd() const {
+LangOptions::getCLangStd() const {
if (C2y)
return clang::LangOptionsBase::C_2y;
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 27bc4cf7108cc..762e17b0f88a0 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -459,14 +459,14 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
// value is, are implementation-defined.
// (Removed in C++20.)
if (!LangOpts.CPlusPlus) {
- if (auto LangStd = LangOpts.GetCLangStd())
+ if (auto LangStd = LangOpts.getCLangStd())
Builder.defineMacro("__STDC_VERSION__", Twine(*LangStd) + "L");
else if (!LangOpts.GNUMode && LangOpts.Digraphs)
Builder.defineMacro("__STDC_VERSION__", "199409L");
} else {
// -- __cplusplus
Builder.defineMacro("__cplusplus",
- Twine(*LangOpts.GetCPlusPlusLangStd()) + "L");
+ Twine(*LangOpts.getCPlusPlusLangStd()) + "L");
// -- __STDCPP_DEFAULT_NEW_ALIGNMENT__
// [C++17] An integer literal of type std::size_t whose value is the
diff --git a/clang/unittests/Basic/LangOptionsTest.cpp b/clang/unittests/Basic/LangOptionsTest.cpp
index 5abb2cd8498e6..393f0ee106705 100644
--- a/clang/unittests/Basic/LangOptionsTest.cpp
+++ b/clang/unittests/Basic/LangOptionsTest.cpp
@@ -17,46 +17,46 @@ using namespace clang;
namespace {
TEST(LangOptsTest, CStdLang) {
LangOptions opts;
- EXPECT_FALSE(opts.GetCLangStd());
+ EXPECT_FALSE(opts.getCLangStd());
opts.C99 = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_99);
+ EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_99);
opts.C11 = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_11);
+ EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_11);
opts.C17 = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_17);
+ EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_17);
opts.C23 = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_23);
+ EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_23);
opts.C2y = 1;
- EXPECT_EQ(opts.GetCLangStd(), clang::LangOptionsBase::CLangStd::C_2y);
+ EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_2y);
- EXPECT_FALSE(opts.GetCPlusPlusLangStd());
+ EXPECT_FALSE(opts.getCPlusPlusLangStd());
}
TEST(LangOptsTest, CppStdLang) {
LangOptions opts;
- EXPECT_FALSE(opts.GetCPlusPlusLangStd());
+ EXPECT_FALSE(opts.getCPlusPlusLangStd());
opts.CPlusPlus = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ EXPECT_EQ(opts.getCPlusPlusLangStd(),
clang::LangOptionsBase::CPlusPlusLangStd::CPP_03);
opts.CPlusPlus11 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ EXPECT_EQ(opts.getCPlusPlusLangStd(),
clang::LangOptionsBase::CPlusPlusLangStd::CPP_11);
opts.CPlusPlus14 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ EXPECT_EQ(opts.getCPlusPlusLangStd(),
clang::LangOptionsBase::CPlusPlusLangStd::CPP_14);
opts.CPlusPlus17 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ EXPECT_EQ(opts.getCPlusPlusLangStd(),
clang::LangOptionsBase::CPlusPlusLangStd::CPP_17);
opts.CPlusPlus20 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ EXPECT_EQ(opts.getCPlusPlusLangStd(),
clang::LangOptionsBase::CPlusPlusLangStd::CPP_20);
opts.CPlusPlus23 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ EXPECT_EQ(opts.getCPlusPlusLangStd(),
clang::LangOptionsBase::CPlusPlusLangStd::CPP_23);
opts.CPlusPlus26 = 1;
- EXPECT_EQ(opts.GetCPlusPlusLangStd(),
+ EXPECT_EQ(opts.getCPlusPlusLangStd(),
clang::LangOptionsBase::CPlusPlusLangStd::CPP_26);
- EXPECT_FALSE(opts.GetCLangStd());
+ EXPECT_FALSE(opts.getCLangStd());
}
} // namespace
>From bde7c0170fc4529cc12d425e40b6f1440d39ce83 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 15 Oct 2025 09:57:54 +0100
Subject: [PATCH 5/5] fixup! use LangStandard to defined version codes
---
clang/include/clang/Basic/LangOptions.h | 26 +-----
clang/include/clang/Basic/LangStandard.h | 7 +-
clang/include/clang/Basic/LangStandards.def | 90 +++++++++++----------
clang/include/clang/Driver/Options.td | 9 ++-
clang/lib/Basic/LangOptions.cpp | 70 ++++++++--------
clang/lib/Basic/LangStandards.cpp | 13 +--
clang/lib/Frontend/CompilerInvocation.cpp | 4 +-
clang/lib/Frontend/InitPreprocessor.cpp | 6 +-
clang/unittests/Basic/LangOptionsTest.cpp | 36 ++++-----
9 files changed, 120 insertions(+), 141 deletions(-)
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index e4d08b599f6be..260a7537edb9d 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -184,28 +184,6 @@ class LangOptionsBase {
HLSL_202y = 2029,
};
- /// C language version codes as defined by the standard.
- enum CLangStd : uint32_t {
- // FIXME: Use correct value for C2y.
- C_2y = 202400,
- C_23 = 202311,
- C_17 = 201710,
- C_11 = 201112,
- C_99 = 199901,
- };
-
- /// C++ language version codes as defined by the standard.
- enum CPlusPlusLangStd : uint32_t {
- // FIXME: Use correct value for C++26.
- CPP_26 = 202400,
- CPP_23 = 202302,
- CPP_20 = 202002,
- CPP_17 = 201703,
- CPP_14 = 201402,
- CPP_11 = 201103,
- CPP_03 = 199711,
- };
-
/// Clang versions with different platform ABI conformance.
enum class ClangABI {
#define ABI_VER_MAJOR_MINOR(Major, Minor) Ver##Major##_##Minor,
@@ -781,12 +759,12 @@ class LangOptions : public LangOptionsBase {
/// Returns the most applicable C standard-compliant language version code.
/// If none could be determined, returns \ref std::nullopt.
- std::optional<CLangStd> getCLangStd() const;
+ std::optional<uint32_t> getCLangStd() const;
/// Returns the most applicable C++ standard-compliant language
/// version code.
/// If none could be determined, returns \ref std::nullopt.
- std::optional<CPlusPlusLangStd> getCPlusPlusLangStd() const;
+ std::optional<uint32_t> getCPlusPlusLangStd() const;
};
/// Floating point control options
diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h
index 49412232c9c5e..64645fee933a5 100644
--- a/clang/include/clang/Basic/LangStandard.h
+++ b/clang/include/clang/Basic/LangStandard.h
@@ -70,8 +70,7 @@ enum LangFeatures {
/// standard.
struct LangStandard {
enum Kind {
-#define LANGSTANDARD(id, name, lang, desc, features) \
- lang_##id,
+#define LANGSTANDARD(id, name, lang, desc, features, version) lang_##id,
#include "clang/Basic/LangStandards.def"
lang_unspecified
};
@@ -80,6 +79,7 @@ struct LangStandard {
const char *Description;
unsigned Flags;
clang::Language Language;
+ std::optional<uint32_t> Version;
public:
/// getName - Get the name of this standard.
@@ -91,6 +91,9 @@ struct LangStandard {
/// Get the language that this standard describes.
clang::Language getLanguage() const { return Language; }
+ /// Get the version code for this language standard.
+ std::optional<uint32_t> getVersion() const { return Version; }
+
/// Language supports '//' comments.
bool hasLineComments() const { return Flags & LineComment; }
diff --git a/clang/include/clang/Basic/LangStandards.def b/clang/include/clang/Basic/LangStandards.def
index 244692ab4296a..4edc93503cdf5 100644
--- a/clang/include/clang/Basic/LangStandards.def
+++ b/clang/include/clang/Basic/LangStandards.def
@@ -10,7 +10,7 @@
#error "LANGSTANDARD must be defined before including this file"
#endif
-/// LANGSTANDARD(IDENT, NAME, LANG, DESC, FEATURES)
+/// LANGSTANDARD(IDENT, NAME, LANG, DESC, FEATURES, VERSION)
///
/// \param IDENT - The name of the standard as a C++ identifier.
/// \param NAME - The name of the standard.
@@ -18,6 +18,8 @@
/// \param DESC - A short description of the standard.
/// \param FEATURES - The standard features as flags, these are enums from the
/// clang::frontend namespace, which is assumed to be available.
+/// \param VERSION - The official version code for this standard.
+/// Has value 'std::nullopt' if no official version exists.
/// LANGSTANDARD_ALIAS(IDENT, ALIAS)
/// \param IDENT - The name of the standard as a C++ identifier.
@@ -36,186 +38,188 @@
// C89-ish modes.
LANGSTANDARD(c89, "c89",
- C, "ISO C 1990", 0)
+ C, "ISO C 1990", 0, std::nullopt)
LANGSTANDARD_ALIAS(c89, "c90")
LANGSTANDARD_ALIAS(c89, "iso9899:1990")
LANGSTANDARD(c94, "iso9899:199409",
C, "ISO C 1990 with amendment 1",
- Digraphs)
+ Digraphs, 199409)
LANGSTANDARD(gnu89, "gnu89",
C, "ISO C 1990 with GNU extensions",
- LineComment | Digraphs | GNUMode)
+ LineComment | Digraphs | GNUMode, std::nullopt)
LANGSTANDARD_ALIAS(gnu89, "gnu90")
// C99-ish modes
LANGSTANDARD(c99, "c99",
C, "ISO C 1999",
- LineComment | C99 | Digraphs | HexFloat)
+ LineComment | C99 | Digraphs | HexFloat, 199901)
LANGSTANDARD_ALIAS(c99, "iso9899:1999")
LANGSTANDARD_ALIAS_DEPR(c99, "c9x")
LANGSTANDARD_ALIAS_DEPR(c99, "iso9899:199x")
LANGSTANDARD(gnu99, "gnu99",
C, "ISO C 1999 with GNU extensions",
- LineComment | C99 | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | Digraphs | GNUMode | HexFloat, 199901)
LANGSTANDARD_ALIAS_DEPR(gnu99, "gnu9x")
// C11 modes
LANGSTANDARD(c11, "c11",
C, "ISO C 2011",
- LineComment | C99 | C11 | Digraphs | HexFloat)
+ LineComment | C99 | C11 | Digraphs | HexFloat, 201112)
LANGSTANDARD_ALIAS(c11, "iso9899:2011")
LANGSTANDARD_ALIAS_DEPR(c11, "c1x")
LANGSTANDARD_ALIAS_DEPR(c11, "iso9899:201x")
LANGSTANDARD(gnu11, "gnu11",
C, "ISO C 2011 with GNU extensions",
- LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat, 201112)
LANGSTANDARD_ALIAS_DEPR(gnu11, "gnu1x")
// C17 modes
LANGSTANDARD(c17, "c17",
C, "ISO C 2017",
- LineComment | C99 | C11 | C17 | Digraphs | HexFloat)
+ LineComment | C99 | C11 | C17 | Digraphs | HexFloat, 201710)
LANGSTANDARD_ALIAS(c17, "iso9899:2017")
LANGSTANDARD_ALIAS(c17, "c18")
LANGSTANDARD_ALIAS(c17, "iso9899:2018")
LANGSTANDARD(gnu17, "gnu17",
C, "ISO C 2017 with GNU extensions",
- LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | C11 | C17 | Digraphs | GNUMode | HexFloat, 201710)
LANGSTANDARD_ALIAS(gnu17, "gnu18")
// C23 modes
LANGSTANDARD(c23, "c23",
C, "ISO C 2023",
- LineComment | C99 | C11 | C17 | C23 | Digraphs | HexFloat)
+ LineComment | C99 | C11 | C17 | C23 | Digraphs | HexFloat, 202311)
LANGSTANDARD_ALIAS(c23, "iso9899:2024")
LANGSTANDARD_ALIAS_DEPR(c23, "c2x")
LANGSTANDARD(gnu23, "gnu23",
C, "ISO C 2023 with GNU extensions",
- LineComment | C99 | C11 | C17 | C23 | Digraphs | GNUMode | HexFloat)
+ LineComment | C99 | C11 | C17 | C23 | Digraphs | GNUMode | HexFloat, 202311)
LANGSTANDARD_ALIAS_DEPR(gnu23, "gnu2x")
// C2y modes
+// FIXME: Use correct version code for C2y once published.
LANGSTANDARD(c2y, "c2y",
C, "Working Draft for ISO C2y",
- LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | HexFloat)
+ 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)
+ LineComment | C99 | C11 | C17 | C23 | C2y | Digraphs | GNUMode | HexFloat, 202400)
// TODO: Add the iso9899:202y alias once ISO publishes the standard.
// C++ modes
LANGSTANDARD(cxx98, "c++98",
CXX, "ISO C++ 1998 with amendments",
- LineComment | CPlusPlus | Digraphs)
+ LineComment | CPlusPlus | Digraphs, 199711)
LANGSTANDARD_ALIAS(cxx98, "c++03")
LANGSTANDARD(gnucxx98, "gnu++98",
CXX, "ISO C++ 1998 with amendments and GNU extensions",
- LineComment | CPlusPlus | Digraphs | GNUMode)
+ LineComment | CPlusPlus | Digraphs | GNUMode, 199711)
LANGSTANDARD_ALIAS(gnucxx98, "gnu++03")
LANGSTANDARD(cxx11, "c++11",
CXX, "ISO C++ 2011 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | Digraphs)
+ LineComment | CPlusPlus | CPlusPlus11 | Digraphs, 201103)
LANGSTANDARD_ALIAS_DEPR(cxx11, "c++0x")
LANGSTANDARD(gnucxx11, "gnu++11", CXX,
"ISO C++ 2011 with amendments and GNU extensions",
- LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode)
+ LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode, 201103)
LANGSTANDARD_ALIAS_DEPR(gnucxx11, "gnu++0x")
LANGSTANDARD(cxx14, "c++14",
CXX, "ISO C++ 2014 with amendments",
- LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs)
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs, 201402)
LANGSTANDARD_ALIAS_DEPR(cxx14, "c++1y")
LANGSTANDARD(gnucxx14, "gnu++14",
CXX, "ISO C++ 2014 with amendments and GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs |
- GNUMode)
+ GNUMode, 201402)
LANGSTANDARD_ALIAS_DEPR(gnucxx14, "gnu++1y")
LANGSTANDARD(cxx17, "c++17",
CXX, "ISO C++ 2017 with amendments",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- Digraphs | HexFloat)
+ Digraphs | HexFloat, 201703)
LANGSTANDARD_ALIAS_DEPR(cxx17, "c++1z")
LANGSTANDARD(gnucxx17, "gnu++17",
CXX, "ISO C++ 2017 with amendments and GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- Digraphs | HexFloat | GNUMode)
+ Digraphs | HexFloat | GNUMode, 201703)
LANGSTANDARD_ALIAS_DEPR(gnucxx17, "gnu++1z")
LANGSTANDARD(cxx20, "c++20",
CXX, "ISO C++ 2020 DIS",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | Digraphs | HexFloat)
+ CPlusPlus20 | Digraphs | HexFloat, 202002)
LANGSTANDARD_ALIAS_DEPR(cxx20, "c++2a")
LANGSTANDARD(gnucxx20, "gnu++20",
CXX, "ISO C++ 2020 DIS with GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | Digraphs | HexFloat | GNUMode)
+ CPlusPlus20 | Digraphs | HexFloat | GNUMode, 202002)
LANGSTANDARD_ALIAS_DEPR(gnucxx20, "gnu++2a")
LANGSTANDARD(cxx23, "c++23",
CXX, "ISO C++ 2023 DIS",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat)
+ CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat, 202302)
LANGSTANDARD_ALIAS_DEPR(cxx23, "c++2b")
LANGSTANDARD(gnucxx23, "gnu++23",
CXX, "ISO C++ 2023 DIS with GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat | GNUMode)
+ CPlusPlus20 | CPlusPlus23 | Digraphs | HexFloat | GNUMode, 202302)
LANGSTANDARD_ALIAS_DEPR(gnucxx23, "gnu++2b")
+// FIXME: Use correct version code for C++26 once published.
LANGSTANDARD(cxx26, "c++2c",
CXX, "Working draft for C++2c",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat)
+ CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat, 202400)
LANGSTANDARD_ALIAS(cxx26, "c++26")
LANGSTANDARD(gnucxx26, "gnu++2c",
CXX, "Working draft for C++2c with GNU extensions",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat | GNUMode)
+ CPlusPlus20 | CPlusPlus23 | CPlusPlus26 | Digraphs | HexFloat | GNUMode, 202400)
LANGSTANDARD_ALIAS(gnucxx26, "gnu++26")
// OpenCL
LANGSTANDARD(opencl10, "cl1.0",
OpenCL, "OpenCL 1.0",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD_ALIAS_DEPR(opencl10, "cl")
LANGSTANDARD(opencl11, "cl1.1",
OpenCL, "OpenCL 1.1",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD(opencl12, "cl1.2",
OpenCL, "OpenCL 1.2",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD(opencl20, "cl2.0",
OpenCL, "OpenCL 2.0",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD(opencl30, "cl3.0",
OpenCL, "OpenCL 3.0",
- LineComment | C99 | Digraphs | HexFloat | OpenCL)
+ LineComment | C99 | Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD(openclcpp10, "clc++1.0",
OpenCL, "C++ for OpenCL 1.0",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- Digraphs | HexFloat | OpenCL)
+ Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD_ALIAS(openclcpp10, "clc++")
LANGSTANDARD(openclcpp2021, "clc++2021",
OpenCL, "C++ for OpenCL 2021",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 |
- Digraphs | HexFloat | OpenCL)
+ Digraphs | HexFloat | OpenCL, std::nullopt)
LANGSTANDARD_ALIAS_DEPR(opencl10, "CL")
LANGSTANDARD_ALIAS_DEPR(opencl11, "CL1.1")
@@ -229,35 +233,35 @@ LANGSTANDARD_ALIAS_DEPR(openclcpp2021, "CLC++2021")
// HLSL
LANGSTANDARD(hlsl, "hlsl",
HLSL, "High Level Shader Language",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2015, "hlsl2015",
HLSL, "High Level Shader Language 2015",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2016, "hlsl2016",
HLSL, "High Level Shader Language 2016",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2017, "hlsl2017",
HLSL, "High Level Shader Language 2017",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2018, "hlsl2018",
HLSL, "High Level Shader Language 2018",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl2021, "hlsl2021",
HLSL, "High Level Shader Language 2021",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl202x, "hlsl202x",
HLSL, "High Level Shader Language 202x",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
LANGSTANDARD(hlsl202y, "hlsl202y",
HLSL, "High Level Shader Language 202y",
- LineComment | HLSL | CPlusPlus | CPlusPlus11)
+ LineComment | HLSL | CPlusPlus | CPlusPlus11, std::nullopt)
#undef LANGSTANDARD
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index a55a5236b2da1..6a47e9ff90fe8 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6211,11 +6211,12 @@ def static : Flag<["-", "--"], "static">, Group<Link_Group>,
Flags<[NoArgumentUnused]>;
def std_default_EQ : Joined<["-"], "std-default=">;
def std_EQ : Joined<["-", "--"], "std=">,
- Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
- Group<CompileOnly_Group>, HelpText<"Language standard to compile for">,
- ValuesCode<[{
+ Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+ Group<CompileOnly_Group>,
+ HelpText<"Language standard to compile for">,
+ ValuesCode<[{
static constexpr const char VALUES_CODE [] =
- #define LANGSTANDARD(id, name, lang, desc, features) name ","
+ #define LANGSTANDARD(id, name, lang, desc, features, version) name ","
#define LANGSTANDARD_ALIAS(id, alias) alias ","
#include "clang/Basic/LangStandards.def"
;
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index 0961004f93d4b..641a3dba0e67a 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/LangStandard.h"
#include "llvm/Support/Path.h"
using namespace clang;
@@ -244,48 +245,45 @@ LLVM_DUMP_METHOD void FPOptionsOverride::dump() {
llvm::errs() << "\n";
}
-std::optional<clang::LangOptionsBase::CPlusPlusLangStd>
-LangOptions::getCPlusPlusLangStd() const {
+std::optional<uint32_t> LangOptions::getCPlusPlusLangStd() const {
if (!CPlusPlus)
return std::nullopt;
+ LangStandard::Kind Std;
if (CPlusPlus26)
- return clang::LangOptionsBase::CPP_26;
-
- if (CPlusPlus23)
- return clang::LangOptionsBase::CPP_23;
-
- if (CPlusPlus20)
- return clang::LangOptionsBase::CPP_20;
-
- if (CPlusPlus17)
- return clang::LangOptionsBase::CPP_17;
-
- if (CPlusPlus14)
- return clang::LangOptionsBase::CPP_14;
-
- if (CPlusPlus11)
- return clang::LangOptionsBase::CPP_11;
-
- return clang::LangOptionsBase::CPP_03;
+ Std = LangStandard::lang_cxx26;
+ else if (CPlusPlus23)
+ Std = LangStandard::lang_cxx23;
+ else if (CPlusPlus20)
+ Std = LangStandard::lang_cxx20;
+ else if (CPlusPlus17)
+ Std = LangStandard::lang_cxx17;
+ else if (CPlusPlus14)
+ Std = LangStandard::lang_cxx14;
+ else if (CPlusPlus11)
+ Std = LangStandard::lang_cxx11;
+ else
+ Std = LangStandard::lang_cxx98;
+
+ return LangStandard::getLangStandardForKind(Std).getVersion();
}
-std::optional<clang::LangOptionsBase::CLangStd>
-LangOptions::getCLangStd() const {
+std::optional<uint32_t> LangOptions::getCLangStd() const {
+ LangStandard::Kind Std;
if (C2y)
- return clang::LangOptionsBase::C_2y;
-
- if (C23)
- return clang::LangOptionsBase::C_23;
-
- if (C17)
- return clang::LangOptionsBase::C_17;
-
- if (C11)
- return clang::LangOptionsBase::C_11;
-
- if (C99)
- return clang::LangOptionsBase::C_99;
+ Std = LangStandard::lang_c2y;
+ else if (C23)
+ Std = LangStandard::lang_c23;
+ else if (C17)
+ Std = LangStandard::lang_c17;
+ else if (C11)
+ Std = LangStandard::lang_c11;
+ else if (C99)
+ Std = LangStandard::lang_c99;
+ else if (!GNUMode && Digraphs)
+ Std = LangStandard::lang_c94;
+ else
+ return std::nullopt;
- return std::nullopt;
+ return LangStandard::getLangStandardForKind(Std).getVersion();
}
diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp
index c49d095018b20..01c524b7220fb 100644
--- a/clang/lib/Basic/LangStandards.cpp
+++ b/clang/lib/Basic/LangStandards.cpp
@@ -46,16 +46,18 @@ StringRef clang::languageToString(Language L) {
llvm_unreachable("unhandled language kind");
}
-#define LANGSTANDARD(id, name, lang, desc, features) \
- static const LangStandard Lang_##id = {name, desc, features, Language::lang};
+#define LANGSTANDARD(id, name, lang, desc, features, version) \
+ static const LangStandard Lang_##id = {name, desc, features, Language::lang, \
+ version};
#include "clang/Basic/LangStandards.def"
const LangStandard &LangStandard::getLangStandardForKind(Kind K) {
switch (K) {
case lang_unspecified:
llvm::report_fatal_error("getLangStandardForKind() on unspecified kind");
-#define LANGSTANDARD(id, name, lang, desc, features) \
- case lang_##id: return Lang_##id;
+#define LANGSTANDARD(id, name, lang, desc, features, version) \
+ case lang_##id: \
+ return Lang_##id;
#include "clang/Basic/LangStandards.def"
}
llvm_unreachable("Invalid language kind!");
@@ -63,7 +65,8 @@ const LangStandard &LangStandard::getLangStandardForKind(Kind K) {
LangStandard::Kind LangStandard::getLangKind(StringRef Name) {
return llvm::StringSwitch<Kind>(Name)
-#define LANGSTANDARD(id, name, lang, desc, features) .Case(name, lang_##id)
+#define LANGSTANDARD(id, name, lang, desc, features, version) \
+ .Case(name, lang_##id)
#define LANGSTANDARD_ALIAS(id, alias) .Case(alias, lang_##id)
#include "clang/Basic/LangStandards.def"
.Default(lang_unspecified);
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 292adce8180bc..5bd15f5d4ca31 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4012,13 +4012,13 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
auto Diag = Diags.Report(diag::note_drv_use_standard);
Diag << Std.getName() << Std.getDescription();
unsigned NumAliases = 0;
-#define LANGSTANDARD(id, name, lang, desc, features)
+#define LANGSTANDARD(id, name, lang, desc, features, version)
#define LANGSTANDARD_ALIAS(id, alias) \
if (KindValue == LangStandard::lang_##id) ++NumAliases;
#define LANGSTANDARD_ALIAS_DEPR(id, alias)
#include "clang/Basic/LangStandards.def"
Diag << NumAliases;
-#define LANGSTANDARD(id, name, lang, desc, features)
+#define LANGSTANDARD(id, name, lang, desc, features, version)
#define LANGSTANDARD_ALIAS(id, alias) \
if (KindValue == LangStandard::lang_##id) Diag << alias;
#define LANGSTANDARD_ALIAS_DEPR(id, alias)
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 762e17b0f88a0..63da549da6a49 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -459,10 +459,8 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
// value is, are implementation-defined.
// (Removed in C++20.)
if (!LangOpts.CPlusPlus) {
- if (auto LangStd = LangOpts.getCLangStd())
- Builder.defineMacro("__STDC_VERSION__", Twine(*LangStd) + "L");
- else if (!LangOpts.GNUMode && LangOpts.Digraphs)
- Builder.defineMacro("__STDC_VERSION__", "199409L");
+ Builder.defineMacro("__STDC_VERSION__",
+ Twine(*LangOpts.getCLangStd()) + "L");
} else {
// -- __cplusplus
Builder.defineMacro("__cplusplus",
diff --git a/clang/unittests/Basic/LangOptionsTest.cpp b/clang/unittests/Basic/LangOptionsTest.cpp
index 393f0ee106705..0d7d5ec86b0b8 100644
--- a/clang/unittests/Basic/LangOptionsTest.cpp
+++ b/clang/unittests/Basic/LangOptionsTest.cpp
@@ -7,8 +7,6 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/LangOptions.h"
-#include "clang/Testing/CommandLineArgs.h"
-#include "gmock/gmock.h"
#include "gtest/gtest.h"
using namespace llvm;
@@ -18,16 +16,19 @@ namespace {
TEST(LangOptsTest, CStdLang) {
LangOptions opts;
EXPECT_FALSE(opts.getCLangStd());
+ opts.GNUMode = 0;
+ opts.Digraphs = 1;
+ EXPECT_EQ(opts.getCLangStd(), 199409);
opts.C99 = 1;
- EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_99);
+ EXPECT_EQ(opts.getCLangStd(), 199901);
opts.C11 = 1;
- EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_11);
+ EXPECT_EQ(opts.getCLangStd(), 201112);
opts.C17 = 1;
- EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_17);
+ EXPECT_EQ(opts.getCLangStd(), 201710);
opts.C23 = 1;
- EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_23);
+ EXPECT_EQ(opts.getCLangStd(), 202311);
opts.C2y = 1;
- EXPECT_EQ(opts.getCLangStd(), clang::LangOptionsBase::CLangStd::C_2y);
+ EXPECT_EQ(opts.getCLangStd(), 202400);
EXPECT_FALSE(opts.getCPlusPlusLangStd());
}
@@ -36,26 +37,19 @@ TEST(LangOptsTest, CppStdLang) {
LangOptions opts;
EXPECT_FALSE(opts.getCPlusPlusLangStd());
opts.CPlusPlus = 1;
- EXPECT_EQ(opts.getCPlusPlusLangStd(),
- clang::LangOptionsBase::CPlusPlusLangStd::CPP_03);
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 199711);
opts.CPlusPlus11 = 1;
- EXPECT_EQ(opts.getCPlusPlusLangStd(),
- clang::LangOptionsBase::CPlusPlusLangStd::CPP_11);
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 201103);
opts.CPlusPlus14 = 1;
- EXPECT_EQ(opts.getCPlusPlusLangStd(),
- clang::LangOptionsBase::CPlusPlusLangStd::CPP_14);
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 201402);
opts.CPlusPlus17 = 1;
- EXPECT_EQ(opts.getCPlusPlusLangStd(),
- clang::LangOptionsBase::CPlusPlusLangStd::CPP_17);
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 201703);
opts.CPlusPlus20 = 1;
- EXPECT_EQ(opts.getCPlusPlusLangStd(),
- clang::LangOptionsBase::CPlusPlusLangStd::CPP_20);
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 202002);
opts.CPlusPlus23 = 1;
- EXPECT_EQ(opts.getCPlusPlusLangStd(),
- clang::LangOptionsBase::CPlusPlusLangStd::CPP_23);
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 202302);
opts.CPlusPlus26 = 1;
- EXPECT_EQ(opts.getCPlusPlusLangStd(),
- clang::LangOptionsBase::CPlusPlusLangStd::CPP_26);
+ EXPECT_EQ(opts.getCPlusPlusLangStd(), 202400);
EXPECT_FALSE(opts.getCLangStd());
}
More information about the cfe-commits
mailing list