diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp index 484d9badde397..a2c95fd03bd7b 100644 --- a/lldb/source/Target/Language.cpp +++ b/lldb/source/Target/Language.cpp @@ -542,9 +542,26 @@ Language::Language() = default; // Destructor Language::~Language() = default; +static std::optional +ToDwarfSourceLanguage(lldb::LanguageType language_type) { + if (language_type < lldb::eLanguageTypeLastStandardLanguage) + return static_cast(language_type); + + switch (language_type) { + case eLanguageTypeMipsAssembler: + return llvm::dwarf::DW_LANG_Mips_Assembler; + default: + return std::nullopt; + } +} + SourceLanguage::SourceLanguage(lldb::LanguageType language_type) { - auto lname = - llvm::dwarf::toDW_LNAME((llvm::dwarf::SourceLanguage)language_type); + std::optional dwarf_lang = + ToDwarfSourceLanguage(language_type); + if (!dwarf_lang) + return; + + auto lname = llvm::dwarf::toDW_LNAME(*dwarf_lang); if (!lname) return; name = lname->first; @@ -559,11 +576,8 @@ lldb::LanguageType SourceLanguage::AsLanguageType() const { } llvm::StringRef SourceLanguage::GetDescription() const { - LanguageType type = AsLanguageType(); - if (type) - return Language::GetNameForLanguageType(type); return llvm::dwarf::LanguageDescription( - (llvm::dwarf::SourceLanguageName)name); + static_cast(name)); } bool SourceLanguage::IsC() const { return name == llvm::dwarf::DW_LNAME_C; } diff --git a/lldb/unittests/Target/CMakeLists.txt b/lldb/unittests/Target/CMakeLists.txt index 3169339ec699f..0c79675a3d890 100644 --- a/lldb/unittests/Target/CMakeLists.txt +++ b/lldb/unittests/Target/CMakeLists.txt @@ -2,6 +2,7 @@ add_lldb_unittest(TargetTests ABITest.cpp DynamicRegisterInfoTest.cpp ExecutionContextTest.cpp + Language.cpp LocateModuleCallbackTest.cpp MemoryRegionInfoTest.cpp MemoryTest.cpp diff --git a/lldb/unittests/Target/Language.cpp b/lldb/unittests/Target/Language.cpp new file mode 100644 index 0000000000000..a00fda78d569a --- /dev/null +++ b/lldb/unittests/Target/Language.cpp @@ -0,0 +1,69 @@ +//===-- LanguageTest.cpp --------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Language.h" +#include "lldb/lldb-enumerations.h" +#include "gtest/gtest.h" + +using namespace lldb_private; +using namespace lldb; + +namespace { +class LanguageTest : public ::testing::Test {}; +} // namespace + +TEST_F(LanguageTest, SourceLanguage_GetDescription) { + for (uint32_t i = 1; i < lldb::eNumLanguageTypes; ++i) { + // 0x29 is unassigned + if (i == 0x29) + continue; + + auto lang_type = static_cast(i); + if (lang_type == lldb::eLanguageTypeLastStandardLanguage) + continue; + + SourceLanguage lang(lang_type); + + // eLanguageTypeHIP is not implemented as a DW_LNAME because of a conflict. + if (lang_type == lldb::eLanguageTypeHIP) + EXPECT_FALSE(lang); + else + EXPECT_TRUE(lang); + } + + EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus).GetDescription(), + "ISO C++"); + EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus_17).GetDescription(), + "ISO C++"); + EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus_20).GetDescription(), + "ISO C++"); + + EXPECT_EQ(SourceLanguage(eLanguageTypeObjC).GetDescription(), "Objective C"); + EXPECT_EQ(SourceLanguage(eLanguageTypeMipsAssembler).GetDescription(), + "Assembly"); + + auto next_vendor_language = + static_cast(eLanguageTypeMipsAssembler + 1); + if (next_vendor_language < eNumLanguageTypes) + EXPECT_NE(SourceLanguage(next_vendor_language).GetDescription(), "Unknown"); + + EXPECT_EQ(SourceLanguage(eLanguageTypeUnknown).GetDescription(), "Unknown"); +} + +TEST_F(LanguageTest, SourceLanguage_AsLanguageType) { + EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus).AsLanguageType(), + eLanguageTypeC_plus_plus); + EXPECT_EQ(SourceLanguage(eLanguageTypeC_plus_plus_03).AsLanguageType(), + eLanguageTypeC_plus_plus_03); + + // Vendor-specific language code. + EXPECT_EQ(SourceLanguage(eLanguageTypeMipsAssembler).AsLanguageType(), + eLanguageTypeAssembly); + EXPECT_EQ(SourceLanguage(eLanguageTypeUnknown).AsLanguageType(), + eLanguageTypeUnknown); +}