[gn build] Port 0154dce8d39d
[llvm-project.git] / llvm / unittests / DebugInfo / LogicalView / CodeViewReaderTest.cpp
blob7639f001e30dd78907b48f2f0bfc97b1d4b5017f
1 //===- llvm/unittest/DebugInfo/LogicalView/CodeViewReaderTest.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 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
10 #include "llvm/DebugInfo/LogicalView/Core/LVLine.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/DebugInfo/LogicalView/LVReaderHandler.h"
15 #include "llvm/MC/TargetRegistry.h"
16 #include "llvm/Support/COM.h"
17 #include "llvm/Support/InitLLVM.h"
18 #include "llvm/Support/ScopedPrinter.h"
19 #include "llvm/Support/TargetSelect.h"
20 #include "llvm/Support/ToolOutputFile.h"
21 #include "llvm/Testing/Support/Error.h"
23 #include "gtest/gtest.h"
25 using namespace llvm;
26 using namespace llvm::logicalview;
28 extern const char *TestMainArgv0;
30 namespace {
32 const char *CodeViewClang = "test-codeview-clang.o";
33 const char *CodeViewMsvc = "test-codeview-msvc.o";
34 const char *CodeViewMsvcLib = "test-codeview-msvc.lib";
35 const char *CodeViewMsvcLibContentName =
36 "test-codeview-msvc.lib(test-codeview-msvc.o)";
37 const char *CodeViewPdbMsvc = "test-codeview-pdb-msvc.o";
39 // Helper function to get the first scope child from the given parent.
40 LVScope *getFirstScopeChild(LVScope *Parent) {
41 EXPECT_NE(Parent, nullptr);
42 const LVScopes *Scopes = Parent->getScopes();
43 EXPECT_NE(Scopes, nullptr);
44 EXPECT_EQ(Scopes->size(), 1u);
46 LVScopes::const_iterator Iter = Scopes->begin();
47 LVScope *Child = *Iter;
48 EXPECT_NE(Child, nullptr);
49 return Child;
52 // Helper function to create a reader.
53 std::unique_ptr<LVReader> createReader(LVReaderHandler &ReaderHandler,
54 SmallString<128> &InputsDir,
55 StringRef Filename) {
56 SmallString<128> ObjectName(InputsDir);
57 llvm::sys::path::append(ObjectName, Filename);
59 Expected<std::unique_ptr<LVReader>> ReaderOrErr =
60 ReaderHandler.createReader(std::string(ObjectName));
61 EXPECT_THAT_EXPECTED(ReaderOrErr, Succeeded());
62 std::unique_ptr<LVReader> Reader = std::move(*ReaderOrErr);
63 EXPECT_NE(Reader, nullptr);
64 return Reader;
67 // Check the logical elements basic properties (Clang - Codeview).
68 void checkElementPropertiesClangCodeview(LVReader *Reader) {
69 LVScopeRoot *Root = Reader->getScopesRoot();
70 LVScopeCompileUnit *CompileUnit =
71 static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));
72 LVScopeFunction *Function =
73 static_cast<LVScopeFunction *>(getFirstScopeChild(CompileUnit));
75 EXPECT_EQ(Root->getFileFormatName(), "COFF-x86-64");
76 EXPECT_EQ(Root->getName(), CodeViewClang);
78 EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);
79 EXPECT_TRUE(CompileUnit->getProducer().starts_with("clang"));
80 EXPECT_EQ(CompileUnit->getName(), "test.cpp");
82 EXPECT_EQ(Function->lineCount(), 16u);
83 EXPECT_EQ(Function->scopeCount(), 1u);
84 EXPECT_EQ(Function->symbolCount(), 3u);
85 EXPECT_EQ(Function->typeCount(), 1u);
86 EXPECT_EQ(Function->rangeCount(), 1u);
88 const LVLocations *Ranges = Function->getRanges();
89 ASSERT_NE(Ranges, nullptr);
90 ASSERT_EQ(Ranges->size(), 1u);
91 LVLocations::const_iterator IterLocation = Ranges->begin();
92 LVLocation *Location = (*IterLocation);
93 EXPECT_STREQ(Location->getIntervalInfo().c_str(),
94 "{Range} Lines 2:9 [0x0000000000:0x0000000046]");
96 LVRange RangeList;
97 Function->getRanges(RangeList);
99 const LVRangeEntries &RangeEntries = RangeList.getEntries();
100 ASSERT_EQ(RangeEntries.size(), 2u);
101 LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();
102 LVRangeEntry RangeEntry = *IterRanges;
103 EXPECT_EQ(RangeEntry.lower(), 0u);
104 EXPECT_EQ(RangeEntry.upper(), 0x46u);
105 EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
106 EXPECT_EQ(RangeEntry.scope()->getName(), "foo");
107 EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);
109 ++IterRanges;
110 RangeEntry = *IterRanges;
111 EXPECT_EQ(RangeEntry.lower(), 0x21u);
112 EXPECT_EQ(RangeEntry.upper(), 0x35u);
113 EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
114 EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");
115 EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);
117 const LVPublicNames &PublicNames = CompileUnit->getPublicNames();
118 ASSERT_EQ(PublicNames.size(), 1u);
119 LVPublicNames::const_iterator IterNames = PublicNames.cbegin();
120 LVScope *Foo = (*IterNames).first;
121 EXPECT_EQ(Foo->getName(), "foo");
122 EXPECT_EQ(Foo->getLineNumber(), 0u);
123 LVNameInfo NameInfo = (*IterNames).second;
124 EXPECT_EQ(NameInfo.first, 0u);
125 EXPECT_EQ(NameInfo.second, 0x46u);
127 // Lines (debug and assembler) for 'foo'.
128 const LVLines *Lines = Foo->getLines();
129 ASSERT_NE(Lines, nullptr);
130 EXPECT_EQ(Lines->size(), 0x10u);
133 // Check the logical elements basic properties (MSVC - Codeview).
134 void checkElementPropertiesMsvcCodeview(LVReader *Reader) {
135 LVScopeRoot *Root = Reader->getScopesRoot();
136 LVScopeCompileUnit *CompileUnit =
137 static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));
138 LVScopeFunction *Function =
139 static_cast<LVScopeFunction *>(getFirstScopeChild(CompileUnit));
141 EXPECT_EQ(Root->getFileFormatName(), "COFF-x86-64");
142 EXPECT_EQ(Root->getName(), CodeViewMsvc);
144 EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);
145 EXPECT_TRUE(CompileUnit->getProducer().starts_with("Microsoft"));
146 EXPECT_EQ(CompileUnit->getName(), "test.cpp");
148 EXPECT_EQ(Function->lineCount(), 14u);
149 EXPECT_EQ(Function->scopeCount(), 1u);
150 EXPECT_EQ(Function->symbolCount(), 3u);
151 EXPECT_EQ(Function->typeCount(), 0u);
152 EXPECT_EQ(Function->rangeCount(), 1u);
154 const LVLocations *Ranges = Function->getRanges();
155 ASSERT_NE(Ranges, nullptr);
156 ASSERT_EQ(Ranges->size(), 1u);
157 LVLocations::const_iterator IterLocation = Ranges->begin();
158 LVLocation *Location = (*IterLocation);
159 EXPECT_STREQ(Location->getIntervalInfo().c_str(),
160 "{Range} Lines 2:9 [0x0000000000:0x0000000031]");
162 LVRange RangeList;
163 Function->getRanges(RangeList);
165 const LVRangeEntries &RangeEntries = RangeList.getEntries();
166 ASSERT_EQ(RangeEntries.size(), 2u);
167 LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();
168 LVRangeEntry RangeEntry = *IterRanges;
169 EXPECT_EQ(RangeEntry.lower(), 0u);
170 EXPECT_EQ(RangeEntry.upper(), 0x31u);
171 EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
172 EXPECT_EQ(RangeEntry.scope()->getName(), "foo");
173 EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);
175 ++IterRanges;
176 RangeEntry = *IterRanges;
177 EXPECT_EQ(RangeEntry.lower(), 0x1bu);
178 EXPECT_EQ(RangeEntry.upper(), 0x28u);
179 EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
180 EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");
181 EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);
183 const LVPublicNames &PublicNames = CompileUnit->getPublicNames();
184 ASSERT_EQ(PublicNames.size(), 1u);
185 LVPublicNames::const_iterator IterNames = PublicNames.cbegin();
186 LVScope *Foo = (*IterNames).first;
187 EXPECT_EQ(Foo->getName(), "foo");
188 EXPECT_EQ(Foo->getLineNumber(), 0u);
189 LVNameInfo NameInfo = (*IterNames).second;
190 EXPECT_EQ(NameInfo.first, 0u);
191 EXPECT_EQ(NameInfo.second, 0x31u);
193 // Lines (debug and assembler) for 'foo'.
194 const LVLines *Lines = Foo->getLines();
195 ASSERT_NE(Lines, nullptr);
196 EXPECT_EQ(Lines->size(), 0x0eu);
199 // Check the logical elements basic properties (MSVC library - Codeview).
200 void checkElementPropertiesMsvcLibraryCodeview(LVReader *Reader) {
201 LVScopeRoot *Root = Reader->getScopesRoot();
202 LVScopeCompileUnit *CompileUnit =
203 static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));
204 LVScopeFunction *Function =
205 static_cast<LVScopeFunction *>(getFirstScopeChild(CompileUnit));
207 EXPECT_EQ(Root->getFileFormatName(), "COFF-x86-64");
208 EXPECT_EQ(Root->getName(), CodeViewMsvcLibContentName);
210 EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);
211 EXPECT_TRUE(CompileUnit->getProducer().starts_with("Microsoft"));
212 EXPECT_EQ(CompileUnit->getName(), "test.cpp");
214 EXPECT_EQ(Function->lineCount(), 14u);
215 EXPECT_EQ(Function->scopeCount(), 1u);
216 EXPECT_EQ(Function->symbolCount(), 3u);
217 EXPECT_EQ(Function->typeCount(), 0u);
218 EXPECT_EQ(Function->rangeCount(), 1u);
220 const LVLocations *Ranges = Function->getRanges();
221 ASSERT_NE(Ranges, nullptr);
222 ASSERT_EQ(Ranges->size(), 1u);
223 LVLocations::const_iterator IterLocation = Ranges->begin();
224 LVLocation *Location = (*IterLocation);
225 EXPECT_STREQ(Location->getIntervalInfo().c_str(),
226 "{Range} Lines 2:9 [0x0000000000:0x0000000031]");
228 LVRange RangeList;
229 Function->getRanges(RangeList);
231 const LVRangeEntries &RangeEntries = RangeList.getEntries();
232 ASSERT_EQ(RangeEntries.size(), 2u);
233 LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();
234 LVRangeEntry RangeEntry = *IterRanges;
235 EXPECT_EQ(RangeEntry.lower(), 0u);
236 EXPECT_EQ(RangeEntry.upper(), 0x31u);
237 EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
238 EXPECT_EQ(RangeEntry.scope()->getName(), "foo");
239 EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);
241 ++IterRanges;
242 RangeEntry = *IterRanges;
243 EXPECT_EQ(RangeEntry.lower(), 0x1bu);
244 EXPECT_EQ(RangeEntry.upper(), 0x28u);
245 EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
246 EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");
247 EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);
249 const LVPublicNames &PublicNames = CompileUnit->getPublicNames();
250 ASSERT_EQ(PublicNames.size(), 1u);
251 LVPublicNames::const_iterator IterNames = PublicNames.cbegin();
252 LVScope *Foo = (*IterNames).first;
253 EXPECT_EQ(Foo->getName(), "foo");
254 EXPECT_EQ(Foo->getLineNumber(), 0u);
255 LVNameInfo NameInfo = (*IterNames).second;
256 EXPECT_EQ(NameInfo.first, 0u);
257 EXPECT_EQ(NameInfo.second, 0x31u);
259 // Lines (debug and assembler) for 'foo'.
260 const LVLines *Lines = Foo->getLines();
261 ASSERT_NE(Lines, nullptr);
262 EXPECT_EQ(Lines->size(), 0x0eu);
265 // Check the logical elements basic properties (MSVC - PDB).
266 void checkElementPropertiesMsvcCodeviewPdb(LVReader *Reader) {
267 LVScopeRoot *Root = Reader->getScopesRoot();
268 LVScopeCompileUnit *CompileUnit =
269 static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));
270 LVScopeFunction *Function =
271 static_cast<LVScopeFunction *>(getFirstScopeChild(CompileUnit));
273 EXPECT_EQ(Root->getFileFormatName(), "COFF-x86-64");
274 EXPECT_EQ(Root->getName(), CodeViewPdbMsvc);
276 EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);
277 EXPECT_TRUE(CompileUnit->getProducer().starts_with("Microsoft"));
278 EXPECT_EQ(CompileUnit->getName(), "test.cpp");
280 EXPECT_EQ(Function->lineCount(), 14u);
281 EXPECT_EQ(Function->scopeCount(), 1u);
282 EXPECT_EQ(Function->symbolCount(), 3u);
283 EXPECT_EQ(Function->typeCount(), 0u);
284 EXPECT_EQ(Function->rangeCount(), 1u);
286 const LVLocations *Ranges = Function->getRanges();
287 ASSERT_NE(Ranges, nullptr);
288 ASSERT_EQ(Ranges->size(), 1u);
289 LVLocations::const_iterator IterLocation = Ranges->begin();
290 LVLocation *Location = (*IterLocation);
291 EXPECT_STREQ(Location->getIntervalInfo().c_str(),
292 "{Range} Lines 2:9 [0x0000000000:0x0000000031]");
294 LVRange RangeList;
295 Function->getRanges(RangeList);
297 const LVRangeEntries &RangeEntries = RangeList.getEntries();
298 ASSERT_EQ(RangeEntries.size(), 2u);
299 LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();
300 LVRangeEntry RangeEntry = *IterRanges;
301 EXPECT_EQ(RangeEntry.lower(), 0u);
302 EXPECT_EQ(RangeEntry.upper(), 0x31u);
303 EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
304 EXPECT_EQ(RangeEntry.scope()->getName(), "foo");
305 EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);
307 ++IterRanges;
308 RangeEntry = *IterRanges;
309 EXPECT_EQ(RangeEntry.lower(), 0x1bu);
310 EXPECT_EQ(RangeEntry.upper(), 0x28u);
311 EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);
312 EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");
313 EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);
315 const LVPublicNames &PublicNames = CompileUnit->getPublicNames();
316 ASSERT_EQ(PublicNames.size(), 1u);
317 LVPublicNames::const_iterator IterNames = PublicNames.cbegin();
318 LVScope *Foo = (*IterNames).first;
319 EXPECT_EQ(Foo->getName(), "foo");
320 EXPECT_EQ(Foo->getLineNumber(), 0u);
321 LVNameInfo NameInfo = (*IterNames).second;
322 EXPECT_EQ(NameInfo.first, 0u);
323 EXPECT_EQ(NameInfo.second, 0x31u);
325 // Lines (debug and assembler) for 'foo'.
326 const LVLines *Lines = Foo->getLines();
327 ASSERT_NE(Lines, nullptr);
328 EXPECT_EQ(Lines->size(), 0x0eu);
331 struct SelectionInfo {
332 const char *Name;
333 LVElementGetFunction Function;
336 // Check the logical elements selection.
337 void checkElementSelection(LVReader *Reader, std::vector<SelectionInfo> &Data,
338 size_t Size) {
339 LVScopeRoot *Root = Reader->getScopesRoot();
340 LVScopeCompileUnit *CompileUnit =
341 static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));
343 // Get the matched elements.
344 LVElements MatchedElements = CompileUnit->getMatchedElements();
345 std::map<StringRef, LVElement *> MapElements;
346 for (LVElement *Element : MatchedElements)
347 MapElements[Element->getName()] = Element;
348 ASSERT_EQ(MapElements.size(), Size);
350 std::map<StringRef, LVElement *>::iterator Iter = MapElements.begin();
351 for (const SelectionInfo &Entry : Data) {
352 // Get matched element.
353 EXPECT_NE(Iter, MapElements.end());
354 LVElement *Element = Iter->second;
355 ASSERT_NE(Element, nullptr);
356 EXPECT_NE(Element->getName().find(Entry.Name), StringRef::npos);
357 EXPECT_EQ((Element->*Entry.Function)(), 1u);
358 ++Iter;
361 // Get the parents for the matched elements.
362 LVScopes MatchedScopes = CompileUnit->getMatchedScopes();
363 std::set<StringRef> SetScopes;
364 for (LVScope *Scope : MatchedScopes)
365 SetScopes.insert(Scope->getName());
366 ASSERT_EQ(SetScopes.size(), 3u);
368 // Parents of selected elements.
369 std::set<StringRef>::iterator IterScope;
370 IterScope = SetScopes.find("foo");
371 EXPECT_NE(IterScope, SetScopes.end());
372 IterScope = SetScopes.find("foo::?");
373 EXPECT_NE(IterScope, SetScopes.end());
374 IterScope = SetScopes.find("test.cpp");
375 EXPECT_NE(IterScope, SetScopes.end());
378 // Check the logical elements comparison.
379 void checkElementComparison(LVReader *Reference, LVReader *Target) {
380 LVCompare Compare(nulls());
381 Error Err = Compare.execute(Reference, Target);
382 ASSERT_THAT_ERROR(std::move(Err), Succeeded());
384 // Get comparison table.
385 LVPassTable PassTable = Compare.getPassTable();
386 ASSERT_EQ(PassTable.size(), 2u);
388 LVReader *Reader;
389 LVElement *Element;
390 LVComparePass Pass;
392 // Reference: Missing TypeDefinition 'INTEGER'
393 std::tie(Reader, Element, Pass) = PassTable[0];
394 ASSERT_NE(Reader, nullptr);
395 ASSERT_NE(Element, nullptr);
396 EXPECT_EQ(Reader, Reference);
397 EXPECT_EQ(Element->getLevel(), 3u);
398 EXPECT_EQ(Element->getLineNumber(), 0u);
399 EXPECT_EQ(Element->getName(), "INTEGER");
400 EXPECT_EQ(Pass, LVComparePass::Missing);
402 // Target: Added TypeDefinition 'INTEGER'
403 std::tie(Reader, Element, Pass) = PassTable[1];
404 ASSERT_NE(Reader, nullptr);
405 ASSERT_NE(Element, nullptr);
406 EXPECT_EQ(Reader, Target);
407 EXPECT_EQ(Element->getLevel(), 4u);
408 EXPECT_EQ(Element->getLineNumber(), 0u);
409 EXPECT_EQ(Element->getName(), "INTEGER");
410 EXPECT_EQ(Pass, LVComparePass::Added);
413 // Logical elements properties.
414 void elementProperties(SmallString<128> &InputsDir) {
415 // Reader options.
416 LVOptions ReaderOptions;
417 ReaderOptions.setAttributeOffset();
418 ReaderOptions.setAttributeFormat();
419 ReaderOptions.setAttributeFilename();
420 ReaderOptions.setAttributeProducer();
421 ReaderOptions.setAttributePublics();
422 ReaderOptions.setAttributeRange();
423 ReaderOptions.setAttributeLocation();
424 ReaderOptions.setPrintAll();
425 ReaderOptions.resolveDependencies();
427 std::vector<std::string> Objects;
428 ScopedPrinter W(outs());
429 LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);
431 // Check logical elements properties.
433 std::unique_ptr<LVReader> Reader =
434 createReader(ReaderHandler, InputsDir, CodeViewClang);
435 checkElementPropertiesClangCodeview(Reader.get());
438 std::unique_ptr<LVReader> Reader =
439 createReader(ReaderHandler, InputsDir, CodeViewMsvc);
440 checkElementPropertiesMsvcCodeview(Reader.get());
443 std::unique_ptr<LVReader> Reader =
444 createReader(ReaderHandler, InputsDir, CodeViewMsvcLib);
445 checkElementPropertiesMsvcLibraryCodeview(Reader.get());
448 std::unique_ptr<LVReader> Reader =
449 createReader(ReaderHandler, InputsDir, CodeViewPdbMsvc);
450 checkElementPropertiesMsvcCodeviewPdb(Reader.get());
454 // Logical elements selection.
455 void elementSelection(SmallString<128> &InputsDir) {
456 // Reader options.
457 LVOptions ReaderOptions;
458 ReaderOptions.setAttributeOffset();
459 ReaderOptions.setPrintAll();
461 ReaderOptions.setSelectIgnoreCase();
462 ReaderOptions.setSelectUseRegex();
464 ReaderOptions.setReportList(); // Matched elements.
465 ReaderOptions.setReportView(); // Parents for matched elements.
467 // Add patterns.
468 ReaderOptions.Select.Generic.insert("foo");
469 ReaderOptions.Select.Generic.insert("movl[ \t]?%");
470 ReaderOptions.Select.Generic.insert("INT[a-z]*");
471 ReaderOptions.Select.Generic.insert("CONSTANT");
473 ReaderOptions.resolveDependencies();
475 std::vector<std::string> Objects;
476 ScopedPrinter W(outs());
477 LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);
479 // Check logical elements selection.
481 std::vector<SelectionInfo> DataClang = {
482 {"* const int", &LVElement::getIsType},
483 {"CONSTANT", &LVElement::getIsSymbol},
484 {"INTEGER", &LVElement::getIsType},
485 {"INTPTR", &LVElement::getIsType},
486 {"ParamPtr", &LVElement::getIsSymbol},
487 {"const int", &LVElement::getIsType},
488 {"foo", &LVElement::getIsScope},
489 {"foo::?", &LVElement::getIsScope},
490 {"int", &LVElement::getIsType},
491 {"movl", &LVElement::getIsLine},
492 {"movl", &LVElement::getIsLine}};
493 std::unique_ptr<LVReader> Reader =
494 createReader(ReaderHandler, InputsDir, CodeViewClang);
495 checkElementSelection(Reader.get(), DataClang, DataClang.size());
498 std::vector<SelectionInfo> DataMsvc = {
499 {"* const int", &LVElement::getIsType},
500 {"CONSTANT", &LVElement::getIsSymbol},
501 {"INTEGER", &LVElement::getIsType},
502 {"INTPTR", &LVElement::getIsType},
503 {"ParamPtr", &LVElement::getIsSymbol},
504 {"const int", &LVElement::getIsType},
505 {"foo", &LVElement::getIsScope},
506 {"foo::?", &LVElement::getIsScope},
507 {"int", &LVElement::getIsType},
508 {"movl", &LVElement::getIsLine}};
509 std::unique_ptr<LVReader> Reader =
510 createReader(ReaderHandler, InputsDir, CodeViewMsvc);
511 checkElementSelection(Reader.get(), DataMsvc, DataMsvc.size());
515 // Compare logical elements.
516 void compareElements(SmallString<128> &InputsDir) {
517 // Reader options.
518 LVOptions ReaderOptions;
519 ReaderOptions.setAttributeOffset();
520 ReaderOptions.setPrintLines();
521 ReaderOptions.setPrintSymbols();
522 ReaderOptions.setPrintTypes();
523 ReaderOptions.setCompareLines();
524 ReaderOptions.setCompareSymbols();
525 ReaderOptions.setCompareTypes();
527 ReaderOptions.resolveDependencies();
529 std::vector<std::string> Objects;
530 ScopedPrinter W(outs());
531 LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);
533 // Check logical comparison.
534 std::unique_ptr<LVReader> Reference =
535 createReader(ReaderHandler, InputsDir, CodeViewClang);
536 std::unique_ptr<LVReader> Target =
537 createReader(ReaderHandler, InputsDir, CodeViewMsvc);
538 checkElementComparison(Reference.get(), Target.get());
541 TEST(LogicalViewTest, CodeViewReader) {
542 // Initialize targets and assembly printers/parsers.
543 llvm::InitializeAllTargetInfos();
544 llvm::InitializeAllTargetMCs();
545 InitializeAllDisassemblers();
547 llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);
549 // This test requires a x86-registered-target.
550 Triple TT;
551 TT.setArch(Triple::x86_64);
552 TT.setVendor(Triple::UnknownVendor);
553 TT.setOS(Triple::UnknownOS);
555 std::string TargetLookupError;
556 if (!TargetRegistry::lookupTarget(std::string(TT.str()), TargetLookupError))
557 return;
559 SmallString<128> InputsDir = unittest::getInputFileDirectory(TestMainArgv0);
561 // Logical elements general properties and selection.
562 elementProperties(InputsDir);
563 elementSelection(InputsDir);
565 // Compare logical elements.
566 compareElements(InputsDir);
569 } // namespace