LLVM 23.0.0git
LVLocation.cpp
Go to the documentation of this file.
1//===-- LVLocation.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 LVOperation and LVLocation classes.
10//
11//===----------------------------------------------------------------------===//
12
17
18using namespace llvm;
19using namespace llvm::logicalview;
20
21#define DEBUG_TYPE "Location"
22
23void LVOperation::print(raw_ostream &OS, bool Full) const {}
24
25// Identify the most common type of operations and print them using a high
26// level format, trying to isolate the DWARF complexity.
28 std::string String;
30
31 auto PrintRegisterInfo = [&](LVSmall Code) {
32 //-----------------------------------------------------------------------
33 // 2.5.1.1 Literal encodings.
34 //-----------------------------------------------------------------------
35 if (dwarf::DW_OP_lit0 <= Code && Code <= dwarf::DW_OP_lit31) {
36 Stream << format("lit%d", Code - dwarf::DW_OP_lit0);
37 return;
38 }
39
40 //-----------------------------------------------------------------------
41 // 2.5.1.2 Register values.
42 //-----------------------------------------------------------------------
43 if (dwarf::DW_OP_breg0 <= Code && Code <= dwarf::DW_OP_breg31) {
44 std::string RegisterName(getReader().getRegisterName(Code, Operands));
45 Stream << format("breg%d+%d%s", Code - dwarf::DW_OP_breg0, Operands[0],
46 RegisterName.c_str());
47 return;
48 }
49
50 //-----------------------------------------------------------------------
51 // 2.6.1.1.3 Register location descriptions.
52 //-----------------------------------------------------------------------
53 if (dwarf::DW_OP_reg0 <= Code && Code <= dwarf::DW_OP_reg31) {
54 std::string RegisterName(getReader().getRegisterName(Code, Operands));
55 Stream << format("reg%d%s", Code - dwarf::DW_OP_reg0,
56 RegisterName.c_str());
57 return;
58 }
59
60 Stream << format("#0x%02x ", Code) << hexString(Operands[0]) << " "
61 << hexString(Operands[1]) << "#";
62 };
63
64 switch (Opcode) {
65 //-------------------------------------------------------------------------
66 // 2.5.1.1 Literal encodings.
67 //-------------------------------------------------------------------------
68 case dwarf::DW_OP_addr:
69 Stream << "addr " << hexString(Operands[0]);
70 break;
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]);
77 break;
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]);
84 break;
85 case dwarf::DW_OP_addrx:
86 Stream << "addrx " << unsigned(Operands[0]);
87 break;
88 case dwarf::DW_OP_constx:
89 Stream << "constx " << unsigned(Operands[0]);
90 break;
91 case dwarf::DW_OP_const_type:
92 Stream << "TODO: DW_OP_const_type";
93 break;
94
95 //-------------------------------------------------------------------------
96 // 2.5.1.2 Register values.
97 //-------------------------------------------------------------------------
98 case dwarf::DW_OP_fbreg:
99 Stream << "fbreg " << int(Operands[0]);
100 break;
101 case dwarf::DW_OP_bregx: {
102 std::string RegisterName(getReader().getRegisterName(Opcode, Operands));
103 Stream << format("bregx %d%s+%d", Operands[0], RegisterName.c_str(),
104 unsigned(Operands[1]));
105 break;
106 }
107 case dwarf::DW_OP_regval_type: {
108 std::string RegisterName(getReader().getRegisterName(Opcode, Operands));
109 Stream << format("regval_type %d%s+%d", Operands[0], RegisterName.c_str(),
110 unsigned(Operands[1]));
111 break;
112 }
113
114 //-------------------------------------------------------------------------
115 // 2.5.1.3 Stack operations.
116 //-------------------------------------------------------------------------
117 case dwarf::DW_OP_dup:
118 Stream << "dup";
119 break;
120 case dwarf::DW_OP_drop:
121 Stream << "drop";
122 break;
123 case dwarf::DW_OP_pick:
124 Stream << "pick " << unsigned(Operands[0]);
125 break;
126 case dwarf::DW_OP_over:
127 Stream << "over";
128 break;
129 case dwarf::DW_OP_swap:
130 Stream << "swap";
131 break;
132 case dwarf::DW_OP_rot:
133 Stream << "rot";
134 break;
135 case dwarf::DW_OP_deref:
136 Stream << "deref";
137 break;
138 case dwarf::DW_OP_deref_size:
139 Stream << "deref_size " << unsigned(Operands[0]);
140 break;
141 case dwarf::DW_OP_deref_type:
142 Stream << "deref_type " << unsigned(Operands[0]) << " DIE offset "
143 << hexString(Operands[1]);
144 break;
145 case dwarf::DW_OP_xderef:
146 Stream << "xderef";
147 break;
148 case dwarf::DW_OP_xderef_size:
149 Stream << "xderef_size " << unsigned(Operands[0]);
150 break;
151 case dwarf::DW_OP_xderef_type:
152 Stream << "xderef_type " << unsigned(Operands[0]) << " DIE offset "
153 << hexString(Operands[1]);
154 break;
155 case dwarf::DW_OP_push_object_address:
156 Stream << "push_object_address";
157 break;
158 case dwarf::DW_OP_form_tls_address:
159 Stream << "form_tls_address";
160 break;
161 case dwarf::DW_OP_call_frame_cfa:
162 Stream << "call_frame_cfa";
163 break;
164
165 //-------------------------------------------------------------------------
166 // 2.5.1.4 Arithmetic and Logical Operations.
167 //-------------------------------------------------------------------------
168 case dwarf::DW_OP_abs:
169 Stream << "abs";
170 break;
171 case dwarf::DW_OP_and:
172 Stream << "and";
173 break;
174 case dwarf::DW_OP_div:
175 Stream << "div";
176 break;
177 case dwarf::DW_OP_minus:
178 Stream << "minus";
179 break;
180 case dwarf::DW_OP_mod:
181 Stream << "mod";
182 break;
183 case dwarf::DW_OP_mul:
184 Stream << "mul";
185 break;
186 case dwarf::DW_OP_neg:
187 Stream << "neg";
188 break;
189 case dwarf::DW_OP_not:
190 Stream << "not";
191 break;
192 case dwarf::DW_OP_or:
193 Stream << "or";
194 break;
195 case dwarf::DW_OP_plus:
196 Stream << "plus";
197 break;
198 case dwarf::DW_OP_plus_uconst:
199 Stream << "plus_uconst " << unsigned(Operands[0]);
200 break;
201 case dwarf::DW_OP_shl:
202 Stream << "shl";
203 break;
204 case dwarf::DW_OP_shr:
205 Stream << "shr";
206 break;
207 case dwarf::DW_OP_shra:
208 Stream << "shra";
209 break;
210 case dwarf::DW_OP_xor:
211 Stream << "xor";
212 break;
213
214 //-------------------------------------------------------------------------
215 // 2.5.1.5 Control Flow Operations.
216 //-------------------------------------------------------------------------
217 case dwarf::DW_OP_le:
218 Stream << "le";
219 break;
220 case dwarf::DW_OP_ge:
221 Stream << "ge";
222 break;
223 case dwarf::DW_OP_eq:
224 Stream << "eq";
225 break;
226 case dwarf::DW_OP_lt:
227 Stream << "lt";
228 break;
229 case dwarf::DW_OP_gt:
230 Stream << "gt";
231 break;
232 case dwarf::DW_OP_ne:
233 Stream << "ne";
234 break;
235 case dwarf::DW_OP_skip:
236 Stream << "skip " << signed(Operands[0]);
237 break;
238 case dwarf::DW_OP_bra:
239 Stream << "bra " << signed(Operands[0]);
240 break;
241 case dwarf::DW_OP_call2:
242 Stream << "call2 DIE offset " << hexString(Operands[0]);
243 break;
244 case dwarf::DW_OP_call4:
245 Stream << "call4 DIE offset " << hexString(Operands[0]);
246 break;
247 case dwarf::DW_OP_call_ref:
248 Stream << "call_ref DIE offset " << hexString(Operands[0]);
249 break;
250
251 //-------------------------------------------------------------------------
252 // 2.5.1.6 Type Conversions.
253 //-------------------------------------------------------------------------
254 case dwarf::DW_OP_convert:
255 Stream << "convert DIE offset " << hexString(Operands[0]);
256 break;
257 case dwarf::DW_OP_reinterpret:
258 Stream << "reinterpret DIE offset " << hexString(Operands[0]);
259 break;
260
261 //-------------------------------------------------------------------------
262 // 2.5.1.7 Special Operations.
263 //-------------------------------------------------------------------------
264 case dwarf::DW_OP_nop:
265 Stream << "nop";
266 break;
267 case dwarf::DW_OP_entry_value:
268 Stream << "TODO: DW_OP_entry_value";
269 break;
270
271 //-------------------------------------------------------------------------
272 // 2.6.1.1.3 Register location descriptions.
273 //-------------------------------------------------------------------------
274 case dwarf::DW_OP_regx:
275 Stream << "regx" << getReader().getRegisterName(Opcode, Operands);
276 break;
277
278 //-------------------------------------------------------------------------
279 // 2.6.1.1.4 Implicit location descriptions.
280 //-------------------------------------------------------------------------
281 case dwarf::DW_OP_stack_value:
282 Stream << "stack_value";
283 break;
284 case dwarf::DW_OP_implicit_value:
285 Stream << "TODO: DW_OP_implicit_value";
286 break;
287 case dwarf::DW_OP_implicit_pointer:
288 Stream << "implicit_pointer DIE offset " << hexString(Operands[0]) << " "
289 << int(Operands[1]);
290 break;
291
292 //-------------------------------------------------------------------------
293 // 2.6.1.2 Composite location descriptions.
294 //-------------------------------------------------------------------------
295 case dwarf::DW_OP_piece:
296 Stream << "piece " << int(Operands[0]);
297 break;
298 case dwarf::DW_OP_bit_piece:
299 Stream << "bit_piece " << int(Operands[0]) << " offset "
300 << int(Operands[1]);
301 break;
302
303 //-------------------------------------------------------------------------
304 // GNU extensions.
305 //-------------------------------------------------------------------------
306 case dwarf::DW_OP_GNU_entry_value:
307 Stream << "gnu_entry_value ";
308 PrintRegisterInfo(dwarf::DW_OP_reg0);
309 break;
310 case dwarf::DW_OP_GNU_push_tls_address:
311 Stream << "gnu_push_tls_address";
312 break;
313 case dwarf::DW_OP_GNU_addr_index:
314 Stream << "gnu_addr_index " << unsigned(Operands[0]);
315 break;
316 case dwarf::DW_OP_GNU_const_index:
317 Stream << "gnu_const_index " << unsigned(Operands[0]);
318 break;
319
320 //-------------------------------------------------------------------------
321 // Member location.
322 //-------------------------------------------------------------------------
324 Stream << "offset " << int(Operands[0]);
325 break;
326
327 //-------------------------------------------------------------------------
328 // Missing location.
329 //-------------------------------------------------------------------------
331 Stream << "missing";
332 break;
333
334 //-------------------------------------------------------------------------
335 // Register values.
336 //-------------------------------------------------------------------------
337 default:
338 PrintRegisterInfo(Opcode);
339 break;
340 }
341
342 return String;
343}
344
345// Identify the most common type of operations and print them using a high
346// level format, trying to isolate the CodeView complexity.
348 std::string String;
350
351 // Get original CodeView operation code.
352 uint16_t OperationCode = getCodeViewOperationCode(Opcode);
353
354 switch (OperationCode) {
355 // Operands: [Offset].
356 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL:
357 Stream << "frame_pointer_rel " << int(Operands[0]);
358 break;
359 case codeview::SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
360 Stream << "frame_pointer_rel_full_scope " << int(Operands[0]);
361 break;
362
363 // Operands: [Register].
364 case codeview::SymbolKind::S_DEFRANGE_REGISTER:
365 Stream << "register " << getReader().getRegisterName(Opcode, Operands);
366 break;
367 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER:
368 Stream << "subfield_register "
369 << getReader().getRegisterName(Opcode, Operands);
370 break;
371
372 // Operands: [Register, Offset].
373 case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL:
374 Stream << "register_rel " << getReader().getRegisterName(Opcode, Operands)
375 << " offset " << int(Operands[1]);
376 break;
377 // Operands: [Register, Offset, OffsetInUdt].
378 case codeview::SymbolKind::S_DEFRANGE_REGISTER_REL_INDIR:
379 Stream << "register_rel_indir "
380 << getReader().getRegisterName(Opcode, Operands) << " offset "
381 << int(Operands[1]) << " offset_in_udt " << int(Operands[2]);
382 break;
383
384 // Operands: [Program].
385 case codeview::SymbolKind::S_DEFRANGE:
386 Stream << "frame " << int(Operands[0]);
387 break;
388 case codeview::SymbolKind::S_DEFRANGE_SUBFIELD:
389 Stream << "subfield " << int(Operands[0]);
390 break;
391
392 default:
393 Stream << format("#0x%02x: ", Opcode) << hexString(Operands[0]) << " "
394 << hexString(Operands[1]) << "#";
395 break;
396 }
397
398 return String;
399}
400
401namespace {
402const char *const KindBaseClassOffset = "BaseClassOffset";
403const char *const KindBaseClassStep = "BaseClassStep";
404const char *const KindClassOffset = "ClassOffset";
405const char *const KindFixedAddress = "FixedAddress";
406const char *const KindMissingInfo = "Missing";
407const char *const KindOperation = "Operation";
408const char *const KindOperationList = "OperationList";
409const char *const KindRegister = "Register";
410const char *const KindUndefined = "Undefined";
411} // end anonymous namespace
412
413//===----------------------------------------------------------------------===//
414// DWARF location information.
415//===----------------------------------------------------------------------===//
416const char *LVLocation::kind() const {
417 const char *Kind = KindUndefined;
418 if (getIsBaseClassOffset())
419 Kind = KindBaseClassOffset;
420 else if (getIsBaseClassStep())
421 Kind = KindBaseClassStep;
422 else if (getIsClassOffset())
423 Kind = KindClassOffset;
424 else if (getIsFixedAddress())
425 Kind = KindFixedAddress;
426 else if (getIsGapEntry())
427 Kind = KindMissingInfo;
428 else if (getIsOperation())
429 Kind = KindOperation;
430 else if (getIsOperationList())
431 Kind = KindOperationList;
432 else if (getIsRegister())
433 Kind = KindRegister;
434 return Kind;
435}
436
437std::string LVLocation::getIntervalInfo() const {
438 static const char *const Question = "?";
439 std::string String;
441 if (getIsAddressRange())
442 Stream << "{Range}";
443
444 auto PrintLine = [&](const LVLine *Line) {
445 if (Line) {
446 std::string TheLine;
447 TheLine = Line->lineNumberAsStringStripped();
448 Stream << TheLine.c_str();
449 } else {
450 Stream << Question;
451 }
452 };
453
454 Stream << " Lines ";
455 PrintLine(getLowerLine());
456 Stream << ":";
457 PrintLine(getUpperLine());
458
459 if (options().getAttributeOffset())
460 // Print the active range (low pc and high pc).
461 Stream << " [" << hexString(getLowerAddress()) << ":"
462 << hexString(getUpperAddress()) << "]";
463
464 return String;
465}
466
467// Validate the ranges associated with the location.
469 // Traverse the locations and validate them against the address to line
470 // mapping in the current compile unit. Record those invalid ranges.
471 // A valid range must meet the following conditions:
472 // a) line(lopc) <= line(hipc)
473 // b) line(lopc) and line(hipc) are valid.
474
475 if (!hasAssociatedRange())
476 return true;
477
479 LVLine *LowLine = Range.first;
480 LVLine *HighLine = Range.second;
481 if (LowLine)
482 setLowerLine(LowLine);
483 else {
484 setIsInvalidLower();
485 return false;
486 }
487 if (HighLine)
488 setUpperLine(HighLine);
489 else {
490 setIsInvalidUpper();
491 return false;
492 }
493 // Check for a valid interval.
494 if (LowLine->getLineNumber() > HighLine->getLineNumber()) {
495 setIsInvalidRange();
496 return false;
497 }
498
499 return true;
500}
501
503 float &Percentage) {
504 if (!options().getAttributeCoverage() && !Locations)
505 return false;
506
507 // Calculate the coverage depending on the kind of location. We have
508 // the simple and composed locations.
509 if (Locations->size() == 1) {
510 // Simple: fixed address, class offset, stack offset.
511 LVLocation *Location = Locations->front();
512 // Some types of locations do not have specific kind. Now is the time
513 // to set those types, depending on the operation type.
514 Location->updateKind();
515 if (Location->getIsLocationSimple()) {
516 Factor = 100;
517 Percentage = 100;
518 return true;
519 }
520 }
521
522 // Composed locations.
523 LVAddress LowerAddress = 0;
524 LVAddress UpperAddress = 0;
525 for (const LVLocation *Location : *Locations)
526 // Do not include locations representing a gap.
527 if (!Location->getIsGapEntry()) {
528 LowerAddress = Location->getLowerAddress();
529 UpperAddress = Location->getUpperAddress();
530 Factor += (UpperAddress > LowerAddress) ? UpperAddress - LowerAddress
531 : LowerAddress - UpperAddress;
532 }
533
534 Percentage = 0;
535 return false;
536}
537
538void LVLocation::printRaw(raw_ostream &OS, bool Full) const {
539 // Print the active range (low pc and high pc).
540 OS << " [" << hexString(getLowerAddress()) << ":"
541 << hexString(getUpperAddress()) << "]\n";
542 // Print any DWARF operations.
543 printRawExtra(OS, Full);
544}
545
547 if (hasAssociatedRange())
548 OS << getIntervalInfo();
549}
550
551void LVLocation::print(raw_ostream &OS, bool Full) const {
552 if (getReader().doPrintLocation(this)) {
554 printExtra(OS, Full);
555 }
556}
557
559 printInterval(OS, Full);
560 OS << "\n";
561}
562
563//===----------------------------------------------------------------------===//
564// DWARF location for a symbol.
565//===----------------------------------------------------------------------===//
566// Add a Location Entry.
568 LVUnsigned SectionOffset,
569 uint64_t LocDescOffset) {
572
573 // Record the offset where the location information begins.
574 setOffset(LocDescOffset ? LocDescOffset : SectionOffset);
575
576 // A -1 HighPC value, indicates no range.
578 setIsDiscardedRange();
579
580 // Update the location kind, using the DWARF attribute.
581 setKind();
582}
583
584// Add a Location Record.
586 ArrayRef<LVUnsigned> Operands) {
587 if (!Entries)
588 Entries = std::make_unique<LVOperations>();
589 Entries->push_back(getReader().createOperation(Opcode, Operands));
590}
591
592// Based on the DWARF attribute, define the location kind.
594 switch (getAttr()) {
595 case dwarf::DW_AT_data_member_location:
596 setIsClassOffset();
597 break;
598 case dwarf::DW_AT_location:
599 // Depending on the operand, we have a fixed address.
600 setIsFixedAddress();
601 break;
602 default:
603 break;
604 }
605 // For those symbols with absolute location information, ignore any
606 // gaps in their location description; that is the case with absolute
607 // memory addresses and members located at specific offsets.
608 if (hasAssociatedRange())
609 getParentSymbol()->setFillGaps();
610}
611
613 // Update the location type for simple ones.
614 if (Entries && Entries->size() == 1) {
615 if (dwarf::DW_OP_fbreg == Entries->front()->getOpcode())
616 setIsStackOffset();
617 }
618}
619
621 if (Entries)
622 for (const LVOperation *Operation : *Entries)
623 Operation->print(OS, Full);
624}
625
626// Print location (formatted version).
628 if (!Locations || Locations->empty())
629 return;
630
631 // Print the symbol coverage.
632 if (options().getAttributeCoverage()) {
633 // The location entries are contained within a symbol. Get a location,
634 // to access basic information about indentation, parent, etc.
635 LVLocation *Location = Locations->front();
636 LVSymbol *Symbol = Location->getParentSymbol();
637 float Percentage = Symbol->getCoveragePercentage();
638
639 // The coverage is dependent on the kind of location.
640 std::string String;
642 Stream << format("%.2f%%", Percentage);
643 if (!Location->getIsLocationSimple())
644 Stream << format(" (%d/%d)", Symbol->getCoverageFactor(),
645 Symbol->getParentScope()->getCoverageFactor());
646 Symbol->printAttributes(OS, Full, "{Coverage} ", Symbol, StringRef(String),
647 /*UseQuotes=*/false,
648 /*PrintRef=*/false);
649 }
650
651 // Print the symbol location, including the missing entries.
652 if (getReader().doPrintLocation(/*Location=*/nullptr))
653 for (const LVLocation *Location : *Locations)
654 Location->print(OS, Full);
655}
656
658 OS << "{Location}";
659 if (getIsCallSite())
660 OS << " -> CallSite";
661 printInterval(OS, Full);
662 OS << "\n";
663
664 // Print location entries.
665 if (Full && Entries) {
666 bool CodeViewLocation = getParentSymbol()->getHasCodeViewLocation();
667 std::stringstream Stream;
668 std::string Leading;
669 for (LVOperation *Operation : *Entries) {
670 Stream << Leading
671 << (CodeViewLocation ? Operation->getOperandsCodeViewInfo()
672 : Operation->getOperandsDWARFInfo());
673 Leading = ", ";
674 }
675 printAttributes(OS, Full, "{Entry} ", const_cast<LVLocationSymbol *>(this),
676 StringRef(Stream.str()),
677 /*UseQuotes=*/false,
678 /*PrintRef=*/false);
679 }
680}
static std::string getRegisterName(const TargetRegisterInfo *TRI, Register Reg)
PowerPC Reduce CR logical Operation
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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
Definition LVLocation.h:136
const LVLine * getLowerLine() const
Definition LVLocation.h:127
void setUpperLine(LVLine *Line)
Definition LVLocation.h:130
std::string getIntervalInfo() const
virtual void printRawExtra(raw_ostream &OS, bool Full=true) const
Definition LVLocation.h:158
void printRaw(raw_ostream &OS, bool Full=true) const
LVAddress getLowerAddress() const override
Definition LVLocation.h:133
const LVLine * getUpperLine() const
Definition LVLocation.h:129
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)
Definition LVLocation.h:128
LVAddress getUpperAddress() const override
Definition LVLocation.h:135
void printInterval(raw_ostream &OS, bool Full=true) const
void setLowerAddress(LVAddress Address) override
Definition LVLocation.h:134
virtual void print(raw_ostream &OS, bool Full=true) const
Definition LVObject.cpp:156
void printAttributes(raw_ostream &OS, bool Full=true) const
Definition LVObject.cpp:137
dwarf::Attribute getAttr() const
Definition LVObject.h:234
LVSymbol * getParentSymbol() const
Definition LVObject.h:260
uint32_t getLineNumber() const
Definition LVObject.h:274
void setOffset(LVOffset DieOffset)
Definition LVObject.h:241
LLVM_ABI void print(raw_ostream &OS, bool Full=true) const
LLVM_ABI std::string getOperandsDWARFInfo()
LLVM_ABI std::string getOperandsCodeViewInfo()
virtual std::string getRegisterName(LVSmall Opcode, ArrayRef< uint64_t > Operands)
Definition LVReader.h:291
LVLineRange lineRange(LVLocation *Location) const
Definition LVScope.cpp:1276
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
#define UINT64_MAX
Definition DataTypes.h:77
@ DW_OP_hi_user
Definition Dwarf.h:143
std::string hexString(uint64_t Value, size_t Width=HEX_WIDTH)
Definition LVSupport.h:129
LVReader & getReader()
Definition LVReader.h:360
uint64_t LVUnsigned
Definition LVObject.h:41
uint16_t getCodeViewOperationCode(uint8_t Code)
Definition LVSupport.h:271
LVScopeCompileUnit * getReaderCompileUnit()
Definition LVReader.h:364
std::pair< LVLine *, LVLine * > LVLineRange
Definition LVLocation.h:23
uint8_t LVSmall
Definition LVObject.h:42
uint64_t LVAddress
Definition LVObject.h:36
const LVSmall LVLocationMemberOffset
Definition LVLocation.h:26
LVOptions & options()
Definition LVOptions.h:448
SmallVector< LVLocation *, 8 > LVLocations
Definition LVObject.h:78
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.
Definition Format.h:129