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