xref: /llvm-project/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp (revision 2e6bb8c9b82c185f0e96895b1f69045cfb0640b4)
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