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