441 lines · cpp
1//===- unittest/BinaryFormat/DwarfTest.cpp - Dwarf support tests ----------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/BinaryFormat/Dwarf.h"10#include "llvm/ADT/StringRef.h"11#include "llvm/Support/FormatVariadic.h"12#include "gtest/gtest.h"13 14using namespace llvm;15using namespace llvm::dwarf;16 17namespace {18 19TEST(DwarfTest, TagStringOnInvalid) {20 // This is invalid, so it shouldn't be stringified.21 EXPECT_EQ(StringRef(), TagString(DW_TAG_invalid));22 23 // These aren't really tags: they describe ranges within tags. They24 // shouldn't be stringified either.25 EXPECT_EQ(StringRef(), TagString(DW_TAG_lo_user));26 EXPECT_EQ(StringRef(), TagString(DW_TAG_hi_user));27 EXPECT_EQ(StringRef(), TagString(DW_TAG_user_base));28}29 30TEST(DwarfTest, getTag) {31 // A couple of valid tags.32 EXPECT_EQ(DW_TAG_array_type, getTag("DW_TAG_array_type"));33 EXPECT_EQ(DW_TAG_module, getTag("DW_TAG_module"));34 35 // Invalid tags.36 EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_invalid"));37 EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_madeuptag"));38 EXPECT_EQ(DW_TAG_invalid, getTag("something else"));39 40 // Tag range markers should not be recognized.41 EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_lo_user"));42 EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_hi_user"));43 EXPECT_EQ(DW_TAG_invalid, getTag("DW_TAG_user_base"));44}45 46TEST(DwarfTest, getOperationEncoding) {47 // Some valid ops.48 EXPECT_EQ(DW_OP_deref, getOperationEncoding("DW_OP_deref"));49 EXPECT_EQ(DW_OP_bit_piece, getOperationEncoding("DW_OP_bit_piece"));50 51 // Invalid ops.52 EXPECT_EQ(0u, getOperationEncoding("DW_OP_otherthings"));53 EXPECT_EQ(0u, getOperationEncoding("other"));54 55 // Markers shouldn't be recognized.56 EXPECT_EQ(0u, getOperationEncoding("DW_OP_lo_user"));57 EXPECT_EQ(0u, getOperationEncoding("DW_OP_hi_user"));58}59 60TEST(DwarfTest, LanguageStringOnInvalid) {61 // This is invalid, so it shouldn't be stringified.62 EXPECT_EQ(StringRef(), LanguageString(0));63 64 // These aren't really tags: they describe ranges within tags. They65 // shouldn't be stringified either.66 EXPECT_EQ(StringRef(), LanguageString(DW_LANG_lo_user));67 EXPECT_EQ(StringRef(), LanguageString(DW_LANG_hi_user));68}69 70TEST(DwarfTest, getLanguage) {71 // A couple of valid languages.72 EXPECT_EQ(DW_LANG_C89, getLanguage("DW_LANG_C89"));73 EXPECT_EQ(DW_LANG_C_plus_plus_11, getLanguage("DW_LANG_C_plus_plus_11"));74 EXPECT_EQ(DW_LANG_OCaml, getLanguage("DW_LANG_OCaml"));75 EXPECT_EQ(DW_LANG_Mips_Assembler, getLanguage("DW_LANG_Mips_Assembler"));76 77 // Invalid languages.78 EXPECT_EQ(0u, getLanguage("DW_LANG_invalid"));79 EXPECT_EQ(0u, getLanguage("DW_TAG_array_type"));80 EXPECT_EQ(0u, getLanguage("something else"));81 82 // Language range markers should not be recognized.83 EXPECT_EQ(0u, getLanguage("DW_LANG_lo_user"));84 EXPECT_EQ(0u, getLanguage("DW_LANG_hi_user"));85}86 87TEST(DwarfTest, AttributeEncodingStringOnInvalid) {88 // This is invalid, so it shouldn't be stringified.89 EXPECT_EQ(StringRef(), AttributeEncodingString(0));90 91 // These aren't really tags: they describe ranges within tags. They92 // shouldn't be stringified either.93 EXPECT_EQ(StringRef(), AttributeEncodingString(DW_ATE_lo_user));94 EXPECT_EQ(StringRef(), AttributeEncodingString(DW_ATE_hi_user));95}96 97TEST(DwarfTest, getAttributeEncoding) {98 // A couple of valid languages.99 EXPECT_EQ(DW_ATE_boolean, getAttributeEncoding("DW_ATE_boolean"));100 EXPECT_EQ(DW_ATE_imaginary_float,101 getAttributeEncoding("DW_ATE_imaginary_float"));102 103 // Invalid languages.104 EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_invalid"));105 EXPECT_EQ(0u, getAttributeEncoding("DW_TAG_array_type"));106 EXPECT_EQ(0u, getAttributeEncoding("something else"));107 108 // AttributeEncoding range markers should not be recognized.109 EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_lo_user"));110 EXPECT_EQ(0u, getAttributeEncoding("DW_ATE_hi_user"));111}112 113TEST(DwarfTest, VirtualityString) {114 EXPECT_EQ(StringRef("DW_VIRTUALITY_none"),115 VirtualityString(DW_VIRTUALITY_none));116 EXPECT_EQ(StringRef("DW_VIRTUALITY_virtual"),117 VirtualityString(DW_VIRTUALITY_virtual));118 EXPECT_EQ(StringRef("DW_VIRTUALITY_pure_virtual"),119 VirtualityString(DW_VIRTUALITY_pure_virtual));120 121 // DW_VIRTUALITY_max should be pure virtual.122 EXPECT_EQ(StringRef("DW_VIRTUALITY_pure_virtual"),123 VirtualityString(DW_VIRTUALITY_max));124 125 // Invalid numbers shouldn't be stringified.126 EXPECT_EQ(StringRef(), VirtualityString(DW_VIRTUALITY_max + 1));127 EXPECT_EQ(StringRef(), VirtualityString(DW_VIRTUALITY_max + 77));128}129 130TEST(DwarfTest, getVirtuality) {131 EXPECT_EQ(DW_VIRTUALITY_none, getVirtuality("DW_VIRTUALITY_none"));132 EXPECT_EQ(DW_VIRTUALITY_virtual, getVirtuality("DW_VIRTUALITY_virtual"));133 EXPECT_EQ(DW_VIRTUALITY_pure_virtual,134 getVirtuality("DW_VIRTUALITY_pure_virtual"));135 136 // Invalid strings.137 EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("DW_VIRTUALITY_invalid"));138 EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("DW_VIRTUALITY_max"));139 EXPECT_EQ(DW_VIRTUALITY_invalid, getVirtuality("something else"));140}141 142TEST(DwarfTest, FixedFormSizes) {143 std::optional<uint8_t> RefSize;144 std::optional<uint8_t> AddrSize;145 146 // Test 32 bit DWARF version 2 with 4 byte addresses.147 FormParams Params_2_4_32 = {2, 4, DWARF32};148 RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_2_4_32);149 AddrSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_2_4_32);150 EXPECT_TRUE(RefSize.has_value());151 EXPECT_TRUE(AddrSize.has_value());152 EXPECT_EQ(*RefSize, *AddrSize);153 154 // Test 32 bit DWARF version 2 with 8 byte addresses.155 FormParams Params_2_8_32 = {2, 8, DWARF32};156 RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_2_8_32);157 AddrSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_2_8_32);158 EXPECT_TRUE(RefSize.has_value());159 EXPECT_TRUE(AddrSize.has_value());160 EXPECT_EQ(*RefSize, *AddrSize);161 162 // DW_FORM_ref_addr is 4 bytes in DWARF 32 in DWARF version 3 and beyond.163 FormParams Params_3_4_32 = {3, 4, DWARF32};164 RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_3_4_32);165 EXPECT_TRUE(RefSize.has_value());166 EXPECT_EQ(*RefSize, 4);167 168 FormParams Params_4_4_32 = {4, 4, DWARF32};169 RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_4_4_32);170 EXPECT_TRUE(RefSize.has_value());171 EXPECT_EQ(*RefSize, 4);172 173 FormParams Params_5_4_32 = {5, 4, DWARF32};174 RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_5_4_32);175 EXPECT_TRUE(RefSize.has_value());176 EXPECT_EQ(*RefSize, 4);177 178 // DW_FORM_ref_addr is 8 bytes in DWARF 64 in DWARF version 3 and beyond.179 FormParams Params_3_8_64 = {3, 8, DWARF64};180 RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_3_8_64);181 EXPECT_TRUE(RefSize.has_value());182 EXPECT_EQ(*RefSize, 8);183 184 FormParams Params_4_8_64 = {4, 8, DWARF64};185 RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_4_8_64);186 EXPECT_TRUE(RefSize.has_value());187 EXPECT_EQ(*RefSize, 8);188 189 FormParams Params_5_8_64 = {5, 8, DWARF64};190 RefSize = getFixedFormByteSize(DW_FORM_ref_addr, Params_5_8_64);191 EXPECT_TRUE(RefSize.has_value());192 EXPECT_EQ(*RefSize, 8);193}194 195TEST(DwarfTest, format_provider) {196 EXPECT_EQ("DW_AT_name", formatv("{0}", DW_AT_name).str());197 EXPECT_EQ("DW_AT_unknown_3fff", formatv("{0}", DW_AT_hi_user).str());198 EXPECT_EQ("DW_FORM_addr", formatv("{0}", DW_FORM_addr).str());199 EXPECT_EQ("DW_FORM_unknown_1f00", formatv("{0}", DW_FORM_lo_user).str());200 EXPECT_EQ("DW_IDX_compile_unit", formatv("{0}", DW_IDX_compile_unit).str());201 EXPECT_EQ("DW_IDX_unknown_3fff", formatv("{0}", DW_IDX_hi_user).str());202 EXPECT_EQ("DW_TAG_compile_unit", formatv("{0}", DW_TAG_compile_unit).str());203 EXPECT_EQ("DW_TAG_unknown_ffff", formatv("{0}", DW_TAG_hi_user).str());204 EXPECT_EQ("DW_OP_lit0", formatv("{0}", DW_OP_lit0).str());205 EXPECT_EQ("DW_OP_unknown_ff", formatv("{0}", DW_OP_hi_user).str());206}207 208TEST(DwarfTest, lname) {209 auto roundtrip = [](llvm::dwarf::SourceLanguage sl) {210 auto name_version = toDW_LNAME(sl);211 // Ignore ones without a defined mapping.212 if (sl == DW_LANG_Mips_Assembler || sl == DW_LANG_GOOGLE_RenderScript ||213 !name_version.has_value())214 return sl;215 return dwarf::toDW_LANG(name_version->first, name_version->second)216 .value_or(sl);217 };218#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \219 EXPECT_EQ(roundtrip(DW_LANG_##NAME), DW_LANG_##NAME);220#include "llvm/BinaryFormat/Dwarf.def"221}222 223TEST(DwarfTest, lname_getSourceLanguageName) {224 // Some basics.225 EXPECT_EQ(getSourceLanguageName("DW_LNAME_Ada"), DW_LNAME_Ada);226 EXPECT_EQ(getSourceLanguageName("DW_LNAME_Metal"), DW_LNAME_Metal);227 228 // Test invalid input.229 EXPECT_EQ(getSourceLanguageName(""), 0U);230 EXPECT_EQ(getSourceLanguageName("blah"), 0U);231 EXPECT_EQ(getSourceLanguageName("DW_LNAME__something_unlikely"), 0U);232 EXPECT_EQ(getSourceLanguageName("DW_LANG_C"), 0U);233 234 // Test that we cover all DW_LNAME_ names.235#define xstr(X) #X236#define HANDLE_DW_LNAME(ID, NAME, DESC, LOWER_BOUND) \237 EXPECT_EQ(getSourceLanguageName(xstr(DW_LNAME_##NAME)), DW_LNAME_##NAME);238#include "llvm/BinaryFormat/Dwarf.def"239}240 241TEST(DwarfTest, lname_SourceLanguageNameString) {242 // Some basics.243 EXPECT_EQ(SourceLanguageNameString(DW_LNAME_C_plus_plus),244 "DW_LNAME_C_plus_plus");245 EXPECT_EQ(SourceLanguageNameString(DW_LNAME_CPP_for_OpenCL),246 "DW_LNAME_CPP_for_OpenCL");247 248 // Test invalid input.249 EXPECT_EQ(SourceLanguageNameString(static_cast<SourceLanguageName>(0)), "");250 251 // Test that we cover all DW_LNAME_ names.252#define xstr(X) #X253#define HANDLE_DW_LNAME(ID, NAME, DESC, LOWER_BOUND) \254 EXPECT_EQ(SourceLanguageNameString(DW_LNAME_##NAME), xstr(DW_LNAME_##NAME));255#include "llvm/BinaryFormat/Dwarf.def"256}257 258struct LanguageDescriptionTestCase {259 llvm::dwarf::SourceLanguageName LName;260 uint32_t LVersion;261 llvm::StringRef ExpectedDescription;262};263 264LanguageDescriptionTestCase 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 399struct LanguageDescriptionTestFixture400 : public testing::Test,401 public testing::WithParamInterface<LanguageDescriptionTestCase> {};402 403TEST_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 else415 // 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 to423 // DW_LNAME_.424 ASSERT_TRUE(DWLName);425 426 // There is no official DW_LANG_ code for C++98. So the roundtripping turns it427 // 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 else432 EXPECT_EQ(llvm::dwarf::LanguageDescription(DWLName->first, DWLName->second),433 ExpectedDescription);434}435 436INSTANTIATE_TEST_SUITE_P(LanguageDescriptionTests,437 LanguageDescriptionTestFixture,438 ::testing::ValuesIn(LanguageDescriptionTestCases));439 440} // end namespace441