| //===- llvm/unittest/DebugInfo/LogicalView/LogicalElementsTest.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 "llvm/DebugInfo/LogicalView/Core/LVLine.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/Support/ScopedPrinter.h" |
| #include "llvm/Support/ToolOutputFile.h" |
| #include "llvm/Testing/Support/Error.h" |
| |
| #include "gtest/gtest.h" |
| |
| using namespace llvm; |
| using namespace llvm::logicalview; |
| |
| namespace { |
| |
| class ReaderTestElements : public LVReader { |
| #define CREATE(VARIABLE, CREATE_FUNCTION) \ |
| VARIABLE = CREATE_FUNCTION(); \ |
| EXPECT_NE(VARIABLE, nullptr); |
| |
| // Types. |
| LVType *IntegerType = nullptr; |
| LVType *UnsignedType = nullptr; |
| LVType *GlobalType = nullptr; |
| LVType *LocalType = nullptr; |
| LVType *NestedType = nullptr; |
| LVTypeDefinition *TypeDefinitionOne = nullptr; |
| LVTypeDefinition *TypeDefinitionTwo = nullptr; |
| LVTypeEnumerator *EnumeratorOne = nullptr; |
| LVTypeEnumerator *EnumeratorTwo = nullptr; |
| LVTypeImport *TypeImport = nullptr; |
| LVTypeParam *TypeParam = nullptr; |
| LVTypeSubrange *TypeSubrange = nullptr; |
| |
| // Scopes. |
| LVScope *NestedScope = nullptr; |
| LVScopeAggregate *Aggregate = nullptr; |
| LVScopeArray *Array = nullptr; |
| LVScopeEnumeration *Enumeration = nullptr; |
| LVScopeFunction *Function = nullptr; |
| LVScopeFunction *ClassFunction = nullptr; |
| LVScopeFunctionInlined *InlinedFunction = nullptr; |
| LVScopeNamespace *Namespace = nullptr; |
| |
| // Symbols. |
| LVSymbol *GlobalVariable = nullptr; |
| LVSymbol *LocalVariable = nullptr; |
| LVSymbol *ClassMember = nullptr; |
| LVSymbol *NestedVariable = nullptr; |
| LVSymbol *Parameter = nullptr; |
| |
| // Lines. |
| LVLine *LocalLine = nullptr; |
| LVLine *NestedLine = nullptr; |
| |
| protected: |
| void add(LVScope *Parent, LVElement *Element); |
| void set(LVElement *Element, StringRef Name, LVOffset Offset, |
| uint32_t LineNumber = 0, LVElement *Type = nullptr); |
| |
| public: |
| ReaderTestElements(ScopedPrinter &W) : LVReader("", "", W) { |
| setInstance(this); |
| } |
| |
| Error createScopes() { return LVReader::createScopes(); } |
| Error printScopes() { return LVReader::printScopes(); } |
| |
| void createElements(); |
| void addElements(); |
| void initElements(); |
| }; |
| |
| // Helper function to add a logical element to a given scope. |
| void ReaderTestElements::add(LVScope *Parent, LVElement *Child) { |
| Parent->addElement(Child); |
| EXPECT_EQ(Child->getParent(), Parent); |
| EXPECT_EQ(Child->getLevel(), Parent->getLevel() + 1); |
| } |
| |
| // Helper function to set the initial values for a given logical element. |
| void ReaderTestElements::set(LVElement *Element, StringRef Name, |
| LVOffset Offset, uint32_t LineNumber, |
| LVElement *Type) { |
| Element->setName(Name); |
| Element->setOffset(Offset); |
| Element->setLineNumber(LineNumber); |
| Element->setType(Type); |
| EXPECT_EQ(Element->getName(), Name); |
| EXPECT_EQ(Element->getOffset(), Offset); |
| EXPECT_EQ(Element->getLineNumber(), LineNumber); |
| EXPECT_EQ(Element->getType(), Type); |
| } |
| |
| // Create the logical elements. |
| void ReaderTestElements::createElements() { |
| // Create scope root. |
| Error Err = createScopes(); |
| ASSERT_THAT_ERROR(std::move(Err), Succeeded()); |
| Root = getScopesRoot(); |
| ASSERT_NE(Root, nullptr); |
| |
| // Create the logical types. |
| CREATE(IntegerType, createType); |
| CREATE(UnsignedType, createType); |
| CREATE(GlobalType, createType); |
| CREATE(LocalType, createType); |
| CREATE(NestedType, createType); |
| CREATE(EnumeratorOne, createTypeEnumerator); |
| CREATE(EnumeratorTwo, createTypeEnumerator); |
| CREATE(TypeDefinitionOne, createTypeDefinition); |
| CREATE(TypeDefinitionTwo, createTypeDefinition); |
| CREATE(TypeSubrange, createTypeSubrange); |
| CREATE(TypeParam, createTypeParam); |
| CREATE(TypeImport, createTypeImport); |
| |
| // Create the logical scopes. |
| CREATE(NestedScope, createScope); |
| CREATE(Aggregate, createScopeAggregate); |
| CREATE(Array, createScopeArray); |
| CREATE(CompileUnit, createScopeCompileUnit); |
| CREATE(Enumeration, createScopeEnumeration); |
| CREATE(Function, createScopeFunction); |
| CREATE(ClassFunction, createScopeFunction); |
| CREATE(InlinedFunction, createScopeFunctionInlined); |
| CREATE(Namespace, createScopeNamespace); |
| |
| // Create the logical symbols. |
| CREATE(GlobalVariable, createSymbol); |
| CREATE(LocalVariable, createSymbol); |
| CREATE(ClassMember, createSymbol); |
| CREATE(NestedVariable, createSymbol); |
| CREATE(Parameter, createSymbol); |
| |
| // Create the logical lines. |
| CREATE(LocalLine, createLine); |
| CREATE(NestedLine, createLine); |
| } |
| |
| // Create the logical view adding the created logical elements. |
| void ReaderTestElements::addElements() { |
| setCompileUnit(CompileUnit); |
| |
| // Root |
| // CompileUnit |
| // IntegerType |
| // UnsignedType |
| // Array |
| // TypeSubrange |
| // Function |
| // Parameter |
| // LocalVariable |
| // LocalType |
| // LocalLine |
| // InlinedFunction |
| // TypeImport |
| // TypeParam |
| // NestedScope |
| // NestedVariable |
| // NestedType |
| // NestedLine |
| // GlobalVariable |
| // GlobalType |
| // Namespace |
| // Aggregate |
| // ClassMember |
| // ClassFunction |
| // Enumeration |
| // EnumeratorOne |
| // EnumeratorTwo |
| // TypeDefinitionOne |
| // TypeDefinitionTwo |
| |
| add(Root, CompileUnit); |
| EXPECT_EQ(Root->lineCount(), 0u); |
| EXPECT_EQ(Root->scopeCount(), 1u); |
| EXPECT_EQ(Root->symbolCount(), 0u); |
| EXPECT_EQ(Root->typeCount(), 0u); |
| |
| // Add elements to CompileUnit. |
| add(CompileUnit, IntegerType); |
| add(CompileUnit, UnsignedType); |
| add(CompileUnit, Array); |
| add(CompileUnit, Function); |
| add(CompileUnit, GlobalVariable); |
| add(CompileUnit, GlobalType); |
| add(CompileUnit, Namespace); |
| EXPECT_EQ(CompileUnit->lineCount(), 0u); |
| EXPECT_EQ(CompileUnit->scopeCount(), 3u); |
| EXPECT_EQ(CompileUnit->symbolCount(), 1u); |
| EXPECT_EQ(CompileUnit->typeCount(), 3u); |
| |
| // Add elements to Namespace. |
| add(Namespace, Aggregate); |
| add(Namespace, Enumeration); |
| add(Namespace, TypeDefinitionOne); |
| add(Namespace, TypeDefinitionTwo); |
| EXPECT_EQ(Namespace->lineCount(), 0u); |
| EXPECT_EQ(Namespace->scopeCount(), 2u); |
| EXPECT_EQ(Namespace->symbolCount(), 0u); |
| EXPECT_EQ(Namespace->typeCount(), 2u); |
| |
| // Add elements to Function. |
| add(Function, Parameter); |
| add(Function, LocalVariable); |
| add(Function, LocalType); |
| add(Function, LocalLine); |
| add(Function, InlinedFunction); |
| add(Function, TypeImport); |
| add(Function, TypeParam); |
| add(Function, NestedScope); |
| EXPECT_EQ(Function->lineCount(), 1u); |
| EXPECT_EQ(Function->scopeCount(), 2u); |
| EXPECT_EQ(Function->symbolCount(), 2u); |
| EXPECT_EQ(Function->typeCount(), 3u); |
| |
| // Add elements to NestedScope. |
| add(NestedScope, NestedVariable); |
| add(NestedScope, NestedType); |
| add(NestedScope, NestedLine); |
| EXPECT_EQ(NestedScope->lineCount(), 1u); |
| EXPECT_EQ(NestedScope->scopeCount(), 0u); |
| EXPECT_EQ(NestedScope->symbolCount(), 1u); |
| EXPECT_EQ(NestedScope->typeCount(), 1u); |
| |
| // Add elements to Enumeration. |
| add(Enumeration, EnumeratorOne); |
| add(Enumeration, EnumeratorTwo); |
| EXPECT_EQ(Enumeration->lineCount(), 0u); |
| EXPECT_EQ(Enumeration->scopeCount(), 0u); |
| EXPECT_EQ(Enumeration->symbolCount(), 0u); |
| EXPECT_EQ(Enumeration->typeCount(), 2u); |
| |
| // Add elements to Aggregate. |
| add(Aggregate, ClassMember); |
| add(Aggregate, ClassFunction); |
| EXPECT_EQ(Aggregate->lineCount(), 0u); |
| EXPECT_EQ(Aggregate->scopeCount(), 1u); |
| EXPECT_EQ(Aggregate->symbolCount(), 1u); |
| EXPECT_EQ(Aggregate->typeCount(), 0u); |
| |
| // Add elements to Array. |
| add(Array, TypeSubrange); |
| EXPECT_EQ(Array->lineCount(), 0u); |
| EXPECT_EQ(Array->scopeCount(), 0u); |
| EXPECT_EQ(Array->symbolCount(), 0u); |
| EXPECT_EQ(Array->typeCount(), 1u); |
| } |
| |
| // Set initial values to logical elements. |
| void ReaderTestElements::initElements() { |
| setFilename("LogicalElements.obj"); |
| EXPECT_EQ(getFilename(), "LogicalElements.obj"); |
| |
| Root->setFileFormatName("FileFormat"); |
| EXPECT_EQ(Root->getFileFormatName(), "FileFormat"); |
| |
| // Types. |
| set(IntegerType, "int", 0x1000); |
| set(UnsignedType, "unsigned", 0x1010); |
| set(GlobalType, "GlobalType", 0x1020, 1020); |
| set(LocalType, "LocalType", 0x1030, 1030); |
| set(NestedType, "NestedType", 0x1040, 1040); |
| |
| set(TypeDefinitionOne, "INTEGER", 0x1040, 1040, IntegerType); |
| set(TypeDefinitionTwo, "INT", 0x1050, 1050, TypeDefinitionOne); |
| EXPECT_EQ(TypeDefinitionOne->getUnderlyingType(), IntegerType); |
| EXPECT_EQ(TypeDefinitionTwo->getUnderlyingType(), IntegerType); |
| |
| set(EnumeratorOne, "one", 0x1060, 1060); |
| EnumeratorOne->setValue("blue"); |
| EXPECT_EQ(EnumeratorOne->getValue(), "blue"); |
| |
| set(EnumeratorTwo, "two", 0x1070, 1070); |
| EnumeratorTwo->setValue("red"); |
| EXPECT_EQ(EnumeratorTwo->getValue(), "red"); |
| |
| set(TypeSubrange, "", 0x1080, 1080, IntegerType); |
| TypeSubrange->setCount(5); |
| EXPECT_EQ(TypeSubrange->getCount(), 5); |
| |
| TypeSubrange->setLowerBound(10); |
| TypeSubrange->setUpperBound(15); |
| EXPECT_EQ(TypeSubrange->getLowerBound(), 10); |
| EXPECT_EQ(TypeSubrange->getUpperBound(), 15); |
| |
| TypeSubrange->setBounds(20, 25); |
| std::pair<unsigned, unsigned> Pair; |
| Pair = TypeSubrange->getBounds(); |
| EXPECT_EQ(Pair.first, 20u); |
| EXPECT_EQ(Pair.second, 25u); |
| |
| set(TypeParam, "INTEGER", 0x1090, 1090, UnsignedType); |
| TypeParam->setValue("10"); |
| EXPECT_EQ(TypeParam->getValue(), "10"); |
| |
| set(TypeImport, "", 0x1090, 1090, Aggregate); |
| EXPECT_EQ(TypeImport->getType(), Aggregate); |
| |
| // Scopes. |
| set(Aggregate, "Class", 0x2000, 2000); |
| set(Enumeration, "Colors", 0x2010, 2010); |
| set(Function, "function", 0x2020, 2020, GlobalType); |
| set(ClassFunction, "foo", 0x2030, 2030, TypeDefinitionTwo); |
| set(Namespace, "nsp", 0x2040, 2040); |
| set(NestedScope, "", 0x2050, 2050); |
| set(Array, "", 0x2060, 2060, UnsignedType); |
| set(InlinedFunction, "bar", 0x2070, 2070, TypeDefinitionOne); |
| set(CompileUnit, "test.cpp", 0x2080, 2080); |
| |
| // Symbols. |
| set(GlobalVariable, "GlobalVariable", 0x3000, 3000); |
| set(LocalVariable, "LocalVariable", 0x3010, 3010, TypeDefinitionOne); |
| set(ClassMember, "Member", 0x3020, 3020, IntegerType); |
| set(Parameter, "Param", 0x3030, 3030, UnsignedType); |
| set(NestedVariable, "NestedVariable", 0x3040, 3040); |
| |
| // Lines. |
| set(LocalLine, "", 0x4000, 4000); |
| set(NestedLine, "", 0x4010, 4010); |
| } |
| |
| TEST(LogicalViewTest, LogicalElements) { |
| ScopedPrinter W(outs()); |
| ReaderTestElements Reader(W); |
| |
| Reader.createElements(); |
| Reader.addElements(); |
| Reader.initElements(); |
| } |
| |
| } // namespace |