21#define DEBUG_TYPE "Location"
35 if (dwarf::DW_OP_lit0 <=
Code &&
Code <= dwarf::DW_OP_lit31) {
36 Stream <<
format(
"lit%d",
Code - dwarf::DW_OP_lit0);
43 if (dwarf::DW_OP_breg0 <=
Code &&
Code <= dwarf::DW_OP_breg31) {
45 Stream <<
format(
"breg%d+%d%s",
Code - dwarf::DW_OP_breg0, Operands[0],
46 RegisterName.c_str());
53 if (dwarf::DW_OP_reg0 <=
Code &&
Code <= dwarf::DW_OP_reg31) {
55 Stream <<
format(
"reg%d%s",
Code - dwarf::DW_OP_reg0,
56 RegisterName.c_str());
68 case dwarf::DW_OP_addr:
69 Stream <<
"addr " <<
hexString(Operands[0]);
71 case dwarf::DW_OP_constu:
72 case dwarf::DW_OP_const1u:
73 case dwarf::DW_OP_const2u:
74 case dwarf::DW_OP_const4u:
75 case dwarf::DW_OP_const8u:
76 Stream <<
"const_u " <<
unsigned(Operands[0]);
78 case dwarf::DW_OP_consts:
79 case dwarf::DW_OP_const1s:
80 case dwarf::DW_OP_const2s:
81 case dwarf::DW_OP_const4s:
82 case dwarf::DW_OP_const8s:
83 Stream <<
"const_s " << int(Operands[0]);
85 case dwarf::DW_OP_addrx:
86 Stream <<
"addrx " <<
unsigned(Operands[0]);
88 case dwarf::DW_OP_constx:
89 Stream <<
"constx " <<
unsigned(Operands[0]);
91 case dwarf::DW_OP_const_type:
92 Stream <<
"TODO: DW_OP_const_type";
98 case dwarf::DW_OP_fbreg:
99 Stream <<
"fbreg " << int(Operands[0]);
101 case dwarf::DW_OP_bregx: {
103 Stream <<
format(
"bregx %d%s+%d", Operands[0], RegisterName.c_str(),
104 unsigned(Operands[1]));
107 case dwarf::DW_OP_regval_type: {
109 Stream <<
format(
"regval_type %d%s+%d", Operands[0], RegisterName.c_str(),
110 unsigned(Operands[1]));
117 case dwarf::DW_OP_dup:
120 case dwarf::DW_OP_drop:
123 case dwarf::DW_OP_pick:
124 Stream <<
"pick " <<
unsigned(Operands[0]);
126 case dwarf::DW_OP_over:
129 case dwarf::DW_OP_swap:
132 case dwarf::DW_OP_rot:
135 case dwarf::DW_OP_deref:
138 case dwarf::DW_OP_deref_size:
139 Stream <<
"deref_size " <<
unsigned(Operands[0]);
141 case dwarf::DW_OP_deref_type:
142 Stream <<
"deref_type " <<
unsigned(Operands[0]) <<
" DIE offset "
145 case dwarf::DW_OP_xderef:
148 case dwarf::DW_OP_xderef_size:
149 Stream <<
"xderef_size " <<
unsigned(Operands[0]);
151 case dwarf::DW_OP_xderef_type:
152 Stream <<
"xderef_type " <<
unsigned(Operands[0]) <<
" DIE offset "
155 case dwarf::DW_OP_push_object_address:
156 Stream <<
"push_object_address";
158 case dwarf::DW_OP_form_tls_address:
159 Stream <<
"form_tls_address " <<
hexString(Operands[0]);
161 case dwarf::DW_OP_call_frame_cfa:
162 Stream <<
"call_frame_cfa";
168 case dwarf::DW_OP_abs:
171 case dwarf::DW_OP_and:
174 case dwarf::DW_OP_div:
177 case dwarf::DW_OP_minus:
180 case dwarf::DW_OP_mod:
183 case dwarf::DW_OP_mul:
186 case dwarf::DW_OP_neg:
189 case dwarf::DW_OP_not:
192 case dwarf::DW_OP_or:
195 case dwarf::DW_OP_plus:
198 case dwarf::DW_OP_plus_uconst:
199 Stream <<
"plus_uconst " <<
unsigned(Operands[0]);
201 case dwarf::DW_OP_shl:
204 case dwarf::DW_OP_shr:
207 case dwarf::DW_OP_shra:
210 case dwarf::DW_OP_xor:
217 case dwarf::DW_OP_le:
220 case dwarf::DW_OP_ge:
223 case dwarf::DW_OP_eq:
226 case dwarf::DW_OP_lt:
229 case dwarf::DW_OP_gt:
232 case dwarf::DW_OP_ne:
235 case dwarf::DW_OP_skip:
236 Stream <<
"skip " << signed(Operands[0]);
238 case dwarf::DW_OP_bra:
239 Stream <<
"bra " << signed(Operands[0]);
241 case dwarf::DW_OP_call2:
242 Stream <<
"call2 DIE offset " <<
hexString(Operands[0]);
244 case dwarf::DW_OP_call4:
245 Stream <<
"call4 DIE offset " <<
hexString(Operands[0]);
247 case dwarf::DW_OP_call_ref:
248 Stream <<
"call_ref DIE offset " <<
hexString(Operands[0]);
254 case dwarf::DW_OP_convert:
255 Stream <<
"convert DIE offset " <<
hexString(Operands[0]);
257 case dwarf::DW_OP_reinterpret:
258 Stream <<
"reinterpret DIE offset " <<
hexString(Operands[0]);
264 case dwarf::DW_OP_nop:
267 case dwarf::DW_OP_entry_value:
268 Stream <<
"TODO: DW_OP_entry_value";
274 case dwarf::DW_OP_regx:
281 case dwarf::DW_OP_stack_value:
282 Stream <<
"stack_value";
284 case dwarf::DW_OP_implicit_value:
285 Stream <<
"TODO: DW_OP_implicit_value";
287 case dwarf::DW_OP_implicit_pointer:
288 Stream <<
"implicit_pointer DIE offset " <<
hexString(Operands[0]) <<
" "
295 case dwarf::DW_OP_piece:
296 Stream <<
"piece " << int(Operands[0]);
298 case dwarf::DW_OP_bit_piece:
299 Stream <<
"bit_piece " << int(Operands[0]) <<
" offset "
306 case dwarf::DW_OP_GNU_entry_value:
307 Stream <<
"gnu_entry_value ";
308 PrintRegisterInfo(dwarf::DW_OP_reg0);
310 case dwarf::DW_OP_GNU_push_tls_address:
311 Stream <<
"gnu_push_tls_address " <<
hexString(Operands[0]);
313 case dwarf::DW_OP_GNU_addr_index:
314 Stream <<
"gnu_addr_index " <<
unsigned(Operands[0]);
316 case dwarf::DW_OP_GNU_const_index:
317 Stream <<
"gnu_const_index " <<
unsigned(Operands[0]);
324 Stream <<
"offset " << int(Operands[0]);
338 PrintRegisterInfo(Opcode);
354 switch (OperationCode) {
356 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL:
357 Stream <<
"frame_pointer_rel " << int(Operands[0]);
359 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
360 Stream <<
"frame_pointer_rel_full_scope " << int(Operands[0]);
364 case codeview::SymbolKind::S_DEFRANGE_REGISTER:
367 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER:
368 Stream <<
"subfield_register "
373 case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL:
375 <<
" offset " << int(Operands[1]);
379 case codeview::SymbolKind::S_DEFRANGE:
380 Stream <<
"frame " << int(Operands[0]);
382 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD:
383 Stream <<
"subfield " << int(Operands[0]);
396const char *
const KindBaseClassOffset =
"BaseClassOffset";
397const char *
const KindBaseClassStep =
"BaseClassStep";
398const char *
const KindClassOffset =
"ClassOffset";
399const char *
const KindFixedAddress =
"FixedAddress";
400const char *
const KindMissingInfo =
"Missing";
401const char *
const KindOperation =
"Operation";
402const char *
const KindOperationList =
"OperationList";
403const char *
const KindRegister =
"Register";
404const char *
const KindUndefined =
"Undefined";
411 const char *
Kind = KindUndefined;
412 if (getIsBaseClassOffset())
413 Kind = KindBaseClassOffset;
414 else if (getIsBaseClassStep())
415 Kind = KindBaseClassStep;
416 else if (getIsClassOffset())
417 Kind = KindClassOffset;
418 else if (getIsFixedAddress())
419 Kind = KindFixedAddress;
420 else if (getIsGapEntry())
421 Kind = KindMissingInfo;
422 else if (getIsOperation())
423 Kind = KindOperation;
424 else if (getIsOperationList())
425 Kind = KindOperationList;
426 else if (getIsRegister())
432 static const char *
const Question =
"?";
435 if (getIsAddressRange())
441 TheLine =
Line->lineNumberAsStringStripped();
442 Stream << TheLine.c_str();
453 if (
options().getAttributeOffset())
469 if (!hasAssociatedRange())
509 if (
Location->getIsLocationSimple()) {
522 LowerAddress =
Location->getLowerAddress();
523 UpperAddress =
Location->getUpperAddress();
524 Factor += (UpperAddress > LowerAddress) ? UpperAddress - LowerAddress
525 : LowerAddress - UpperAddress;
541 if (hasAssociatedRange())
568 setOffset(LocDescOffset ? LocDescOffset : SectionOffset);
572 setIsDiscardedRange();
582 Entries = std::make_unique<LVOperations>();
589 case dwarf::DW_AT_data_member_location:
592 case dwarf::DW_AT_location:
602 if (hasAssociatedRange())
606void LVLocationSymbol::updateKind() {
608 if (Entries && Entries->size() == 1) {
609 if (dwarf::DW_OP_fbreg == Entries->front()->getOpcode())
626 if (
options().getAttributeCoverage()) {
636 Stream <<
format(
"%.2f%%", Percentage);
637 if (!
Location->getIsLocationSimple())
646 if (
getReader().doPrintLocation(
nullptr))
654 OS <<
" -> CallSite";
659 if (
Full && Entries) {
661 std::stringstream Stream;
665 << (CodeViewLocation ?
Operation->getOperandsCodeViewInfo()
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
mir Rename Register Operands
PowerPC Reduce CR logical Operation
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
void printExtra(raw_ostream &OS, bool Full=true) const override
void printRawExtra(raw_ostream &OS, bool Full=true) const override
void addObject(LVAddress LowPC, LVAddress HighPC, LVUnsigned SectionOffset, uint64_t LocDescOffset) override
const char * kind() const override
static bool calculateCoverage(LVLocations *Locations, unsigned &Factor, float &Percentage)
void setUpperAddress(LVAddress Address) override
const LVLine * getLowerLine() const
void setUpperLine(LVLine *Line)
std::string getIntervalInfo() const
virtual void printRawExtra(raw_ostream &OS, bool Full=true) const
void printRaw(raw_ostream &OS, bool Full=true) const
LVAddress getLowerAddress() const override
const LVLine * getUpperLine() const
void printExtra(raw_ostream &OS, bool Full=true) const override
static void print(LVLocations *Locations, raw_ostream &OS, bool Full=true)
void setLowerLine(LVLine *Line)
LVAddress getUpperAddress() const override
void printInterval(raw_ostream &OS, bool Full=true) const
void setLowerAddress(LVAddress Address) override
LVScope * getParentScope() const
virtual void print(raw_ostream &OS, bool Full=true) const
void printAttributes(raw_ostream &OS, bool Full=true) const
dwarf::Attribute getAttr() const
LVSymbol * getParentSymbol() const
uint32_t getLineNumber() const
void setOffset(LVOffset DieOffset)
void print(raw_ostream &OS, bool Full=true) const
std::string getOperandsDWARFInfo()
std::string getOperandsCodeViewInfo()
virtual std::string getRegisterName(LVSmall Opcode, ArrayRef< uint64_t > Operands)
LVLineRange lineRange(LVLocation *Location) const
unsigned getCoverageFactor() const
float getCoveragePercentage() const
unsigned getCoverageFactor() const
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
std::string hexString(uint64_t Value, size_t Width=HEX_WIDTH)
std::pair< LVLine *, LVLine * > LVLineRange
uint16_t getCodeViewOperationCode(uint8_t Code)
LVScopeCompileUnit * getReaderCompileUnit()
const LVSmall LVLocationMemberOffset
This is an optimization pass for GlobalISel generic memory operations.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.