-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[llvm][DebugInfo][test] DwarfTest: parameterize LanguageDescription tests #162863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[llvm][DebugInfo][test] DwarfTest: parameterize LanguageDescription tests #162863
Conversation
@llvm/pr-subscribers-llvm-binary-utilities @llvm/pr-subscribers-debuginfo Author: Michael Buch (Michael137) ChangesBetter test coverage. The round-tripping test makes sure that if we ever change The round-tripping test found an incorrect version check in Full diff: https://github.com/llvm/llvm-project/pull/162863.diff 2 Files Affected:
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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good - I wasn't thinking of exhaustively testing the original table, FWIW, but I don't object entirely either.
Thanks!
…ests (llvm#162863) 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 (see the table at the bottom of https://dwarfstd.org/languages-v6.html for reference).
…ests (llvm#162863) 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 (see the table at the bottom of https://dwarfstd.org/languages-v6.html for reference).
Better test coverage.
The round-tripping test makes sure that if we ever change
llvm::dwarf::toDW_Lang
orllvm::dwarf::toDW_LName
, we don't break theLanguageDescription
API.The round-tripping test found an incorrect version check in
llvm::dwarf::toDW_Lang
, which I corrected as part of this PR (see the table at the bottom of https://dwarfstd.org/languages-v6.html for reference).