1e28b9357SCarlos Alberto Enciso //===-- LVSymbol.cpp ------------------------------------------------------===//
2e28b9357SCarlos Alberto Enciso //
3e28b9357SCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e28b9357SCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information.
5e28b9357SCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e28b9357SCarlos Alberto Enciso //
7e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
8e28b9357SCarlos Alberto Enciso //
9e28b9357SCarlos Alberto Enciso // This implements the LVSymbol class.
10e28b9357SCarlos Alberto Enciso //
11e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
12e28b9357SCarlos Alberto Enciso
13e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
14e98a4c5aSCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
153c397c90SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
16e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
17e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
18e28b9357SCarlos Alberto Enciso
19e28b9357SCarlos Alberto Enciso using namespace llvm;
20e28b9357SCarlos Alberto Enciso using namespace llvm::logicalview;
21e28b9357SCarlos Alberto Enciso
22e28b9357SCarlos Alberto Enciso #define DEBUG_TYPE "Symbol"
23e28b9357SCarlos Alberto Enciso
24e28b9357SCarlos Alberto Enciso namespace {
25e28b9357SCarlos Alberto Enciso const char *const KindCallSiteParameter = "CallSiteParameter";
26e28b9357SCarlos Alberto Enciso const char *const KindConstant = "Constant";
27e28b9357SCarlos Alberto Enciso const char *const KindInherits = "Inherits";
28e28b9357SCarlos Alberto Enciso const char *const KindMember = "Member";
29e28b9357SCarlos Alberto Enciso const char *const KindParameter = "Parameter";
30e28b9357SCarlos Alberto Enciso const char *const KindUndefined = "Undefined";
31e28b9357SCarlos Alberto Enciso const char *const KindUnspecified = "Unspecified";
32e28b9357SCarlos Alberto Enciso const char *const KindVariable = "Variable";
33e28b9357SCarlos Alberto Enciso } // end anonymous namespace
34e28b9357SCarlos Alberto Enciso
35e28b9357SCarlos Alberto Enciso // Return a string representation for the symbol kind.
kind() const36e28b9357SCarlos Alberto Enciso const char *LVSymbol::kind() const {
37e28b9357SCarlos Alberto Enciso const char *Kind = KindUndefined;
38e28b9357SCarlos Alberto Enciso if (getIsCallSiteParameter())
39e28b9357SCarlos Alberto Enciso Kind = KindCallSiteParameter;
40e28b9357SCarlos Alberto Enciso else if (getIsConstant())
41e28b9357SCarlos Alberto Enciso Kind = KindConstant;
42e28b9357SCarlos Alberto Enciso else if (getIsInheritance())
43e28b9357SCarlos Alberto Enciso Kind = KindInherits;
44e28b9357SCarlos Alberto Enciso else if (getIsMember())
45e28b9357SCarlos Alberto Enciso Kind = KindMember;
46e28b9357SCarlos Alberto Enciso else if (getIsParameter())
47e28b9357SCarlos Alberto Enciso Kind = KindParameter;
48e28b9357SCarlos Alberto Enciso else if (getIsUnspecified())
49e28b9357SCarlos Alberto Enciso Kind = KindUnspecified;
50e28b9357SCarlos Alberto Enciso else if (getIsVariable())
51e28b9357SCarlos Alberto Enciso Kind = KindVariable;
52e28b9357SCarlos Alberto Enciso return Kind;
53e28b9357SCarlos Alberto Enciso }
54e28b9357SCarlos Alberto Enciso
550332a8e7SCarlos Alberto Enciso LVSymbolDispatch LVSymbol::Dispatch = {
560332a8e7SCarlos Alberto Enciso {LVSymbolKind::IsCallSiteParameter, &LVSymbol::getIsCallSiteParameter},
570332a8e7SCarlos Alberto Enciso {LVSymbolKind::IsConstant, &LVSymbol::getIsConstant},
580332a8e7SCarlos Alberto Enciso {LVSymbolKind::IsInheritance, &LVSymbol::getIsInheritance},
590332a8e7SCarlos Alberto Enciso {LVSymbolKind::IsMember, &LVSymbol::getIsMember},
600332a8e7SCarlos Alberto Enciso {LVSymbolKind::IsParameter, &LVSymbol::getIsParameter},
610332a8e7SCarlos Alberto Enciso {LVSymbolKind::IsUnspecified, &LVSymbol::getIsUnspecified},
620332a8e7SCarlos Alberto Enciso {LVSymbolKind::IsVariable, &LVSymbol::getIsVariable}};
630332a8e7SCarlos Alberto Enciso
643c397c90SCarlos Alberto Enciso // Add a Location Entry.
addLocation(dwarf::Attribute Attr,LVAddress LowPC,LVAddress HighPC,LVUnsigned SectionOffset,uint64_t LocDescOffset,bool CallSiteLocation)653c397c90SCarlos Alberto Enciso void LVSymbol::addLocation(dwarf::Attribute Attr, LVAddress LowPC,
663c397c90SCarlos Alberto Enciso LVAddress HighPC, LVUnsigned SectionOffset,
673c397c90SCarlos Alberto Enciso uint64_t LocDescOffset, bool CallSiteLocation) {
683c397c90SCarlos Alberto Enciso if (!Locations)
697fbcc244SCarlos Alberto Enciso Locations = std::make_unique<LVLocations>();
703c397c90SCarlos Alberto Enciso
713c397c90SCarlos Alberto Enciso // Create the location entry.
727fbcc244SCarlos Alberto Enciso CurrentLocation = getReader().createLocationSymbol();
733c397c90SCarlos Alberto Enciso CurrentLocation->setParent(this);
743c397c90SCarlos Alberto Enciso CurrentLocation->setAttr(Attr);
753c397c90SCarlos Alberto Enciso if (CallSiteLocation)
763c397c90SCarlos Alberto Enciso CurrentLocation->setIsCallSite();
773c397c90SCarlos Alberto Enciso CurrentLocation->addObject(LowPC, HighPC, SectionOffset, LocDescOffset);
783c397c90SCarlos Alberto Enciso Locations->push_back(CurrentLocation);
793c397c90SCarlos Alberto Enciso
803c397c90SCarlos Alberto Enciso // Mark the symbol as having location information.
813c397c90SCarlos Alberto Enciso setHasLocation();
823c397c90SCarlos Alberto Enciso }
833c397c90SCarlos Alberto Enciso
843c397c90SCarlos Alberto Enciso // Add a Location Record.
addLocationOperands(LVSmall Opcode,ArrayRef<uint64_t> Operands)85*2e6bb8c9SScott Linder void LVSymbol::addLocationOperands(LVSmall Opcode,
86*2e6bb8c9SScott Linder ArrayRef<uint64_t> Operands) {
873c397c90SCarlos Alberto Enciso if (CurrentLocation)
88*2e6bb8c9SScott Linder CurrentLocation->addObject(Opcode, Operands);
893c397c90SCarlos Alberto Enciso }
903c397c90SCarlos Alberto Enciso
913c397c90SCarlos Alberto Enciso // Add a Location Entry.
addLocationConstant(dwarf::Attribute Attr,LVUnsigned Constant,uint64_t LocDescOffset)923c397c90SCarlos Alberto Enciso void LVSymbol::addLocationConstant(dwarf::Attribute Attr, LVUnsigned Constant,
933c397c90SCarlos Alberto Enciso uint64_t LocDescOffset) {
943c397c90SCarlos Alberto Enciso // Create a Location Entry, with the global information.
953c397c90SCarlos Alberto Enciso addLocation(Attr,
963c397c90SCarlos Alberto Enciso /*LowPC=*/0, /*HighPC=*/-1,
973c397c90SCarlos Alberto Enciso /*SectionOffset=*/0, LocDescOffset);
983c397c90SCarlos Alberto Enciso
993c397c90SCarlos Alberto Enciso // Add records to Location Entry.
100*2e6bb8c9SScott Linder addLocationOperands(/*Opcode=*/LVLocationMemberOffset, {Constant});
1013c397c90SCarlos Alberto Enciso }
1023c397c90SCarlos Alberto Enciso
addLocationGap(LVLocations::iterator Pos,LVAddress LowPC,LVAddress HighPC)1033c397c90SCarlos Alberto Enciso LVLocations::iterator LVSymbol::addLocationGap(LVLocations::iterator Pos,
1043c397c90SCarlos Alberto Enciso LVAddress LowPC,
1053c397c90SCarlos Alberto Enciso LVAddress HighPC) {
1063c397c90SCarlos Alberto Enciso // Create a location entry for the gap.
1077fbcc244SCarlos Alberto Enciso LVLocation *Gap = getReader().createLocationSymbol();
1083c397c90SCarlos Alberto Enciso Gap->setParent(this);
1093c397c90SCarlos Alberto Enciso Gap->setAttr(dwarf::DW_AT_location);
1103c397c90SCarlos Alberto Enciso Gap->addObject(LowPC, HighPC,
1113c397c90SCarlos Alberto Enciso /*section_offset=*/0,
1123c397c90SCarlos Alberto Enciso /*locdesc_offset=*/0);
1133c397c90SCarlos Alberto Enciso
1143c397c90SCarlos Alberto Enciso LVLocations::iterator Iter = Locations->insert(Pos, Gap);
1153c397c90SCarlos Alberto Enciso
1163c397c90SCarlos Alberto Enciso // Add gap to Location Entry.
117*2e6bb8c9SScott Linder Gap->addObject(dwarf::DW_OP_hi_user, {});
1183c397c90SCarlos Alberto Enciso
1193c397c90SCarlos Alberto Enciso // Mark the entry as a gap.
1203c397c90SCarlos Alberto Enciso Gap->setIsGapEntry();
1213c397c90SCarlos Alberto Enciso
1223c397c90SCarlos Alberto Enciso return Iter;
1233c397c90SCarlos Alberto Enciso }
1243c397c90SCarlos Alberto Enciso
fillLocationGaps()1253c397c90SCarlos Alberto Enciso void LVSymbol::fillLocationGaps() {
1263c397c90SCarlos Alberto Enciso // The symbol has locations records. Fill gaps in the location list.
1273c397c90SCarlos Alberto Enciso if (!getHasLocation() || !getFillGaps())
1283c397c90SCarlos Alberto Enciso return;
1293c397c90SCarlos Alberto Enciso
1303c397c90SCarlos Alberto Enciso // Get the parent range information and add dummy location entries.
1313c397c90SCarlos Alberto Enciso const LVLocations *Ranges = getParentScope()->getRanges();
1323c397c90SCarlos Alberto Enciso if (!Ranges)
1333c397c90SCarlos Alberto Enciso return;
1343c397c90SCarlos Alberto Enciso
1353c397c90SCarlos Alberto Enciso for (const LVLocation *Entry : *Ranges) {
1363c397c90SCarlos Alberto Enciso LVAddress ParentLowPC = Entry->getLowerAddress();
1373c397c90SCarlos Alberto Enciso LVAddress ParentHighPC = Entry->getUpperAddress();
1383c397c90SCarlos Alberto Enciso
1393c397c90SCarlos Alberto Enciso // Traverse the symbol locations and for each location contained in
1403c397c90SCarlos Alberto Enciso // the current parent range, insert locations for any existing gap.
1413c397c90SCarlos Alberto Enciso LVLocation *Location;
1423c397c90SCarlos Alberto Enciso LVAddress LowPC = 0;
1433c397c90SCarlos Alberto Enciso LVAddress Marker = ParentLowPC;
1443c397c90SCarlos Alberto Enciso for (LVLocations::iterator Iter = Locations->begin();
1453c397c90SCarlos Alberto Enciso Iter != Locations->end(); ++Iter) {
1463c397c90SCarlos Alberto Enciso Location = *Iter;
1473c397c90SCarlos Alberto Enciso LowPC = Location->getLowerAddress();
1483c397c90SCarlos Alberto Enciso if (LowPC != Marker) {
1493c397c90SCarlos Alberto Enciso // We have a gap at [Marker,LowPC - 1].
1503c397c90SCarlos Alberto Enciso Iter = addLocationGap(Iter, Marker, LowPC - 1);
1513c397c90SCarlos Alberto Enciso ++Iter;
1523c397c90SCarlos Alberto Enciso }
1533c397c90SCarlos Alberto Enciso
1543c397c90SCarlos Alberto Enciso // Move to the next item in the location list.
1553c397c90SCarlos Alberto Enciso Marker = Location->getUpperAddress() + 1;
1563c397c90SCarlos Alberto Enciso }
1573c397c90SCarlos Alberto Enciso
1583c397c90SCarlos Alberto Enciso // Check any gap at the end.
1593c397c90SCarlos Alberto Enciso if (Marker < ParentHighPC)
1603c397c90SCarlos Alberto Enciso // We have a gap at [Marker,ParentHighPC].
1613c397c90SCarlos Alberto Enciso addLocationGap(Locations->end(), Marker, ParentHighPC);
1623c397c90SCarlos Alberto Enciso }
1633c397c90SCarlos Alberto Enciso }
1643c397c90SCarlos Alberto Enciso
1653c397c90SCarlos Alberto Enciso // Get all the locations based on the valid function.
getLocations(LVLocations & LocationList,LVValidLocation ValidLocation,bool RecordInvalid)1663c397c90SCarlos Alberto Enciso void LVSymbol::getLocations(LVLocations &LocationList,
1673c397c90SCarlos Alberto Enciso LVValidLocation ValidLocation, bool RecordInvalid) {
1683c397c90SCarlos Alberto Enciso if (!Locations)
1693c397c90SCarlos Alberto Enciso return;
1703c397c90SCarlos Alberto Enciso
1713c397c90SCarlos Alberto Enciso for (LVLocation *Location : *Locations) {
1723c397c90SCarlos Alberto Enciso // Add the invalid location object.
1733c397c90SCarlos Alberto Enciso if (!(Location->*ValidLocation)() && RecordInvalid)
1743c397c90SCarlos Alberto Enciso LocationList.push_back(Location);
1753c397c90SCarlos Alberto Enciso }
1763c397c90SCarlos Alberto Enciso
1773c397c90SCarlos Alberto Enciso // Calculate coverage factor.
1783c397c90SCarlos Alberto Enciso calculateCoverage();
1793c397c90SCarlos Alberto Enciso }
1803c397c90SCarlos Alberto Enciso
getLocations(LVLocations & LocationList) const1813c397c90SCarlos Alberto Enciso void LVSymbol::getLocations(LVLocations &LocationList) const {
1823c397c90SCarlos Alberto Enciso if (!Locations)
1833c397c90SCarlos Alberto Enciso return;
1843c397c90SCarlos Alberto Enciso
1853c397c90SCarlos Alberto Enciso for (LVLocation *Location : *Locations)
1863c397c90SCarlos Alberto Enciso LocationList.push_back(Location);
1873c397c90SCarlos Alberto Enciso }
1883c397c90SCarlos Alberto Enciso
1893c397c90SCarlos Alberto Enciso // Calculate coverage factor.
calculateCoverage()1903c397c90SCarlos Alberto Enciso void LVSymbol::calculateCoverage() {
1917fbcc244SCarlos Alberto Enciso if (!LVLocation::calculateCoverage(Locations.get(), CoverageFactor,
1923c397c90SCarlos Alberto Enciso CoveragePercentage)) {
1933c397c90SCarlos Alberto Enciso LVScope *Parent = getParentScope();
1943c397c90SCarlos Alberto Enciso if (Parent->getIsInlinedFunction()) {
1953c397c90SCarlos Alberto Enciso // For symbols representing the inlined function parameters and its
1963c397c90SCarlos Alberto Enciso // variables, get the outer most parent that contains their location
1973c397c90SCarlos Alberto Enciso // lower address.
1983c397c90SCarlos Alberto Enciso // The symbol can have a set of non-contiguous locations. We are using
1993c397c90SCarlos Alberto Enciso // only the first location entry to get the outermost parent.
2003c397c90SCarlos Alberto Enciso // If no scope contains the location, assume its enclosing parent.
2013c397c90SCarlos Alberto Enciso LVScope *Scope =
2023c397c90SCarlos Alberto Enciso Parent->outermostParent(Locations->front()->getLowerAddress());
2033c397c90SCarlos Alberto Enciso if (Scope)
2043c397c90SCarlos Alberto Enciso Parent = Scope;
2053c397c90SCarlos Alberto Enciso }
2063c397c90SCarlos Alberto Enciso unsigned CoverageParent = Parent->getCoverageFactor();
2073c397c90SCarlos Alberto Enciso // Get a percentage rounded to two decimal digits. This avoids
2083c397c90SCarlos Alberto Enciso // implementation-defined rounding inside printing functions.
2093c397c90SCarlos Alberto Enciso CoveragePercentage =
2103c397c90SCarlos Alberto Enciso CoverageParent
2113c397c90SCarlos Alberto Enciso ? rint((double(CoverageFactor) / CoverageParent) * 100.0 * 100.0) /
2123c397c90SCarlos Alberto Enciso 100.0
2133c397c90SCarlos Alberto Enciso : 0;
2142c155d37SCarlos Alberto Enciso // Record invalid coverage entry.
2152c155d37SCarlos Alberto Enciso if (options().getWarningCoverages() && CoveragePercentage > 100)
2162c155d37SCarlos Alberto Enciso getReaderCompileUnit()->addInvalidCoverage(this);
2173c397c90SCarlos Alberto Enciso }
2183c397c90SCarlos Alberto Enciso }
2193c397c90SCarlos Alberto Enciso
resolveName()220e28b9357SCarlos Alberto Enciso void LVSymbol::resolveName() {
221e28b9357SCarlos Alberto Enciso if (getIsResolvedName())
222e28b9357SCarlos Alberto Enciso return;
223e28b9357SCarlos Alberto Enciso setIsResolvedName();
224e28b9357SCarlos Alberto Enciso
225e28b9357SCarlos Alberto Enciso LVElement::resolveName();
2260332a8e7SCarlos Alberto Enciso
2270332a8e7SCarlos Alberto Enciso // Resolve any given pattern.
2280332a8e7SCarlos Alberto Enciso patterns().resolvePatternMatch(this);
229e28b9357SCarlos Alberto Enciso }
230e28b9357SCarlos Alberto Enciso
resolveReferences()231e28b9357SCarlos Alberto Enciso void LVSymbol::resolveReferences() {
232e28b9357SCarlos Alberto Enciso // The symbols can have the following references to other elements:
233e28b9357SCarlos Alberto Enciso // A Type:
234e28b9357SCarlos Alberto Enciso // DW_AT_type -> Type or Scope
235e28b9357SCarlos Alberto Enciso // DW_AT_import -> Type
236e28b9357SCarlos Alberto Enciso // A Reference:
237e28b9357SCarlos Alberto Enciso // DW_AT_specification -> Symbol
238e28b9357SCarlos Alberto Enciso // DW_AT_abstract_origin -> Symbol
239e28b9357SCarlos Alberto Enciso // DW_AT_extension -> Symbol
240e28b9357SCarlos Alberto Enciso
241e28b9357SCarlos Alberto Enciso // Resolve any referenced symbol.
242e28b9357SCarlos Alberto Enciso LVSymbol *Reference = getReference();
243e28b9357SCarlos Alberto Enciso if (Reference) {
244e28b9357SCarlos Alberto Enciso Reference->resolve();
245e28b9357SCarlos Alberto Enciso // Recursively resolve the symbol names.
246e28b9357SCarlos Alberto Enciso resolveReferencesChain();
247e28b9357SCarlos Alberto Enciso }
248e28b9357SCarlos Alberto Enciso
249e28b9357SCarlos Alberto Enciso // Set the file/line information using the Debug Information entry.
250e28b9357SCarlos Alberto Enciso setFile(Reference);
251e28b9357SCarlos Alberto Enciso
252e28b9357SCarlos Alberto Enciso // Resolve symbol type.
253e28b9357SCarlos Alberto Enciso if (LVElement *Element = getType()) {
254e28b9357SCarlos Alberto Enciso Element->resolve();
255e28b9357SCarlos Alberto Enciso
256e28b9357SCarlos Alberto Enciso // In the case of demoted typedefs, use the underlying type.
257e28b9357SCarlos Alberto Enciso if (Element->getIsTypedefReduced()) {
258e28b9357SCarlos Alberto Enciso Element = Element->getType();
259e28b9357SCarlos Alberto Enciso Element->resolve();
260e28b9357SCarlos Alberto Enciso }
261e28b9357SCarlos Alberto Enciso
262e28b9357SCarlos Alberto Enciso // If the type is a template parameter, get its type, which can
263e28b9357SCarlos Alberto Enciso // point to a type or scope, depending on the argument instance.
264e28b9357SCarlos Alberto Enciso setGenericType(Element);
265e28b9357SCarlos Alberto Enciso }
266e28b9357SCarlos Alberto Enciso
267e28b9357SCarlos Alberto Enciso // Resolve the variable associated type.
268e28b9357SCarlos Alberto Enciso if (!getType() && Reference)
269e28b9357SCarlos Alberto Enciso setType(Reference->getType());
270e28b9357SCarlos Alberto Enciso }
271e28b9357SCarlos Alberto Enciso
resolveReferencesChain()272e28b9357SCarlos Alberto Enciso StringRef LVSymbol::resolveReferencesChain() {
273e28b9357SCarlos Alberto Enciso // If the symbol have a DW_AT_specification or DW_AT_abstract_origin,
274e28b9357SCarlos Alberto Enciso // follow the chain to resolve the name from those references.
275e28b9357SCarlos Alberto Enciso if (getHasReference() && !isNamed())
276e28b9357SCarlos Alberto Enciso setName(getReference()->resolveReferencesChain());
277e28b9357SCarlos Alberto Enciso
278e28b9357SCarlos Alberto Enciso return getName();
279e28b9357SCarlos Alberto Enciso }
280e28b9357SCarlos Alberto Enciso
markMissingParents(const LVSymbols * References,const LVSymbols * Targets)281e98a4c5aSCarlos Alberto Enciso void LVSymbol::markMissingParents(const LVSymbols *References,
282e98a4c5aSCarlos Alberto Enciso const LVSymbols *Targets) {
283e98a4c5aSCarlos Alberto Enciso if (!(References && Targets))
284e98a4c5aSCarlos Alberto Enciso return;
285e98a4c5aSCarlos Alberto Enciso
286e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
287e98a4c5aSCarlos Alberto Enciso dbgs() << "\n[LVSymbol::markMissingParents]\n";
288e98a4c5aSCarlos Alberto Enciso for (const LVSymbol *Reference : *References)
289e98a4c5aSCarlos Alberto Enciso dbgs() << "References: "
290e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Reference->kind()) << ", "
291e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Reference->getName()) << "\n";
292e98a4c5aSCarlos Alberto Enciso for (const LVSymbol *Target : *Targets)
293e98a4c5aSCarlos Alberto Enciso dbgs() << "Targets : "
294e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Target->kind()) << ", "
295e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Target->getName()) << "\n";
296e98a4c5aSCarlos Alberto Enciso });
297e98a4c5aSCarlos Alberto Enciso
298e98a4c5aSCarlos Alberto Enciso for (LVSymbol *Reference : *References) {
299e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
300e98a4c5aSCarlos Alberto Enciso dbgs() << "Search Reference: Name = "
301e98a4c5aSCarlos Alberto Enciso << formattedName(Reference->getName()) << "\n";
302e98a4c5aSCarlos Alberto Enciso });
303e98a4c5aSCarlos Alberto Enciso if (!Reference->findIn(Targets))
304e98a4c5aSCarlos Alberto Enciso Reference->markBranchAsMissing();
305e98a4c5aSCarlos Alberto Enciso }
306e98a4c5aSCarlos Alberto Enciso }
307e98a4c5aSCarlos Alberto Enciso
findIn(const LVSymbols * Targets) const308e98a4c5aSCarlos Alberto Enciso LVSymbol *LVSymbol::findIn(const LVSymbols *Targets) const {
309e98a4c5aSCarlos Alberto Enciso if (!Targets)
310e98a4c5aSCarlos Alberto Enciso return nullptr;
311e98a4c5aSCarlos Alberto Enciso
312e98a4c5aSCarlos Alberto Enciso LLVM_DEBUG({
313e98a4c5aSCarlos Alberto Enciso dbgs() << "\n[LVSymbol::findIn]\n"
314e98a4c5aSCarlos Alberto Enciso << "Reference: "
315e98a4c5aSCarlos Alberto Enciso << "Level = " << getLevel() << ", "
316e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(kind()) << ", "
317e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(getName()) << "\n";
318e98a4c5aSCarlos Alberto Enciso for (const LVSymbol *Target : *Targets)
319e98a4c5aSCarlos Alberto Enciso dbgs() << "Target : "
320e98a4c5aSCarlos Alberto Enciso << "Level = " << Target->getLevel() << ", "
321e98a4c5aSCarlos Alberto Enciso << "Kind = " << formattedKind(Target->kind()) << ", "
322e98a4c5aSCarlos Alberto Enciso << "Name = " << formattedName(Target->getName()) << "\n";
323e98a4c5aSCarlos Alberto Enciso });
324e98a4c5aSCarlos Alberto Enciso
325e98a4c5aSCarlos Alberto Enciso for (LVSymbol *Target : *Targets)
326e98a4c5aSCarlos Alberto Enciso if (equals(Target))
327e98a4c5aSCarlos Alberto Enciso return Target;
328e98a4c5aSCarlos Alberto Enciso
329e98a4c5aSCarlos Alberto Enciso return nullptr;
330e98a4c5aSCarlos Alberto Enciso }
331e98a4c5aSCarlos Alberto Enciso
332e98a4c5aSCarlos Alberto Enciso // Check for a match on the arguments of a function.
parametersMatch(const LVSymbols * References,const LVSymbols * Targets)333e98a4c5aSCarlos Alberto Enciso bool LVSymbol::parametersMatch(const LVSymbols *References,
334e98a4c5aSCarlos Alberto Enciso const LVSymbols *Targets) {
335e98a4c5aSCarlos Alberto Enciso if (!References && !Targets)
336e98a4c5aSCarlos Alberto Enciso return true;
337e98a4c5aSCarlos Alberto Enciso if (References && Targets) {
338e98a4c5aSCarlos Alberto Enciso LVSymbols ReferenceParams;
339e98a4c5aSCarlos Alberto Enciso getParameters(References, &ReferenceParams);
340e98a4c5aSCarlos Alberto Enciso LVSymbols TargetParams;
341e98a4c5aSCarlos Alberto Enciso getParameters(Targets, &TargetParams);
342e98a4c5aSCarlos Alberto Enciso return LVSymbol::equals(&ReferenceParams, &TargetParams);
343e98a4c5aSCarlos Alberto Enciso }
344e98a4c5aSCarlos Alberto Enciso return false;
345e98a4c5aSCarlos Alberto Enciso }
346e98a4c5aSCarlos Alberto Enciso
347e98a4c5aSCarlos Alberto Enciso // Return the symbols which are parameters.
getParameters(const LVSymbols * Symbols,LVSymbols * Parameters)348e98a4c5aSCarlos Alberto Enciso void LVSymbol::getParameters(const LVSymbols *Symbols, LVSymbols *Parameters) {
349e98a4c5aSCarlos Alberto Enciso if (Symbols)
350e98a4c5aSCarlos Alberto Enciso for (LVSymbol *Symbol : *Symbols)
351e98a4c5aSCarlos Alberto Enciso if (Symbol->getIsParameter())
352e98a4c5aSCarlos Alberto Enciso Parameters->push_back(Symbol);
353e98a4c5aSCarlos Alberto Enciso }
354e98a4c5aSCarlos Alberto Enciso
equals(const LVSymbol * Symbol) const355e98a4c5aSCarlos Alberto Enciso bool LVSymbol::equals(const LVSymbol *Symbol) const {
356e98a4c5aSCarlos Alberto Enciso if (!LVElement::equals(Symbol))
357e98a4c5aSCarlos Alberto Enciso return false;
358e98a4c5aSCarlos Alberto Enciso
359e98a4c5aSCarlos Alberto Enciso // Check if any reference is the same.
360e98a4c5aSCarlos Alberto Enciso if (!referenceMatch(Symbol))
361e98a4c5aSCarlos Alberto Enciso return false;
362e98a4c5aSCarlos Alberto Enciso
363e98a4c5aSCarlos Alberto Enciso if (getReference() && !getReference()->equals(Symbol->getReference()))
364e98a4c5aSCarlos Alberto Enciso return false;
365e98a4c5aSCarlos Alberto Enciso
366e98a4c5aSCarlos Alberto Enciso return true;
367e98a4c5aSCarlos Alberto Enciso }
368e98a4c5aSCarlos Alberto Enciso
equals(const LVSymbols * References,const LVSymbols * Targets)369e98a4c5aSCarlos Alberto Enciso bool LVSymbol::equals(const LVSymbols *References, const LVSymbols *Targets) {
370e98a4c5aSCarlos Alberto Enciso if (!References && !Targets)
371e98a4c5aSCarlos Alberto Enciso return true;
372e98a4c5aSCarlos Alberto Enciso if (References && Targets && References->size() == Targets->size()) {
373e98a4c5aSCarlos Alberto Enciso for (const LVSymbol *Reference : *References)
374e98a4c5aSCarlos Alberto Enciso if (!Reference->findIn(Targets))
375e98a4c5aSCarlos Alberto Enciso return false;
376e98a4c5aSCarlos Alberto Enciso return true;
377e98a4c5aSCarlos Alberto Enciso }
378e98a4c5aSCarlos Alberto Enciso return false;
379e98a4c5aSCarlos Alberto Enciso }
380e98a4c5aSCarlos Alberto Enciso
report(LVComparePass Pass)381e98a4c5aSCarlos Alberto Enciso void LVSymbol::report(LVComparePass Pass) {
382e98a4c5aSCarlos Alberto Enciso getComparator().printItem(this, Pass);
383e98a4c5aSCarlos Alberto Enciso }
384e98a4c5aSCarlos Alberto Enciso
printLocations(raw_ostream & OS,bool Full) const3853c397c90SCarlos Alberto Enciso void LVSymbol::printLocations(raw_ostream &OS, bool Full) const {
3863c397c90SCarlos Alberto Enciso if (Locations)
3873c397c90SCarlos Alberto Enciso for (const LVLocation *Location : *Locations)
3883c397c90SCarlos Alberto Enciso Location->printRaw(OS, Full);
3893c397c90SCarlos Alberto Enciso }
3903c397c90SCarlos Alberto Enciso
print(raw_ostream & OS,bool Full) const391e28b9357SCarlos Alberto Enciso void LVSymbol::print(raw_ostream &OS, bool Full) const {
392e28b9357SCarlos Alberto Enciso if (getIncludeInPrint() && getReader().doPrintSymbol(this)) {
393e28b9357SCarlos Alberto Enciso getReaderCompileUnit()->incrementPrintedSymbols();
394e28b9357SCarlos Alberto Enciso LVElement::print(OS, Full);
395e28b9357SCarlos Alberto Enciso printExtra(OS, Full);
396e28b9357SCarlos Alberto Enciso }
397e28b9357SCarlos Alberto Enciso }
398e28b9357SCarlos Alberto Enciso
printExtra(raw_ostream & OS,bool Full) const399e28b9357SCarlos Alberto Enciso void LVSymbol::printExtra(raw_ostream &OS, bool Full) const {
400e28b9357SCarlos Alberto Enciso // Accessibility depends on the parent (class, structure).
401e28b9357SCarlos Alberto Enciso uint32_t AccessCode = 0;
402e28b9357SCarlos Alberto Enciso if (getIsMember() || getIsInheritance())
403e28b9357SCarlos Alberto Enciso AccessCode = getParentScope()->getIsClass() ? dwarf::DW_ACCESS_private
404e28b9357SCarlos Alberto Enciso : dwarf::DW_ACCESS_public;
405e28b9357SCarlos Alberto Enciso
406e28b9357SCarlos Alberto Enciso const LVSymbol *Symbol = getIsInlined() ? Reference : this;
407e28b9357SCarlos Alberto Enciso std::string Attributes =
408e28b9357SCarlos Alberto Enciso Symbol->getIsCallSiteParameter()
409e28b9357SCarlos Alberto Enciso ? ""
410e28b9357SCarlos Alberto Enciso : formatAttributes(Symbol->externalString(),
411e28b9357SCarlos Alberto Enciso Symbol->accessibilityString(AccessCode),
412e28b9357SCarlos Alberto Enciso virtualityString());
413e28b9357SCarlos Alberto Enciso
414e28b9357SCarlos Alberto Enciso OS << formattedKind(Symbol->kind()) << " " << Attributes;
415e28b9357SCarlos Alberto Enciso if (Symbol->getIsUnspecified())
416e28b9357SCarlos Alberto Enciso OS << formattedName(Symbol->getName());
417e28b9357SCarlos Alberto Enciso else {
418e28b9357SCarlos Alberto Enciso if (Symbol->getIsInheritance())
419e28b9357SCarlos Alberto Enciso OS << Symbol->typeOffsetAsString()
420e28b9357SCarlos Alberto Enciso << formattedNames(Symbol->getTypeQualifiedName(),
421e28b9357SCarlos Alberto Enciso Symbol->typeAsString());
422e28b9357SCarlos Alberto Enciso else {
423e28b9357SCarlos Alberto Enciso OS << formattedName(Symbol->getName());
424e28b9357SCarlos Alberto Enciso // Print any bitfield information.
425e28b9357SCarlos Alberto Enciso if (uint32_t Size = getBitSize())
426e28b9357SCarlos Alberto Enciso OS << ":" << Size;
427e28b9357SCarlos Alberto Enciso OS << " -> " << Symbol->typeOffsetAsString()
428e28b9357SCarlos Alberto Enciso << formattedNames(Symbol->getTypeQualifiedName(),
429e28b9357SCarlos Alberto Enciso Symbol->typeAsString());
430e28b9357SCarlos Alberto Enciso }
431e28b9357SCarlos Alberto Enciso }
432e28b9357SCarlos Alberto Enciso
433e28b9357SCarlos Alberto Enciso // Print any initial value if any.
434e28b9357SCarlos Alberto Enciso if (ValueIndex)
435e28b9357SCarlos Alberto Enciso OS << " = " << formattedName(getValue());
436e28b9357SCarlos Alberto Enciso OS << "\n";
437e28b9357SCarlos Alberto Enciso
438e28b9357SCarlos Alberto Enciso if (Full && options().getPrintFormatting()) {
439e28b9357SCarlos Alberto Enciso if (getLinkageNameIndex())
440e28b9357SCarlos Alberto Enciso printLinkageName(OS, Full, const_cast<LVSymbol *>(this));
441e28b9357SCarlos Alberto Enciso if (LVSymbol *Reference = getReference())
442e28b9357SCarlos Alberto Enciso Reference->printReference(OS, Full, const_cast<LVSymbol *>(this));
4433c397c90SCarlos Alberto Enciso
4443c397c90SCarlos Alberto Enciso // Print location information.
4457fbcc244SCarlos Alberto Enciso LVLocation::print(Locations.get(), OS, Full);
446e28b9357SCarlos Alberto Enciso }
447e28b9357SCarlos Alberto Enciso }
448