xref: /llvm-project/llvm/unittests/DebugInfo/LogicalView/LogicalElementsTest.cpp (revision 7fbcc24409efdb37cec79ad461ef383f6ffc5ef2)
1 //===- llvm/unittest/DebugInfo/LogicalView/LogicalElementsTest.cpp --------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
10 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
11 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
12 #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
13 #include "llvm/DebugInfo/LogicalView/Core/LVType.h"
14 #include "llvm/Support/ScopedPrinter.h"
15 #include "llvm/Support/ToolOutputFile.h"
16 #include "llvm/Testing/Support/Error.h"
17 
18 #include "gtest/gtest.h"
19 
20 using namespace llvm;
21 using namespace llvm::logicalview;
22 
23 namespace {
24 
25 class ReaderTestElements : public LVReader {
26 #define CREATE(VARIABLE, CREATE_FUNCTION)                                      \
27   VARIABLE = CREATE_FUNCTION();                                                \
28   EXPECT_NE(VARIABLE, nullptr);
29 
30   // Types.
31   LVType *IntegerType = nullptr;
32   LVType *UnsignedType = nullptr;
33   LVType *GlobalType = nullptr;
34   LVType *LocalType = nullptr;
35   LVType *NestedType = nullptr;
36   LVTypeDefinition *TypeDefinitionOne = nullptr;
37   LVTypeDefinition *TypeDefinitionTwo = nullptr;
38   LVTypeEnumerator *EnumeratorOne = nullptr;
39   LVTypeEnumerator *EnumeratorTwo = nullptr;
40   LVTypeImport *TypeImport = nullptr;
41   LVTypeParam *TypeParam = nullptr;
42   LVTypeSubrange *TypeSubrange = nullptr;
43 
44   // Scopes.
45   LVScope *NestedScope = nullptr;
46   LVScopeAggregate *Aggregate = nullptr;
47   LVScopeArray *Array = nullptr;
48   LVScopeEnumeration *Enumeration = nullptr;
49   LVScopeFunction *Function = nullptr;
50   LVScopeFunction *ClassFunction = nullptr;
51   LVScopeFunctionInlined *InlinedFunction = nullptr;
52   LVScopeNamespace *Namespace = nullptr;
53 
54   // Symbols.
55   LVSymbol *GlobalVariable = nullptr;
56   LVSymbol *LocalVariable = nullptr;
57   LVSymbol *ClassMember = nullptr;
58   LVSymbol *NestedVariable = nullptr;
59   LVSymbol *Parameter = nullptr;
60 
61   // Lines.
62   LVLine *LocalLine = nullptr;
63   LVLine *NestedLine = nullptr;
64 
65 protected:
66   void add(LVScope *Parent, LVElement *Element);
67   void set(LVElement *Element, StringRef Name, LVOffset Offset,
68            uint32_t LineNumber = 0, LVElement *Type = nullptr);
69 
70 public:
ReaderTestElements(ScopedPrinter & W)71   ReaderTestElements(ScopedPrinter &W) : LVReader("", "", W) {
72     setInstance(this);
73   }
74 
createScopes()75   Error createScopes() { return LVReader::createScopes(); }
printScopes()76   Error printScopes() { return LVReader::printScopes(); }
77 
78   void createElements();
79   void addElements();
80   void initElements();
81 };
82 
83 // Helper function to add a logical element to a given scope.
add(LVScope * Parent,LVElement * Child)84 void ReaderTestElements::add(LVScope *Parent, LVElement *Child) {
85   Parent->addElement(Child);
86   EXPECT_EQ(Child->getParent(), Parent);
87   EXPECT_EQ(Child->getLevel(), Parent->getLevel() + 1);
88 }
89 
90 // Helper function to set the initial values for a given logical element.
set(LVElement * Element,StringRef Name,LVOffset Offset,uint32_t LineNumber,LVElement * Type)91 void ReaderTestElements::set(LVElement *Element, StringRef Name,
92                              LVOffset Offset, uint32_t LineNumber,
93                              LVElement *Type) {
94   Element->setName(Name);
95   Element->setOffset(Offset);
96   Element->setLineNumber(LineNumber);
97   Element->setType(Type);
98   EXPECT_EQ(Element->getName(), Name);
99   EXPECT_EQ(Element->getOffset(), Offset);
100   EXPECT_EQ(Element->getLineNumber(), LineNumber);
101   EXPECT_EQ(Element->getType(), Type);
102 }
103 
104 // Create the logical elements.
createElements()105 void ReaderTestElements::createElements() {
106   // Create scope root.
107   Error Err = createScopes();
108   ASSERT_THAT_ERROR(std::move(Err), Succeeded());
109   Root = getScopesRoot();
110   ASSERT_NE(Root, nullptr);
111 
112   // Create the logical types.
113   CREATE(IntegerType, createType);
114   CREATE(UnsignedType, createType);
115   CREATE(GlobalType, createType);
116   CREATE(LocalType, createType);
117   CREATE(NestedType, createType);
118   CREATE(EnumeratorOne, createTypeEnumerator);
119   CREATE(EnumeratorTwo, createTypeEnumerator);
120   CREATE(TypeDefinitionOne, createTypeDefinition);
121   CREATE(TypeDefinitionTwo, createTypeDefinition);
122   CREATE(TypeSubrange, createTypeSubrange);
123   CREATE(TypeParam, createTypeParam);
124   CREATE(TypeImport, createTypeImport);
125 
126   // Create the logical scopes.
127   CREATE(NestedScope, createScope);
128   CREATE(Aggregate, createScopeAggregate);
129   CREATE(Array, createScopeArray);
130   CREATE(CompileUnit, createScopeCompileUnit);
131   CREATE(Enumeration, createScopeEnumeration);
132   CREATE(Function, createScopeFunction);
133   CREATE(ClassFunction, createScopeFunction);
134   CREATE(InlinedFunction, createScopeFunctionInlined);
135   CREATE(Namespace, createScopeNamespace);
136 
137   // Create the logical symbols.
138   CREATE(GlobalVariable, createSymbol);
139   CREATE(LocalVariable, createSymbol);
140   CREATE(ClassMember, createSymbol);
141   CREATE(NestedVariable, createSymbol);
142   CREATE(Parameter, createSymbol);
143 
144   // Create the logical lines.
145   CREATE(LocalLine, createLine);
146   CREATE(NestedLine, createLine);
147 }
148 
149 // Create the logical view adding the created logical elements.
addElements()150 void ReaderTestElements::addElements() {
151   setCompileUnit(CompileUnit);
152 
153   // Root
154   //   CompileUnit
155   //     IntegerType
156   //     UnsignedType
157   //     Array
158   //       TypeSubrange
159   //     Function
160   //       Parameter
161   //       LocalVariable
162   //       LocalType
163   //       LocalLine
164   //       InlinedFunction
165   //       TypeImport
166   //       TypeParam
167   //       NestedScope
168   //         NestedVariable
169   //         NestedType
170   //         NestedLine
171   //     GlobalVariable
172   //     GlobalType
173   //     Namespace
174   //       Aggregate
175   //         ClassMember
176   //         ClassFunction
177   //       Enumeration
178   //         EnumeratorOne
179   //         EnumeratorTwo
180   //       TypeDefinitionOne
181   //       TypeDefinitionTwo
182 
183   add(Root, CompileUnit);
184   EXPECT_EQ(Root->lineCount(), 0u);
185   EXPECT_EQ(Root->scopeCount(), 1u);
186   EXPECT_EQ(Root->symbolCount(), 0u);
187   EXPECT_EQ(Root->typeCount(), 0u);
188 
189   // Add elements to CompileUnit.
190   add(CompileUnit, IntegerType);
191   add(CompileUnit, UnsignedType);
192   add(CompileUnit, Array);
193   add(CompileUnit, Function);
194   add(CompileUnit, GlobalVariable);
195   add(CompileUnit, GlobalType);
196   add(CompileUnit, Namespace);
197   EXPECT_EQ(CompileUnit->lineCount(), 0u);
198   EXPECT_EQ(CompileUnit->scopeCount(), 3u);
199   EXPECT_EQ(CompileUnit->symbolCount(), 1u);
200   EXPECT_EQ(CompileUnit->typeCount(), 3u);
201 
202   // Add elements to Namespace.
203   add(Namespace, Aggregate);
204   add(Namespace, Enumeration);
205   add(Namespace, TypeDefinitionOne);
206   add(Namespace, TypeDefinitionTwo);
207   EXPECT_EQ(Namespace->lineCount(), 0u);
208   EXPECT_EQ(Namespace->scopeCount(), 2u);
209   EXPECT_EQ(Namespace->symbolCount(), 0u);
210   EXPECT_EQ(Namespace->typeCount(), 2u);
211 
212   // Add elements to Function.
213   add(Function, Parameter);
214   add(Function, LocalVariable);
215   add(Function, LocalType);
216   add(Function, LocalLine);
217   add(Function, InlinedFunction);
218   add(Function, TypeImport);
219   add(Function, TypeParam);
220   add(Function, NestedScope);
221   EXPECT_EQ(Function->lineCount(), 1u);
222   EXPECT_EQ(Function->scopeCount(), 2u);
223   EXPECT_EQ(Function->symbolCount(), 2u);
224   EXPECT_EQ(Function->typeCount(), 3u);
225 
226   // Add elements to NestedScope.
227   add(NestedScope, NestedVariable);
228   add(NestedScope, NestedType);
229   add(NestedScope, NestedLine);
230   EXPECT_EQ(NestedScope->lineCount(), 1u);
231   EXPECT_EQ(NestedScope->scopeCount(), 0u);
232   EXPECT_EQ(NestedScope->symbolCount(), 1u);
233   EXPECT_EQ(NestedScope->typeCount(), 1u);
234 
235   // Add elements to Enumeration.
236   add(Enumeration, EnumeratorOne);
237   add(Enumeration, EnumeratorTwo);
238   EXPECT_EQ(Enumeration->lineCount(), 0u);
239   EXPECT_EQ(Enumeration->scopeCount(), 0u);
240   EXPECT_EQ(Enumeration->symbolCount(), 0u);
241   EXPECT_EQ(Enumeration->typeCount(), 2u);
242 
243   // Add elements to Aggregate.
244   add(Aggregate, ClassMember);
245   add(Aggregate, ClassFunction);
246   EXPECT_EQ(Aggregate->lineCount(), 0u);
247   EXPECT_EQ(Aggregate->scopeCount(), 1u);
248   EXPECT_EQ(Aggregate->symbolCount(), 1u);
249   EXPECT_EQ(Aggregate->typeCount(), 0u);
250 
251   // Add elements to Array.
252   add(Array, TypeSubrange);
253   EXPECT_EQ(Array->lineCount(), 0u);
254   EXPECT_EQ(Array->scopeCount(), 0u);
255   EXPECT_EQ(Array->symbolCount(), 0u);
256   EXPECT_EQ(Array->typeCount(), 1u);
257 }
258 
259 // Set initial values to logical elements.
initElements()260 void ReaderTestElements::initElements() {
261   setFilename("LogicalElements.obj");
262   EXPECT_EQ(getFilename(), "LogicalElements.obj");
263 
264   Root->setFileFormatName("FileFormat");
265   EXPECT_EQ(Root->getFileFormatName(), "FileFormat");
266 
267   // Types.
268   set(IntegerType, "int", 0x1000);
269   set(UnsignedType, "unsigned", 0x1010);
270   set(GlobalType, "GlobalType", 0x1020, 1020);
271   set(LocalType, "LocalType", 0x1030, 1030);
272   set(NestedType, "NestedType", 0x1040, 1040);
273 
274   set(TypeDefinitionOne, "INTEGER", 0x1040, 1040, IntegerType);
275   set(TypeDefinitionTwo, "INT", 0x1050, 1050, TypeDefinitionOne);
276   EXPECT_EQ(TypeDefinitionOne->getUnderlyingType(), IntegerType);
277   EXPECT_EQ(TypeDefinitionTwo->getUnderlyingType(), IntegerType);
278 
279   set(EnumeratorOne, "one", 0x1060, 1060);
280   EnumeratorOne->setValue("blue");
281   EXPECT_EQ(EnumeratorOne->getValue(), "blue");
282 
283   set(EnumeratorTwo, "two", 0x1070, 1070);
284   EnumeratorTwo->setValue("red");
285   EXPECT_EQ(EnumeratorTwo->getValue(), "red");
286 
287   set(TypeSubrange, "", 0x1080, 1080, IntegerType);
288   TypeSubrange->setCount(5);
289   EXPECT_EQ(TypeSubrange->getCount(), 5);
290 
291   TypeSubrange->setLowerBound(10);
292   TypeSubrange->setUpperBound(15);
293   EXPECT_EQ(TypeSubrange->getLowerBound(), 10);
294   EXPECT_EQ(TypeSubrange->getUpperBound(), 15);
295 
296   TypeSubrange->setBounds(20, 25);
297   std::pair<unsigned, unsigned> Pair;
298   Pair = TypeSubrange->getBounds();
299   EXPECT_EQ(Pair.first, 20u);
300   EXPECT_EQ(Pair.second, 25u);
301 
302   set(TypeParam, "INTEGER", 0x1090, 1090, UnsignedType);
303   TypeParam->setValue("10");
304   EXPECT_EQ(TypeParam->getValue(), "10");
305 
306   set(TypeImport, "", 0x1090, 1090, Aggregate);
307   EXPECT_EQ(TypeImport->getType(), Aggregate);
308 
309   // Scopes.
310   set(Aggregate, "Class", 0x2000, 2000);
311   set(Enumeration, "Colors", 0x2010, 2010);
312   set(Function, "function", 0x2020, 2020, GlobalType);
313   set(ClassFunction, "foo", 0x2030, 2030, TypeDefinitionTwo);
314   set(Namespace, "nsp", 0x2040, 2040);
315   set(NestedScope, "", 0x2050, 2050);
316   set(Array, "", 0x2060, 2060, UnsignedType);
317   set(InlinedFunction, "bar", 0x2070, 2070, TypeDefinitionOne);
318   set(CompileUnit, "test.cpp", 0x2080, 2080);
319 
320   // Symbols.
321   set(GlobalVariable, "GlobalVariable", 0x3000, 3000);
322   set(LocalVariable, "LocalVariable", 0x3010, 3010, TypeDefinitionOne);
323   set(ClassMember, "Member", 0x3020, 3020, IntegerType);
324   set(Parameter, "Param", 0x3030, 3030, UnsignedType);
325   set(NestedVariable, "NestedVariable", 0x3040, 3040);
326 
327   // Lines.
328   set(LocalLine, "", 0x4000, 4000);
329   set(NestedLine, "", 0x4010, 4010);
330 }
331 
TEST(LogicalViewTest,LogicalElements)332 TEST(LogicalViewTest, LogicalElements) {
333   ScopedPrinter W(outs());
334   ReaderTestElements Reader(W);
335 
336   Reader.createElements();
337   Reader.addElements();
338   Reader.initElements();
339 }
340 
341 } // namespace
342