26 std::vector<Desc> Descriptions;
27 Descriptions.resize(0xff);
70 for (
uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
72 for (
uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
74 for (
uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
90 Descriptions[DW_OP_implicit_value] =
93 Descriptions[DW_OP_WASM_location] =
103 Descriptions[DW_OP_regval_type] =
114 if (Opcode >= Descriptions.
size())
116 return Descriptions[Opcode];
125 static constexpr unsigned LlvmUserDescriptionsSize = 1
126#define HANDLE_DW_OP_LLVM_USEROP(ID, NAME) +1
127#include "llvm/BinaryFormat/Dwarf.def"
129 std::vector<Desc> Descriptions;
130 Descriptions.resize(LlvmUserDescriptionsSize);
136 assert(Opcode == DW_OP_LLVM_user);
143 std::optional<DwarfFormat>
Format) {
153 for (
unsigned Operand = 0; Operand <
Desc.
Op.
size(); ++Operand) {
159 assert(Operand == 0 &&
"SubOp operand must be the first operand");
165 "SizeSubOpLEB Description must begin with SizeSubOpLEB operand");
170 Operands[Operand] = (int8_t)Operands[Operand];
175 Operands[Operand] = (int16_t)Operands[Operand];
180 Operands[Operand] = (int32_t)Operands[Operand];
186 Operands[Operand] =
Data.getUnsigned(&
Offset, AddressSize);
205 switch (Operands[0]) {
224 Operands[Operand] =
Offset;
225 Offset += Operands[Operand - 1];
231 OperandEndOffsets[Operand] =
Offset;
243 auto Die = U->getDIEForOffset(U->getOffset() +
Operands[Operand]);
244 if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
250 OS <<
" \"" << *
Name <<
"\"";
252 OS <<
format(
" <invalid base_type ref: 0x%" PRIx64
">",
267 if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
268 Opcode == DW_OP_regval_type)
270 else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
271 DwarfRegNum = Opcode - DW_OP_breg0;
273 DwarfRegNum = Opcode - DW_OP_reg0;
277 if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
278 Opcode == DW_OP_bregx)
283 if (Opcode == DW_OP_regval_type)
301 OS <<
"<decoding error>";
306 assert(!
Name.empty() &&
"DW_OP has no name!");
309 if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
310 (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
311 Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
312 Opcode == DW_OP_regval_type)
316 for (
unsigned Operand = 0; Operand <
Desc.
Op.
size(); ++Operand) {
322 assert(!SubName.
empty() &&
"DW_OP SubOp has no name!");
323 OS <<
" " << SubName;
328 if (Opcode == DW_OP_convert &&
Operands[Operand] == 0)
346 for (
unsigned i = 0; i <
Operands[Operand - 1]; ++i)
351 else if (Opcode != DW_OP_entry_value &&
352 Opcode != DW_OP_GNU_entry_value)
363 if (
Data.getData().empty())
366 for (
auto &
Op : *
this) {
367 DumpOpts.
IsEH = IsEH;
370 while (FailOffset <
Data.getData().size())
383 if (EntryValExprSize) {
385 if (EntryValExprSize == 0)
395 for (
unsigned Operand = 0; Operand <
Op.Desc.
Op.
size(); ++Operand) {
396 unsigned Size =
Op.Desc.
Op[Operand];
403 if (
Op.Opcode == DW_OP_convert &&
Op.Operands[Operand] == 0)
405 auto Die = U->getDIEForOffset(U->getOffset() +
Op.Operands[Operand]);
406 if (!Die || Die.getTag() != dwarf::DW_TAG_base_type)
415 for (
auto &
Op : *
this)
447 case dwarf::DW_OP_regx: {
451 auto RegName = GetNameForDWARFReg(DwarfRegNum,
false);
458 case dwarf::DW_OP_bregx: {
461 auto RegName = GetNameForDWARFReg(DwarfRegNum,
false);
470 case dwarf::DW_OP_entry_value:
471 case dwarf::DW_OP_GNU_entry_value: {
484 case dwarf::DW_OP_stack_value: {
491 case dwarf::DW_OP_nop: {
494 case dwarf::DW_OP_LLVM_user: {
499 if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
502 uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
503 auto RegName = GetNameForDWARFReg(DwarfRegNum,
false);
508 }
else if (Opcode >= dwarf::DW_OP_breg0 &&
509 Opcode <= dwarf::DW_OP_breg31) {
510 int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
512 auto RegName = GetNameForDWARFReg(DwarfRegNum,
false);
523 << (int)Opcode <<
")>";
531 if (Stack.size() != 1) {
532 OS <<
"<stack of size " << Stack.size() <<
", expected 1>";
537 OS <<
"[" << Stack.front().String <<
"]";
539 OS << Stack.front().String;
551 if (AddressSize !=
RHS.AddressSize || Format !=
RHS.Format)
553 return Data.getData() ==
RHS.Data.getData();
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallString class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
This class represents an Operation in the Expression.
std::optional< unsigned > getSubCode() const
@ DwarfNA
Serves as a marker for unused entries.
static bool verify(const Operation &Op, DWARFUnit *U)
Verify Op. Does not affect the return of isError().
bool print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, DWARFUnit *U) const
uint64_t getEndOffset() const
@ SizeSubOpLEB
The operand is a ULEB128 encoded SubOpcode.
@ SizeBlock
Preceding operand contains block size.
uint64_t getRawOperand(unsigned Idx) const
An iterator to go through the expression operations.
bool verify(DWARFUnit *U)
bool printCompact(raw_ostream &OS, std::function< StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg=nullptr)
Print the expression in a format intended to be compact and useful to a user, but not perfectly unamb...
bool operator==(const DWARFExpression &RHS) const
void print(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFUnit *U, bool IsEH=false) const
static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, uint8_t Opcode, const ArrayRef< uint64_t > Operands)
Lightweight error class with error context and mandatory checking.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an SmallVector or SmallString.
StringRef SubOperationEncodingString(unsigned OpEncoding, unsigned SubOpEncoding)
StringRef OperationEncodingString(unsigned Encoding)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
uint8_t getDwarfOffsetByteSize(DwarfFormat Format)
The size of a reference determined by the DWARF 32/64-bit format.
This is an optimization pass for GlobalISel generic memory operations.
static Desc getSubOpDesc(unsigned Opcode, unsigned SubOpcode)
static std::vector< Desc > getOpDescriptions()
static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, const DWARFExpression::iterator E, std::function< StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg=nullptr)
static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS, DIDumpOptions DumpOpts, ArrayRef< uint64_t > Operands, unsigned Operand)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
static Desc getDescImpl(ArrayRef< Desc > Descriptions, unsigned Opcode)
DWARFExpression::Operation Op
static Desc getOpDesc(unsigned Opcode)
static std::vector< Desc > getSubOpDescriptions()
Container for dump options that control which debug information will be dumped.
std::function< llvm::StringRef(uint64_t DwarfRegNum, bool IsEH)> GetNameForDWARFReg
Description of the encoding of one expression Op.
DwarfVersion Version
Dwarf version where the Op was introduced.
SmallVector< Encoding > Op
Encoding for Op operands.
A user-facing string representation of a DWARF expression.
PrintedExpr(ExprKind K=Address)