[lldb] [llvm] [lldb][Language] Make SourceLanguage::GetDescription for language version (PR #162050)

Michael Buch via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 6 02:17:00 PDT 2025


https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/162050

>From d7181bd6005b586150e4cbac68e9cfb40354c682 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 6 Oct 2025 09:37:51 +0100
Subject: [PATCH 1/3] [llvm][Dwarf] Add LanguageDescription API that accounts
 for version

Currently `llvm::dwarf::LanguageDescription` returns a stringified
`DW_LNAME`. It would be useful to have an API that returns the language
name for a particular `DW_LNAME_`/version pair. LLDB's use case is that
it wants to display a human readable description of the language we got
from debug-info in diagnostics. We could maintain a side-table in LLDB
but though this might generally be useful to live next to the
`LanguageDescription` API.

(cherry picked from commit 544d86112320b1512e3ce3aaa11d177f47d5e206)
---
 llvm/include/llvm/BinaryFormat/Dwarf.h |   7 ++
 llvm/lib/BinaryFormat/Dwarf.cpp        | 111 +++++++++++++++++++++++++
 2 files changed, 118 insertions(+)

diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h
index 2c5012510a5c3..624e5f63f2270 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.h
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -500,8 +500,15 @@ toDW_LNAME(SourceLanguage language) {
   return {};
 }
 
+/// Returns a version-independent language name.
 LLVM_ABI llvm::StringRef LanguageDescription(SourceLanguageName name);
 
+/// Returns a language name corresponding to the specified version.
+/// If the version is not recognized for the specified language, returns
+/// the version-independent name.
+LLVM_ABI llvm::StringRef LanguageDescription(SourceLanguageName Name,
+                                             uint32_t Version);
+
 inline bool isCPlusPlus(SourceLanguage S) {
   bool result = false;
   // Deliberately enumerate all the language options so we get a warning when
diff --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp
index 8b24044e19e50..0202dffc3d6b2 100644
--- a/llvm/lib/BinaryFormat/Dwarf.cpp
+++ b/llvm/lib/BinaryFormat/Dwarf.cpp
@@ -472,6 +472,117 @@ StringRef llvm::dwarf::LanguageDescription(dwarf::SourceLanguageName lname) {
   return "Unknown";
 }
 
+StringRef llvm::dwarf::LanguageDescription(dwarf::SourceLanguageName Name,
+                                           uint32_t Version) {
+  switch (Name) {
+  // YYYY
+  case DW_LNAME_Ada: {
+    if (Version <= 1983)
+      return "Ada 83";
+    if (Version <= 1995)
+      return "Ada 95";
+    if (Version <= 2005)
+      return "Ada 2005";
+    if (Version <= 2012)
+      return "Ada 2012";
+  } break;
+
+  case DW_LNAME_Cobol: {
+    if (Version <= 1974)
+      return "COBOL-74";
+    if (Version <= 1985)
+      return "COBOL-85";
+  } break;
+
+  case DW_LNAME_Fortran: {
+    if (Version <= 1977)
+      return "FORTRAN 77";
+    if (Version <= 1990)
+      return "FORTRAN 90";
+    if (Version <= 1995)
+      return "Fortran 95";
+    if (Version <= 2003)
+      return "Fortran 2003";
+    if (Version <= 2008)
+      return "Fortran 2008";
+    if (Version <= 2018)
+      return "Fortran 2018";
+  } break;
+
+  // YYYYMM
+  case DW_LNAME_C: {
+    if (Version == 0)
+      break;
+    if (Version <= 198912)
+      return "C89";
+    if (Version <= 199901)
+      return "C99";
+    if (Version <= 201112)
+      return "C11";
+    if (Version <= 201710)
+      return "C17";
+  } break;
+
+  case DW_LNAME_C_plus_plus: {
+    if (Version == 0)
+      break;
+    if (Version <= 199711)
+      return "C++98";
+    if (Version <= 200310)
+      return "C++03";
+    if (Version <= 201103)
+      return "C++11";
+    if (Version <= 201402)
+      return "C++14";
+    if (Version <= 201703)
+      return "C++17";
+    if (Version <= 202002)
+      return "C++20";
+  } break;
+
+  case DW_LNAME_ObjC_plus_plus:
+  case DW_LNAME_ObjC:
+  case DW_LNAME_Move:
+  case DW_LNAME_SYCL:
+  case DW_LNAME_BLISS:
+  case DW_LNAME_Crystal:
+  case DW_LNAME_D:
+  case DW_LNAME_Dylan:
+  case DW_LNAME_Go:
+  case DW_LNAME_Haskell:
+  case DW_LNAME_HLSL:
+  case DW_LNAME_Java:
+  case DW_LNAME_Julia:
+  case DW_LNAME_Kotlin:
+  case DW_LNAME_Modula2:
+  case DW_LNAME_Modula3:
+  case DW_LNAME_OCaml:
+  case DW_LNAME_OpenCL_C:
+  case DW_LNAME_Pascal:
+  case DW_LNAME_PLI:
+  case DW_LNAME_Python:
+  case DW_LNAME_RenderScript:
+  case DW_LNAME_Rust:
+  case DW_LNAME_Swift:
+  case DW_LNAME_UPC:
+  case DW_LNAME_Zig:
+  case DW_LNAME_Assembly:
+  case DW_LNAME_C_sharp:
+  case DW_LNAME_Mojo:
+  case DW_LNAME_GLSL:
+  case DW_LNAME_GLSL_ES:
+  case DW_LNAME_OpenCL_CPP:
+  case DW_LNAME_CPP_for_OpenCL:
+  case DW_LNAME_Ruby:
+  case DW_LNAME_Hylo:
+  case DW_LNAME_Metal:
+    break;
+  }
+
+  // Fallback to un-versioned name.
+  return LanguageDescription(Name);
+}
+
 StringRef llvm::dwarf::CaseString(unsigned Case) {
   switch (Case) {
   case DW_ID_case_sensitive:

>From 2770852fad27a5a756d5f31a6d32a80e564c9b9d Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 6 Oct 2025 09:48:28 +0100
Subject: [PATCH 2/3] [lldb][Language] Make SourceLanguage::GetDescription for
 language version

This makes sure we also include the version number in the description.

For `C++17`, this would, e.g., now return `"C++17"` instead of `"ISO C++"`.
---
 lldb/source/Target/Language.cpp        | 2 +-
 lldb/unittests/Target/LanguageTest.cpp | 9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp
index 395718ecbe292..9119f8989ed98 100644
--- a/lldb/source/Target/Language.cpp
+++ b/lldb/source/Target/Language.cpp
@@ -582,7 +582,7 @@ lldb::LanguageType SourceLanguage::AsLanguageType() const {
 
 llvm::StringRef SourceLanguage::GetDescription() const {
   return llvm::dwarf::LanguageDescription(
-      static_cast<llvm::dwarf::SourceLanguageName>(name));
+      static_cast<llvm::dwarf::SourceLanguageName>(name), version);
 }
 bool SourceLanguage::IsC() const { return name == llvm::dwarf::DW_LNAME_C; }
 
diff --git a/lldb/unittests/Target/LanguageTest.cpp b/lldb/unittests/Target/LanguageTest.cpp
index a00fda78d569a..e9745c9315b72 100644
--- a/lldb/unittests/Target/LanguageTest.cpp
+++ b/lldb/unittests/Target/LanguageTest.cpp
@@ -39,9 +39,14 @@ TEST_F(LanguageTest, SourceLanguage_GetDescription) {
   EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus).GetDescription(),
             "ISO C++");
   EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus_17).GetDescription(),
-            "ISO C++");
+            "C++17");
   EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus_20).GetDescription(),
