brintos

brintos / llvm-project-archived public Read only

0
0
Text · 18.1 KiB · 7cd6813 Raw
591 lines · cpp
1//===- llvm/unittest/DebugInfo/LogicalView/LocationRangesTest.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/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 20using namespace llvm;21using namespace llvm::logicalview;22 23namespace {24 25class ReaderTest : public LVReader {26protected:27  void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine);28  void add(LVScope *Parent, LVElement *Element);29  void set(LVElement *Element, StringRef Name, LVOffset Offset,30           uint32_t LineNumber = 0, LVElement *Type = nullptr);31  void set(LVLocation *Location, LVLine *LowerLine, LVLine *UpperLine,32           LVAddress LowerAddress, LVAddress UpperAddress);33 34public:35  ReaderTest(ScopedPrinter &W) : LVReader("", "", W) { setInstance(this); }36 37  Error createScopes() override { return LVReader::createScopes(); }38};39 40// Helper function to add a logical element to a given scope.41void ReaderTest::add(LVScope *Parent, LVElement *Child) {42  Parent->addElement(Child);43  EXPECT_EQ(Child->getParent(), Parent);44  EXPECT_EQ(Child->getLevel(), Parent->getLevel() + 1);45}46 47// Helper function to set the initial values for a given logical element.48void ReaderTest::set(LVElement *Element, StringRef Name, LVOffset Offset,49                     uint32_t LineNumber, LVElement *Type) {50  Element->setName(Name);51  Element->setOffset(Offset);52  Element->setLineNumber(LineNumber);53  Element->setType(Type);54  EXPECT_EQ(Element->getName(), Name);55  EXPECT_EQ(Element->getOffset(), Offset);56  EXPECT_EQ(Element->getLineNumber(), LineNumber);57  EXPECT_EQ(Element->getType(), Type);58}59 60// Helper function to set the initial values for a given logical location.61void ReaderTest::set(LVLocation *Location, LVLine *LowerLine, LVLine *UpperLine,62                     LVAddress LowerAddress, LVAddress UpperAddress) {63  Location->setLowerLine(LowerLine);64  Location->setUpperLine(UpperLine);65  Location->setLowerAddress(LowerAddress);66  Location->setUpperAddress(UpperAddress);67  EXPECT_EQ(Location->getLowerLine(), LowerLine);68  EXPECT_EQ(Location->getUpperLine(), UpperLine);69  EXPECT_EQ(Location->getLowerAddress(), LowerAddress);70  EXPECT_EQ(Location->getUpperAddress(), UpperAddress);71}72 73// Helper function to add a logical location to a logical symbol.74void ReaderTest::add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine) {75  dwarf::Attribute Attr = dwarf::DW_AT_location;76 77  Symbol->addLocation(Attr, LowerLine->getAddress(), UpperLine->getAddress(),78                      /*SectionOffset=*/0, /*LocDesOffset=*/0);79}80 81class ReaderTestLocations : public ReaderTest {82#define CREATE(VARIABLE, CREATE_FUNCTION)                                      \83  VARIABLE = CREATE_FUNCTION();                                                \84  EXPECT_NE(VARIABLE, nullptr);85 86  // Types.87  LVType *IntegerType = nullptr;88 89  // Scopes.90  LVScope *NestedScope = nullptr;91  LVScopeFunction *Function = nullptr;92 93  // Symbols.94  LVSymbol *LocalVariable = nullptr;95  LVSymbol *NestedVariable = nullptr;96  LVSymbol *Parameter = nullptr;97 98  // Lines.99  LVLine *LineOne = nullptr;100  LVLine *LineTwo = nullptr;101  LVLine *LineThree = nullptr;102  LVLine *LineFour = nullptr;103  LVLine *LineFive = nullptr;104  LVLine *LineSix = nullptr;105 106  // Locations.107  LVLocation *LocationOne = nullptr;108  LVLocation *LocationTwo = nullptr;109  LVLocation *LocationThree = nullptr;110  LVLocation *LocationFour = nullptr;111  LVLocation *LocationFive = nullptr;112  LVLocation *LocationSix = nullptr;113 114public:115  ReaderTestLocations(ScopedPrinter &W) : ReaderTest(W) {}116 117  void createElements();118  void addElements();119  void initElements();120};121 122// Create the logical elements.123void ReaderTestLocations::createElements() {124  // Create scope root.125  Error Err = createScopes();126  ASSERT_THAT_ERROR(std::move(Err), Succeeded());127  Root = getScopesRoot();128  EXPECT_NE(Root, nullptr);129 130  // Create the logical types.131  CREATE(IntegerType, createType);132 133  // Create the logical scopes.134  CREATE(NestedScope, createScope);135  CREATE(CompileUnit, createScopeCompileUnit);136  CREATE(Function, createScopeFunction);137 138  // Create the logical symbols.139  CREATE(LocalVariable, createSymbol);140  CREATE(NestedVariable, createSymbol);141  CREATE(Parameter, createSymbol);142 143  // Create the logical lines.144  CREATE(LineOne, createLine);145  CREATE(LineTwo, createLine);146  CREATE(LineThree, createLine);147  CREATE(LineFour, createLine);148  CREATE(LineFive, createLine);149  CREATE(LineSix, createLine);150 151  // Create the logical locations.152  CREATE(LocationOne, createLocation);153  CREATE(LocationTwo, createLocation);154  CREATE(LocationThree, createLocation);155  CREATE(LocationFour, createLocation);156  CREATE(LocationFive, createLocation);157  CREATE(LocationSix, createLocation);158}159 160// Create the logical view adding the created logical elements.161void ReaderTestLocations::addElements() {162  setCompileUnit(CompileUnit);163 164  // Root165  //   CompileUnit166  //     IntegerType167  //     Function168  //       LocationOne169  //       LocationTwo170  //       LocationFive171  //       LocationSix172  //       Parameter173  //       LocalVariable174  //       LineOne175  //       LineTwo176  //       NestedScope177  //         LocationThree178  //         LocationFour179  //         NestedVariable180  //         LineThree181  //         LineFour182  //       LineFive183  //       LineSix184 185  // Add elements to Root.186  add(Root, CompileUnit);187 188  // Add elements to CompileUnit.189  add(CompileUnit, IntegerType);190  add(CompileUnit, Function);191 192  // Add elements to Function.193  add(Function, Parameter);194  add(Function, LocalVariable);195  add(Function, LineOne);196  add(Function, LineTwo);197  add(Function, LineFive);198  add(Function, LineSix);199  add(Function, NestedScope);200 201  // Add elements to NestedScope.202  add(NestedScope, NestedVariable);203  add(NestedScope, LineThree);204  add(NestedScope, LineFour);205}206 207// Set initial values to logical elements.208void ReaderTestLocations::initElements() {209  // Types.210  set(IntegerType, "int", 0x1000);211 212  // Scopes.213  set(CompileUnit, "foo.cpp", 0x2000);214  set(Function, "foo", 0x2010, 100, IntegerType);215  set(NestedScope, "", 0x2020, 300);216 217  // Symbols.218  set(Parameter, "Param", 0x3000, 110, IntegerType);219  set(LocalVariable, "LocalVariable", 0x3000, 120, IntegerType);220  set(NestedVariable, "NestedVariable", 0x3010, 310, IntegerType);221 222  // Lines.223  set(LineOne, "", 0x5000, 100);224  set(LineTwo, "", 0x5200, 200);225  set(LineThree, "", 0x5400, 300);226  set(LineFour, "", 0x5600, 400);227  set(LineFive, "", 0x5800, 500);228  set(LineSix, "", 0x6000, 600);229 230  // Locations.231  set(LocationOne, LineOne, LineOne, 0x5000, 0x5100);232  EXPECT_STREQ(LocationOne->getIntervalInfo().c_str(),233               " Lines 100:100 [0x0000005000:0x0000005100]");234 235  set(LocationTwo, LineTwo, LineTwo, 0x5200, 0x5300);236  EXPECT_STREQ(LocationTwo->getIntervalInfo().c_str(),237               " Lines 200:200 [0x0000005200:0x0000005300]");238 239  set(LocationThree, LineThree, LineThree, 0x5400, 0x5500);240  EXPECT_STREQ(LocationThree->getIntervalInfo().c_str(),241               " Lines 300:300 [0x0000005400:0x0000005500]");242 243  set(LocationFour, LineFour, LineFour, 0x5600, 0x5700);244  LocationFour->setIsAddressRange();245  EXPECT_STREQ(LocationFour->getIntervalInfo().c_str(),246               "{Range} Lines 400:400 [0x0000005600:0x0000005700]");247 248  set(LocationFive, LineFive, LineFive, 0x5800, 0x5900);249  LocationFive->setIsAddressRange();250  EXPECT_STREQ(LocationFive->getIntervalInfo().c_str(),251               "{Range} Lines 500:500 [0x0000005800:0x0000005900]");252 253  set(LocationSix, LineSix, LineSix, 0x6000, 0x6100);254  LocationSix->setIsAddressRange();255  EXPECT_STREQ(LocationSix->getIntervalInfo().c_str(),256               "{Range} Lines 600:600 [0x0000006000:0x0000006100]");257 258  // Add ranges to Function.259  // Function: LocationOne, LocationTwo, LocationFive, LocationSix260  Function->addObject(LocationOne);261  Function->addObject(LocationTwo);262  Function->addObject(LocationFive);263  Function->addObject(LocationSix);264  EXPECT_EQ(Function->rangeCount(), 4u);265 266  // Add ranges to NestedScope.267  // NestedScope: LocationThree, LocationFour268  NestedScope->addObject(LocationThree);269  NestedScope->addObject(LocationFour);270  EXPECT_EQ(NestedScope->rangeCount(), 2u);271 272  // Get all ranges.273  LVRange Ranges;274  CompileUnit->getRanges(Ranges);275  Ranges.startSearch();276  EXPECT_EQ(Ranges.getEntry(0x4000), nullptr);277 278  EXPECT_EQ(Ranges.getEntry(0x5060), Function);279  EXPECT_EQ(Ranges.getEntry(0x5850), Function);280  EXPECT_EQ(Ranges.getEntry(0x5010, 0x5090), Function);281  EXPECT_EQ(Ranges.getEntry(0x5210, 0x5290), Function);282  EXPECT_EQ(Ranges.getEntry(0x5810, 0x5890), Function);283  EXPECT_EQ(Ranges.getEntry(0x6010, 0x6090), Function);284 285  EXPECT_EQ(Ranges.getEntry(0x5400), NestedScope);286  EXPECT_EQ(Ranges.getEntry(0x5650), NestedScope);287  EXPECT_EQ(Ranges.getEntry(0x5410, 0x5490), NestedScope);288  EXPECT_EQ(Ranges.getEntry(0x5610, 0x5690), NestedScope);289 290  EXPECT_EQ(Ranges.getEntry(0x8000), nullptr);291  Ranges.endSearch();292 293  // Add locations to symbols.294  // Parameter:       [LineOne, LineSix]295  // LocalVariable:   [LineTwo, LineSix], [LineFour, LineFive]296  // NestedVariable:  [LineThree, LineFour]297  add(Parameter, LineOne, LineSix);298  add(LocalVariable, LineTwo, LineSix);299  add(LocalVariable, LineFour, LineFive);300  add(NestedVariable, LineThree, LineFour);301 302  LVLocation *Location;303  LVLocations Locations;304  Parameter->getLocations(Locations);305  ASSERT_EQ(Locations.size(), 1u);306  Location = Locations[0];307  EXPECT_EQ(Location->getLowerAddress(), LineOne->getAddress());308  EXPECT_EQ(Location->getUpperAddress(), LineSix->getAddress());309 310  Locations.clear();311  LocalVariable->getLocations(Locations);312  ASSERT_EQ(Locations.size(), 2u);313  Location = Locations[0];314  EXPECT_EQ(Location->getLowerAddress(), LineTwo->getAddress());315  EXPECT_EQ(Location->getUpperAddress(), LineSix->getAddress());316  Location = Locations[1];317  EXPECT_EQ(Location->getLowerAddress(), LineFour->getAddress());318  EXPECT_EQ(Location->getUpperAddress(), LineFive->getAddress());319 320  Locations.clear();321  NestedVariable->getLocations(Locations);322  ASSERT_EQ(Locations.size(), 1u);323  Location = Locations[0];324  EXPECT_EQ(Location->getLowerAddress(), LineThree->getAddress());325  EXPECT_EQ(Location->getUpperAddress(), LineFour->getAddress());326}327 328class ReaderTestCoverage : public ReaderTest {329  // Types.330  LVType *IntegerType = nullptr;331 332  // Scopes.333  LVScopeFunction *Function = nullptr;334  LVScopeFunctionInlined *InlinedFunction = nullptr;335 336  // Symbols.337  LVSymbol *Variable = nullptr;338  LVSymbol *Parameter = nullptr;339 340  // Lines.341  LVLine *LineOne = nullptr;342  LVLine *LineTwo = nullptr;343  LVLine *LineThree = nullptr;344  LVLine *LineFour = nullptr;345  LVLine *LineFive = nullptr;346  LVLine *LineSix = nullptr;347 348  // Locations.349  LVLocation *LocationOne = nullptr;350  LVLocation *LocationTwo = nullptr;351  LVLocation *LocationFive = nullptr;352  LVLocation *LocationSix = nullptr;353 354public:355  ReaderTestCoverage(ScopedPrinter &W) : ReaderTest(W) {}356 357  void createElements();358  void addElements();359  void initElements();360};361 362// Create the logical elements.363void ReaderTestCoverage::createElements() {364  // Create scope root.365  Error Err = createScopes();366  ASSERT_THAT_ERROR(std::move(Err), Succeeded());367  Root = getScopesRoot();368  EXPECT_NE(Root, nullptr);369 370  // Create the logical types.371  IntegerType = createType();372  EXPECT_NE(IntegerType, nullptr);373 374  // Create the logical scopes.375  CompileUnit = createScopeCompileUnit();376  EXPECT_NE(CompileUnit, nullptr);377  Function = createScopeFunction();378  EXPECT_NE(Function, nullptr);379  InlinedFunction = createScopeFunctionInlined();380  EXPECT_NE(InlinedFunction, nullptr);381 382  // Create the logical symbols.383  Variable = createSymbol();384  EXPECT_NE(Variable, nullptr);385  Parameter = createSymbol();386  EXPECT_NE(Parameter, nullptr);387 388  // Create the logical lines.389  LineOne = createLine();390  EXPECT_NE(LineOne, nullptr);391  LineTwo = createLine();392  EXPECT_NE(LineTwo, nullptr);393  LineThree = createLine();394  EXPECT_NE(LineThree, nullptr);395  LineFour = createLine();396  EXPECT_NE(LineFour, nullptr);397  LineFive = createLine();398  EXPECT_NE(LineFive, nullptr);399  LineSix = createLine();400  EXPECT_NE(LineSix, nullptr);401 402  // Create the logical locations.403  LocationOne = createLocation();404  EXPECT_NE(LocationOne, nullptr);405  LocationTwo = createLocation();406  EXPECT_NE(LocationTwo, nullptr);407  LocationFive = createLocation();408  EXPECT_NE(LocationFive, nullptr);409  LocationSix = createLocation();410  EXPECT_NE(LocationSix, nullptr);411}412 413// Create the logical view adding the created logical elements.414void ReaderTestCoverage::addElements() {415  setCompileUnit(CompileUnit);416 417  // Root418  //   CompileUnit419  //     IntegerType420  //     Function421  //       Ranges422  //         [LineOne, LineOne]423  //         [LineTwo, LineSix]424  //         [LineSix, LineSix]425  //       LineOne426  //       LineTwo427  //       InlinedFunction428  //         Ranges429  //           [LineFive, LineFive]430  //         Parameter431  //           Location432  //             [LineThree, LineThree]433  //         Variable434  //           Location435  //             [LineFour, LineFive]436  //             [LineFive, LineSix]437  //         LineThree438  //         LineFour439  //         LineFive440  //       LineSix441 442  // Add elements to Root.443  add(Root, CompileUnit);444 445  // Add elements to CompileUnit.446  add(CompileUnit, IntegerType);447  add(CompileUnit, Function);448 449  // Add elements to Function.450  add(Function, InlinedFunction);451  add(Function, LineOne);452  add(Function, LineTwo);453  add(Function, LineSix);454 455  // Add elements to function InlinedFunction.456  add(InlinedFunction, Parameter);457  add(InlinedFunction, Variable);458  add(InlinedFunction, LineThree);459  add(InlinedFunction, LineFour);460  add(InlinedFunction, LineFive);461}462 463// Set initial values to logical elements.464void ReaderTestCoverage::initElements() {465  // Types.466  set(IntegerType, "int", 0x1000);467 468  // Scopes.469  set(CompileUnit, "foo.cpp", 0x2000);470  set(Function, "foo", 0x2500, 100, IntegerType);471  set(InlinedFunction, "InlinedFunction", 0x3000, 300);472 473  // Symbols.474  set(Parameter, "Parameter", 0x3100, 310, IntegerType);475  set(Variable, "Variable", 0x3200, 320, IntegerType);476 477  // Lines.478  set(LineOne, "", 0x5000, 100);479  set(LineTwo, "", 0x5200, 200);480  set(LineThree, "", 0x5400, 300);481  set(LineFour, "", 0x5600, 400);482  set(LineFive, "", 0x5800, 500);483  set(LineSix, "", 0x6000, 600);484 485  // Locations.486  set(LocationOne, LineOne, LineOne, 0x5000, 0x5199);487  EXPECT_STREQ(LocationOne->getIntervalInfo().c_str(),488               " Lines 100:100 [0x0000005000:0x0000005199]");489 490  set(LocationTwo, LineTwo, LineSix, 0x5200, 0x6100);491  EXPECT_STREQ(LocationTwo->getIntervalInfo().c_str(),492               " Lines 200:600 [0x0000005200:0x0000006100]");493 494  set(LocationFive, LineFive, LineFive, 0x5800, 0x5900);495  EXPECT_STREQ(LocationFive->getIntervalInfo().c_str(),496               " Lines 500:500 [0x0000005800:0x0000005900]");497 498  set(LocationSix, LineSix, LineSix, 0x6000, 0x6100);499  EXPECT_STREQ(LocationSix->getIntervalInfo().c_str(),500               " Lines 600:600 [0x0000006000:0x0000006100]");501 502  // Add ranges to Function.503  // Function: LocationOne, LocationTwo, LocationSix504  Function->addObject(LocationOne);505  Function->addObject(LocationTwo);506  Function->addObject(LocationSix);507  EXPECT_EQ(Function->rangeCount(), 3u);508 509  // Add ranges to Inlined.510  // Inlined: LocationFive511  InlinedFunction->addObject(LocationFive);512  EXPECT_EQ(InlinedFunction->rangeCount(), 1u);513 514  // Add locations to symbols.515  // Parameter: [LineThree, LineThree]516  // Variable:  [LineFour, LineFive], [LineFive, LineSix]517  add(Parameter, LineThree, LineThree);518  add(Variable, LineFour, LineFive);519  add(Variable, LineFive, LineSix);520 521  CompileUnit->processRangeLocationCoverage();522 523  LVLocation *Location;524  LVLocations Locations;525  Parameter->getLocations(Locations);526  ASSERT_EQ(Locations.size(), 1u);527  Location = Locations[0];528  EXPECT_EQ(Location->getLowerAddress(), LineThree->getAddress());529  EXPECT_EQ(Location->getUpperAddress(), LineThree->getAddress());530 531  Locations.clear();532  Variable->getLocations(Locations);533  ASSERT_EQ(Locations.size(), 2u);534  Location = Locations[0];535  EXPECT_EQ(Location->getLowerAddress(), LineFour->getAddress());536  EXPECT_EQ(Location->getUpperAddress(), LineFive->getAddress());537  Location = Locations[1];538  EXPECT_EQ(Location->getLowerAddress(), LineFive->getAddress());539  EXPECT_EQ(Location->getUpperAddress(), LineSix->getAddress());540 541  // Test the changes done to 'LVScope::outermostParent' to use the542  // ranges allocated int the current scope during the scopes traversal.543  // These are the pre-conditions for the symbol:544  // - Its parent must be an inlined function.545  // - Have more than one location description.546 547  // Before the changes: Parameter: CoveragePercentage = 100.00548  // After the changes:  Parameter: CoveragePercentage = 100.00549  EXPECT_FLOAT_EQ(Parameter->getCoveragePercentage(), 100.00f);550 551  // Before the changes: Variable: CoveragePercentage = 1000.00552  // After the changes:  Variable: CoveragePercentage = 56.83553  EXPECT_FLOAT_EQ(Variable->getCoveragePercentage(), 56.83f);554}555 556TEST(LogicalViewTest, LocationRanges) {557  ScopedPrinter W(outs());558  ReaderTestLocations Reader(W);559 560  // Reader options.561  LVOptions ReaderOptions;562  ReaderOptions.setAttributeOffset();563  ReaderOptions.setPrintAll();564  ReaderOptions.resolveDependencies();565  options().setOptions(&ReaderOptions);566 567  Reader.createElements();568  Reader.addElements();569  Reader.initElements();570}571 572TEST(LogicalViewTest, LocationCoverage) {573  ScopedPrinter W(outs());574  ReaderTestCoverage Reader(W);575 576  // Reader options.577  LVOptions ReaderOptions;578  ReaderOptions.setAttributeOffset();579  ReaderOptions.setAttributeRange();580  ReaderOptions.setAttributeLocation();581  ReaderOptions.setPrintAll();582  ReaderOptions.resolveDependencies();583  options().setOptions(&ReaderOptions);584 585  Reader.createElements();586  Reader.addElements();587  Reader.initElements();588}589 590} // namespace591