1 //===-- LVSymbol.h ----------------------------------------------*- C++ -*-===//
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 file defines the LVSymbol class, which is used to describe a debug
10 // information symbol.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSYMBOL_H
15 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSYMBOL_H
16 
17 #include "llvm/DebugInfo/LogicalView/Core/LVElement.h"
18 
19 namespace llvm {
20 namespace logicalview {
21 
22 enum class LVSymbolKind {
23   IsCallSiteParameter,
24   IsConstant,
25   IsInheritance,
26   IsMember,
27   IsParameter,
28   IsUnspecified,
29   IsVariable,
30   LastEntry
31 };
32 using LVSymbolKindSet = std::set<LVSymbolKind>;
33 using LVSymbolDispatch = std::map<LVSymbolKind, LVSymbolGetFunction>;
34 using LVSymbolRequest = std::vector<LVSymbolGetFunction>;
35 
36 class LVSymbol final : public LVElement {
37   enum class Property { HasLocation, FillGaps, LastEntry };
38 
39   // Typed bitvector with kinds and properties for this symbol.
40   LVProperties<LVSymbolKind> Kinds;
41   LVProperties<Property> Properties;
42   static LVSymbolDispatch Dispatch;
43 
44   // CodeView symbol Linkage name.
45   size_t LinkageNameIndex = 0;
46 
47   // Reference to DW_AT_specification, DW_AT_abstract_origin attribute.
48   LVSymbol *Reference = nullptr;
49   LVAutoLocations *Locations = nullptr;
50   LVLocation *CurrentLocation = nullptr;
51 
52   // Bitfields length.
53   uint32_t BitSize = 0;
54 
55   // Index in the String pool representing any initial value.
56   size_t ValueIndex = 0;
57 
58   // Coverage factor in units (bytes).
59   unsigned CoverageFactor = 0;
60   float CoveragePercentage = 0;
61 
62   // Add a location gap into the location list.
63   LVAutoLocations::iterator addLocationGap(LVAutoLocations::iterator Pos,
64                                            LVAddress LowPC, LVAddress HighPC);
65 
66   // Find the current symbol in the given 'Targets'.
67   LVSymbol *findIn(const LVSymbols *Targets) const;
68 
69 public:
70   LVSymbol() : LVElement(LVSubclassID::LV_SYMBOL) {
71     setIsSymbol();
72     setIncludeInPrint();
73   }
74   LVSymbol(const LVSymbol &) = delete;
75   LVSymbol &operator=(const LVSymbol &) = delete;
76   ~LVSymbol() { delete Locations; }
77 
78   static bool classof(const LVElement *Element) {
79     return Element->getSubclassID() == LVSubclassID::LV_SYMBOL;
80   }
81 
82   KIND(LVSymbolKind, IsCallSiteParameter);
83   KIND(LVSymbolKind, IsConstant);
84   KIND(LVSymbolKind, IsInheritance);
85   KIND(LVSymbolKind, IsMember);
86   KIND(LVSymbolKind, IsParameter);
87   KIND(LVSymbolKind, IsUnspecified);
88   KIND(LVSymbolKind, IsVariable);
89 
90   PROPERTY(Property, HasLocation);
91   PROPERTY(Property, FillGaps);
92 
93   const char *kind() const override;
94 
95   // Access DW_AT_specification, DW_AT_abstract_origin reference.
96   LVSymbol *getReference() const { return Reference; }
97   void setReference(LVSymbol *Symbol) override {
98     Reference = Symbol;
99     setHasReference();
100   }
101   void setReference(LVElement *Element) override {
102     assert((!Element || isa<LVSymbol>(Element)) && "Invalid element");
103     setReference(static_cast<LVSymbol *>(Element));
104   }
105 
106   void setLinkageName(StringRef LinkageName) override {
107     LinkageNameIndex = getStringPool().getIndex(LinkageName);
108   }
109   StringRef getLinkageName() const override {
110     return getStringPool().getString(LinkageNameIndex);
111   }
112   size_t getLinkageNameIndex() const override { return LinkageNameIndex; }
113 
114   uint32_t getBitSize() const override { return BitSize; }
115   void setBitSize(uint32_t Size) override { BitSize = Size; }
116 
117   // Process the values for a DW_AT_const_value.
118   std::string getValue() const override {
119     return std::string(getStringPool().getString(ValueIndex));
120   }
121   void setValue(StringRef Value) override {
122     ValueIndex = getStringPool().getIndex(Value);
123   }
124   size_t getValueIndex() const override { return ValueIndex; }
125 
126   // Add a Location Entry.
127   void addLocationConstant(dwarf::Attribute Attr, LVUnsigned Constant,
128                            uint64_t LocDescOffset);
129   void addLocationOperands(LVSmall Opcode, uint64_t Operand1,
130                            uint64_t Operand2);
131   void addLocation(dwarf::Attribute Attr, LVAddress LowPC, LVAddress HighPC,
132                    LVUnsigned SectionOffset, uint64_t LocDescOffset,
133                    bool CallSiteLocation = false);
134 
135   // Fill gaps in the location list.
136   void fillLocationGaps();
137 
138   // Get all the locations associated with symbols.
139   void getLocations(LVLocations &LocationList, LVValidLocation ValidLocation,
140                     bool RecordInvalid = false);
141   void getLocations(LVLocations &LocationList) const;
142 
143   // Calculate coverage factor.
144   void calculateCoverage();
145 
146   unsigned getCoverageFactor() const { return CoverageFactor; }
147   void setCoverageFactor(unsigned Value) { CoverageFactor = Value; }
148   float getCoveragePercentage() const { return CoveragePercentage; }
149   void setCoveragePercentage(float Value) { CoveragePercentage = Value; }
150 
151   // Print location in raw format.
152   void printLocations(raw_ostream &OS, bool Full = true) const;
153 
154   // Follow a chain of references given by DW_AT_abstract_origin and/or
155   // DW_AT_specification and update the symbol name.
156   StringRef resolveReferencesChain();
157 
158   void resolveName() override;
159   void resolveReferences() override;
160 
161   static LVSymbolDispatch &getDispatch() { return Dispatch; }
162 
163   static bool parametersMatch(const LVSymbols *References,
164                               const LVSymbols *Targets);
165 
166   static void getParameters(const LVSymbols *Symbols, LVSymbols *Parameters);
167 
168   // Iterate through the 'References' set and check that all its elements
169   // are present in the 'Targets' set. For a missing element, mark its
170   // parents as missing.
171   static void markMissingParents(const LVSymbols *References,
172                                  const LVSymbols *Targets);
173 
174   // Returns true if current type is logically equal to the given 'Symbol'.
175   bool equals(const LVSymbol *Symbol) const;
176 
177   // Returns true if the given 'References' are logically equal to the
178   // given 'Targets'.
179   static bool equals(const LVSymbols *References, const LVSymbols *Targets);
180 
181   // Report the current symbol as missing or added during comparison.
182   void report(LVComparePass Pass) override;
183 
184   void print(raw_ostream &OS, bool Full = true) const override;
185   void printExtra(raw_ostream &OS, bool Full = true) const override;
186 
187 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
188   void dump() const override { print(dbgs()); }
189 #endif
190 };
191 
192 } // end namespace logicalview
193 } // end namespace llvm
194 
195 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSYMBOL_H
196