@@ -255,41 +255,186 @@ TEST(DwarfTest, lname_SourceLanguageNameString) {
255255#include " llvm/BinaryFormat/Dwarf.def"
256256}
257257
258- TEST (DWARFDebugInfo, TestLanguageDescription_Versioned) {
259- // Tests for the llvm::dwarf::LanguageDescription API that
260- // takes a name *and* a version.
261-
262- // Unknown language.
263- EXPECT_EQ (
264- llvm::dwarf::LanguageDescription (static_cast <SourceLanguageName>(0 )),
265- " Unknown" );
266-
267- EXPECT_EQ (
268- llvm::dwarf::LanguageDescription (static_cast <SourceLanguageName>(0 ), 0 ),
269- " Unknown" );
270-
271- // Test that specifying an invalid version falls back to a valid language name
272- // regardless.
273- EXPECT_EQ (llvm::dwarf::LanguageDescription (DW_LNAME_ObjC, 0 ), " Objective C" );
274- EXPECT_EQ (llvm::dwarf::LanguageDescription (DW_LNAME_Julia, 0 ), " Julia" );
275-
276- // Check some versions.
277- EXPECT_EQ (llvm::dwarf::LanguageDescription (DW_LNAME_C_plus_plus, 199711 ),
278- " C++98" );
279- EXPECT_EQ (llvm::dwarf::LanguageDescription (DW_LNAME_C_plus_plus, 201402 ),
280- " C++14" );
281-
282- // Versions round up.
283- EXPECT_EQ (llvm::dwarf::LanguageDescription (DW_LNAME_C_plus_plus, 201400 ),
284- " C++14" );
285-
286- // Version 0 for C and C++ is an unversioned name.
287- EXPECT_EQ (llvm::dwarf::LanguageDescription (DW_LNAME_C, 0 ), " C (K&R and ISO)" );
288- EXPECT_EQ (llvm::dwarf::LanguageDescription (DW_LNAME_C_plus_plus, 0 ),
289- " ISO C++" );
290-
291- // Version 0 for other versioned languages may not be the unversioned name.
292- EXPECT_EQ (llvm::dwarf::LanguageDescription (DW_LNAME_Fortran, 0 ),
293- " FORTRAN 77" );
258+ struct LanguageDescriptionTestCase {
259+ llvm::dwarf::SourceLanguageName LName;
260+ uint32_t LVersion;
261+ llvm::StringRef ExpectedDescription;
262+ };
263+
264+ LanguageDescriptionTestCase LanguageDescriptionTestCases[] = {
265+ {static_cast <SourceLanguageName>(0 ), 0 , " Unknown" },
266+ {static_cast <SourceLanguageName>(0 ), 1 , " Unknown" },
267+ {DW_LNAME_Ada, 0 , " Ada 83" },
268+ {DW_LNAME_Ada, 1982 , " Ada 83" },
269+ {DW_LNAME_Ada, 1983 , " Ada 83" },
270+ {DW_LNAME_Ada, 1994 , " Ada 95" },
271+ {DW_LNAME_Ada, 1995 , " Ada 95" },
272+ {DW_LNAME_Ada, 2004 , " Ada 2005" },
273+ {DW_LNAME_Ada, 2005 , " Ada 2005" },
274+ {DW_LNAME_Ada, 2011 , " Ada 2012" },
275+ {DW_LNAME_Ada, 2012 , " Ada 2012" },
276+ {DW_LNAME_Ada, 2013 , " ISO Ada" },
277+ {DW_LNAME_Cobol, 0 , " COBOL-74" },
278+ {DW_LNAME_Cobol, 1973 , " COBOL-74" },
279+ {DW_LNAME_Cobol, 1974 , " COBOL-74" },
280+ {DW_LNAME_Cobol, 1984 , " COBOL-85" },
281+ {DW_LNAME_Cobol, 1985 , " COBOL-85" },
282+ {DW_LNAME_Cobol, 1986 , " ISO Cobol" },
283+ {DW_LNAME_Fortran, 0 , " FORTRAN 77" },
284+ {DW_LNAME_Fortran, 1976 , " FORTRAN 77" },
285+ {DW_LNAME_Fortran, 1977 , " FORTRAN 77" },
286+ {DW_LNAME_Fortran, 1989 , " FORTRAN 90" },
287+ {DW_LNAME_Fortran, 1990 , " FORTRAN 90" },
288+ {DW_LNAME_Fortran, 1994 , " Fortran 95" },
289+ {DW_LNAME_Fortran, 1995 , " Fortran 95" },
290+ {DW_LNAME_Fortran, 2002 , " Fortran 2003" },
291+ {DW_LNAME_Fortran, 2003 , " Fortran 2003" },
292+ {DW_LNAME_Fortran, 2007 , " Fortran 2008" },
293+ {DW_LNAME_Fortran, 2008 , " Fortran 2008" },
294+ {DW_LNAME_Fortran, 2017 , " Fortran 2018" },
295+ {DW_LNAME_Fortran, 2018 , " Fortran 2018" },
296+ {DW_LNAME_Fortran, 2019 , " ISO Fortran" },
297+ {DW_LNAME_C, 0 , " C (K&R and ISO)" },
298+ {DW_LNAME_C, 198911 , " C89" },
299+ {DW_LNAME_C, 198912 , " C89" },
300+ {DW_LNAME_C, 199901 , " C99" },
301+ {DW_LNAME_C, 199902 , " C11" },
302+ {DW_LNAME_C, 201111 , " C11" },
303+ {DW_LNAME_C, 201112 , " C11" },
304+ {DW_LNAME_C, 201201 , " C17" },
305+ {DW_LNAME_C, 201709 , " C17" },
306+ {DW_LNAME_C, 201710 , " C17" },
307+ {DW_LNAME_C, 201711 , " C (K&R and ISO)" },
308+ {DW_LNAME_C_plus_plus, 0 , " ISO C++" },
309+ {DW_LNAME_C_plus_plus, 199710 , " C++98" },
310+ {DW_LNAME_C_plus_plus, 199711 , " C++98" },
311+ {DW_LNAME_C_plus_plus, 199712 , " C++03" },
312+ {DW_LNAME_C_plus_plus, 200310 , " C++03" },
313+ {DW_LNAME_C_plus_plus, 200311 , " C++11" },
314+ {DW_LNAME_C_plus_plus, 201102 , " C++11" },
315+ {DW_LNAME_C_plus_plus, 201103 , " C++11" },
316+ {DW_LNAME_C_plus_plus, 201104 , " C++14" },
317+ {DW_LNAME_C_plus_plus, 201401 , " C++14" },
318+ {DW_LNAME_C_plus_plus, 201402 , " C++14" },
319+ {DW_LNAME_C_plus_plus, 201403 , " C++17" },
320+ {DW_LNAME_C_plus_plus, 201702 , " C++17" },
321+ {DW_LNAME_C_plus_plus, 201703 , " C++17" },
322+ {DW_LNAME_C_plus_plus, 201704 , " C++20" },
323+ {DW_LNAME_C_plus_plus, 202001 , " C++20" },
324+ {DW_LNAME_C_plus_plus, 202002 , " C++20" },
325+ {DW_LNAME_C_plus_plus, 202003 , " ISO C++" },
326+ {DW_LNAME_ObjC_plus_plus, 0 , LanguageDescription (DW_LNAME_ObjC_plus_plus)},
327+ {DW_LNAME_ObjC_plus_plus, 1 , LanguageDescription (DW_LNAME_ObjC_plus_plus)},
328+ {DW_LNAME_ObjC, 0 , LanguageDescription (DW_LNAME_ObjC)},
329+ {DW_LNAME_ObjC, 1 , LanguageDescription (DW_LNAME_ObjC)},
330+ {DW_LNAME_Move, 0 , LanguageDescription (DW_LNAME_Move)},
331+ {DW_LNAME_Move, 1 , LanguageDescription (DW_LNAME_Move)},
332+ {DW_LNAME_SYCL, 0 , LanguageDescription (DW_LNAME_SYCL)},
333+ {DW_LNAME_SYCL, 1 , LanguageDescription (DW_LNAME_SYCL)},
334+ {DW_LNAME_BLISS, 0 , LanguageDescription (DW_LNAME_BLISS)},
335+ {DW_LNAME_BLISS, 1 , LanguageDescription (DW_LNAME_BLISS)},
336+ {DW_LNAME_Crystal, 0 , LanguageDescription (DW_LNAME_Crystal)},
337+ {DW_LNAME_Crystal, 1 , LanguageDescription (DW_LNAME_Crystal)},
338+ {DW_LNAME_D, 0 , LanguageDescription (DW_LNAME_D)},
339+ {DW_LNAME_D, 1 , LanguageDescription (DW_LNAME_D)},
340+ {DW_LNAME_Dylan, 0 , LanguageDescription (DW_LNAME_Dylan)},
341+ {DW_LNAME_Dylan, 1 , LanguageDescription (DW_LNAME_Dylan)},
342+ {DW_LNAME_Go, 0 , LanguageDescription (DW_LNAME_Go)},
343+ {DW_LNAME_Go, 1 , LanguageDescription (DW_LNAME_Go)},
344+ {DW_LNAME_Haskell, 0 , LanguageDescription (DW_LNAME_Haskell)},
345+ {DW_LNAME_Haskell, 1 , LanguageDescription (DW_LNAME_Haskell)},
346+ {DW_LNAME_HLSL, 0 , LanguageDescription (DW_LNAME_HLSL)},
347+ {DW_LNAME_HLSL, 1 , LanguageDescription (DW_LNAME_HLSL)},
348+ {DW_LNAME_Java, 0 , LanguageDescription (DW_LNAME_Java)},
349+ {DW_LNAME_Java, 1 , LanguageDescription (DW_LNAME_Java)},
350+ {DW_LNAME_Julia, 0 , LanguageDescription (DW_LNAME_Julia)},
351+ {DW_LNAME_Julia, 1 , LanguageDescription (DW_LNAME_Julia)},
352+ {DW_LNAME_Kotlin, 0 , LanguageDescription (DW_LNAME_Kotlin)},
353+ {DW_LNAME_Kotlin, 1 , LanguageDescription (DW_LNAME_Kotlin)},
354+ {DW_LNAME_Modula2, 0 , LanguageDescription (DW_LNAME_Modula2)},
355+ {DW_LNAME_Modula2, 1 , LanguageDescription (DW_LNAME_Modula2)},
356+ {DW_LNAME_Modula3, 0 , LanguageDescription (DW_LNAME_Modula3)},
357+ {DW_LNAME_Modula3, 1 , LanguageDescription (DW_LNAME_Modula3)},
358+ {DW_LNAME_OCaml, 0 , LanguageDescription (DW_LNAME_OCaml)},
359+ {DW_LNAME_OCaml, 1 , LanguageDescription (DW_LNAME_OCaml)},
360+ {DW_LNAME_OpenCL_C, 0 , LanguageDescription (DW_LNAME_OpenCL_C)},
361+ {DW_LNAME_OpenCL_C, 1 , LanguageDescription (DW_LNAME_OpenCL_C)},
362+ {DW_LNAME_Pascal, 0 , LanguageDescription (DW_LNAME_Pascal)},
363+ {DW_LNAME_Pascal, 1 , LanguageDescription (DW_LNAME_Pascal)},
364+ {DW_LNAME_PLI, 0 , LanguageDescription (DW_LNAME_PLI)},
365+ {DW_LNAME_PLI, 1 , LanguageDescription (DW_LNAME_PLI)},
366+ {DW_LNAME_Python, 0 , LanguageDescription (DW_LNAME_Python)},
367+ {DW_LNAME_Python, 1 , LanguageDescription (DW_LNAME_Python)},
368+ {DW_LNAME_RenderScript, 0 , LanguageDescription (DW_LNAME_RenderScript)},
369+ {DW_LNAME_RenderScript, 1 , LanguageDescription (DW_LNAME_RenderScript)},
370+ {DW_LNAME_Rust, 0 , LanguageDescription (DW_LNAME_Rust)},
371+ {DW_LNAME_Rust, 1 , LanguageDescription (DW_LNAME_Rust)},
372+ {DW_LNAME_Swift, 0 , LanguageDescription (DW_LNAME_Swift)},
373+ {DW_LNAME_Swift, 1 , LanguageDescription (DW_LNAME_Swift)},
374+ {DW_LNAME_UPC, 0 , LanguageDescription (DW_LNAME_UPC)},
375+ {DW_LNAME_UPC, 1 , LanguageDescription (DW_LNAME_UPC)},
376+ {DW_LNAME_Zig, 0 , LanguageDescription (DW_LNAME_Zig)},
377+ {DW_LNAME_Zig, 1 , LanguageDescription (DW_LNAME_Zig)},
378+ {DW_LNAME_Assembly, 0 , LanguageDescription (DW_LNAME_Assembly)},
379+ {DW_LNAME_Assembly, 1 , LanguageDescription (DW_LNAME_Assembly)},
380+ {DW_LNAME_C_sharp, 0 , LanguageDescription (DW_LNAME_C_sharp)},
381+ {DW_LNAME_C_sharp, 1 , LanguageDescription (DW_LNAME_C_sharp)},
382+ {DW_LNAME_Mojo, 0 , LanguageDescription (DW_LNAME_Mojo)},
383+ {DW_LNAME_Mojo, 1 , LanguageDescription (DW_LNAME_Mojo)},
384+ {DW_LNAME_GLSL, 0 , LanguageDescription (DW_LNAME_GLSL)},
385+ {DW_LNAME_GLSL, 1 , LanguageDescription (DW_LNAME_GLSL)},
386+ {DW_LNAME_GLSL_ES, 0 , LanguageDescription (DW_LNAME_GLSL_ES)},
387+ {DW_LNAME_GLSL_ES, 1 , LanguageDescription (DW_LNAME_GLSL_ES)},
388+ {DW_LNAME_OpenCL_CPP, 0 , LanguageDescription (DW_LNAME_OpenCL_CPP)},
389+ {DW_LNAME_OpenCL_CPP, 1 , LanguageDescription (DW_LNAME_OpenCL_CPP)},
390+ {DW_LNAME_CPP_for_OpenCL, 0 , LanguageDescription (DW_LNAME_CPP_for_OpenCL)},
391+ {DW_LNAME_CPP_for_OpenCL, 1 , LanguageDescription (DW_LNAME_CPP_for_OpenCL)},
392+ {DW_LNAME_Ruby, 0 , LanguageDescription (DW_LNAME_Ruby)},
393+ {DW_LNAME_Ruby, 1 , LanguageDescription (DW_LNAME_Ruby)},
394+ {DW_LNAME_Hylo, 0 , LanguageDescription (DW_LNAME_Hylo)},
395+ {DW_LNAME_Hylo, 1 , LanguageDescription (DW_LNAME_Hylo)},
396+ {DW_LNAME_Metal, 0 , LanguageDescription (DW_LNAME_Metal)},
397+ {DW_LNAME_Metal, 1 , LanguageDescription (DW_LNAME_Metal)}};
398+
399+ struct LanguageDescriptionTestFixture
400+ : public testing::Test,
401+ public testing::WithParamInterface<LanguageDescriptionTestCase> {};
402+
403+ TEST_P (LanguageDescriptionTestFixture, TestLanguageDescription) {
404+ auto [LName, LVersion, ExpectedDescription] = GetParam ();
405+
406+ // Basic test.
407+ EXPECT_EQ (llvm::dwarf::LanguageDescription (LName, LVersion),
408+ ExpectedDescription);
409+
410+ // Now do the same test but roundtrip through the DW_LANG_ <-> DW_LNAME_
411+ // conversion APIs first.
412+
413+ auto DWLang = llvm::dwarf::toDW_LANG (LName, LVersion);
414+ // Some languages are not 1-to-1 mapped. In which case there's nothing else
415+ // to test.
416+ if (!DWLang)
417+ return ;
418+
419+ std::optional<std::pair<SourceLanguageName, uint32_t >> DWLName =
420+ llvm::dwarf::toDW_LNAME (*DWLang);
421+
422+ // We are roundtripping, so there definitely should be a mapping back to
423+ // DW_LNAME_.
424+ ASSERT_TRUE (DWLName);
425+
426+ // There is no official DW_LANG_ code for C++98. So the roundtripping turns it
427+ // into a plain DW_LANG_C_plus_plus.
428+ if (DWLang == DW_LANG_C_plus_plus && LVersion <= 199711 )
429+ EXPECT_EQ (llvm::dwarf::LanguageDescription (DWLName->first , DWLName->second ),
430+ " ISO C++" );
431+ else
432+ EXPECT_EQ (llvm::dwarf::LanguageDescription (DWLName->first , DWLName->second ),
433+ ExpectedDescription);
294434}
435+
436+ INSTANTIATE_TEST_SUITE_P (LanguageDescriptionTests,
437+ LanguageDescriptionTestFixture,
438+ ::testing::ValuesIn (LanguageDescriptionTestCases));
439+
295440} // end namespace
0 commit comments