1 //===- llvm/unittest/DebugInfo/LogicalView/CodeViewReaderTest.cpp ---------===//
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
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"
26 using namespace llvm::logicalview
;
28 extern const char *TestMainArgv0
;
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);
52 // Helper function to create a reader.
53 std::unique_ptr
<LVReader
> createReader(LVReaderHandler
&ReaderHandler
,
54 SmallString
<128> &InputsDir
,
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);
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]");
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);
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]");
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);
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]");
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);
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]");
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);
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
{
333 LVElementGetFunction Function
;
336 // Check the logical elements selection.
337 void checkElementSelection(LVReader
*Reader
, std::vector
<SelectionInfo
> &Data
,
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);
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);
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
) {
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
) {
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.
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
) {
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.
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
))
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
);