xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/LogicalView/Core/LVLocation.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- LVLocation.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 LVOperation and LVLocation classes, which are used
10 // to describe variable locations.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H
15 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H
16 
17 #include "llvm/DebugInfo/LogicalView/Core/LVObject.h"
18 #include "llvm/Support/Compiler.h"
19 
20 namespace llvm {
21 namespace logicalview {
22 
23 using LVLineRange = std::pair<LVLine *, LVLine *>;
24 
25 // The DW_AT_data_member_location attribute is a simple member offset.
26 const LVSmall LVLocationMemberOffset = 0;
27 
28 class LVOperation final {
29   // To describe an operation:
30   // OpCode
31   // Operands[0]: First operand.
32   // Operands[1]: Second operand.
33   //   OP_bregx, OP_bit_piece, OP_[GNU_]const_type,
34   //   OP_[GNU_]deref_type, OP_[GNU_]entry_value, OP_implicit_value,
35   //   OP_[GNU_]implicit_pointer, OP_[GNU_]regval_type, OP_xderef_type.
36   LVSmall Opcode = 0;
37   SmallVector<uint64_t> Operands;
38 
39 public:
40   LVOperation() = delete;
LVOperation(LVSmall Opcode,ArrayRef<LVUnsigned> Operands)41   LVOperation(LVSmall Opcode, ArrayRef<LVUnsigned> Operands)
42       : Opcode(Opcode), Operands(Operands) {}
43   LVOperation(const LVOperation &) = delete;
44   LVOperation &operator=(const LVOperation &) = delete;
45   ~LVOperation() = default;
46 
getOpcode()47   LVSmall getOpcode() const { return Opcode; }
48   LLVM_ABI std::string getOperandsDWARFInfo();
49   LLVM_ABI std::string getOperandsCodeViewInfo();
50 
51   LLVM_ABI void print(raw_ostream &OS, bool Full = true) const;
52 
53 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump()54   void dump() const { print(dbgs()); }
55 #endif
56 };
57 
58 class LLVM_ABI LVLocation : public LVObject {
59   enum class Property {
60     IsAddressRange,
61     IsBaseClassOffset,
62     IsBaseClassStep,
63     IsClassOffset,
64     IsFixedAddress,
65     IsLocationSimple,
66     IsGapEntry,
67     IsOperation,
68     IsOperationList,
69     IsRegister,
70     IsStackOffset,
71     IsDiscardedRange,
72     IsInvalidRange,
73     IsInvalidLower,
74     IsInvalidUpper,
75     IsCallSite,
76     LastEntry
77   };
78   // Typed bitvector with properties for this location.
79   LVProperties<Property> Properties;
80 
81   // True if the location it is associated with a debug range.
hasAssociatedRange()82   bool hasAssociatedRange() const {
83     return !getIsClassOffset() && !getIsDiscardedRange();
84   }
85 
86 protected:
87   // Line numbers associated with locations ranges.
88   LVLine *LowerLine = nullptr;
89   LVLine *UpperLine = nullptr;
90 
91   // Active range:
92   // LowPC: an offset from an applicable base address, not a PC value.
93   // HighPC: an offset from an applicable base address, or a length.
94   LVAddress LowPC = 0;
95   LVAddress HighPC = 0;
96 
97   void setKind();
98 
99 public:
LVLocation()100   LVLocation() : LVObject() { setIsLocation(); }
101   LVLocation(const LVLocation &) = delete;
102   LVLocation &operator=(const LVLocation &) = delete;
103   virtual ~LVLocation() = default;
104 
105   PROPERTY(Property, IsAddressRange);
106   PROPERTY(Property, IsBaseClassOffset);
107   PROPERTY(Property, IsBaseClassStep);
108   PROPERTY_1(Property, IsClassOffset, IsLocationSimple);
109   PROPERTY_1(Property, IsFixedAddress, IsLocationSimple);
110   PROPERTY(Property, IsLocationSimple);
111   PROPERTY(Property, IsGapEntry);
112   PROPERTY(Property, IsOperationList);
113   PROPERTY(Property, IsOperation);
114   PROPERTY(Property, IsRegister);
115   PROPERTY_1(Property, IsStackOffset, IsLocationSimple);
116   PROPERTY(Property, IsDiscardedRange);
117   PROPERTY(Property, IsInvalidRange);
118   PROPERTY(Property, IsInvalidLower);
119   PROPERTY(Property, IsInvalidUpper);
120   PROPERTY(Property, IsCallSite);
121 
122   const char *kind() const override;
123   // Mark the locations that have only DW_OP_fbreg as stack offset based.
updateKind()124   virtual void updateKind() {}
125 
126   // Line numbers for locations.
getLowerLine()127   const LVLine *getLowerLine() const { return LowerLine; }
setLowerLine(LVLine * Line)128   void setLowerLine(LVLine *Line) { LowerLine = Line; }
getUpperLine()129   const LVLine *getUpperLine() const { return UpperLine; }
setUpperLine(LVLine * Line)130   void setUpperLine(LVLine *Line) { UpperLine = Line; }
131 
132   // Addresses for locations.
getLowerAddress()133   LVAddress getLowerAddress() const override { return LowPC; }
setLowerAddress(LVAddress Address)134   void setLowerAddress(LVAddress Address) override { LowPC = Address; }
getUpperAddress()135   LVAddress getUpperAddress() const override { return HighPC; }
setUpperAddress(LVAddress Address)136   void setUpperAddress(LVAddress Address) override { HighPC = Address; }
137 
138   std::string getIntervalInfo() const;
139 
140   bool validateRanges();
141 
142   // In order to calculate a symbol coverage (percentage), take the ranges
143   // and obtain the number of units (bytes) covered by those ranges. We can't
144   // use the line numbers, because they can be zero or invalid.
145   // We return:
146   //   false: No locations or multiple locations.
147   //   true: a single location.
148   static bool calculateCoverage(LVLocations *Locations, unsigned &Factor,
149                                 float &Percentage);
150 
addObject(LVAddress LowPC,LVAddress HighPC,LVUnsigned SectionOffset,uint64_t LocDescOffset)151   virtual void addObject(LVAddress LowPC, LVAddress HighPC,
152                          LVUnsigned SectionOffset, uint64_t LocDescOffset) {}
addObject(LVSmall Opcode,ArrayRef<LVUnsigned> Operands)153   virtual void addObject(LVSmall Opcode, ArrayRef<LVUnsigned> Operands) {}
154 
155   static void print(LVLocations *Locations, raw_ostream &OS, bool Full = true);
156   void printInterval(raw_ostream &OS, bool Full = true) const;
157   void printRaw(raw_ostream &OS, bool Full = true) const;
158   virtual void printRawExtra(raw_ostream &OS, bool Full = true) const {}
159 
160   void print(raw_ostream &OS, bool Full = true) const override;
161   void printExtra(raw_ostream &OS, bool Full = true) const override;
162 };
163 
164 class LLVM_ABI LVLocationSymbol final : public LVLocation {
165   // Location descriptors for the active range.
166   std::unique_ptr<LVOperations> Entries;
167 
168   void updateKind() override;
169 
170 public:
LVLocationSymbol()171   LVLocationSymbol() : LVLocation() {}
172   LVLocationSymbol(const LVLocationSymbol &) = delete;
173   LVLocationSymbol &operator=(const LVLocationSymbol &) = delete;
174   ~LVLocationSymbol() = default;
175 
176   void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset,
177                  uint64_t LocDescOffset) override;
178   void addObject(LVSmall Opcode, ArrayRef<LVUnsigned> Operands) override;
179 
180   void printRawExtra(raw_ostream &OS, bool Full = true) const override;
181   void printExtra(raw_ostream &OS, bool Full = true) const override;
182 };
183 
184 } // end namespace logicalview
185 } // end namespace llvm
186 
187 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLOCATION_H
188