brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.7 KiB · f9aa050 Raw
609 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 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"22 23#include "gtest/gtest.h"24#include <algorithm>25 26using namespace llvm;27using namespace llvm::logicalview;28 29extern const char *TestMainArgv0;30 31namespace {32 33const char *CodeViewClang = "test-codeview-clang.o";34const char *CodeViewMsvc = "test-codeview-msvc.o";35const char *CodeViewMsvcLib = "test-codeview-msvc.lib";36const char *CodeViewMsvcLibContentName =37    "test-codeview-msvc.lib(test-codeview-msvc.o)";38const char *CodeViewPdbMsvc = "test-codeview-pdb-msvc.o";39 40// Helper function to get the first scope child from the given parent.41LVScope *getFirstScopeChild(LVScope *Parent) {42  EXPECT_NE(Parent, nullptr);43  const LVScopes *Scopes = Parent->getScopes();44  EXPECT_NE(Scopes, nullptr);45  EXPECT_EQ(Scopes->size(), 1u);46 47  LVScopes::const_iterator Iter = Scopes->begin();48  LVScope *Child = *Iter;49  EXPECT_NE(Child, nullptr);50  return Child;51}52 53// Helper function to create a reader.54std::unique_ptr<LVReader> createReader(LVReaderHandler &ReaderHandler,55                                       SmallString<128> &InputsDir,56                                       StringRef Filename) {57  SmallString<128> ObjectName(InputsDir);58  llvm::sys::path::append(ObjectName, Filename);59 60  Expected<std::unique_ptr<LVReader>> ReaderOrErr =61      ReaderHandler.createReader(std::string(ObjectName));62  EXPECT_THAT_EXPECTED(ReaderOrErr, Succeeded());63  std::unique_ptr<LVReader> Reader = std::move(*ReaderOrErr);64  EXPECT_NE(Reader, nullptr);65  return Reader;66}67 68// Check the logical elements basic properties (Clang - Codeview).69void checkElementPropertiesClangCodeview(LVReader *Reader) {70  LVScopeRoot *Root = Reader->getScopesRoot();71  LVScopeCompileUnit *CompileUnit =72      static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));73  LVScopeFunction *Function =74      static_cast<LVScopeFunction *>(getFirstScopeChild(CompileUnit));75 76  EXPECT_EQ(Root->getFileFormatName(), "COFF-x86-64");77  EXPECT_EQ(Root->getName(), CodeViewClang);78 79  EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);80  EXPECT_TRUE(CompileUnit->getProducer().starts_with("clang"));81  EXPECT_EQ(CompileUnit->getName(), "test.cpp");82  LVSourceLanguage Language = CompileUnit->getSourceLanguage();83  EXPECT_TRUE(Language.isValid());84  ASSERT_EQ(Language, LVSourceLanguage::CV_LANG_Cpp);85  ASSERT_EQ(Language.getName(), "Cpp");86 87  EXPECT_EQ(Function->lineCount(), 16u);88  EXPECT_EQ(Function->scopeCount(), 1u);89  EXPECT_EQ(Function->symbolCount(), 3u);90  EXPECT_EQ(Function->typeCount(), 1u);91  EXPECT_EQ(Function->rangeCount(), 1u);92 93  const LVLocations *Ranges = Function->getRanges();94  ASSERT_NE(Ranges, nullptr);95  ASSERT_EQ(Ranges->size(), 1u);96  LVLocations::const_iterator IterLocation = Ranges->begin();97  LVLocation *Location = (*IterLocation);98  EXPECT_STREQ(Location->getIntervalInfo().c_str(),99               "{Range} Lines 2:9 [0x0000000000:0x0000000046]");100 101  LVRange RangeList;102  Function->getRanges(RangeList);103 104  const LVRangeEntries &RangeEntries = RangeList.getEntries();105  ASSERT_EQ(RangeEntries.size(), 2u);106  LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();107  LVRangeEntry RangeEntry = *IterRanges;108  EXPECT_EQ(RangeEntry.lower(), 0u);109  EXPECT_EQ(RangeEntry.upper(), 0x46u);110  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);111  EXPECT_EQ(RangeEntry.scope()->getName(), "foo");112  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);113 114  ++IterRanges;115  RangeEntry = *IterRanges;116  EXPECT_EQ(RangeEntry.lower(), 0x21u);117  EXPECT_EQ(RangeEntry.upper(), 0x35u);118  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);119  EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");120  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);121 122  const LVPublicNames &PublicNames = CompileUnit->getPublicNames();123  ASSERT_EQ(PublicNames.size(), 1u);124  LVPublicNames::const_iterator IterNames = PublicNames.cbegin();125  LVScope *Foo = (*IterNames).first;126  EXPECT_EQ(Foo->getName(), "foo");127  EXPECT_EQ(Foo->getLineNumber(), 0u);128  LVNameInfo NameInfo = (*IterNames).second;129  EXPECT_EQ(NameInfo.first, 0u);130  EXPECT_EQ(NameInfo.second, 0x46u);131 132  // Lines (debug and assembler) for 'foo'.133  const LVLines *Lines = Foo->getLines();134  ASSERT_NE(Lines, nullptr);135  EXPECT_EQ(Lines->size(), 0x10u);136 137  // Check size of types in CompileUnit.138  const LVTypes *Types = CompileUnit->getTypes();139  ASSERT_NE(Types, nullptr);140  EXPECT_EQ(Types->size(), 6u);141 142  const auto BoolType = llvm::find_if(143      *Types, [](const LVElement *elt) { return elt->getName() == "bool"; });144  ASSERT_NE(BoolType, Types->end());145  const auto IntType = llvm::find_if(146      *Types, [](const LVElement *elt) { return elt->getName() == "int"; });147  ASSERT_NE(IntType, Types->end());148  EXPECT_EQ(static_cast<LVType *>(*BoolType)->getBitSize(), 8u);149  EXPECT_EQ(static_cast<LVType *>(*BoolType)->getStorageSizeInBytes(), 1u);150  EXPECT_EQ(static_cast<LVType *>(*IntType)->getBitSize(), 32u);151  EXPECT_EQ(static_cast<LVType *>(*IntType)->getStorageSizeInBytes(), 4u);152}153 154// Check the logical elements basic properties (MSVC - Codeview).155void checkElementPropertiesMsvcCodeview(LVReader *Reader) {156  LVScopeRoot *Root = Reader->getScopesRoot();157  LVScopeCompileUnit *CompileUnit =158      static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));159  LVScopeFunction *Function =160      static_cast<LVScopeFunction *>(getFirstScopeChild(CompileUnit));161 162  EXPECT_EQ(Root->getFileFormatName(), "COFF-x86-64");163  EXPECT_EQ(Root->getName(), CodeViewMsvc);164 165  EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);166  EXPECT_TRUE(CompileUnit->getProducer().starts_with("Microsoft"));167  EXPECT_EQ(CompileUnit->getName(), "test.cpp");168 169  EXPECT_EQ(Function->lineCount(), 14u);170  EXPECT_EQ(Function->scopeCount(), 1u);171  EXPECT_EQ(Function->symbolCount(), 3u);172  EXPECT_EQ(Function->typeCount(), 0u);173  EXPECT_EQ(Function->rangeCount(), 1u);174 175  const LVLocations *Ranges = Function->getRanges();176  ASSERT_NE(Ranges, nullptr);177  ASSERT_EQ(Ranges->size(), 1u);178  LVLocations::const_iterator IterLocation = Ranges->begin();179  LVLocation *Location = (*IterLocation);180  EXPECT_STREQ(Location->getIntervalInfo().c_str(),181               "{Range} Lines 2:9 [0x0000000000:0x0000000031]");182 183  LVRange RangeList;184  Function->getRanges(RangeList);185 186  const LVRangeEntries &RangeEntries = RangeList.getEntries();187  ASSERT_EQ(RangeEntries.size(), 2u);188  LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();189  LVRangeEntry RangeEntry = *IterRanges;190  EXPECT_EQ(RangeEntry.lower(), 0u);191  EXPECT_EQ(RangeEntry.upper(), 0x31u);192  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);193  EXPECT_EQ(RangeEntry.scope()->getName(), "foo");194  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);195 196  ++IterRanges;197  RangeEntry = *IterRanges;198  EXPECT_EQ(RangeEntry.lower(), 0x1bu);199  EXPECT_EQ(RangeEntry.upper(), 0x28u);200  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);201  EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");202  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);203 204  const LVPublicNames &PublicNames = CompileUnit->getPublicNames();205  ASSERT_EQ(PublicNames.size(), 1u);206  LVPublicNames::const_iterator IterNames = PublicNames.cbegin();207  LVScope *Foo = (*IterNames).first;208  EXPECT_EQ(Foo->getName(), "foo");209  EXPECT_EQ(Foo->getLineNumber(), 0u);210  LVNameInfo NameInfo = (*IterNames).second;211  EXPECT_EQ(NameInfo.first, 0u);212  EXPECT_EQ(NameInfo.second, 0x31u);213 214  // Lines (debug and assembler) for 'foo'.215  const LVLines *Lines = Foo->getLines();216  ASSERT_NE(Lines, nullptr);217  EXPECT_EQ(Lines->size(), 0x0eu);218 219  // Check size of types in CompileUnit.220  const LVTypes *Types = CompileUnit->getTypes();221  ASSERT_NE(Types, nullptr);222  EXPECT_EQ(Types->size(), 8u);223 224  const auto BoolType = llvm::find_if(225      *Types, [](const LVElement *elt) { return elt->getName() == "bool"; });226  ASSERT_NE(BoolType, Types->end());227  const auto IntType = llvm::find_if(228      *Types, [](const LVElement *elt) { return elt->getName() == "int"; });229  ASSERT_NE(IntType, Types->end());230  EXPECT_EQ(static_cast<LVType *>(*BoolType)->getBitSize(), 8u);231  EXPECT_EQ(static_cast<LVType *>(*BoolType)->getStorageSizeInBytes(), 1u);232  EXPECT_EQ(static_cast<LVType *>(*IntType)->getBitSize(), 32u);233  EXPECT_EQ(static_cast<LVType *>(*IntType)->getStorageSizeInBytes(), 4u);234}235 236// Check the logical elements basic properties (MSVC library - Codeview).237void checkElementPropertiesMsvcLibraryCodeview(LVReader *Reader) {238  LVScopeRoot *Root = Reader->getScopesRoot();239  LVScopeCompileUnit *CompileUnit =240      static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));241  LVScopeFunction *Function =242      static_cast<LVScopeFunction *>(getFirstScopeChild(CompileUnit));243 244  EXPECT_EQ(Root->getFileFormatName(), "COFF-x86-64");245  EXPECT_EQ(Root->getName(), CodeViewMsvcLibContentName);246 247  EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);248  EXPECT_TRUE(CompileUnit->getProducer().starts_with("Microsoft"));249  EXPECT_EQ(CompileUnit->getName(), "test.cpp");250 251  EXPECT_EQ(Function->lineCount(), 14u);252  EXPECT_EQ(Function->scopeCount(), 1u);253  EXPECT_EQ(Function->symbolCount(), 3u);254  EXPECT_EQ(Function->typeCount(), 0u);255  EXPECT_EQ(Function->rangeCount(), 1u);256 257  const LVLocations *Ranges = Function->getRanges();258  ASSERT_NE(Ranges, nullptr);259  ASSERT_EQ(Ranges->size(), 1u);260  LVLocations::const_iterator IterLocation = Ranges->begin();261  LVLocation *Location = (*IterLocation);262  EXPECT_STREQ(Location->getIntervalInfo().c_str(),263               "{Range} Lines 2:9 [0x0000000000:0x0000000031]");264 265  LVRange RangeList;266  Function->getRanges(RangeList);267 268  const LVRangeEntries &RangeEntries = RangeList.getEntries();269  ASSERT_EQ(RangeEntries.size(), 2u);270  LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();271  LVRangeEntry RangeEntry = *IterRanges;272  EXPECT_EQ(RangeEntry.lower(), 0u);273  EXPECT_EQ(RangeEntry.upper(), 0x31u);274  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);275  EXPECT_EQ(RangeEntry.scope()->getName(), "foo");276  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);277 278  ++IterRanges;279  RangeEntry = *IterRanges;280  EXPECT_EQ(RangeEntry.lower(), 0x1bu);281  EXPECT_EQ(RangeEntry.upper(), 0x28u);282  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);283  EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");284  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);285 286  const LVPublicNames &PublicNames = CompileUnit->getPublicNames();287  ASSERT_EQ(PublicNames.size(), 1u);288  LVPublicNames::const_iterator IterNames = PublicNames.cbegin();289  LVScope *Foo = (*IterNames).first;290  EXPECT_EQ(Foo->getName(), "foo");291  EXPECT_EQ(Foo->getLineNumber(), 0u);292  LVNameInfo NameInfo = (*IterNames).second;293  EXPECT_EQ(NameInfo.first, 0u);294  EXPECT_EQ(NameInfo.second, 0x31u);295 296  // Lines (debug and assembler) for 'foo'.297  const LVLines *Lines = Foo->getLines();298  ASSERT_NE(Lines, nullptr);299  EXPECT_EQ(Lines->size(), 0x0eu);300}301 302// Check the logical elements basic properties (MSVC - PDB).303void checkElementPropertiesMsvcCodeviewPdb(LVReader *Reader) {304  LVScopeRoot *Root = Reader->getScopesRoot();305  LVScopeCompileUnit *CompileUnit =306      static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));307  LVScopeFunction *Function =308      static_cast<LVScopeFunction *>(getFirstScopeChild(CompileUnit));309 310  EXPECT_EQ(Root->getFileFormatName(), "COFF-x86-64");311  EXPECT_EQ(Root->getName(), CodeViewPdbMsvc);312 313  EXPECT_EQ(CompileUnit->getBaseAddress(), 0u);314  EXPECT_TRUE(CompileUnit->getProducer().starts_with("Microsoft"));315  EXPECT_EQ(CompileUnit->getName(), "test.cpp");316 317  EXPECT_EQ(Function->lineCount(), 14u);318  EXPECT_EQ(Function->scopeCount(), 1u);319  EXPECT_EQ(Function->symbolCount(), 3u);320  EXPECT_EQ(Function->typeCount(), 0u);321  EXPECT_EQ(Function->rangeCount(), 1u);322 323  const LVLocations *Ranges = Function->getRanges();324  ASSERT_NE(Ranges, nullptr);325  ASSERT_EQ(Ranges->size(), 1u);326  LVLocations::const_iterator IterLocation = Ranges->begin();327  LVLocation *Location = (*IterLocation);328  EXPECT_STREQ(Location->getIntervalInfo().c_str(),329               "{Range} Lines 2:9 [0x0000000000:0x0000000031]");330 331  LVRange RangeList;332  Function->getRanges(RangeList);333 334  const LVRangeEntries &RangeEntries = RangeList.getEntries();335  ASSERT_EQ(RangeEntries.size(), 2u);336  LVRangeEntries::const_iterator IterRanges = RangeEntries.cbegin();337  LVRangeEntry RangeEntry = *IterRanges;338  EXPECT_EQ(RangeEntry.lower(), 0u);339  EXPECT_EQ(RangeEntry.upper(), 0x31u);340  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);341  EXPECT_EQ(RangeEntry.scope()->getName(), "foo");342  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);343 344  ++IterRanges;345  RangeEntry = *IterRanges;346  EXPECT_EQ(RangeEntry.lower(), 0x1bu);347  EXPECT_EQ(RangeEntry.upper(), 0x28u);348  EXPECT_EQ(RangeEntry.scope()->getLineNumber(), 0u);349  EXPECT_EQ(RangeEntry.scope()->getName(), "foo::?");350  EXPECT_EQ(RangeEntry.scope()->getOffset(), 0u);351 352  const LVPublicNames &PublicNames = CompileUnit->getPublicNames();353  ASSERT_EQ(PublicNames.size(), 1u);354  LVPublicNames::const_iterator IterNames = PublicNames.cbegin();355  LVScope *Foo = (*IterNames).first;356  EXPECT_EQ(Foo->getName(), "foo");357  EXPECT_EQ(Foo->getLineNumber(), 0u);358  LVNameInfo NameInfo = (*IterNames).second;359  EXPECT_EQ(NameInfo.first, 0u);360  EXPECT_EQ(NameInfo.second, 0x31u);361 362  // Lines (debug and assembler) for 'foo'.363  const LVLines *Lines = Foo->getLines();364  ASSERT_NE(Lines, nullptr);365  EXPECT_EQ(Lines->size(), 0x0eu);366}367 368struct SelectionInfo {369  const char *Name;370  LVElementGetFunction Function;371};372 373// Check the logical elements selection.374void checkElementSelection(LVReader *Reader, std::vector<SelectionInfo> &Data,375                           size_t Size) {376  LVScopeRoot *Root = Reader->getScopesRoot();377  LVScopeCompileUnit *CompileUnit =378      static_cast<LVScopeCompileUnit *>(getFirstScopeChild(Root));379 380  // Get the matched elements.381  LVElements MatchedElements = CompileUnit->getMatchedElements();382  std::map<StringRef, LVElement *> MapElements;383  for (LVElement *Element : MatchedElements)384    MapElements[Element->getName()] = Element;385  ASSERT_EQ(MapElements.size(), Size);386 387  std::map<StringRef, LVElement *>::iterator Iter = MapElements.begin();388  for (const SelectionInfo &Entry : Data) {389    // Get matched element.390    EXPECT_NE(Iter, MapElements.end());391    LVElement *Element = Iter->second;392    ASSERT_NE(Element, nullptr);393    EXPECT_NE(Element->getName().find(Entry.Name), StringRef::npos);394    EXPECT_EQ((Element->*Entry.Function)(), 1u);395    ++Iter;396  }397 398  // Get the parents for the matched elements.399  LVScopes MatchedScopes = CompileUnit->getMatchedScopes();400  std::set<StringRef> SetScopes;401  for (LVScope *Scope : MatchedScopes)402    SetScopes.insert(Scope->getName());403  ASSERT_EQ(SetScopes.size(), 3u);404 405  // Parents of selected elements.406  std::set<StringRef>::iterator IterScope;407  IterScope = SetScopes.find("foo");408  EXPECT_NE(IterScope, SetScopes.end());409  IterScope = SetScopes.find("foo::?");410  EXPECT_NE(IterScope, SetScopes.end());411  IterScope = SetScopes.find("test.cpp");412  EXPECT_NE(IterScope, SetScopes.end());413}414 415// Check the logical elements comparison.416void checkElementComparison(LVReader *Reference, LVReader *Target) {417  LVCompare Compare(nulls());418  Error Err = Compare.execute(Reference, Target);419  ASSERT_THAT_ERROR(std::move(Err), Succeeded());420 421  // Get comparison table.422  LVPassTable PassTable = Compare.getPassTable();423  ASSERT_EQ(PassTable.size(), 2u);424 425  LVReader *Reader;426  LVElement *Element;427  LVComparePass Pass;428 429  // Reference: Missing TypeDefinition 'INTEGER'430  std::tie(Reader, Element, Pass) = PassTable[0];431  ASSERT_NE(Reader, nullptr);432  ASSERT_NE(Element, nullptr);433  EXPECT_EQ(Reader, Reference);434  EXPECT_EQ(Element->getLevel(), 3u);435  EXPECT_EQ(Element->getLineNumber(), 0u);436  EXPECT_EQ(Element->getName(), "INTEGER");437  EXPECT_EQ(Pass, LVComparePass::Missing);438 439  // Target: Added TypeDefinition 'INTEGER'440  std::tie(Reader, Element, Pass) = PassTable[1];441  ASSERT_NE(Reader, nullptr);442  ASSERT_NE(Element, nullptr);443  EXPECT_EQ(Reader, Target);444  EXPECT_EQ(Element->getLevel(), 4u);445  EXPECT_EQ(Element->getLineNumber(), 0u);446  EXPECT_EQ(Element->getName(), "INTEGER");447  EXPECT_EQ(Pass, LVComparePass::Added);448}449 450// Logical elements properties.451void elementProperties(SmallString<128> &InputsDir) {452  // Reader options.453  LVOptions ReaderOptions;454  ReaderOptions.setAttributeOffset();455  ReaderOptions.setAttributeFormat();456  ReaderOptions.setAttributeFilename();457  ReaderOptions.setAttributeProducer();458  ReaderOptions.setAttributePublics();459  ReaderOptions.setAttributeRange();460  ReaderOptions.setAttributeLanguage();461  ReaderOptions.setAttributeLocation();462  ReaderOptions.setAttributeSize();463  ReaderOptions.setPrintAll();464  ReaderOptions.resolveDependencies();465 466  std::vector<std::string> Objects;467  ScopedPrinter W(outs());468  LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);469 470  // Check logical elements properties.471  {472    std::unique_ptr<LVReader> Reader =473        createReader(ReaderHandler, InputsDir, CodeViewClang);474    checkElementPropertiesClangCodeview(Reader.get());475  }476  {477    std::unique_ptr<LVReader> Reader =478        createReader(ReaderHandler, InputsDir, CodeViewMsvc);479    checkElementPropertiesMsvcCodeview(Reader.get());480  }481  {482    std::unique_ptr<LVReader> Reader =483        createReader(ReaderHandler, InputsDir, CodeViewMsvcLib);484    checkElementPropertiesMsvcLibraryCodeview(Reader.get());485  }486  {487    std::unique_ptr<LVReader> Reader =488        createReader(ReaderHandler, InputsDir, CodeViewPdbMsvc);489    checkElementPropertiesMsvcCodeviewPdb(Reader.get());490  }491}492 493// Logical elements selection.494void elementSelection(SmallString<128> &InputsDir) {495  // Reader options.496  LVOptions ReaderOptions;497  ReaderOptions.setAttributeOffset();498  ReaderOptions.setPrintAll();499 500  ReaderOptions.setSelectIgnoreCase();501  ReaderOptions.setSelectUseRegex();502 503  ReaderOptions.setReportList(); // Matched elements.504  ReaderOptions.setReportView(); // Parents for matched elements.505 506  // Add patterns.507  ReaderOptions.Select.Generic.insert("foo");508  ReaderOptions.Select.Generic.insert("movl[ \t]?%");509  ReaderOptions.Select.Generic.insert("INT[a-z]*");510  ReaderOptions.Select.Generic.insert("CONSTANT");511 512  ReaderOptions.resolveDependencies();513 514  std::vector<std::string> Objects;515  ScopedPrinter W(outs());516  LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);517 518  // Check logical elements selection.519  {520    std::vector<SelectionInfo> DataClang = {521        {"* const int", &LVElement::getIsType},522        {"CONSTANT", &LVElement::getIsSymbol},523        {"INTEGER", &LVElement::getIsType},524        {"INTPTR", &LVElement::getIsType},525        {"ParamPtr", &LVElement::getIsSymbol},526        {"const int", &LVElement::getIsType},527        {"foo", &LVElement::getIsScope},528        {"foo::?", &LVElement::getIsScope},529        {"int", &LVElement::getIsType},530        {"movl", &LVElement::getIsLine},531        {"movl", &LVElement::getIsLine}};532    std::unique_ptr<LVReader> Reader =533        createReader(ReaderHandler, InputsDir, CodeViewClang);534    checkElementSelection(Reader.get(), DataClang, DataClang.size());535  }536  {537    std::vector<SelectionInfo> DataMsvc = {538        {"* const int", &LVElement::getIsType},539        {"CONSTANT", &LVElement::getIsSymbol},540        {"INTEGER", &LVElement::getIsType},541        {"INTPTR", &LVElement::getIsType},542        {"ParamPtr", &LVElement::getIsSymbol},543        {"const int", &LVElement::getIsType},544        {"foo", &LVElement::getIsScope},545        {"foo::?", &LVElement::getIsScope},546        {"int", &LVElement::getIsType},547        {"movl", &LVElement::getIsLine}};548    std::unique_ptr<LVReader> Reader =549        createReader(ReaderHandler, InputsDir, CodeViewMsvc);550    checkElementSelection(Reader.get(), DataMsvc, DataMsvc.size());551  }552}553 554// Compare logical elements.555void compareElements(SmallString<128> &InputsDir) {556  // Reader options.557  LVOptions ReaderOptions;558  ReaderOptions.setAttributeOffset();559  ReaderOptions.setPrintLines();560  ReaderOptions.setPrintSymbols();561  ReaderOptions.setPrintTypes();562  ReaderOptions.setCompareLines();563  ReaderOptions.setCompareSymbols();564  ReaderOptions.setCompareTypes();565 566  ReaderOptions.resolveDependencies();567 568  std::vector<std::string> Objects;569  ScopedPrinter W(outs());570  LVReaderHandler ReaderHandler(Objects, W, ReaderOptions);571 572  // Check logical comparison.573  std::unique_ptr<LVReader> Reference =574      createReader(ReaderHandler, InputsDir, CodeViewClang);575  std::unique_ptr<LVReader> Target =576      createReader(ReaderHandler, InputsDir, CodeViewMsvc);577  checkElementComparison(Reference.get(), Target.get());578}579 580TEST(LogicalViewTest, CodeViewReader) {581  // Initialize targets and assembly printers/parsers.582  llvm::InitializeAllTargetInfos();583  llvm::InitializeAllTargetMCs();584  InitializeAllDisassemblers();585 586  llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded);587 588  // This test requires a x86-registered-target.589  Triple TT;590  TT.setArch(Triple::x86_64);591  TT.setVendor(Triple::UnknownVendor);592  TT.setOS(Triple::UnknownOS);593 594  std::string TargetLookupError;595  if (!TargetRegistry::lookupTarget(TT, TargetLookupError))596    return;597 598  SmallString<128> InputsDir = unittest::getInputFileDirectory(TestMainArgv0);599 600  // Logical elements general properties and selection.601  elementProperties(InputsDir);602  elementSelection(InputsDir);603 604  // Compare logical elements.605  compareElements(InputsDir);606}607 608} // namespace609