[llvm] [llvm-debuginfo-analyzer] Common handling of unsigned attribute values. (PR #116027)
Paul T Robinson via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 26 11:58:36 PST 2024
================
@@ -0,0 +1,369 @@
+//===- llvm/unittest/DebugInfo/LogicalView/DWARFGeneratedTest.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 "../DWARF/DwarfGenerator.h"
+#include "../DWARF/DwarfUtils.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
+#include "llvm/DebugInfo/LogicalView/Core/LVType.h"
+#include "llvm/DebugInfo/LogicalView/LVReaderHandler.h"
+#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/COM.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Testing/Support/Error.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace llvm::logicalview;
+using namespace llvm::dwarf;
+using namespace llvm::dwarf::utils;
+
+namespace {
+
+// Helper function to get the first compile unit.
+LVScopeCompileUnit *getFirstCompileUnit(LVScopeRoot *Root) {
+ EXPECT_NE(Root, nullptr);
+ const LVScopes *CompileUnits = Root->getScopes();
+ EXPECT_NE(CompileUnits, nullptr);
+ EXPECT_EQ(CompileUnits->size(), 1u);
+
+ LVScopes::const_iterator Iter = CompileUnits->begin();
+ EXPECT_NE(Iter, nullptr);
+ LVScopeCompileUnit *CompileUnit = static_cast<LVScopeCompileUnit *>(*Iter);
+ EXPECT_NE(CompileUnit, nullptr);
+ return CompileUnit;
+}
+
+// Helper function to create a reader.
+std::unique_ptr<LVReader> createReader(LVReaderHandler &ReaderHandler,
+ SmallString<128> &InputsDir,
+ StringRef Filename) {
+ SmallString<128> ObjectName(InputsDir);
+ llvm::sys::path::append(ObjectName, Filename);
+
+ Expected<std::unique_ptr<LVReader>> ReaderOrErr =
+ ReaderHandler.createReader(std::string(ObjectName));
+ EXPECT_THAT_EXPECTED(ReaderOrErr, Succeeded());
+ std::unique_ptr<LVReader> Reader = std::move(*ReaderOrErr);
+ EXPECT_NE(Reader, nullptr);
+ return Reader;
+}
+
+// Create a file with generated DWARF.
+void generateDebugInfo(StringRef Path, Triple &Triple) {
+ uint16_t Version = 5;
+ auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
+ ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
+ dwarfgen::Generator *DG = ExpectedDG.get().get();
+ dwarfgen::CompileUnit &CU = DG->addCompileUnit();
+
+ dwarfgen::DIE CUDie = CU.getUnitDIE();
+ CUDie.addAttribute(DW_AT_name, DW_FORM_strp, "test.cpp");
+ CUDie.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C_plus_plus);
+ CUDie.addAttribute(DW_AT_producer, DW_FORM_strp, "dwarfgen::Generator");
+
+ dwarfgen::DIE ScopeValueDie = CUDie.addChild(DW_TAG_inlined_subroutine);
+ ScopeValueDie.addAttribute(DW_AT_accessibility, DW_FORM_data1, 1);
+ ScopeValueDie.addAttribute(DW_AT_inline, DW_FORM_data4, 2);
+ ScopeValueDie.addAttribute(DW_AT_virtuality, DW_FORM_data4, 3);
+ ScopeValueDie.addAttribute(DW_AT_call_file, DW_FORM_data4, 4);
+ ScopeValueDie.addAttribute(DW_AT_call_line, DW_FORM_data4, 5);
+ ScopeValueDie.addAttribute(DW_AT_decl_file, DW_FORM_data4, 6);
+ ScopeValueDie.addAttribute(DW_AT_decl_line, DW_FORM_data4, 7);
+ ScopeValueDie.addAttribute(DW_AT_GNU_discriminator, DW_FORM_data4, 8);
+
+ dwarfgen::DIE ScopeNoValueDie = CUDie.addChild(DW_TAG_inlined_subroutine);
+ ScopeNoValueDie.addAttribute(DW_AT_accessibility, DW_FORM_sdata, 1);
+ ScopeNoValueDie.addAttribute(DW_AT_inline, DW_FORM_sdata, 2);
+ ScopeNoValueDie.addAttribute(DW_AT_virtuality, DW_FORM_sdata, 3);
+ ScopeNoValueDie.addAttribute(DW_AT_call_file, DW_FORM_sdata, 4);
+ ScopeNoValueDie.addAttribute(DW_AT_call_line, DW_FORM_sdata, 5);
+ ScopeNoValueDie.addAttribute(DW_AT_decl_file, DW_FORM_sdata, 6);
+ ScopeNoValueDie.addAttribute(DW_AT_decl_line, DW_FORM_sdata, 7);
+ ScopeNoValueDie.addAttribute(DW_AT_GNU_discriminator, DW_FORM_sdata, 8);
+
+ dwarfgen::DIE ScopeImplicitDie = CUDie.addChild(DW_TAG_inlined_subroutine);
+ ScopeImplicitDie.addAttribute(DW_AT_accessibility, DW_FORM_implicit_const, 1);
+ ScopeImplicitDie.addAttribute(DW_AT_inline, DW_FORM_implicit_const, 2);
+ ScopeImplicitDie.addAttribute(DW_AT_virtuality, DW_FORM_implicit_const, 3);
+ ScopeImplicitDie.addAttribute(DW_AT_call_file, DW_FORM_implicit_const, 4);
+ ScopeImplicitDie.addAttribute(DW_AT_call_line, DW_FORM_implicit_const, 5);
+ ScopeImplicitDie.addAttribute(DW_AT_decl_file, DW_FORM_implicit_const, 6);
+ ScopeImplicitDie.addAttribute(DW_AT_decl_line, DW_FORM_implicit_const, 7);
+ ScopeImplicitDie.addAttribute(DW_AT_GNU_discriminator, DW_FORM_implicit_const,
+ 8);
+
+ dwarfgen::DIE SymbolValueDie = CUDie.addChild(DW_TAG_variable);
+ SymbolValueDie.addAttribute(DW_AT_bit_size, DW_FORM_data1, 1);
+
+ dwarfgen::DIE SymbolNoValueDie = CUDie.addChild(DW_TAG_variable);
+ SymbolNoValueDie.addAttribute(DW_AT_bit_size, DW_FORM_sdata, 1);
+
+ dwarfgen::DIE SymbolImplicitDie = CUDie.addChild(DW_TAG_variable);
+ SymbolImplicitDie.addAttribute(DW_AT_bit_size, DW_FORM_implicit_const, 1);
+
+ dwarfgen::DIE TypeValueCountDie = CUDie.addChild(DW_TAG_subrange_type);
+ TypeValueCountDie.addAttribute(DW_AT_count, DW_FORM_data4, 1);
+
+ dwarfgen::DIE TypeNoValueCountDie = CUDie.addChild(DW_TAG_subrange_type);
+ TypeNoValueCountDie.addAttribute(DW_AT_count, DW_FORM_sdata, 1);
+
+ dwarfgen::DIE TypeImplicitCountDie = CUDie.addChild(DW_TAG_subrange_type);
+ TypeImplicitCountDie.addAttribute(DW_AT_count, DW_FORM_implicit_const, 1);
+
+ dwarfgen::DIE TypeValueRangeDie = CUDie.addChild(DW_TAG_subrange_type);
+ TypeValueRangeDie.addAttribute(DW_AT_lower_bound, DW_FORM_data4, 1);
+ TypeValueRangeDie.addAttribute(DW_AT_upper_bound, DW_FORM_data4, 2);
+
+ dwarfgen::DIE TypeNoValueRangeDie = CUDie.addChild(DW_TAG_subrange_type);
+ TypeNoValueRangeDie.addAttribute(DW_AT_lower_bound, DW_FORM_addr, 3);
+ TypeNoValueRangeDie.addAttribute(DW_AT_upper_bound, DW_FORM_addr, 4);
+
+ dwarfgen::DIE TypeImplicitRangeDie = CUDie.addChild(DW_TAG_subrange_type);
+ TypeImplicitRangeDie.addAttribute(DW_AT_lower_bound, DW_FORM_implicit_const,
+ 5);
+ TypeImplicitRangeDie.addAttribute(DW_AT_upper_bound, DW_FORM_implicit_const,
+ 6);
+
+ // Generate the DWARF.
+ StringRef FileBytes = DG->generate();
+ MemoryBufferRef FileBuffer(FileBytes, "dwarf");
+ auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
+ EXPECT_TRUE((bool)Obj);
+ std::unique_ptr<DWARFContext> DwarfContext = DWARFContext::create(**Obj);
+
+ // Verify the number of compile units is correct.
+ uint32_t NumCUs = DwarfContext->getNumCompileUnits();
+ EXPECT_EQ(NumCUs, 1u);
+ DWARFCompileUnit *U = cast<DWARFCompileUnit>(DwarfContext->getUnitAtIndex(0));
+ auto DieDG = U->getUnitDIE(false);
+ EXPECT_TRUE(DieDG.isValid());
+
+ // Verify the siblings correct order.
+ // ScopeValue
+ // ScopeNoValue
+ // ScopeImplicit
+ auto ScopeValueDieDG = DieDG.getFirstChild();
+ EXPECT_TRUE(ScopeValueDieDG.isValid());
+ EXPECT_EQ(ScopeValueDieDG.getTag(), DW_TAG_inlined_subroutine);
+ auto ScopeNoValueDieDG = ScopeValueDieDG.getSibling();
+ EXPECT_TRUE(ScopeNoValueDieDG.isValid());
+ EXPECT_EQ(ScopeNoValueDieDG.getTag(), DW_TAG_inlined_subroutine);
+ auto ScopeImplicitDieDG = ScopeNoValueDieDG.getSibling();
+ EXPECT_TRUE(ScopeImplicitDieDG.isValid());
+ EXPECT_EQ(ScopeImplicitDieDG.getTag(), DW_TAG_inlined_subroutine);
+
+ // Verify the siblings correct order.
+ // SymbolValue
+ // SymbolNoValue
+ // SymbolImplicitValue
+ auto SymbolValueDieDG = ScopeImplicitDieDG.getSibling();
+ EXPECT_TRUE(SymbolValueDieDG.isValid());
+ EXPECT_EQ(SymbolValueDieDG.getTag(), DW_TAG_variable);
+ auto SymbolNoValueDieDG = SymbolValueDieDG.getSibling();
+ EXPECT_TRUE(SymbolNoValueDieDG.isValid());
+ EXPECT_EQ(SymbolNoValueDieDG.getTag(), DW_TAG_variable);
+ auto SymbolImplicitDieDG = SymbolNoValueDieDG.getSibling();
+ EXPECT_TRUE(SymbolImplicitDieDG.isValid());
+ EXPECT_EQ(SymbolImplicitDieDG.getTag(), DW_TAG_variable);
+
+ // Verify the siblings correct order.
+ // TypeValueCount
+ // TypeNoValueCount
+ // TypeImplicitValueCount
+ auto TypeValueCountDieDG = SymbolImplicitDieDG.getSibling();
+ EXPECT_TRUE(TypeValueCountDieDG.isValid());
+ EXPECT_EQ(TypeValueCountDieDG.getTag(), DW_TAG_subrange_type);
+ auto TypeNoValueCountDieDG = TypeValueCountDieDG.getSibling();
+ EXPECT_TRUE(TypeNoValueCountDieDG.isValid());
+ EXPECT_EQ(TypeNoValueCountDieDG.getTag(), DW_TAG_subrange_type);
+ auto TypeImplicitCountDieDG = TypeNoValueCountDieDG.getSibling();
+ EXPECT_TRUE(TypeImplicitCountDieDG.isValid());
+ EXPECT_EQ(TypeImplicitCountDieDG.getTag(), DW_TAG_subrange_type);
+
+ // Verify the siblings correct order.
+ // TypeValueRange
+ // TypeNoValueRange
+ // TypeImplicitValueRange
+ auto TypeValueRangeDieDG = TypeImplicitCountDieDG.getSibling();
+ EXPECT_TRUE(TypeValueRangeDieDG.isValid());
+ EXPECT_EQ(TypeValueRangeDieDG.getTag(), DW_TAG_subrange_type);
+ auto TypeNoValueRangeDieDG = TypeValueRangeDieDG.getSibling();
+ EXPECT_TRUE(TypeNoValueRangeDieDG.isValid());
+ EXPECT_EQ(TypeNoValueRangeDieDG.getTag(), DW_TAG_subrange_type);
+ auto TypeImplicitRangeDieDG = TypeNoValueRangeDieDG.getSibling();
+ EXPECT_TRUE(TypeImplicitRangeDieDG.isValid());
+ EXPECT_EQ(TypeImplicitRangeDieDG.getTag(), DW_TAG_subrange_type);
+
+ // Save the generated DWARF file to disk.
+ EXPECT_TRUE(DG->saveFile(Path));
+}
+
+// Check the logical elements basic properties.
+void checkElementAttributes(LVReader *Reader) {
+ LVScopeRoot *Root = Reader->getScopesRoot();
+ EXPECT_NE(Root, nullptr);
+ LVScopeCompileUnit *CompileUnit = getFirstCompileUnit(Root);
+
+ const LVScopes *Scopes = CompileUnit->getScopes();
+ ASSERT_NE(Scopes, nullptr);
+ ASSERT_EQ(Scopes->size(), 3u);
+
+ // Check values.
+ LVScopes::const_iterator ScopeIter = Scopes->begin();
+ EXPECT_NE(ScopeIter, nullptr);
+ LVScope *Scope = static_cast<LVScope *>(*ScopeIter);
+ EXPECT_NE(Scope, nullptr);
+ EXPECT_EQ(Scope->getAccessibilityCode(), 1); // Element
+ EXPECT_EQ(Scope->getInlineCode(), 2); // Element
+ EXPECT_EQ(Scope->getVirtualityCode(), 3); // Element
+ EXPECT_EQ(Scope->getCallFilenameIndex(), 5); // ScopeFunctionInlined
+ EXPECT_EQ(Scope->getCallLineNumber(), 5); // ScopeFunctionInlined
+ EXPECT_EQ(Scope->getFilenameIndex(), 7); // Element
+ EXPECT_EQ(Scope->getLineNumber(), 7); // Element
+ EXPECT_EQ(Scope->getDiscriminator(), 8); // ScopeFunctionInlined
+
+ // Check no-values.
+ EXPECT_NE(++ScopeIter, nullptr);
+ Scope = static_cast<LVScope *>(*ScopeIter);
+ EXPECT_NE(Scope, nullptr);
+ EXPECT_EQ(Scope->getAccessibilityCode(), 0); // Element
+ EXPECT_EQ(Scope->getInlineCode(), 0); // Element
+ EXPECT_EQ(Scope->getVirtualityCode(), 0); // Element
+ EXPECT_EQ(Scope->getCallFilenameIndex(), 1); // ScopeFunctionInlined
+ EXPECT_EQ(Scope->getCallLineNumber(), 0); // ScopeFunctionInlined
+ EXPECT_EQ(Scope->getFilenameIndex(), 1); // Element
+ EXPECT_EQ(Scope->getLineNumber(), 0); // Element
+ EXPECT_EQ(Scope->getDiscriminator(), 0); // ScopeFunctionInlined
+
+ // Check implicit values.
+ EXPECT_NE(++ScopeIter, nullptr);
+ Scope = static_cast<LVScope *>(*ScopeIter);
+ EXPECT_NE(Scope, nullptr);
+ EXPECT_EQ(Scope->getAccessibilityCode(), 1); // Element
+ EXPECT_EQ(Scope->getInlineCode(), 2); // Element
+ EXPECT_EQ(Scope->getVirtualityCode(), 3); // Element
+ EXPECT_EQ(Scope->getCallFilenameIndex(), 5); // ScopeFunctionInlined
+ EXPECT_EQ(Scope->getCallLineNumber(), 5); // ScopeFunctionInlined
+ EXPECT_EQ(Scope->getFilenameIndex(), 7); // Element
+ EXPECT_EQ(Scope->getLineNumber(), 7); // Element
+ EXPECT_EQ(Scope->getDiscriminator(), 8); // ScopeFunctionInlined
+
+ const LVSymbols *Symbols = CompileUnit->getSymbols();
+ ASSERT_NE(Symbols, nullptr);
+ ASSERT_EQ(Symbols->size(), 3u);
+
+ // Check values.
+ LVSymbols::const_iterator SymbolIter = Symbols->begin();
+ EXPECT_NE(SymbolIter, nullptr);
----------------
pogo59 wrote:
```suggestion
ASSERT_NE(SymbolIter, nullptr);
```
https://github.com/llvm/llvm-project/pull/116027
More information about the llvm-commits
mailing list