-            "ISO C++");
+            "C++20");
+
+  EXPECT_EQ(SourceLanguage(eLanguageTypeC).GetDescription(),
+            "C (K&R and ISO)");
+  EXPECT_EQ(SourceLanguage(eLanguageTypeC89).GetDescription(),
+            "C89");
 
   EXPECT_EQ(SourceLanguage(eLanguageTypeObjC).GetDescription(), "Objective C");
   EXPECT_EQ(SourceLanguage(eLanguageTypeMipsAssembler).GetDescription(),

>From 054d91d61e79a771e8ab535b3aa18bf637c9cdcc Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 6 Oct 2025 10:16:48 +0100
Subject: [PATCH 3/3] fixup! clang-format

---
 lldb/unittests/Target/LanguageTest.cpp | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/lldb/unittests/Target/LanguageTest.cpp b/lldb/unittests/Target/LanguageTest.cpp
index e9745c9315b72..e3f24bf7ed1f4 100644
--- a/lldb/unittests/Target/LanguageTest.cpp
+++ b/lldb/unittests/Target/LanguageTest.cpp
@@ -43,10 +43,8 @@ TEST_F(LanguageTest, SourceLanguage_GetDescription) {
   EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus_20).GetDescription(),
             "C++20");
 
-  EXPECT_EQ(SourceLanguage(eLanguageTypeC).GetDescription(),
-            "C (K&R and ISO)");
-  EXPECT_EQ(SourceLanguage(eLanguageTypeC89).GetDescription(),
-            "C89");
+  EXPECT_EQ(SourceLanguage(eLanguageTypeC).GetDescription(), "C (K&R and ISO)");
+  EXPECT_EQ(SourceLanguage(eLanguageTypeC89).GetDescription(), "C89");
 
   EXPECT_EQ(SourceLanguage(eLanguageTypeObjC).GetDescription(), "Objective C");
   EXPECT_EQ(SourceLanguage(eLanguageTypeMipsAssembler).GetDescription(),



More information about the llvm-commits mailing list