87 changes: 86 additions & 1 deletion llvm/include/llvm/DebugInfo/LogicalView/Core/LVScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class LVScope : public LVElement {
// only-globals, only-locals, a-pattern.
bool resolvePrinting() const;

// Find the current scope in the given 'Targets'.
LVScope *findIn(const LVScopes *Targets) const;

// Traverse the scope parent tree, executing the given callback function
// on each scope.
void traverseParents(LVScopeGetFunction GetFunction,
Expand Down Expand Up @@ -249,6 +252,10 @@ class LVScope : public LVElement {
// DW_AT_specification, DW_AT_abstract_origin, DW_AT_extension.
virtual LVScope *getReference() const { return nullptr; }

LVScope *getCompileUnitParent() const override {
return LVElement::getCompileUnitParent();
}

// Follow a chain of references given by DW_AT_abstract_origin and/or
// DW_AT_specification and update the scope name.
StringRef resolveReferencesChain();
Expand All @@ -268,6 +275,35 @@ class LVScope : public LVElement {

void resolveElements();

// Iterate through the 'References' set and check that all its elements
// are present in the 'Targets' set. For a missing element, mark its
// parents as missing.
static void markMissingParents(const LVScopes *References,
const LVScopes *Targets,
bool TraverseChildren);

// Checks if the current scope is contained within the target scope.
// Depending on the result, the callback may be performed.
virtual void markMissingParents(const LVScope *Target, bool TraverseChildren);

// Returns true if the current scope and the given 'Scope' have the
// same number of children.
virtual bool equalNumberOfChildren(const LVScope *Scope) const;

// Returns true if current scope is logically equal to the given 'Scope'.
virtual bool equals(const LVScope *Scope) const;

// Returns true if the given 'References' are logically equal to the
// given 'Targets'.
static bool equals(const LVScopes *References, const LVScopes *Targets);

// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
virtual LVScope *findEqualScope(const LVScopes *Scopes) const;

// Report the current scope as missing or added during comparison.
void report(LVComparePass Pass) override;

static LVScopeDispatch &getDispatch() { return Dispatch; }

void print(raw_ostream &OS, bool Full = true) const override;
Expand Down Expand Up @@ -308,6 +344,13 @@ class LVScopeAggregate final : public LVScope {
EncodedArgsIndex = getStringPool().getIndex(EncodedArgs);
}

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
LVScope *findEqualScope(const LVScopes *Scopes) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand All @@ -322,6 +365,9 @@ class LVScopeAlias final : public LVScope {
LVScopeAlias &operator=(const LVScopeAlias &) = delete;
~LVScopeAlias() = default;

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand All @@ -335,6 +381,9 @@ class LVScopeArray final : public LVScope {

void resolveExtra() override;

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand Down Expand Up @@ -510,14 +559,17 @@ class LVScopeCompileUnit final : public LVScope {

// A new element has been added to the scopes tree. Take the following steps:
// Increase the added element counters, for printing summary.
// Notify the Reader if element comparison.
// During comparison notify the Reader of the new element.
void addedElement(LVLine *Line);
void addedElement(LVScope *Scope);
void addedElement(LVSymbol *Symbol);
void addedElement(LVType *Type);

void addSize(LVScope *Scope, LVOffset Lower, LVOffset Upper);

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

void print(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
void printWarnings(raw_ostream &OS, bool Full = true) const override;
Expand All @@ -532,6 +584,9 @@ class LVScopeEnumeration final : public LVScope {
LVScopeEnumeration &operator=(const LVScopeEnumeration &) = delete;
~LVScopeEnumeration() = default;

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand All @@ -544,6 +599,9 @@ class LVScopeFormalPack final : public LVScope {
LVScopeFormalPack &operator=(const LVScopeFormalPack &) = delete;
~LVScopeFormalPack() = default;

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand Down Expand Up @@ -589,6 +647,13 @@ class LVScopeFunction : public LVScope {
void resolveExtra() override;
void resolveReferences() override;

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
LVScope *findEqualScope(const LVScopes *Scopes) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand Down Expand Up @@ -625,6 +690,13 @@ class LVScopeFunctionInlined final : public LVScopeFunction {

void resolveExtra() override;

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
LVScope *findEqualScope(const LVScopes *Scopes) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand Down Expand Up @@ -659,6 +731,13 @@ class LVScopeNamespace final : public LVScope {
setReference(static_cast<LVScope *>(Element));
}

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

// For the given 'Scopes' returns a scope that is logically equal
// to the current scope; otherwise 'nullptr'.
LVScope *findEqualScope(const LVScopes *Scopes) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand All @@ -682,6 +761,9 @@ class LVScopeRoot final : public LVScope {
// Process the collected location, ranges and calculate coverage.
void processRangeInformation();

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

void print(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;
Error doPrintMatches(bool Split, raw_ostream &OS,
Expand All @@ -697,6 +779,9 @@ class LVScopeTemplatePack final : public LVScope {
LVScopeTemplatePack &operator=(const LVScopeTemplatePack &) = delete;
~LVScopeTemplatePack() = default;

// Returns true if current scope is logically equal to the given 'Scope'.
bool equals(const LVScope *Scope) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand Down
24 changes: 24 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVSymbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ class LVSymbol final : public LVElement {
LVAutoLocations::iterator addLocationGap(LVAutoLocations::iterator Pos,
LVAddress LowPC, LVAddress HighPC);

// Find the current symbol in the given 'Targets'.
LVSymbol *findIn(const LVSymbols *Targets) const;

public:
LVSymbol() : LVElement(LVSubclassID::LV_SYMBOL) {
setIsSymbol();
Expand Down Expand Up @@ -157,6 +160,27 @@ class LVSymbol final : public LVElement {

static LVSymbolDispatch &getDispatch() { return Dispatch; }

static bool parametersMatch(const LVSymbols *References,
const LVSymbols *Targets);

static void getParameters(const LVSymbols *Symbols, LVSymbols *Parameters);

// Iterate through the 'References' set and check that all its elements
// are present in the 'Targets' set. For a missing element, mark its
// parents as missing.
static void markMissingParents(const LVSymbols *References,
const LVSymbols *Targets);

// Returns true if current type is logically equal to the given 'Symbol'.
bool equals(const LVSymbol *Symbol) const;

// Returns true if the given 'References' are logically equal to the
// given 'Targets'.
static bool equals(const LVSymbols *References, const LVSymbols *Targets);

// Report the current symbol as missing or added during comparison.
void report(LVComparePass Pass) override;

void print(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;

Expand Down
40 changes: 40 additions & 0 deletions llvm/include/llvm/DebugInfo/LogicalView/Core/LVType.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class LVType : public LVElement {
LVProperties<Property> Properties;
static LVTypeDispatch Dispatch;

// Find the current type in the given 'Targets'.
LVType *findIn(const LVTypes *Targets) const;

public:
LVType() : LVElement(LVSubclassID::LV_TYPE) { setIsType(); }
LVType(const LVType &) = delete;
Expand Down Expand Up @@ -111,6 +114,28 @@ class LVType : public LVElement {

static LVTypeDispatch &getDispatch() { return Dispatch; }

static bool parametersMatch(const LVTypes *References,
const LVTypes *Targets);

static void getParameters(const LVTypes *Types, LVTypes *TypesParam,
LVScopes *ScopesParam);

// Iterate through the 'References' set and check that all its elements
// are present in the 'Targets' set. For a missing element, mark its
// parents as missing.
static void markMissingParents(const LVTypes *References,
const LVTypes *Targets);

// Returns true if current type is logically equal to the given 'Type'.
virtual bool equals(const LVType *Type) const;

// Returns true if the given 'References' are logically equal to the
// given 'Targets'.
static bool equals(const LVTypes *References, const LVTypes *Targets);

// Report the current type as missing or added during comparison.
void report(LVComparePass Pass) override;

void print(raw_ostream &OS, bool Full = true) const override;
void printExtra(raw_ostream &OS, bool Full = true) const override;

Expand All @@ -136,6 +161,9 @@ class LVTypeDefinition final : public LVType {

void resolveExtra() override;

// Returns true if current type is logically equal to the given 'Type'.
bool equals(const LVType *Type) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand All @@ -162,6 +190,9 @@ class LVTypeEnumerator final : public LVType {
}
size_t getValueIndex() const override { return ValueIndex; }

// Returns true if current type is logically equal to the given 'Type'.
bool equals(const LVType *Type) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand All @@ -173,6 +204,9 @@ class LVTypeImport final : public LVType {
LVTypeImport &operator=(const LVTypeImport &) = delete;
~LVTypeImport() = default;

// Returns true if current type is logically equal to the given 'Type'.
bool equals(const LVType *Type) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand All @@ -199,6 +233,9 @@ class LVTypeParam final : public LVType {
// Encode the specific template argument.
void encodeTemplateArgument(std::string &Name) const override;

// Returns true if current type is logically equal to the given 'Type'.
bool equals(const LVType *Type) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand Down Expand Up @@ -241,6 +278,9 @@ class LVTypeSubrange final : public LVType {

void resolveExtra() override;

// Returns true if current type is logically equal to the given 'Type'.
bool equals(const LVType *Type) const override;

void printExtra(raw_ostream &OS, bool Full = true) const override;
};

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/DebugInfo/LogicalView/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ macro(add_lv_impl_folder group)
endmacro()

add_lv_impl_folder(Core
Core/LVCompare.cpp
Core/LVElement.cpp
Core/LVLine.cpp
Core/LVLocation.cpp
Expand Down
428 changes: 428 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVCompare.cpp

Large diffs are not rendered by default.

49 changes: 49 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,55 @@ void LVElement::resolveQualifiedName() {
});
}

bool LVElement::referenceMatch(const LVElement *Element) const {
return (getHasReference() && Element->getHasReference()) ||
(!getHasReference() && !Element->getHasReference());
}

bool LVElement::equals(const LVElement *Element) const {
// The minimum factors that must be the same for an equality are:
// line number, level, name, qualified name and filename.
LLVM_DEBUG({
dbgs() << "\n[Element::equals]\n";
if (options().getAttributeOffset()) {
dbgs() << "Reference: " << hexSquareString(getOffset()) << "\n";
dbgs() << "Target : " << hexSquareString(Element->getOffset()) << "\n";
}
dbgs() << "Reference: "
<< "Kind = " << formattedKind(kind()) << ", "
<< "Name = " << formattedName(getName()) << ", "
<< "Qualified = " << formattedName(getQualifiedName()) << "\n"
<< "Target : "
<< "Kind = " << formattedKind(Element->kind()) << ", "
<< "Name = " << formattedName(Element->getName()) << ", "
<< "Qualified = " << formattedName(Element->getQualifiedName())
<< "\n"
<< "Reference: "
<< "NameIndex = " << getNameIndex() << ", "
<< "QualifiedNameIndex = " << getQualifiedNameIndex() << ", "
<< "FilenameIndex = " << getFilenameIndex() << "\n"
<< "Target : "
<< "NameIndex = " << Element->getNameIndex() << ", "
<< "QualifiedNameIndex = " << Element->getQualifiedNameIndex()
<< ", "
<< "FilenameIndex = " << Element->getFilenameIndex() << "\n";
});
if ((getLineNumber() != Element->getLineNumber()) ||
(getLevel() != Element->getLevel()))
return false;

if ((getQualifiedNameIndex() != Element->getQualifiedNameIndex()) ||
(getNameIndex() != Element->getNameIndex()) ||
(getFilenameIndex() != Element->getFilenameIndex()))
return false;

if (!getType() && !Element->getType())
return true;
if (getType() && Element->getType())
return getType()->equals(Element->getType());
return false;
}

// Print the FileName Index.
void LVElement::printFileIndex(raw_ostream &OS, bool Full) const {
if (options().getPrintFormatting() && options().getAttributeAnySource() &&
Expand Down
82 changes: 82 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
#include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"

using namespace llvm;
Expand Down Expand Up @@ -65,6 +66,77 @@ std::string LVLine::noLineAsString(bool ShowZero) const {
: (" - ");
}

void LVLine::markMissingParents(const LVLines *References,
const LVLines *Targets) {
if (!(References && Targets))
return;

LLVM_DEBUG({
dbgs() << "\n[LVLine::markMissingParents]\n";
for (const LVLine *Reference : *References)
dbgs() << "References: "
<< "Kind = " << formattedKind(Reference->kind()) << ", "
<< "Line = " << Reference->getLineNumber() << "\n";
for (const LVLine *Target : *Targets)
dbgs() << "Targets : "
<< "Kind = " << formattedKind(Target->kind()) << ", "
<< "Line = " << Target->getLineNumber() << "\n";
});

for (LVLine *Reference : *References) {
LLVM_DEBUG({
dbgs() << "Search Reference: Line = " << Reference->getLineNumber()
<< "\n";
});
if (!Reference->findIn(Targets))
Reference->markBranchAsMissing();
}
}

LVLine *LVLine::findIn(const LVLines *Targets) const {
if (!Targets)
return nullptr;

LLVM_DEBUG({
dbgs() << "\n[LVLine::findIn]\n"
<< "Reference: "
<< "Level = " << getLevel() << ", "
<< "Kind = " << formattedKind(kind()) << ", "
<< "Line = " << getLineNumber() << "\n";
for (const LVLine *Target : *Targets)
dbgs() << "Target : "
<< "Level = " << Target->getLevel() << ", "
<< "Kind = " << formattedKind(Target->kind()) << ", "
<< "Line = " << Target->getLineNumber() << "\n";
});

for (LVLine *Line : *Targets)
if (equals(Line))
return Line;

return nullptr;
}

bool LVLine::equals(const LVLine *Line) const {
return LVElement::equals(Line);
}

bool LVLine::equals(const LVLines *References, const LVLines *Targets) {
if (!References && !Targets)
return true;
if (References && Targets && References->size() == Targets->size()) {
for (const LVLine *Reference : *References)
if (!Reference->findIn(Targets))
return false;
return true;
}
return false;
}

void LVLine::report(LVComparePass Pass) {
getComparator().printItem(this, Pass);
}

void LVLine::print(raw_ostream &OS, bool Full) const {
if (getReader().doPrintLine(this)) {
getReaderCompileUnit()->incrementPrintedLines();
Expand Down Expand Up @@ -118,6 +190,12 @@ std::string LVLineDebug::statesInfo(bool Formatted) const {
return String;
}

bool LVLineDebug::equals(const LVLine *Line) const {
if (!LVLine::equals(Line))
return false;
return getFilenameIndex() == Line->getFilenameIndex();
}

void LVLineDebug::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind());

Expand All @@ -133,6 +211,10 @@ void LVLineDebug::printExtra(raw_ostream &OS, bool Full) const {
//===----------------------------------------------------------------------===//
// Assembler line extracted from the ELF .text section.
//===----------------------------------------------------------------------===//
bool LVLineAssembler::equals(const LVLine *Line) const {
return LVLine::equals(Line);
}

void LVLineAssembler::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind());
OS << " " << formattedName(getName());
Expand Down
15 changes: 15 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ void LVObject::setParent(LVSymbol *Symbol) {
setLevel(Symbol->getLevel() + 1);
}

void LVObject::markBranchAsMissing() {
// Mark the current object as 'missing'; then traverse the parents chain
// marking them as 'special missing' to indicate a missing branch. They
// can not be marked as missing, because will generate incorrect reports.
LVObject *Parent = this;
Parent->setIsMissing();
while (Parent) {
Parent->setIsMissingLink();
Parent = Parent->getParent();
}
}

Error LVObject::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
bool Full) const {
print(OS, Full);
Expand Down Expand Up @@ -129,6 +141,9 @@ void LVObject::printAttributes(raw_ostream &OS, bool Full) const {
if (options().getInternalID())
OS << hexSquareString(getID());
#endif
if (options().getCompareExecute() &&
(options().getAttributeAdded() || options().getAttributeMissing()))
OS << (getIsAdded() ? '+' : getIsMissing() ? '-' : ' ');
if (options().getAttributeOffset())
OS << hexSquareString(getOffset());
if (options().getAttributeLevel()) {
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/DebugInfo/LogicalView/Core/LVReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,8 @@ Error LVReader::doPrint() {
}

Error LVReader::printScopes() {
if (bool DoPrint = options().getPrintExecute()) {
if (bool DoPrint =
(options().getPrintExecute() || options().getComparePrint())) {
if (Error Err = createSplitFolder())
return Err;

Expand Down
357 changes: 353 additions & 4 deletions llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp

Large diffs are not rendered by default.

105 changes: 105 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
#include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
#include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
Expand Down Expand Up @@ -279,6 +280,110 @@ StringRef LVSymbol::resolveReferencesChain() {
return getName();
}

void LVSymbol::markMissingParents(const LVSymbols *References,
const LVSymbols *Targets) {
if (!(References && Targets))
return;

LLVM_DEBUG({
dbgs() << "\n[LVSymbol::markMissingParents]\n";
for (const LVSymbol *Reference : *References)
dbgs() << "References: "
<< "Kind = " << formattedKind(Reference->kind()) << ", "
<< "Name = " << formattedName(Reference->getName()) << "\n";
for (const LVSymbol *Target : *Targets)
dbgs() << "Targets : "
<< "Kind = " << formattedKind(Target->kind()) << ", "
<< "Name = " << formattedName(Target->getName()) << "\n";
});

for (LVSymbol *Reference : *References) {
LLVM_DEBUG({
dbgs() << "Search Reference: Name = "
<< formattedName(Reference->getName()) << "\n";
});
if (!Reference->findIn(Targets))
Reference->markBranchAsMissing();
}
}

LVSymbol *LVSymbol::findIn(const LVSymbols *Targets) const {
if (!Targets)
return nullptr;

LLVM_DEBUG({
dbgs() << "\n[LVSymbol::findIn]\n"
<< "Reference: "
<< "Level = " << getLevel() << ", "
<< "Kind = " << formattedKind(kind()) << ", "
<< "Name = " << formattedName(getName()) << "\n";
for (const LVSymbol *Target : *Targets)
dbgs() << "Target : "
<< "Level = " << Target->getLevel() << ", "
<< "Kind = " << formattedKind(Target->kind()) << ", "
<< "Name = " << formattedName(Target->getName()) << "\n";
});

for (LVSymbol *Target : *Targets)
if (equals(Target))
return Target;

return nullptr;
}

// Check for a match on the arguments of a function.
bool LVSymbol::parametersMatch(const LVSymbols *References,
const LVSymbols *Targets) {
if (!References && !Targets)
return true;
if (References && Targets) {
LVSymbols ReferenceParams;
getParameters(References, &ReferenceParams);
LVSymbols TargetParams;
getParameters(Targets, &TargetParams);
return LVSymbol::equals(&ReferenceParams, &TargetParams);
}
return false;
}

// Return the symbols which are parameters.
void LVSymbol::getParameters(const LVSymbols *Symbols, LVSymbols *Parameters) {
if (Symbols)
for (LVSymbol *Symbol : *Symbols)
if (Symbol->getIsParameter())
Parameters->push_back(Symbol);
}

bool LVSymbol::equals(const LVSymbol *Symbol) const {
if (!LVElement::equals(Symbol))
return false;

// Check if any reference is the same.
if (!referenceMatch(Symbol))
return false;

if (getReference() && !getReference()->equals(Symbol->getReference()))
return false;

return true;
}

bool LVSymbol::equals(const LVSymbols *References, const LVSymbols *Targets) {
if (!References && !Targets)
return true;
if (References && Targets && References->size() == Targets->size()) {
for (const LVSymbol *Reference : *References)
if (!Reference->findIn(Targets))
return false;
return true;
}
return false;
}

void LVSymbol::report(LVComparePass Pass) {
getComparator().printItem(this, Pass);
}

void LVSymbol::printLocations(raw_ostream &OS, bool Full) const {
if (Locations)
for (const LVLocation *Location : *Locations)
Expand Down
153 changes: 153 additions & 0 deletions llvm/lib/DebugInfo/LogicalView/Core/LVType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/LogicalView/Core/LVType.h"
#include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
#include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
#include "llvm/DebugInfo/LogicalView/Core/LVScope.h"

Expand Down Expand Up @@ -169,6 +170,124 @@ StringRef LVType::resolveReferencesChain() {
return getName();
}

void LVType::markMissingParents(const LVTypes *References,
const LVTypes *Targets) {
if (!(References && Targets))
return;

LLVM_DEBUG({
dbgs() << "\n[LVType::markMissingParents]\n";
for (const LVType *Reference : *References)
dbgs() << "References: "
<< "Kind = " << formattedKind(Reference->kind()) << ", "
<< "Name = " << formattedName(Reference->getName()) << "\n";
for (const LVType *Target : *Targets)
dbgs() << "Targets : "
<< "Kind = " << formattedKind(Target->kind()) << ", "
<< "Name = " << formattedName(Target->getName()) << "\n";
});

for (LVType *Reference : *References) {
LLVM_DEBUG({
dbgs() << "Search Reference: Name = "
<< formattedName(Reference->getName()) << "\n";
});
if (!Reference->findIn(Targets))
Reference->markBranchAsMissing();
}
}

LVType *LVType::findIn(const LVTypes *Targets) const {
if (!Targets)
return nullptr;

LLVM_DEBUG({
dbgs() << "\n[LVType::findIn]\n"
<< "Reference: "
<< "Level = " << getLevel() << ", "
<< "Kind = " << formattedKind(kind()) << ", "
<< "Name = " << formattedName(getName()) << "\n";
for (const LVType *Target : *Targets)
dbgs() << "Target : "
<< "Level = " << Target->getLevel() << ", "
<< "Kind = " << formattedKind(Target->kind()) << ", "
<< "Name = " << formattedName(Target->getName()) << "\n";
});

for (LVType *Target : *Targets)
if (equals(Target))
return Target;

return nullptr;
}

// Check for a match on the arguments of a function.
bool LVType::parametersMatch(const LVTypes *References,
const LVTypes *Targets) {
if (!References && !Targets)
return true;
if (References && Targets) {
LVTypes ReferenceTypes;
LVScopes ReferenceScopes;
getParameters(References, &ReferenceTypes, &ReferenceScopes);
LVTypes TargetTypes;
LVScopes TargetScopes;
getParameters(Targets, &TargetTypes, &TargetScopes);
if (!LVType::equals(&ReferenceTypes, &TargetTypes) ||
!LVScope::equals(&ReferenceScopes, &TargetScopes))
return false;
return true;
}
return false;
}

// Return the types which are parameters.
void LVType::getParameters(const LVTypes *Types, LVTypes *TypesParam,
LVScopes *ScopesParam) {
if (!Types)
return;

// During a compare task, the template parameters are expanded to
// point to their real types, to avoid compare conflicts.
for (LVType *Type : *Types) {
if (!Type->getIsTemplateParam())
continue;
if (options().getAttributeArgument()) {
LVScope *Scope = nullptr;
if (Type->getIsKindType())
Type = Type->getTypeAsType();
else {
if (Type->getIsKindScope()) {
Scope = Type->getTypeAsScope();
Type = nullptr;
}
}
Type ? TypesParam->push_back(Type) : ScopesParam->push_back(Scope);
} else
TypesParam->push_back(Type);
}
}

bool LVType::equals(const LVType *Type) const {
return LVElement::equals(Type);
}

bool LVType::equals(const LVTypes *References, const LVTypes *Targets) {
if (!References && !Targets)
return true;
if (References && Targets && References->size() == Targets->size()) {
for (const LVType *Reference : *References)
if (!Reference->findIn(Targets))
return false;
return true;
}
return false;
}

void LVType::report(LVComparePass Pass) {
getComparator().printItem(this, Pass);
}

void LVType::print(raw_ostream &OS, bool Full) const {
if (getIncludeInPrint() &&
(getIsReference() || getReader().doPrintType(this))) {
Expand Down Expand Up @@ -229,6 +348,10 @@ void LVTypeDefinition::resolveExtra() {
Aggregate->setName(getName());
}

bool LVTypeDefinition::equals(const LVType *Type) const {
return LVType::equals(Type);
}

void LVTypeDefinition::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind()) << " " << formattedName(getName()) << " -> "
<< typeOffsetAsString()
Expand All @@ -238,6 +361,10 @@ void LVTypeDefinition::printExtra(raw_ostream &OS, bool Full) const {
//===----------------------------------------------------------------------===//
// DWARF enumerator (DW_TAG_enumerator).
//===----------------------------------------------------------------------===//
bool LVTypeEnumerator::equals(const LVType *Type) const {
return LVType::equals(Type);
}

void LVTypeEnumerator::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind()) << " '" << getName()
<< "' = " << formattedName(getValue()) << "\n";
Expand All @@ -246,6 +373,10 @@ void LVTypeEnumerator::printExtra(raw_ostream &OS, bool Full) const {
//===----------------------------------------------------------------------===//
// DWARF import (DW_TAG_imported_module / DW_TAG_imported_declaration).
//===----------------------------------------------------------------------===//
bool LVTypeImport::equals(const LVType *Type) const {
return LVType::equals(Type);
}

void LVTypeImport::printExtra(raw_ostream &OS, bool Full) const {
std::string Attributes =
formatAttributes(virtualityString(), accessibilityString());
Expand Down Expand Up @@ -316,6 +447,21 @@ void LVTypeParam::encodeTemplateArgument(std::string &Name) const {
Name.append(getValue());
}

bool LVTypeParam::equals(const LVType *Type) const {
if (!LVType::equals(Type))
return false;

// Checks the kind of template argument.
if (getIsTemplateTypeParam() && Type->getIsTemplateTypeParam())
return getType()->equals(Type->getType());

if ((getIsTemplateValueParam() && Type->getIsTemplateValueParam()) ||
(getIsTemplateTemplateParam() && Type->getIsTemplateTemplateParam()))
return getValueIndex() == Type->getValueIndex();

return false;
}

void LVTypeParam::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind()) << " " << formattedName(getName()) << " -> "
<< typeOffsetAsString();
Expand Down Expand Up @@ -365,6 +511,13 @@ void LVTypeSubrange::resolveExtra() {
setName(String);
}

bool LVTypeSubrange::equals(const LVType *Type) const {
if (!LVType::equals(Type))
return false;

return getTypeName() == Type->getTypeName() && getName() == Type->getName();
}

void LVTypeSubrange::printExtra(raw_ostream &OS, bool Full) const {
OS << formattedKind(kind()) << " -> " << typeOffsetAsString()
<< formattedName(getTypeName()) << " " << formattedName(getName()) << "\n";
Expand Down
1 change: 1 addition & 0 deletions llvm/unittests/DebugInfo/LogicalView/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS

add_llvm_unittest(DebugInfoLogicalViewTests
CommandLineOptionsTest.cpp
CompareElementsTest.cpp
SelectElementsTest.cpp
LocationRangesTest.cpp
LogicalElementsTest.cpp
Expand Down
450 changes: 450 additions & 0 deletions llvm/unittests/DebugInfo/LogicalView/CompareElementsTest.cpp

Large diffs are not rendered by default.