xref: /llvm-project/llvm/unittests/DebugInfo/LogicalView/WarningInternalTest.cpp (revision 7fbcc24409efdb37cec79ad461ef383f6ffc5ef2)
12c155d37SCarlos Alberto Enciso //===- llvm/unittest/DebugInfo/LogicalView/WarningInternalTest.cpp --------===//
22c155d37SCarlos Alberto Enciso //
32c155d37SCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42c155d37SCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information.
52c155d37SCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62c155d37SCarlos Alberto Enciso //
72c155d37SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
82c155d37SCarlos Alberto Enciso 
92c155d37SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
102c155d37SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
112c155d37SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
122c155d37SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
132c155d37SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVType.h"
142c155d37SCarlos Alberto Enciso #include "llvm/Support/ScopedPrinter.h"
152c155d37SCarlos Alberto Enciso #include "llvm/Support/ToolOutputFile.h"
162c155d37SCarlos Alberto Enciso #include "llvm/Testing/Support/Error.h"
172c155d37SCarlos Alberto Enciso 
182c155d37SCarlos Alberto Enciso #include "gtest/gtest.h"
192c155d37SCarlos Alberto Enciso 
202c155d37SCarlos Alberto Enciso using namespace llvm;
212c155d37SCarlos Alberto Enciso using namespace llvm::logicalview;
222c155d37SCarlos Alberto Enciso 
232c155d37SCarlos Alberto Enciso namespace {
242c155d37SCarlos Alberto Enciso 
25*7fbcc244SCarlos Alberto Enciso class MyLocation : public LVLocation {
26*7fbcc244SCarlos Alberto Enciso public:
27*7fbcc244SCarlos Alberto Enciso   bool validateRanges();
28*7fbcc244SCarlos Alberto Enciso };
292c155d37SCarlos Alberto Enciso 
302c155d37SCarlos Alberto Enciso // This code emulates the work done by the Readers when processing the
312c155d37SCarlos Alberto Enciso // binary files and the creation of the AddressToLine mapping is done
322c155d37SCarlos Alberto Enciso // automatically, using the text sections.
332c155d37SCarlos Alberto Enciso class MyAddressToLine {
342c155d37SCarlos Alberto Enciso   using LVAddressToLine = std::map<LVAddress, LVLine *>;
352c155d37SCarlos Alberto Enciso   LVAddressToLine AddressToLineData;
362c155d37SCarlos Alberto Enciso 
372c155d37SCarlos Alberto Enciso public:
382c155d37SCarlos Alberto Enciso   MyAddressToLine() = default;
392c155d37SCarlos Alberto Enciso 
insert(LVLine * Line)402c155d37SCarlos Alberto Enciso   void insert(LVLine *Line) {
412c155d37SCarlos Alberto Enciso     AddressToLineData.emplace(Line->getOffset(), Line);
422c155d37SCarlos Alberto Enciso   }
432c155d37SCarlos Alberto Enciso 
442c155d37SCarlos Alberto Enciso   LVLine *lineLowerBound(LVAddress Address);
452c155d37SCarlos Alberto Enciso   LVLine *lineUpperBound(LVAddress Address);
462c155d37SCarlos Alberto Enciso };
472c155d37SCarlos Alberto Enciso 
lineLowerBound(LVAddress Address)482c155d37SCarlos Alberto Enciso LVLine *MyAddressToLine::lineLowerBound(LVAddress Address) {
492c155d37SCarlos Alberto Enciso   LVAddressToLine::const_iterator Iter = AddressToLineData.lower_bound(Address);
502c155d37SCarlos Alberto Enciso   return (Iter != AddressToLineData.end()) ? Iter->second : nullptr;
512c155d37SCarlos Alberto Enciso }
522c155d37SCarlos Alberto Enciso 
lineUpperBound(LVAddress Address)532c155d37SCarlos Alberto Enciso LVLine *MyAddressToLine::lineUpperBound(LVAddress Address) {
542c155d37SCarlos Alberto Enciso   if (AddressToLineData.empty())
552c155d37SCarlos Alberto Enciso     return nullptr;
562c155d37SCarlos Alberto Enciso   LVAddressToLine::const_iterator Iter = AddressToLineData.upper_bound(Address);
572c155d37SCarlos Alberto Enciso   if (Iter != AddressToLineData.begin())
582c155d37SCarlos Alberto Enciso     Iter = std::prev(Iter);
592c155d37SCarlos Alberto Enciso   return Iter->second;
602c155d37SCarlos Alberto Enciso }
612c155d37SCarlos Alberto Enciso 
622c155d37SCarlos Alberto Enciso MyAddressToLine AddressToLine;
632c155d37SCarlos Alberto Enciso 
642c155d37SCarlos Alberto Enciso class ReaderTestWarningInternal : public LVReader {
65*7fbcc244SCarlos Alberto Enciso #define CREATE(VARIABLE, CREATE_FUNCTION)                                      \
66*7fbcc244SCarlos Alberto Enciso   VARIABLE = CREATE_FUNCTION();                                                \
67*7fbcc244SCarlos Alberto Enciso   EXPECT_NE(VARIABLE, nullptr);
68*7fbcc244SCarlos Alberto Enciso 
69*7fbcc244SCarlos Alberto Enciso #define CREATE_CUSTOM(VARIABLE, CREATE_FUNCTION)                               \
70*7fbcc244SCarlos Alberto Enciso   VARIABLE = CREATE_FUNCTION();                                                \
71*7fbcc244SCarlos Alberto Enciso   EXPECT_NE(VARIABLE, nullptr);
72*7fbcc244SCarlos Alberto Enciso 
732c155d37SCarlos Alberto Enciso   // Types.
742c155d37SCarlos Alberto Enciso   LVType *IntegerType = nullptr;
752c155d37SCarlos Alberto Enciso 
762c155d37SCarlos Alberto Enciso   // Scopes.
772c155d37SCarlos Alberto Enciso   LVScope *NestedScope = nullptr;
782c155d37SCarlos Alberto Enciso   LVScopeFunction *Function = nullptr;
792c155d37SCarlos Alberto Enciso 
802c155d37SCarlos Alberto Enciso   // Symbols.
812c155d37SCarlos Alberto Enciso   LVSymbol *LocalVariable = nullptr;
822c155d37SCarlos Alberto Enciso   LVSymbol *NestedVariable = nullptr;
832c155d37SCarlos Alberto Enciso   LVSymbol *Parameter = nullptr;
842c155d37SCarlos Alberto Enciso 
852c155d37SCarlos Alberto Enciso   // Lines.
862c155d37SCarlos Alberto Enciso   LVLine *LineOne = nullptr;
872c155d37SCarlos Alberto Enciso   LVLine *LineTwo = nullptr;
882c155d37SCarlos Alberto Enciso   LVLine *LineThree = nullptr;
892c155d37SCarlos Alberto Enciso   LVLine *LineFour = nullptr;
902c155d37SCarlos Alberto Enciso   LVLine *LineFive = nullptr;
912c155d37SCarlos Alberto Enciso   LVLine *LineSix = nullptr;
922c155d37SCarlos Alberto Enciso 
932c155d37SCarlos Alberto Enciso   // Locations.
942c155d37SCarlos Alberto Enciso   MyLocation *LocationOne = nullptr;
952c155d37SCarlos Alberto Enciso   MyLocation *LocationTwo = nullptr;
962c155d37SCarlos Alberto Enciso   MyLocation *LocationThree = nullptr;
972c155d37SCarlos Alberto Enciso   MyLocation *LocationFour = nullptr;
982c155d37SCarlos Alberto Enciso   MyLocation *LocationFive = nullptr;
992c155d37SCarlos Alberto Enciso   MyLocation *LocationSix = nullptr;
1002c155d37SCarlos Alberto Enciso 
101*7fbcc244SCarlos Alberto Enciso   llvm::SpecificBumpPtrAllocator<MyLocation> AllocatedLocations;
102*7fbcc244SCarlos Alberto Enciso 
1032c155d37SCarlos Alberto Enciso protected:
createCustomLocation()104*7fbcc244SCarlos Alberto Enciso   MyLocation *createCustomLocation() {
105*7fbcc244SCarlos Alberto Enciso     return new (AllocatedLocations.Allocate()) MyLocation();
1062c155d37SCarlos Alberto Enciso   }
107*7fbcc244SCarlos Alberto Enciso 
108*7fbcc244SCarlos Alberto Enciso   void add(LVSymbol *Symbol, LVLine *LowerLine, LVLine *UpperLine);
109*7fbcc244SCarlos Alberto Enciso   void add(LVScope *Parent, LVElement *Element);
1102c155d37SCarlos Alberto Enciso   void set(LVElement *Element, StringRef Name, LVOffset Offset,
1112c155d37SCarlos Alberto Enciso            uint32_t LineNumber = 0, LVElement *Type = nullptr);
1122c155d37SCarlos Alberto Enciso   void set(MyLocation *Location, LVLine *LowerLine, LVLine *UpperLine,
1132c155d37SCarlos Alberto Enciso            LVAddress LowerAddress, LVAddress UpperAddress);
1142c155d37SCarlos Alberto Enciso 
1152c155d37SCarlos Alberto Enciso public:
ReaderTestWarningInternal(ScopedPrinter & W)1162c155d37SCarlos Alberto Enciso   ReaderTestWarningInternal(ScopedPrinter &W) : LVReader("", "", W) {
1172c155d37SCarlos Alberto Enciso     setInstance(this);
1182c155d37SCarlos Alberto Enciso   }
1192c155d37SCarlos Alberto Enciso 
createScopes()1202c155d37SCarlos Alberto Enciso   Error createScopes() { return LVReader::createScopes(); }
1212c155d37SCarlos Alberto Enciso 
1222c155d37SCarlos Alberto Enciso   void setMapping();
1232c155d37SCarlos Alberto Enciso   void createElements();
1242c155d37SCarlos Alberto Enciso   void addElements();
1252c155d37SCarlos Alberto Enciso   void initElements();
1262c155d37SCarlos Alberto Enciso   void resolveElements();
1272c155d37SCarlos Alberto Enciso   void checkWarnings();
1282c155d37SCarlos Alberto Enciso };
1292c155d37SCarlos Alberto Enciso 
validateRanges()1302c155d37SCarlos Alberto Enciso bool MyLocation::validateRanges() {
1312c155d37SCarlos Alberto Enciso   // Traverse the locations and validate them against the address to line
1322c155d37SCarlos Alberto Enciso   // mapping in the current compile unit. Record those invalid ranges.
1332c155d37SCarlos Alberto Enciso   // A valid range must meet the following conditions:
1342c155d37SCarlos Alberto Enciso   // a) line(lopc) <= line(hipc)
1352c155d37SCarlos Alberto Enciso   // b) line(lopc) and line(hipc) are valid.
1362c155d37SCarlos Alberto Enciso 
1372c155d37SCarlos Alberto Enciso   LVLine *LowLine = AddressToLine.lineLowerBound(getLowerAddress());
1382c155d37SCarlos Alberto Enciso   LVLine *HighLine = AddressToLine.lineUpperBound(getUpperAddress());
1392c155d37SCarlos Alberto Enciso   if (LowLine)
1402c155d37SCarlos Alberto Enciso     setLowerLine(LowLine);
1412c155d37SCarlos Alberto Enciso   else {
1422c155d37SCarlos Alberto Enciso     setIsInvalidLower();
1432c155d37SCarlos Alberto Enciso     return false;
1442c155d37SCarlos Alberto Enciso   }
1452c155d37SCarlos Alberto Enciso   if (HighLine)
1462c155d37SCarlos Alberto Enciso     setUpperLine(HighLine);
1472c155d37SCarlos Alberto Enciso   else {
1482c155d37SCarlos Alberto Enciso     setIsInvalidUpper();
1492c155d37SCarlos Alberto Enciso     return false;
1502c155d37SCarlos Alberto Enciso   }
1512c155d37SCarlos Alberto Enciso   // Check for a valid interval.
1522c155d37SCarlos Alberto Enciso   if (LowLine->getLineNumber() > HighLine->getLineNumber()) {
1532c155d37SCarlos Alberto Enciso     setIsInvalidRange();
1542c155d37SCarlos Alberto Enciso     return false;
1552c155d37SCarlos Alberto Enciso   }
1562c155d37SCarlos Alberto Enciso 
1572c155d37SCarlos Alberto Enciso   return true;
1582c155d37SCarlos Alberto Enciso }
1592c155d37SCarlos Alberto Enciso 
1602c155d37SCarlos Alberto Enciso // Map all logical lines with their addresses.
setMapping()1612c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::setMapping() {
1622c155d37SCarlos Alberto Enciso   AddressToLine.insert(LineOne);
1632c155d37SCarlos Alberto Enciso   AddressToLine.insert(LineTwo);
1642c155d37SCarlos Alberto Enciso   AddressToLine.insert(LineThree);
1652c155d37SCarlos Alberto Enciso   AddressToLine.insert(LineFour);
1662c155d37SCarlos Alberto Enciso   AddressToLine.insert(LineFive);
1672c155d37SCarlos Alberto Enciso   AddressToLine.insert(LineSix);
1682c155d37SCarlos Alberto Enciso }
1692c155d37SCarlos Alberto Enciso 
1702c155d37SCarlos Alberto Enciso // Helper function to add a logical element to a given scope.
add(LVScope * Parent,LVElement * Child)1712c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::add(LVScope *Parent, LVElement *Child) {
1722c155d37SCarlos Alberto Enciso   Parent->addElement(Child);
1732c155d37SCarlos Alberto Enciso   EXPECT_EQ(Child->getParent(), Parent);
1742c155d37SCarlos Alberto Enciso   EXPECT_EQ(Child->getLevel(), Parent->getLevel() + 1);
1752c155d37SCarlos Alberto Enciso }
1762c155d37SCarlos Alberto Enciso 
1772c155d37SCarlos Alberto Enciso // Helper function to set the initial values for a given logical element.
set(LVElement * Element,StringRef Name,LVOffset Offset,uint32_t LineNumber,LVElement * Type)1782c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::set(LVElement *Element, StringRef Name,
1792c155d37SCarlos Alberto Enciso                                     LVOffset Offset, uint32_t LineNumber,
1802c155d37SCarlos Alberto Enciso                                     LVElement *Type) {
1812c155d37SCarlos Alberto Enciso   Element->setName(Name);
1822c155d37SCarlos Alberto Enciso   Element->setOffset(Offset);
1832c155d37SCarlos Alberto Enciso   Element->setLineNumber(LineNumber);
1842c155d37SCarlos Alberto Enciso   Element->setType(Type);
1852c155d37SCarlos Alberto Enciso   EXPECT_EQ(Element->getName(), Name);
1862c155d37SCarlos Alberto Enciso   EXPECT_EQ(Element->getOffset(), Offset);
1872c155d37SCarlos Alberto Enciso   EXPECT_EQ(Element->getLineNumber(), LineNumber);
1882c155d37SCarlos Alberto Enciso   EXPECT_EQ(Element->getType(), Type);
1892c155d37SCarlos Alberto Enciso }
1902c155d37SCarlos Alberto Enciso 
1912c155d37SCarlos Alberto Enciso // Helper function to set the initial values for a given logical location.
set(MyLocation * Location,LVLine * LowerLine,LVLine * UpperLine,LVAddress LowerAddress,LVAddress UpperAddress)1922c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::set(MyLocation *Location, LVLine *LowerLine,
1932c155d37SCarlos Alberto Enciso                                     LVLine *UpperLine, LVAddress LowerAddress,
1942c155d37SCarlos Alberto Enciso                                     LVAddress UpperAddress) {
1952c155d37SCarlos Alberto Enciso   Location->setLowerLine(LowerLine);
1962c155d37SCarlos Alberto Enciso   Location->setUpperLine(UpperLine);
1972c155d37SCarlos Alberto Enciso   Location->setLowerAddress(LowerAddress);
1982c155d37SCarlos Alberto Enciso   Location->setUpperAddress(UpperAddress);
1992c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location->getLowerLine(), LowerLine);
2002c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location->getUpperLine(), UpperLine);
2012c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location->getLowerAddress(), LowerAddress);
2022c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location->getUpperAddress(), UpperAddress);
2032c155d37SCarlos Alberto Enciso }
2042c155d37SCarlos Alberto Enciso 
2052c155d37SCarlos Alberto Enciso // Helper function to add a logical location to a logical symbol.
add(LVSymbol * Symbol,LVLine * LowerLine,LVLine * UpperLine)2062c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::add(LVSymbol *Symbol, LVLine *LowerLine,
2072c155d37SCarlos Alberto Enciso                                     LVLine *UpperLine) {
2082c155d37SCarlos Alberto Enciso   dwarf::Attribute Attr = dwarf::DW_AT_location;
2092c155d37SCarlos Alberto Enciso 
2102c155d37SCarlos Alberto Enciso   Symbol->addLocation(Attr, LowerLine->getAddress(), UpperLine->getAddress(),
2112c155d37SCarlos Alberto Enciso                       /*SectionOffset=*/0, /*LocDesOffset=*/0);
2122c155d37SCarlos Alberto Enciso }
2132c155d37SCarlos Alberto Enciso 
2142c155d37SCarlos Alberto Enciso // Create the logical elements.
createElements()2152c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::createElements() {
2162c155d37SCarlos Alberto Enciso   // Create scope root.
2172c155d37SCarlos Alberto Enciso   Error Err = createScopes();
2182c155d37SCarlos Alberto Enciso   ASSERT_THAT_ERROR(std::move(Err), Succeeded());
2192c155d37SCarlos Alberto Enciso   Root = getScopesRoot();
2202c155d37SCarlos Alberto Enciso   EXPECT_NE(Root, nullptr);
2212c155d37SCarlos Alberto Enciso 
2222c155d37SCarlos Alberto Enciso   // Create the logical types.
223*7fbcc244SCarlos Alberto Enciso   CREATE(IntegerType, createType);
2242c155d37SCarlos Alberto Enciso 
2252c155d37SCarlos Alberto Enciso   // Create the logical scopes.
226*7fbcc244SCarlos Alberto Enciso   CREATE(NestedScope, createScope);
227*7fbcc244SCarlos Alberto Enciso   CREATE(CompileUnit, createScopeCompileUnit);
228*7fbcc244SCarlos Alberto Enciso   CREATE(Function, createScopeFunction);
2292c155d37SCarlos Alberto Enciso 
2302c155d37SCarlos Alberto Enciso   // Create the logical symbols.
231*7fbcc244SCarlos Alberto Enciso   CREATE(LocalVariable, createSymbol);
232*7fbcc244SCarlos Alberto Enciso   CREATE(NestedVariable, createSymbol);
233*7fbcc244SCarlos Alberto Enciso   CREATE(Parameter, createSymbol);
2342c155d37SCarlos Alberto Enciso 
2352c155d37SCarlos Alberto Enciso   // Create the logical lines.
236*7fbcc244SCarlos Alberto Enciso   CREATE(LineOne, createLine);
237*7fbcc244SCarlos Alberto Enciso   CREATE(LineTwo, createLine);
238*7fbcc244SCarlos Alberto Enciso   CREATE(LineThree, createLine);
239*7fbcc244SCarlos Alberto Enciso   CREATE(LineFour, createLine);
240*7fbcc244SCarlos Alberto Enciso   CREATE(LineFive, createLine);
241*7fbcc244SCarlos Alberto Enciso   CREATE(LineSix, createLine);
2422c155d37SCarlos Alberto Enciso 
2432c155d37SCarlos Alberto Enciso   // Create the logical locations.
244*7fbcc244SCarlos Alberto Enciso   CREATE_CUSTOM(LocationOne, createCustomLocation);
245*7fbcc244SCarlos Alberto Enciso   CREATE_CUSTOM(LocationTwo, createCustomLocation);
246*7fbcc244SCarlos Alberto Enciso   CREATE_CUSTOM(LocationThree, createCustomLocation);
247*7fbcc244SCarlos Alberto Enciso   CREATE_CUSTOM(LocationFour, createCustomLocation);
248*7fbcc244SCarlos Alberto Enciso   CREATE_CUSTOM(LocationFive, createCustomLocation);
249*7fbcc244SCarlos Alberto Enciso   CREATE_CUSTOM(LocationSix, createCustomLocation);
2502c155d37SCarlos Alberto Enciso }
2512c155d37SCarlos Alberto Enciso 
2522c155d37SCarlos Alberto Enciso // Create the logical view adding the created logical elements.
addElements()2532c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::addElements() {
2542c155d37SCarlos Alberto Enciso   setCompileUnit(CompileUnit);
2552c155d37SCarlos Alberto Enciso 
2562c155d37SCarlos Alberto Enciso   // Root
2572c155d37SCarlos Alberto Enciso   //   CompileUnit
2582c155d37SCarlos Alberto Enciso   //     IntegerType
2592c155d37SCarlos Alberto Enciso   //     Function
2602c155d37SCarlos Alberto Enciso   //       LocationOne
2612c155d37SCarlos Alberto Enciso   //       LocationTwo
2622c155d37SCarlos Alberto Enciso   //       LocationFive
2632c155d37SCarlos Alberto Enciso   //       LocationSix
2642c155d37SCarlos Alberto Enciso   //       Parameter
2652c155d37SCarlos Alberto Enciso   //       LocalVariable
2662c155d37SCarlos Alberto Enciso   //       LineOne
2672c155d37SCarlos Alberto Enciso   //       LineTwo
2682c155d37SCarlos Alberto Enciso   //       NestedScope
2692c155d37SCarlos Alberto Enciso   //         LocationThree
2702c155d37SCarlos Alberto Enciso   //         LocationFour
2712c155d37SCarlos Alberto Enciso   //         NestedVariable
2722c155d37SCarlos Alberto Enciso   //         LineThree
2732c155d37SCarlos Alberto Enciso   //         LineFour
2742c155d37SCarlos Alberto Enciso   //       LineFive
2752c155d37SCarlos Alberto Enciso   //       LineSix
2762c155d37SCarlos Alberto Enciso 
2772c155d37SCarlos Alberto Enciso   // Add elements to Root.
2782c155d37SCarlos Alberto Enciso   add(Root, CompileUnit);
2792c155d37SCarlos Alberto Enciso 
2802c155d37SCarlos Alberto Enciso   // Add elements to CompileUnit.
2812c155d37SCarlos Alberto Enciso   add(CompileUnit, IntegerType);
2822c155d37SCarlos Alberto Enciso   add(CompileUnit, Function);
2832c155d37SCarlos Alberto Enciso 
2842c155d37SCarlos Alberto Enciso   // Add elements to Function.
2852c155d37SCarlos Alberto Enciso   add(Function, Parameter);
2862c155d37SCarlos Alberto Enciso   add(Function, LocalVariable);
2872c155d37SCarlos Alberto Enciso   add(Function, LineOne);
2882c155d37SCarlos Alberto Enciso   add(Function, LineTwo);
2892c155d37SCarlos Alberto Enciso   add(Function, LineFive);
2902c155d37SCarlos Alberto Enciso   add(Function, LineSix);
2912c155d37SCarlos Alberto Enciso   add(Function, NestedScope);
2922c155d37SCarlos Alberto Enciso 
2932c155d37SCarlos Alberto Enciso   // Add elements to NestedScope.
2942c155d37SCarlos Alberto Enciso   add(NestedScope, NestedVariable);
2952c155d37SCarlos Alberto Enciso   add(NestedScope, LineThree);
2962c155d37SCarlos Alberto Enciso   add(NestedScope, LineFour);
2972c155d37SCarlos Alberto Enciso }
2982c155d37SCarlos Alberto Enciso 
resolveElements()2992c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::resolveElements() {
3002c155d37SCarlos Alberto Enciso   // Traverse the given scope and its children checking for any warnings.
3012c155d37SCarlos Alberto Enciso   std::function<void(LVScope * Parent)> TraverseScope = [&](LVScope *Parent) {
3022c155d37SCarlos Alberto Enciso     auto Warnings = [&](auto *Entry) {
3032c155d37SCarlos Alberto Enciso       if (Entry->getIsLine()) {
3042c155d37SCarlos Alberto Enciso         LVLine *Line = (LVLine *)Entry;
3052c155d37SCarlos Alberto Enciso         if (options().getWarningLines() && Line->getIsLineDebug() &&
3062c155d37SCarlos Alberto Enciso             !Line->getLineNumber())
3072c155d37SCarlos Alberto Enciso           CompileUnit->addLineZero(Line);
3082c155d37SCarlos Alberto Enciso       }
3092c155d37SCarlos Alberto Enciso     };
3102c155d37SCarlos Alberto Enciso     auto Traverse = [&](const auto *Set) {
3112c155d37SCarlos Alberto Enciso       if (Set)
3122c155d37SCarlos Alberto Enciso         for (const auto &Entry : *Set) {
3132c155d37SCarlos Alberto Enciso           Warnings(Entry);
3142c155d37SCarlos Alberto Enciso         }
3152c155d37SCarlos Alberto Enciso     };
3162c155d37SCarlos Alberto Enciso 
3172c155d37SCarlos Alberto Enciso     Warnings(Parent);
3182c155d37SCarlos Alberto Enciso 
3192c155d37SCarlos Alberto Enciso     Traverse(Parent->getSymbols());
3202c155d37SCarlos Alberto Enciso     Traverse(Parent->getTypes());
3212c155d37SCarlos Alberto Enciso     Traverse(Parent->getLines());
3222c155d37SCarlos Alberto Enciso 
3232c155d37SCarlos Alberto Enciso     if (const LVScopes *Scopes = Parent->getScopes())
3242c155d37SCarlos Alberto Enciso       for (LVScope *Scope : *Scopes) {
3252c155d37SCarlos Alberto Enciso         Warnings(Scope);
3262c155d37SCarlos Alberto Enciso         TraverseScope(Scope);
3272c155d37SCarlos Alberto Enciso       }
3282c155d37SCarlos Alberto Enciso   };
3292c155d37SCarlos Alberto Enciso 
3302c155d37SCarlos Alberto Enciso   // Start traversing the scopes root and resolve the elements.
3312c155d37SCarlos Alberto Enciso   TraverseScope(Root);
3322c155d37SCarlos Alberto Enciso }
3332c155d37SCarlos Alberto Enciso 
3342c155d37SCarlos Alberto Enciso // Set initial values to logical elements.
initElements()3352c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::initElements() {
3362c155d37SCarlos Alberto Enciso   // Types.
3372c155d37SCarlos Alberto Enciso   set(IntegerType, "int", 0x1000);
3382c155d37SCarlos Alberto Enciso 
3392c155d37SCarlos Alberto Enciso   // Scopes.
3402c155d37SCarlos Alberto Enciso   set(CompileUnit, "foo.cpp", 0x2000);
3412c155d37SCarlos Alberto Enciso   set(Function, "foo", 0x2010, 100, IntegerType);
3422c155d37SCarlos Alberto Enciso   set(NestedScope, "", 0x2020, 300);
3432c155d37SCarlos Alberto Enciso 
3442c155d37SCarlos Alberto Enciso   // Symbols.
3452c155d37SCarlos Alberto Enciso   set(Parameter, "Param", 0x3000, 110, IntegerType);
3462c155d37SCarlos Alberto Enciso   set(LocalVariable, "LocalVariable", 0x3020, 120, IntegerType);
3472c155d37SCarlos Alberto Enciso   set(NestedVariable, "NestedVariable", 0x3010, 310, IntegerType);
3482c155d37SCarlos Alberto Enciso 
3492c155d37SCarlos Alberto Enciso   // Lines.
3502c155d37SCarlos Alberto Enciso   set(LineOne, "", 0x5000, 100);
3512c155d37SCarlos Alberto Enciso   LineOne->setIsLineDebug();
3522c155d37SCarlos Alberto Enciso   set(LineTwo, "", 0x5200, 000);
3532c155d37SCarlos Alberto Enciso   LineTwo->setIsLineDebug();
3542c155d37SCarlos Alberto Enciso   set(LineThree, "", 0x5400, 300);
3552c155d37SCarlos Alberto Enciso   LineThree->setIsLineDebug();
3562c155d37SCarlos Alberto Enciso   set(LineFour, "", 0x5600, 000);
3572c155d37SCarlos Alberto Enciso   LineFour->setIsLineDebug();
3582c155d37SCarlos Alberto Enciso   set(LineFive, "", 0x5800, 500);
3592c155d37SCarlos Alberto Enciso   LineOne->setIsLineDebug();
3602c155d37SCarlos Alberto Enciso   set(LineSix, "", 0x6000, 600);
3612c155d37SCarlos Alberto Enciso   LineSix->setIsLineDebug();
3622c155d37SCarlos Alberto Enciso 
3632c155d37SCarlos Alberto Enciso   // Locations.
3642c155d37SCarlos Alberto Enciso   set(LocationOne, LineOne, LineOne, 0x5000, 0x5100);
3652c155d37SCarlos Alberto Enciso   EXPECT_STREQ(LocationOne->getIntervalInfo().c_str(),
3662c155d37SCarlos Alberto Enciso                " Lines 100:100 [0x0000005000:0x0000005100]");
3672c155d37SCarlos Alberto Enciso 
3682c155d37SCarlos Alberto Enciso   // Uses a Line zero.
3692c155d37SCarlos Alberto Enciso   set(LocationTwo, LineTwo, LineTwo, 0x5200, 0x5300);
3702c155d37SCarlos Alberto Enciso   EXPECT_STREQ(LocationTwo->getIntervalInfo().c_str(),
3712c155d37SCarlos Alberto Enciso                " Lines -:- [0x0000005200:0x0000005300]");
3722c155d37SCarlos Alberto Enciso 
3732c155d37SCarlos Alberto Enciso   set(LocationThree, LineThree, LineThree, 0x5400, 0x5500);
3742c155d37SCarlos Alberto Enciso   EXPECT_STREQ(LocationThree->getIntervalInfo().c_str(),
3752c155d37SCarlos Alberto Enciso                " Lines 300:300 [0x0000005400:0x0000005500]");
3762c155d37SCarlos Alberto Enciso 
3772c155d37SCarlos Alberto Enciso   // Uses a Line zero.
3782c155d37SCarlos Alberto Enciso   set(LocationFour, LineFour, LineFour, 0x5600, 0x5700);
3792c155d37SCarlos Alberto Enciso   LocationFour->setIsAddressRange();
3802c155d37SCarlos Alberto Enciso   EXPECT_STREQ(LocationFour->getIntervalInfo().c_str(),
3812c155d37SCarlos Alberto Enciso                "{Range} Lines -:- [0x0000005600:0x0000005700]");
3822c155d37SCarlos Alberto Enciso 
3832c155d37SCarlos Alberto Enciso   // Invalid range.
3842c155d37SCarlos Alberto Enciso   set(LocationFive, LineFive, LineFive, 0x7800, 0x5900);
3852c155d37SCarlos Alberto Enciso   LocationFive->setIsAddressRange();
3862c155d37SCarlos Alberto Enciso   EXPECT_STREQ(LocationFive->getIntervalInfo().c_str(),
3872c155d37SCarlos Alberto Enciso                "{Range} Lines 500:500 [0x0000007800:0x0000005900]");
3882c155d37SCarlos Alberto Enciso 
3892c155d37SCarlos Alberto Enciso   set(LocationSix, LineSix, LineSix, 0x6000, 0x6100);
3902c155d37SCarlos Alberto Enciso   LocationSix->setIsAddressRange();
3912c155d37SCarlos Alberto Enciso   EXPECT_STREQ(LocationSix->getIntervalInfo().c_str(),
3922c155d37SCarlos Alberto Enciso                "{Range} Lines 600:600 [0x0000006000:0x0000006100]");
3932c155d37SCarlos Alberto Enciso 
3942c155d37SCarlos Alberto Enciso   // Add ranges to Function.
3952c155d37SCarlos Alberto Enciso   // Function: LocationOne, LocationTwo, LocationFive, LocationSix
3962c155d37SCarlos Alberto Enciso   Function->addObject(LocationOne);
3972c155d37SCarlos Alberto Enciso   Function->addObject(LocationTwo);
3982c155d37SCarlos Alberto Enciso   Function->addObject(LocationFive);
3992c155d37SCarlos Alberto Enciso   Function->addObject(LocationSix);
4002c155d37SCarlos Alberto Enciso   EXPECT_EQ(Function->rangeCount(), 4u);
4012c155d37SCarlos Alberto Enciso 
4022c155d37SCarlos Alberto Enciso   // Add ranges to NestedScope.
4032c155d37SCarlos Alberto Enciso   // NestedScope: LocationThree, LocationFour
4042c155d37SCarlos Alberto Enciso   NestedScope->addObject(LocationThree);
4052c155d37SCarlos Alberto Enciso   NestedScope->addObject(LocationFour);
4062c155d37SCarlos Alberto Enciso   EXPECT_EQ(NestedScope->rangeCount(), 2u);
4072c155d37SCarlos Alberto Enciso 
4082c155d37SCarlos Alberto Enciso   // Get all ranges.
4092c155d37SCarlos Alberto Enciso   LVRange Ranges;
4102c155d37SCarlos Alberto Enciso   CompileUnit->getRanges(Ranges);
4112c155d37SCarlos Alberto Enciso   Ranges.startSearch();
4122c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x4000), nullptr);
4132c155d37SCarlos Alberto Enciso 
4142c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5060), Function);
4152c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5850), nullptr);
4162c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5010, 0x5090), Function);
4172c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5210, 0x5290), Function);
4182c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5810, 0x5890), nullptr);
4192c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x6010, 0x6090), Function);
4202c155d37SCarlos Alberto Enciso 
4212c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5400), NestedScope);
4222c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5650), NestedScope);
4232c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5410, 0x5490), NestedScope);
4242c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x5610, 0x5690), NestedScope);
4252c155d37SCarlos Alberto Enciso 
4262c155d37SCarlos Alberto Enciso   EXPECT_EQ(Ranges.getEntry(0x8000), nullptr);
4272c155d37SCarlos Alberto Enciso   Ranges.endSearch();
4282c155d37SCarlos Alberto Enciso 
4292c155d37SCarlos Alberto Enciso   // Add locations to symbols.
4302c155d37SCarlos Alberto Enciso   // Parameter:       [LineOne, LineSix]
4312c155d37SCarlos Alberto Enciso   // LocalVariable:   [LineTwo, LineSix], [LineFour, LineFive]
4322c155d37SCarlos Alberto Enciso   // NestedVariable:  [LineThree, LineFour]
4332c155d37SCarlos Alberto Enciso   add(Parameter, LineOne, LineSix);
4342c155d37SCarlos Alberto Enciso   add(LocalVariable, LineTwo, LineSix);
4352c155d37SCarlos Alberto Enciso   add(LocalVariable, LineFour, LineFive);
4362c155d37SCarlos Alberto Enciso   add(NestedVariable, LineThree, LineFour);
4372c155d37SCarlos Alberto Enciso   add(NestedVariable, LineOne, LineSix);
4382c155d37SCarlos Alberto Enciso }
4392c155d37SCarlos Alberto Enciso 
4402c155d37SCarlos Alberto Enciso // Check logical elements warnigs.
checkWarnings()4412c155d37SCarlos Alberto Enciso void ReaderTestWarningInternal::checkWarnings() {
4422c155d37SCarlos Alberto Enciso   // Map all lines with their addresses.
4432c155d37SCarlos Alberto Enciso   setMapping();
4442c155d37SCarlos Alberto Enciso 
4452c155d37SCarlos Alberto Enciso   // Check for lines with line zero.
4462c155d37SCarlos Alberto Enciso   resolveElements();
4472c155d37SCarlos Alberto Enciso 
4482c155d37SCarlos Alberto Enciso   // Check invalid locations and ranges using a customized validation.
4492c155d37SCarlos Alberto Enciso   CompileUnit->processRangeLocationCoverage(
4502c155d37SCarlos Alberto Enciso       (LVValidLocation)(&MyLocation::validateRanges));
4512c155d37SCarlos Alberto Enciso 
4522c155d37SCarlos Alberto Enciso   // Get lines with line zero. [Parent, Line]
4532c155d37SCarlos Alberto Enciso   //   Function, LineTwo
4542c155d37SCarlos Alberto Enciso   //   NestedScope, LineFour
4552c155d37SCarlos Alberto Enciso   LVOffsetLinesMap LinesZero = CompileUnit->getLinesZero();
4562c155d37SCarlos Alberto Enciso   ASSERT_EQ(LinesZero.size(), 2u);
4572c155d37SCarlos Alberto Enciso 
4582c155d37SCarlos Alberto Enciso   LVOffsetLinesMap::iterator IterZero = LinesZero.begin();
4592c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterZero->first, Function->getOffset());
460*7fbcc244SCarlos Alberto Enciso   LVLines *Lines = &IterZero->second;
4612c155d37SCarlos Alberto Enciso   EXPECT_NE(Lines, nullptr);
4622c155d37SCarlos Alberto Enciso   ASSERT_EQ(Lines->size(), 1u);
4632c155d37SCarlos Alberto Enciso   LVLine *Line = *(Lines->begin());
4642c155d37SCarlos Alberto Enciso   EXPECT_NE(Line, nullptr);
4652c155d37SCarlos Alberto Enciso   EXPECT_EQ(Line, LineTwo);
4662c155d37SCarlos Alberto Enciso 
4672c155d37SCarlos Alberto Enciso   ++IterZero;
4682c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterZero->first, NestedScope->getOffset());
469*7fbcc244SCarlos Alberto Enciso   Lines = &IterZero->second;
4702c155d37SCarlos Alberto Enciso   EXPECT_NE(Lines, nullptr);
4712c155d37SCarlos Alberto Enciso   ASSERT_EQ(Lines->size(), 1u);
4722c155d37SCarlos Alberto Enciso   Line = *(Lines->begin());
4732c155d37SCarlos Alberto Enciso   EXPECT_NE(Line, nullptr);
4742c155d37SCarlos Alberto Enciso   EXPECT_EQ(Line, LineFour);
4752c155d37SCarlos Alberto Enciso 
4762c155d37SCarlos Alberto Enciso   // Elements with invalid offsets.
4772c155d37SCarlos Alberto Enciso   //   Function (line zero)
4782c155d37SCarlos Alberto Enciso   //   NestedScope (line zero)
4792c155d37SCarlos Alberto Enciso   //   NestedVariable (invalid location)
4802c155d37SCarlos Alberto Enciso   LVOffsetElementMap InvalidOffsets = CompileUnit->getWarningOffsets();
4812c155d37SCarlos Alberto Enciso   ASSERT_EQ(InvalidOffsets.size(), 3u);
4822c155d37SCarlos Alberto Enciso 
4832c155d37SCarlos Alberto Enciso   LVOffsetElementMap::iterator IterOffset = InvalidOffsets.begin();
4842c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterOffset->second, Function);
4852c155d37SCarlos Alberto Enciso   ++IterOffset;
4862c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterOffset->second, NestedScope);
4872c155d37SCarlos Alberto Enciso   ++IterOffset;
4882c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterOffset->second, NestedVariable);
4892c155d37SCarlos Alberto Enciso 
4902c155d37SCarlos Alberto Enciso   // Invalid ranges.
4912c155d37SCarlos Alberto Enciso   //   Function
4922c155d37SCarlos Alberto Enciso   LVOffsetLocationsMap InvalidRanges = CompileUnit->getInvalidRanges();
4932c155d37SCarlos Alberto Enciso   ASSERT_EQ(InvalidRanges.size(), 1u);
4942c155d37SCarlos Alberto Enciso 
4952c155d37SCarlos Alberto Enciso   LVOffsetLocationsMap::iterator IterRange = InvalidRanges.begin();
4962c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterRange->first, Function->getOffset());
497*7fbcc244SCarlos Alberto Enciso   LVLocations *Locations = &IterRange->second;
4982c155d37SCarlos Alberto Enciso   EXPECT_NE(Locations, nullptr);
4992c155d37SCarlos Alberto Enciso   ASSERT_EQ(Locations->size(), 1u);
5002c155d37SCarlos Alberto Enciso   LVLocation *Location = *(Locations->begin());
5012c155d37SCarlos Alberto Enciso   EXPECT_NE(Location, nullptr);
5022c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location, LocationFive);
5032c155d37SCarlos Alberto Enciso 
5042c155d37SCarlos Alberto Enciso   // Invalid location.
5052c155d37SCarlos Alberto Enciso   //   NestedVariable
5062c155d37SCarlos Alberto Enciso   LVOffsetLocationsMap InvalidLocations = CompileUnit->getInvalidLocations();
5072c155d37SCarlos Alberto Enciso   ASSERT_EQ(InvalidLocations.size(), 1u);
5082c155d37SCarlos Alberto Enciso 
5092c155d37SCarlos Alberto Enciso   LVOffsetLocationsMap::iterator IterLocations = InvalidLocations.begin();
5102c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterLocations->first, NestedVariable->getOffset());
511*7fbcc244SCarlos Alberto Enciso   Locations = &IterLocations->second;
5122c155d37SCarlos Alberto Enciso   EXPECT_NE(Locations, nullptr);
5132c155d37SCarlos Alberto Enciso   ASSERT_EQ(Locations->size(), 1u);
5142c155d37SCarlos Alberto Enciso   Location = *(Locations->begin());
5152c155d37SCarlos Alberto Enciso   EXPECT_NE(Location, nullptr);
5162c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location->getLowerAddress(), LocationThree->getLowerAddress());
5172c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location->getUpperAddress(), LocationFour->getLowerAddress());
5182c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location->getLowerLine()->getLineNumber(),
5192c155d37SCarlos Alberto Enciso             LineThree->getLineNumber());
5202c155d37SCarlos Alberto Enciso   EXPECT_EQ(Location->getUpperLine()->getLineNumber(), 0u);
5212c155d37SCarlos Alberto Enciso 
5222c155d37SCarlos Alberto Enciso   // Invalid coverages.
5232c155d37SCarlos Alberto Enciso   //   NestedVariable
5242c155d37SCarlos Alberto Enciso   LVOffsetSymbolMap InvalidCoverages = CompileUnit->getInvalidCoverages();
5252c155d37SCarlos Alberto Enciso   ASSERT_EQ(InvalidCoverages.size(), 1u);
5262c155d37SCarlos Alberto Enciso 
5272c155d37SCarlos Alberto Enciso   LVOffsetSymbolMap::iterator IterCoverages = InvalidCoverages.begin();
5282c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterCoverages->first, NestedVariable->getOffset());
5292c155d37SCarlos Alberto Enciso   EXPECT_EQ(IterCoverages->second, NestedVariable);
5302c155d37SCarlos Alberto Enciso   EXPECT_GE((int)NestedVariable->getCoveragePercentage(), 100);
5312c155d37SCarlos Alberto Enciso   EXPECT_EQ((int)NestedVariable->getCoveragePercentage(), 900);
5322c155d37SCarlos Alberto Enciso   EXPECT_EQ(NestedVariable->getCoverageFactor(), 0x1200u);
5332c155d37SCarlos Alberto Enciso 
5342c155d37SCarlos Alberto Enciso   EXPECT_EQ((unsigned)Parameter->getCoveragePercentage(), 100u);
5352c155d37SCarlos Alberto Enciso   EXPECT_EQ(Parameter->getCoverageFactor(), 100u);
5362c155d37SCarlos Alberto Enciso 
5372c155d37SCarlos Alberto Enciso   EXPECT_EQ((unsigned)LocalVariable->getCoveragePercentage(), 47u);
5382c155d37SCarlos Alberto Enciso   EXPECT_EQ(LocalVariable->getCoverageFactor(),
5392c155d37SCarlos Alberto Enciso             LineSix->getAddress() - LineOne->getAddress());
5402c155d37SCarlos Alberto Enciso }
5412c155d37SCarlos Alberto Enciso 
TEST(LogicalViewTest,WarningInternal)5422c155d37SCarlos Alberto Enciso TEST(LogicalViewTest, WarningInternal) {
5432c155d37SCarlos Alberto Enciso   ScopedPrinter W(outs());
5442c155d37SCarlos Alberto Enciso   ReaderTestWarningInternal Reader(W);
5452c155d37SCarlos Alberto Enciso 
5462c155d37SCarlos Alberto Enciso   // Reader options.
5472c155d37SCarlos Alberto Enciso   LVOptions ReaderOptions;
5482c155d37SCarlos Alberto Enciso   ReaderOptions.setAttributeOffset();
5492c155d37SCarlos Alberto Enciso   ReaderOptions.setAttributeRange();
5502c155d37SCarlos Alberto Enciso   ReaderOptions.setAttributeLocation();
5512c155d37SCarlos Alberto Enciso   ReaderOptions.setPrintAll();
5522c155d37SCarlos Alberto Enciso   ReaderOptions.setWarningCoverages();
5532c155d37SCarlos Alberto Enciso   ReaderOptions.setWarningLines();
5542c155d37SCarlos Alberto Enciso   ReaderOptions.setWarningLocations();
5552c155d37SCarlos Alberto Enciso   ReaderOptions.setWarningRanges();
5562c155d37SCarlos Alberto Enciso   ReaderOptions.resolveDependencies();
5572c155d37SCarlos Alberto Enciso   options().setOptions(&ReaderOptions);
5582c155d37SCarlos Alberto Enciso 
5592c155d37SCarlos Alberto Enciso   Reader.createElements();
5602c155d37SCarlos Alberto Enciso   Reader.addElements();
5612c155d37SCarlos Alberto Enciso   Reader.initElements();
5622c155d37SCarlos Alberto Enciso   Reader.checkWarnings();
5632c155d37SCarlos Alberto Enciso }
5642c155d37SCarlos Alberto Enciso 
5652c155d37SCarlos Alberto Enciso } // namespace
566