xref: /llvm-project/llvm/lib/DebugInfo/LogicalView/Core/LVSymbol.cpp (revision e28b9357b14c84f1b48646b64eed01fb19dad250)
1 //===-- LVSymbol.cpp ------------------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This implements the LVSymbol class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
14 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
15 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
16 
17 using namespace llvm;
18 using namespace llvm::logicalview;
19 
20 #define DEBUG_TYPE "Symbol"
21 
22 namespace {
23 const char *const KindCallSiteParameter = "CallSiteParameter";
24 const char *const KindConstant = "Constant";
25 const char *const KindInherits = "Inherits";
26 const char *const KindMember = "Member";
27 const char *const KindParameter = "Parameter";
28 const char *const KindUndefined = "Undefined";
29 const char *const KindUnspecified = "Unspecified";
30 const char *const KindVariable = "Variable";
31 } // end anonymous namespace
32 
33 // Return a string representation for the symbol kind.
34 const char *LVSymbol::kind() const {
35   const char *Kind = KindUndefined;
36   if (getIsCallSiteParameter())
37     Kind = KindCallSiteParameter;
38   else if (getIsConstant())
39     Kind = KindConstant;
40   else if (getIsInheritance())
41     Kind = KindInherits;
42   else if (getIsMember())
43     Kind = KindMember;
44   else if (getIsParameter())
45     Kind = KindParameter;
46   else if (getIsUnspecified())
47     Kind = KindUnspecified;
48   else if (getIsVariable())
49     Kind = KindVariable;
50   return Kind;
51 }
52 
53 void LVSymbol::resolveName() {
54   if (getIsResolvedName())
55     return;
56   setIsResolvedName();
57 
58   LVElement::resolveName();
59 }
60 
61 void LVSymbol::resolveReferences() {
62   // The symbols can have the following references to other elements:
63   //   A Type:
64   //     DW_AT_type             ->  Type or Scope
65   //     DW_AT_import           ->  Type
66   //   A Reference:
67   //     DW_AT_specification    ->  Symbol
68   //     DW_AT_abstract_origin  ->  Symbol
69   //     DW_AT_extension        ->  Symbol
70 
71   // Resolve any referenced symbol.
72   LVSymbol *Reference = getReference();
73   if (Reference) {
74     Reference->resolve();
75     // Recursively resolve the symbol names.
76     resolveReferencesChain();
77   }
78 
79   // Set the file/line information using the Debug Information entry.
80   setFile(Reference);
81 
82   // Resolve symbol type.
83   if (LVElement *Element = getType()) {
84     Element->resolve();
85 
86     // In the case of demoted typedefs, use the underlying type.
87     if (Element->getIsTypedefReduced()) {
88       Element = Element->getType();
89       Element->resolve();
90     }
91 
92     // If the type is a template parameter, get its type, which can
93     // point to a type or scope, depending on the argument instance.
94     setGenericType(Element);
95   }
96 
97   // Resolve the variable associated type.
98   if (!getType() && Reference)
99     setType(Reference->getType());
100 }
101 
102 StringRef LVSymbol::resolveReferencesChain() {
103   // If the symbol have a DW_AT_specification or DW_AT_abstract_origin,
104   // follow the chain to resolve the name from those references.
105   if (getHasReference() && !isNamed())
106     setName(getReference()->resolveReferencesChain());
107 
108   return getName();
109 }
110 
111 void LVSymbol::print(raw_ostream &OS, bool Full) const {
112   if (getIncludeInPrint() && getReader().doPrintSymbol(this)) {
113     getReaderCompileUnit()->incrementPrintedSymbols();
114     LVElement::print(OS, Full);
115     printExtra(OS, Full);
116   }
117 }
118 
119 void LVSymbol::printExtra(raw_ostream &OS, bool Full) const {
120   // Accessibility depends on the parent (class, structure).
121   uint32_t AccessCode = 0;
122   if (getIsMember() || getIsInheritance())
123     AccessCode = getParentScope()->getIsClass() ? dwarf::DW_ACCESS_private
124                                                 : dwarf::DW_ACCESS_public;
125 
126   const LVSymbol *Symbol = getIsInlined() ? Reference : this;
127   std::string Attributes =
128       Symbol->getIsCallSiteParameter()
129           ? ""
130           : formatAttributes(Symbol->externalString(),
131                              Symbol->accessibilityString(AccessCode),
132                              virtualityString());
133 
134   OS << formattedKind(Symbol->kind()) << " " << Attributes;
135   if (Symbol->getIsUnspecified())
136     OS << formattedName(Symbol->getName());
137   else {
138     if (Symbol->getIsInheritance())
139       OS << Symbol->typeOffsetAsString()
140          << formattedNames(Symbol->getTypeQualifiedName(),
141                            Symbol->typeAsString());
142     else {
143       OS << formattedName(Symbol->getName());
144       // Print any bitfield information.
145       if (uint32_t Size = getBitSize())
146         OS << ":" << Size;
147       OS << " -> " << Symbol->typeOffsetAsString()
148          << formattedNames(Symbol->getTypeQualifiedName(),
149                            Symbol->typeAsString());
150     }
151   }
152 
153   // Print any initial value if any.
154   if (ValueIndex)
155     OS << " = " << formattedName(getValue());
156   OS << "\n";
157 
158   if (Full && options().getPrintFormatting()) {
159     if (getLinkageNameIndex())
160       printLinkageName(OS, Full, const_cast<LVSymbol *>(this));
161     if (LVSymbol *Reference = getReference())
162       Reference->printReference(OS, Full, const_cast<LVSymbol *>(this));
163   }
164 }
165