1 //===-- LVSymbol.cpp ------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This implements the LVSymbol class.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
14 #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
15 #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
16 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
17 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
20 using namespace llvm::logicalview
;
22 #define DEBUG_TYPE "Symbol"
25 const char *const KindCallSiteParameter
= "CallSiteParameter";
26 const char *const KindConstant
= "Constant";
27 const char *const KindInherits
= "Inherits";
28 const char *const KindMember
= "Member";
29 const char *const KindParameter
= "Parameter";
30 const char *const KindUndefined
= "Undefined";
31 const char *const KindUnspecified
= "Unspecified";
32 const char *const KindVariable
= "Variable";
33 } // end anonymous namespace
35 // Return a string representation for the symbol kind.
36 const char *LVSymbol::kind() const {
37 const char *Kind
= KindUndefined
;
38 if (getIsCallSiteParameter())
39 Kind
= KindCallSiteParameter
;
40 else if (getIsConstant())
42 else if (getIsInheritance())
44 else if (getIsMember())
46 else if (getIsParameter())
48 else if (getIsUnspecified())
49 Kind
= KindUnspecified
;
50 else if (getIsVariable())
55 LVSymbolDispatch
LVSymbol::Dispatch
= {
56 {LVSymbolKind::IsCallSiteParameter
, &LVSymbol::getIsCallSiteParameter
},
57 {LVSymbolKind::IsConstant
, &LVSymbol::getIsConstant
},
58 {LVSymbolKind::IsInheritance
, &LVSymbol::getIsInheritance
},
59 {LVSymbolKind::IsMember
, &LVSymbol::getIsMember
},
60 {LVSymbolKind::IsParameter
, &LVSymbol::getIsParameter
},
61 {LVSymbolKind::IsUnspecified
, &LVSymbol::getIsUnspecified
},
62 {LVSymbolKind::IsVariable
, &LVSymbol::getIsVariable
}};
64 // Add a Location Entry.
65 void LVSymbol::addLocation(dwarf::Attribute Attr
, LVAddress LowPC
,
66 LVAddress HighPC
, LVUnsigned SectionOffset
,
67 uint64_t LocDescOffset
, bool CallSiteLocation
) {
69 Locations
= std::make_unique
<LVLocations
>();
71 // Create the location entry.
72 CurrentLocation
= getReader().createLocationSymbol();
73 CurrentLocation
->setParent(this);
74 CurrentLocation
->setAttr(Attr
);
76 CurrentLocation
->setIsCallSite();
77 CurrentLocation
->addObject(LowPC
, HighPC
, SectionOffset
, LocDescOffset
);
78 Locations
->push_back(CurrentLocation
);
80 // Mark the symbol as having location information.
84 // Add a Location Record.
85 void LVSymbol::addLocationOperands(LVSmall Opcode
,
86 ArrayRef
<uint64_t> Operands
) {
88 CurrentLocation
->addObject(Opcode
, Operands
);
91 // Add a Location Entry.
92 void LVSymbol::addLocationConstant(dwarf::Attribute Attr
, LVUnsigned Constant
,
93 uint64_t LocDescOffset
) {
94 // Create a Location Entry, with the global information.
96 /*LowPC=*/0, /*HighPC=*/-1,
97 /*SectionOffset=*/0, LocDescOffset
);
99 // Add records to Location Entry.
100 addLocationOperands(/*Opcode=*/LVLocationMemberOffset
, {Constant
});
103 LVLocations::iterator
LVSymbol::addLocationGap(LVLocations::iterator Pos
,
106 // Create a location entry for the gap.
107 LVLocation
*Gap
= getReader().createLocationSymbol();
108 Gap
->setParent(this);
109 Gap
->setAttr(dwarf::DW_AT_location
);
110 Gap
->addObject(LowPC
, HighPC
,
111 /*section_offset=*/0,
112 /*locdesc_offset=*/0);
114 LVLocations::iterator Iter
= Locations
->insert(Pos
, Gap
);
116 // Add gap to Location Entry.
117 Gap
->addObject(dwarf::DW_OP_hi_user
, {});
119 // Mark the entry as a gap.
120 Gap
->setIsGapEntry();
125 void LVSymbol::fillLocationGaps() {
126 // The symbol has locations records. Fill gaps in the location list.
127 if (!getHasLocation() || !getFillGaps())
130 // Get the parent range information and add dummy location entries.
131 const LVLocations
*Ranges
= getParentScope()->getRanges();
135 for (const LVLocation
*Entry
: *Ranges
) {
136 LVAddress ParentLowPC
= Entry
->getLowerAddress();
137 LVAddress ParentHighPC
= Entry
->getUpperAddress();
139 // Traverse the symbol locations and for each location contained in
140 // the current parent range, insert locations for any existing gap.
141 LVLocation
*Location
;
143 LVAddress Marker
= ParentLowPC
;
144 for (LVLocations::iterator Iter
= Locations
->begin();
145 Iter
!= Locations
->end(); ++Iter
) {
147 LowPC
= Location
->getLowerAddress();
148 if (LowPC
!= Marker
) {
149 // We have a gap at [Marker,LowPC - 1].
150 Iter
= addLocationGap(Iter
, Marker
, LowPC
- 1);
154 // Move to the next item in the location list.
155 Marker
= Location
->getUpperAddress() + 1;
158 // Check any gap at the end.
159 if (Marker
< ParentHighPC
)
160 // We have a gap at [Marker,ParentHighPC].
161 addLocationGap(Locations
->end(), Marker
, ParentHighPC
);
165 // Get all the locations based on the valid function.
166 void LVSymbol::getLocations(LVLocations
&LocationList
,
167 LVValidLocation ValidLocation
, bool RecordInvalid
) {
171 for (LVLocation
*Location
: *Locations
) {
172 // Add the invalid location object.
173 if (!(Location
->*ValidLocation
)() && RecordInvalid
)
174 LocationList
.push_back(Location
);
177 // Calculate coverage factor.
181 void LVSymbol::getLocations(LVLocations
&LocationList
) const {
185 for (LVLocation
*Location
: *Locations
)
186 LocationList
.push_back(Location
);
189 // Calculate coverage factor.
190 void LVSymbol::calculateCoverage() {
191 if (!LVLocation::calculateCoverage(Locations
.get(), CoverageFactor
,
192 CoveragePercentage
)) {
193 LVScope
*Parent
= getParentScope();
194 if (Parent
->getIsInlinedFunction()) {
195 // For symbols representing the inlined function parameters and its
196 // variables, get the outer most parent that contains their location
198 // The symbol can have a set of non-contiguous locations. We are using
199 // only the first location entry to get the outermost parent.
200 // If no scope contains the location, assume its enclosing parent.
202 Parent
->outermostParent(Locations
->front()->getLowerAddress());
206 unsigned CoverageParent
= Parent
->getCoverageFactor();
207 // Get a percentage rounded to two decimal digits. This avoids
208 // implementation-defined rounding inside printing functions.
211 ? rint((double(CoverageFactor
) / CoverageParent
) * 100.0 * 100.0) /
214 // Record invalid coverage entry.
215 if (options().getWarningCoverages() && CoveragePercentage
> 100)
216 getReaderCompileUnit()->addInvalidCoverage(this);
220 void LVSymbol::resolveName() {
221 if (getIsResolvedName())
225 LVElement::resolveName();
227 // Resolve any given pattern.
228 patterns().resolvePatternMatch(this);
231 void LVSymbol::resolveReferences() {
232 // The symbols can have the following references to other elements:
234 // DW_AT_type -> Type or Scope
235 // DW_AT_import -> Type
237 // DW_AT_specification -> Symbol
238 // DW_AT_abstract_origin -> Symbol
239 // DW_AT_extension -> Symbol
241 // Resolve any referenced symbol.
242 LVSymbol
*Reference
= getReference();
244 Reference
->resolve();
245 // Recursively resolve the symbol names.
246 resolveReferencesChain();
249 // Set the file/line information using the Debug Information entry.
252 // Resolve symbol type.
253 if (LVElement
*Element
= getType()) {
256 // In the case of demoted typedefs, use the underlying type.
257 if (Element
->getIsTypedefReduced()) {
258 Element
= Element
->getType();
262 // If the type is a template parameter, get its type, which can
263 // point to a type or scope, depending on the argument instance.
264 setGenericType(Element
);
267 // Resolve the variable associated type.
268 if (!getType() && Reference
)
269 setType(Reference
->getType());
272 StringRef
LVSymbol::resolveReferencesChain() {
273 // If the symbol have a DW_AT_specification or DW_AT_abstract_origin,
274 // follow the chain to resolve the name from those references.
275 if (getHasReference() && !isNamed())
276 setName(getReference()->resolveReferencesChain());
281 void LVSymbol::markMissingParents(const LVSymbols
*References
,
282 const LVSymbols
*Targets
) {
283 if (!(References
&& Targets
))
287 dbgs() << "\n[LVSymbol::markMissingParents]\n";
288 for (const LVSymbol
*Reference
: *References
)
289 dbgs() << "References: "
290 << "Kind = " << formattedKind(Reference
->kind()) << ", "
291 << "Name = " << formattedName(Reference
->getName()) << "\n";
292 for (const LVSymbol
*Target
: *Targets
)
293 dbgs() << "Targets : "
294 << "Kind = " << formattedKind(Target
->kind()) << ", "
295 << "Name = " << formattedName(Target
->getName()) << "\n";
298 for (LVSymbol
*Reference
: *References
) {
300 dbgs() << "Search Reference: Name = "
301 << formattedName(Reference
->getName()) << "\n";
303 if (!Reference
->findIn(Targets
))
304 Reference
->markBranchAsMissing();
308 LVSymbol
*LVSymbol::findIn(const LVSymbols
*Targets
) const {
313 dbgs() << "\n[LVSymbol::findIn]\n"
315 << "Level = " << getLevel() << ", "
316 << "Kind = " << formattedKind(kind()) << ", "
317 << "Name = " << formattedName(getName()) << "\n";
318 for (const LVSymbol
*Target
: *Targets
)
319 dbgs() << "Target : "
320 << "Level = " << Target
->getLevel() << ", "
321 << "Kind = " << formattedKind(Target
->kind()) << ", "
322 << "Name = " << formattedName(Target
->getName()) << "\n";
325 for (LVSymbol
*Target
: *Targets
)
332 // Check for a match on the arguments of a function.
333 bool LVSymbol::parametersMatch(const LVSymbols
*References
,
334 const LVSymbols
*Targets
) {
335 if (!References
&& !Targets
)
337 if (References
&& Targets
) {
338 LVSymbols ReferenceParams
;
339 getParameters(References
, &ReferenceParams
);
340 LVSymbols TargetParams
;
341 getParameters(Targets
, &TargetParams
);
342 return LVSymbol::equals(&ReferenceParams
, &TargetParams
);
347 // Return the symbols which are parameters.
348 void LVSymbol::getParameters(const LVSymbols
*Symbols
, LVSymbols
*Parameters
) {
350 for (LVSymbol
*Symbol
: *Symbols
)
351 if (Symbol
->getIsParameter())
352 Parameters
->push_back(Symbol
);
355 bool LVSymbol::equals(const LVSymbol
*Symbol
) const {
356 if (!LVElement::equals(Symbol
))
359 // Check if any reference is the same.
360 if (!referenceMatch(Symbol
))
363 if (getReference() && !getReference()->equals(Symbol
->getReference()))
369 bool LVSymbol::equals(const LVSymbols
*References
, const LVSymbols
*Targets
) {
370 if (!References
&& !Targets
)
372 if (References
&& Targets
&& References
->size() == Targets
->size()) {
373 for (const LVSymbol
*Reference
: *References
)
374 if (!Reference
->findIn(Targets
))
381 void LVSymbol::report(LVComparePass Pass
) {
382 getComparator().printItem(this, Pass
);
385 void LVSymbol::printLocations(raw_ostream
&OS
, bool Full
) const {
387 for (const LVLocation
*Location
: *Locations
)
388 Location
->printRaw(OS
, Full
);
391 void LVSymbol::print(raw_ostream
&OS
, bool Full
) const {
392 if (getIncludeInPrint() && getReader().doPrintSymbol(this)) {
393 getReaderCompileUnit()->incrementPrintedSymbols();
394 LVElement::print(OS
, Full
);
395 printExtra(OS
, Full
);
399 void LVSymbol::printExtra(raw_ostream
&OS
, bool Full
) const {
400 // Accessibility depends on the parent (class, structure).
401 uint32_t AccessCode
= 0;
402 if (getIsMember() || getIsInheritance())
403 AccessCode
= getParentScope()->getIsClass() ? dwarf::DW_ACCESS_private
404 : dwarf::DW_ACCESS_public
;
406 const LVSymbol
*Symbol
= getIsInlined() ? Reference
: this;
407 std::string Attributes
=
408 Symbol
->getIsCallSiteParameter()
410 : formatAttributes(Symbol
->externalString(),
411 Symbol
->accessibilityString(AccessCode
),
414 OS
<< formattedKind(Symbol
->kind()) << " " << Attributes
;
415 if (Symbol
->getIsUnspecified())
416 OS
<< formattedName(Symbol
->getName());
418 if (Symbol
->getIsInheritance())
419 OS
<< Symbol
->typeOffsetAsString()
420 << formattedNames(Symbol
->getTypeQualifiedName(),
421 Symbol
->typeAsString());
423 OS
<< formattedName(Symbol
->getName());
424 // Print any bitfield information.
425 if (uint32_t Size
= getBitSize())
427 OS
<< " -> " << Symbol
->typeOffsetAsString()
428 << formattedNames(Symbol
->getTypeQualifiedName(),
429 Symbol
->typeAsString());
433 // Print any initial value if any.
435 OS
<< " = " << formattedName(getValue());
438 if (Full
&& options().getPrintFormatting()) {
439 if (getLinkageNameIndex())
440 printLinkageName(OS
, Full
, const_cast<LVSymbol
*>(this));
441 if (LVSymbol
*Reference
= getReference())
442 Reference
->printReference(OS
, Full
, const_cast<LVSymbol
*>(this));
444 // Print location information.
445 LVLocation::print(Locations
.get(), OS
, Full
);