llvm-project/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp

343 lines
11 KiB
C++

//===- 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 {
// 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);
template <typename T> T *create() {
T *Element = new (std::nothrow) T();
EXPECT_NE(Element, nullptr);
return 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.
IntegerType = create<LVType>();
UnsignedType = create<LVType>();
GlobalType = create<LVType>();
LocalType = create<LVType>();
NestedType = create<LVType>();
EnumeratorOne = create<LVTypeEnumerator>();
EnumeratorTwo = create<LVTypeEnumerator>();
TypeDefinitionOne = create<LVTypeDefinition>();
TypeDefinitionTwo = create<LVTypeDefinition>();
TypeSubrange = create<LVTypeSubrange>();
TypeParam = create<LVTypeParam>();
TypeImport = create<LVTypeImport>();
// Create the logical scopes.
NestedScope = create<LVScope>();
Aggregate = create<LVScopeAggregate>();
Array = create<LVScopeArray>();
CompileUnit = create<LVScopeCompileUnit>();
Enumeration = create<LVScopeEnumeration>();
Function = create<LVScopeFunction>();
ClassFunction = create<LVScopeFunction>();
InlinedFunction = create<LVScopeFunctionInlined>();
Namespace = create<LVScopeNamespace>();
// Create the logical symbols.
GlobalVariable = create<LVSymbol>();
LocalVariable = create<LVSymbol>();
ClassMember = create<LVSymbol>();
NestedVariable = create<LVSymbol>();
Parameter = create<LVSymbol>();
// Create the logical lines.
LocalLine = create<LVLine>();
NestedLine = create<LVLine>();
}
// 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