[llvm] [llvm][DebugInfo][test] DwarfTest: parameterize LanguageDescription tests (PR #162863)

via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 10 08:00:20 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-debuginfo

Author: Michael Buch (Michael137)

<details>
<summary>Changes</summary>

Better test coverage.

The round-tripping test makes sure that if we ever change `llvm::dwarf::toDW_Lang` or `llvm::dwarf::toDW_LName`, we don't break the `LanguageDescription` API.

The round-tripping test found an incorrect version check in `llvm::dwarf::toDW_Lang`, which I corrected as part of this PR.

---
Full diff: https://github.com/llvm/llvm-project/pull/162863.diff


2 Files Affected:

- (modified) llvm/include/llvm/BinaryFormat/Dwarf.h (+1-1) 
- (modified) llvm/unittests/BinaryFormat/DwarfTest.cpp (+181-36) 


``````````diff
diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h
index 815e85ddd7a92..5039a3fe7ecc7 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.h
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -390,7 +390,7 @@ toDW_LNAME(SourceLanguage language) {
   case DW_LANG_C11:
     return {{DW_LNAME_C, 201112}};
   case DW_LANG_C17:
-    return {{DW_LNAME_C, 201712}};
+    return {{DW_LNAME_C, 201710}};
   case DW_LANG_C_plus_plus:
     return {{DW_LNAME_C_plus_plus, 0}};
   case DW_LANG_C_plus_plus_03:
diff --git a/llvm/unittests/BinaryFormat/DwarfTest.cpp b/llvm/unittests/BinaryFormat/DwarfTest.cpp
index f4519f61adf85..ba7d59182ea53 100644
--- a/llvm/unittests/BinaryFormat/DwarfTest.cpp
+++ b/llvm/unittests/BinaryFormat/DwarfTest.cpp
@@ -255,41 +255,186 @@ TEST(DwarfTest, lname_SourceLanguageNameString) {
 #include "llvm/BinaryFormat/Dwarf.def"
 }
 
-TEST(DWARFDebugInfo, TestLanguageDescription_Versioned) {
-  // Tests for the llvm::dwarf::LanguageDescription API that
-  // takes a name *and* a version.
-
-  // Unknown language.
-  EXPECT_EQ(
-      llvm::dwarf::LanguageDescription(static_cast<SourceLanguageName>(0)),
-      "Unknown");
-
-  EXPECT_EQ(
-      llvm::dwarf::LanguageDescription(static_cast<SourceLanguageName>(0), 0),
-      "Unknown");
-
-  // Test that specifying an invalid version falls back to a valid language name
-  // regardless.
-  EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_ObjC, 0), "Objective C");
-  EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_Julia, 0), "Julia");
-
-  // Check some versions.
-  EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C_plus_plus, 199711),
-            "C++98");
-  EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C_plus_plus, 201402),
-            "C++14");
-
-  // Versions round up.
-  EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C_plus_plus, 201400),
-            "C++14");
-
-  // Version 0 for C and C++ is an unversioned name.
-  EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C, 0), "C (K&R and ISO)");
-  EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_C_plus_plus, 0),
-            "ISO C++");
-
-  // Version 0 for other versioned languages may not be the unversioned name.
-  EXPECT_EQ(llvm::dwarf::LanguageDescription(DW_LNAME_Fortran, 0),
-            "FORTRAN 77");
+struct LanguageDescriptionTestCase {
+  llvm::dwarf::SourceLanguageName LName;
+  uint32_t LVersion;
+  llvm::StringRef ExpectedDescription;
+};
+
+LanguageDescriptionTestCase LanguageDescriptionTestCases[] = {
+    {static_cast<SourceLanguageName>(0), 0, "Unknown"},
+    {static_cast<SourceLanguageName>(0), 1, "Unknown"},
+    {DW_LNAME_Ada, 0, "Ada 83"},
+    {DW_LNAME_Ada, 1982, "Ada 83"},
+    {DW_LNAME_Ada, 1983, "Ada 83"},
+    {DW_LNAME_Ada, 1994, "Ada 95"},
+    {DW_LNAME_Ada, 1995, "Ada 95"},
+    {DW_LNAME_Ada, 2004, "Ada 2005"},
+    {DW_LNAME_Ada, 2005, "Ada 2005"},
+    {DW_LNAME_Ada, 2011, "Ada 2012"},
+    {DW_LNAME_Ada, 2012, "Ada 2012"},
+    {DW_LNAME_Ada, 2013, "ISO Ada"},
+    {DW_LNAME_Cobol, 0, "COBOL-74"},
+    {DW_LNAME_Cobol, 1973, "COBOL-74"},
+    {DW_LNAME_Cobol, 1974, "COBOL-74"},
+    {DW_LNAME_Cobol, 1984, "COBOL-85"},
+    {DW_LNAME_Cobol, 1985, "COBOL-85"},
+    {DW_LNAME_Cobol, 1986, "ISO Cobol"},
+    {DW_LNAME_Fortran, 0, "FORTRAN 77"},
+    {DW_LNAME_Fortran, 1976, "FORTRAN 77"},
+    {DW_LNAME_Fortran, 1977, "FORTRAN 77"},
+    {DW_LNAME_Fortran, 1989, "FORTRAN 90"},
+    {DW_LNAME_Fortran, 1990, "FORTRAN 90"},
+    {DW_LNAME_Fortran, 1994, "Fortran 95"},
+    {DW_LNAME_Fortran, 1995, "Fortran 95"},
+    {DW_LNAME_Fortran, 2002, "Fortran 2003"},
+    {DW_LNAME_Fortran, 2003, "Fortran 2003"},
+    {DW_LNAME_Fortran, 2007, "Fortran 2008"},
+    {DW_LNAME_Fortran, 2008, "Fortran 2008"},
+    {DW_LNAME_Fortran, 2017, "Fortran 2018"},
+    {DW_LNAME_Fortran, 2018, "Fortran 2018"},
+    {DW_LNAME_Fortran, 2019, "ISO Fortran"},
+    {DW_LNAME_C, 0, "C (K&R and ISO)"},
+    {DW_LNAME_C, 198911, "C89"},
+    {DW_LNAME_C, 198912, "C89"},
+    {DW_LNAME_C, 199901, "C99"},
+    {DW_LNAME_C, 199902, "C11"},
+    {DW_LNAME_C, 201111, "C11"},
+    {DW_LNAME_C, 201112, "C11"},
+    {DW_LNAME_C, 201201, "C17"},
+    {DW_LNAME_C, 201709, "C17"},
+    {DW_LNAME_C, 201710, "C17"},
+    {DW_LNAME_C, 201711, "C (K&R and ISO)"},
+    {DW_LNAME_C_plus_plus, 0, "ISO C++"},
+    {DW_LNAME_C_plus_plus, 199710, "C++98"},
+    {DW_LNAME_C_plus_plus, 199711, "C++98"},
+    {DW_LNAME_C_plus_plus, 199712, "C++03"},
+    {DW_LNAME_C_plus_plus, 200310, "C++03"},
+    {DW_LNAME_C_plus_plus, 200311, "C++11"},
+    {DW_LNAME_C_plus_plus, 201102, "C++11"},
+    {DW_LNAME_C_plus_plus, 201103, "C++11"},
+    {DW_LNAME_C_plus_plus, 201104, "C++14"},
+    {DW_LNAME_C_plus_plus, 201401, "C++14"},
+    {DW_LNAME_C_plus_plus, 201402, "C++14"},
+    {DW_LNAME_C_plus_plus, 201403, "C++17"},
+    {DW_LNAME_C_plus_plus, 201702, "C++17"},
+    {DW_LNAME_C_plus_plus, 201703, "C++17"},
+    {DW_LNAME_C_plus_plus, 201704, "C++20"},
+    {DW_LNAME_C_plus_plus, 202001, "C++20"},
+    {DW_LNAME_C_plus_plus, 202002, "C++20"},
+    {DW_LNAME_C_plus_plus, 202003, "ISO C++"},
+    {DW_LNAME_ObjC_plus_plus, 0, LanguageDescription(DW_LNAME_ObjC_plus_plus)},
+    {DW_LNAME_ObjC_plus_plus, 1, LanguageDescription(DW_LNAME_ObjC_plus_plus)},
+    {DW_LNAME_ObjC, 0, LanguageDescription(DW_LNAME_ObjC)},
+    {DW_LNAME_ObjC, 1, LanguageDescription(DW_LNAME_ObjC)},
+    {DW_LNAME_Move, 0, LanguageDescription(DW_LNAME_Move)},
+    {DW_LNAME_Move, 1, LanguageDescription(DW_LNAME_Move)},
+    {DW_LNAME_SYCL, 0, LanguageDescription(DW_LNAME_SYCL)},
+    {DW_LNAME_SYCL, 1, LanguageDescription(DW_LNAME_SYCL)},
+    {DW_LNAME_BLISS, 0, LanguageDescription(DW_LNAME_BLISS)},
+    {DW_LNAME_BLISS, 1, LanguageDescription(DW_LNAME_BLISS)},
+    {DW_LNAME_Crystal, 0, LanguageDescription(DW_LNAME_Crystal)},
+    {DW_LNAME_Crystal, 1, LanguageDescription(DW_LNAME_Crystal)},
+    {DW_LNAME_D, 0, LanguageDescription(DW_LNAME_D)},
+    {DW_LNAME_D, 1, LanguageDescription(DW_LNAME_D)},
+    {DW_LNAME_Dylan, 0, LanguageDescription(DW_LNAME_Dylan)},
+    {DW_LNAME_Dylan, 1, LanguageDescription(DW_LNAME_Dylan)},
+    {DW_LNAME_Go, 0, LanguageDescription(DW_LNAME_Go)},
+    {DW_LNAME_Go, 1, LanguageDescription(DW_LNAME_Go)},
+    {DW_LNAME_Haskell, 0, LanguageDescription(DW_LNAME_Haskell)},
+    {DW_LNAME_Haskell, 1, LanguageDescription(DW_LNAME_Haskell)},
+    {DW_LNAME_HLSL, 0, LanguageDescription(DW_LNAME_HLSL)},
+    {DW_LNAME_HLSL, 1, LanguageDescription(DW_LNAME_HLSL)},
+    {DW_LNAME_Java, 0, LanguageDescription(DW_LNAME_Java)},
+    {DW_LNAME_Java, 1, LanguageDescription(DW_LNAME_Java)},
+    {DW_LNAME_Julia, 0, LanguageDescription(DW_LNAME_Julia)},
+    {DW_LNAME_Julia, 1, LanguageDescription(DW_LNAME_Julia)},
+    {DW_LNAME_Kotlin, 0, LanguageDescription(DW_LNAME_Kotlin)},
+    {DW_LNAME_Kotlin, 1, LanguageDescription(DW_LNAME_Kotlin)},
+    {DW_LNAME_Modula2, 0, LanguageDescription(DW_LNAME_Modula2)},
+    {DW_LNAME_Modula2, 1, LanguageDescription(DW_LNAME_Modula2)},
+    {DW_LNAME_Modula3, 0, LanguageDescription(DW_LNAME_Modula3)},
+    {DW_LNAME_Modula3, 1, LanguageDescription(DW_LNAME_Modula3)},
+    {DW_LNAME_OCaml, 0, LanguageDescription(DW_LNAME_OCaml)},
+    {DW_LNAME_OCaml, 1, LanguageDescription(DW_LNAME_OCaml)},
+    {DW_LNAME_OpenCL_C, 0, LanguageDescription(DW_LNAME_OpenCL_C)},
+    {DW_LNAME_OpenCL_C, 1, LanguageDescription(DW_LNAME_OpenCL_C)},
+    {DW_LNAME_Pascal, 0, LanguageDescription(DW_LNAME_Pascal)},
+    {DW_LNAME_Pascal, 1, LanguageDescription(DW_LNAME_Pascal)},
+    {DW_LNAME_PLI, 0, LanguageDescription(DW_LNAME_PLI)},
+    {DW_LNAME_PLI, 1, LanguageDescription(DW_LNAME_PLI)},
+    {DW_LNAME_Python, 0, LanguageDescription(DW_LNAME_Python)},
+    {DW_LNAME_Python, 1, LanguageDescription(DW_LNAME_Python)},
+    {DW_LNAME_RenderScript, 0, LanguageDescription(DW_LNAME_RenderScript)},
+    {DW_LNAME_RenderScript, 1, LanguageDescription(DW_LNAME_RenderScript)},
+    {DW_LNAME_Rust, 0, LanguageDescription(DW_LNAME_Rust)},
+    {DW_LNAME_Rust, 1, LanguageDescription(DW_LNAME_Rust)},
+    {DW_LNAME_Swift, 0, LanguageDescription(DW_LNAME_Swift)},
+    {DW_LNAME_Swift, 1, LanguageDescription(DW_LNAME_Swift)},
+    {DW_LNAME_UPC, 0, LanguageDescription(DW_LNAME_UPC)},
+    {DW_LNAME_UPC, 1, LanguageDescription(DW_LNAME_UPC)},
+    {DW_LNAME_Zig, 0, LanguageDescription(DW_LNAME_Zig)},
+    {DW_LNAME_Zig, 1, LanguageDescription(DW_LNAME_Zig)},
+    {DW_LNAME_Assembly, 0, LanguageDescription(DW_LNAME_Assembly)},
+    {DW_LNAME_Assembly, 1, LanguageDescription(DW_LNAME_Assembly)},
+    {DW_LNAME_C_sharp, 0, LanguageDescription(DW_LNAME_C_sharp)},
+    {DW_LNAME_C_sharp, 1, LanguageDescription(DW_LNAME_C_sharp)},
+    {DW_LNAME_Mojo, 0, LanguageDescription(DW_LNAME_Mojo)},
+    {DW_LNAME_Mojo, 1, LanguageDescription(DW_LNAME_Mojo)},
+    {DW_LNAME_GLSL, 0, LanguageDescription(DW_LNAME_GLSL)},
+    {DW_LNAME_GLSL, 1, LanguageDescription(DW_LNAME_GLSL)},
+    {DW_LNAME_GLSL_ES, 0, LanguageDescription(DW_LNAME_GLSL_ES)},
+    {DW_LNAME_GLSL_ES, 1, LanguageDescription(DW_LNAME_GLSL_ES)},
+    {DW_LNAME_OpenCL_CPP, 0, LanguageDescription(DW_LNAME_OpenCL_CPP)},
+    {DW_LNAME_OpenCL_CPP, 1, LanguageDescription(DW_LNAME_OpenCL_CPP)},
+    {DW_LNAME_CPP_for_OpenCL, 0, LanguageDescription(DW_LNAME_CPP_for_OpenCL)},
+    {DW_LNAME_CPP_for_OpenCL, 1, LanguageDescription(DW_LNAME_CPP_for_OpenCL)},
+    {DW_LNAME_Ruby, 0, LanguageDescription(DW_LNAME_Ruby)},
+    {DW_LNAME_Ruby, 1, LanguageDescription(DW_LNAME_Ruby)},
+    {DW_LNAME_Hylo, 0, LanguageDescription(DW_LNAME_Hylo)},
+    {DW_LNAME_Hylo, 1, LanguageDescription(DW_LNAME_Hylo)},
+    {DW_LNAME_Metal, 0, LanguageDescription(DW_LNAME_Metal)},
+    {DW_LNAME_Metal, 1, LanguageDescription(DW_LNAME_Metal)}};
+
+struct LanguageDescriptionTestFixture
+    : public testing::Test,
+      public testing::WithParamInterface<LanguageDescriptionTestCase> {};
+
+TEST_P(LanguageDescriptionTestFixture, TestLanguageDescription) {
+  auto [LName, LVersion, ExpectedDescription] = GetParam();
+
+  // Basic test.
+  EXPECT_EQ(llvm::dwarf::LanguageDescription(LName, LVersion),
+            ExpectedDescription);
+
+  // Now do the same test but roundtrip through the DW_LANG_ <-> DW_LNAME_
+  // conversion APIs first.
+
+  auto DWLang = llvm::dwarf::toDW_LANG(LName, LVersion);
+  // Some languages are not 1-to-1 mapped. In which case there's nothing else
+  // to test.
+  if (!DWLang)
+    return;
+
+  std::optional<std::pair<SourceLanguageName, uint32_t>> DWLName =
+      llvm::dwarf::toDW_LNAME(*DWLang);
+
+  // We are roundtripping, so there definitely should be a mapping back to
+  // DW_LNAME_.
+  ASSERT_TRUE(DWLName);
+
+  // There is no official DW_LANG_ code for C++98. So the roundtripping turns it
+  // into a plain DW_LANG_C_plus_plus.
+  if (DWLang == DW_LANG_C_plus_plus && LVersion <= 199711)
+    EXPECT_EQ(llvm::dwarf::LanguageDescription(DWLName->first, DWLName->second),
+              "ISO C++");
+  else
+    EXPECT_EQ(llvm::dwarf::LanguageDescription(DWLName->first, DWLName->second),
+              ExpectedDescription);
 }
+
+INSTANTIATE_TEST_SUITE_P(LanguageDescriptionTests,
+                         LanguageDescriptionTestFixture,
+                         ::testing::ValuesIn(LanguageDescriptionTestCases));
+
 } // end namespace

``````````

</details>


https://github.com/llvm/llvm-project/pull/162863


More information about the llvm-commits mailing list