1 //===- DWARFFormValue.cpp -------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/ADT/None.h"
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/BinaryFormat/Dwarf.h"
15 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
16 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
17 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/Format.h"
20 #include "llvm/Support/WithColor.h"
21 #include "llvm/Support/raw_ostream.h"
27 using namespace dwarf
;
29 static const DWARFFormValue::FormClass DWARF5FormClasses
[] = {
30 DWARFFormValue::FC_Unknown
, // 0x0
31 DWARFFormValue::FC_Address
, // 0x01 DW_FORM_addr
32 DWARFFormValue::FC_Unknown
, // 0x02 unused
33 DWARFFormValue::FC_Block
, // 0x03 DW_FORM_block2
34 DWARFFormValue::FC_Block
, // 0x04 DW_FORM_block4
35 DWARFFormValue::FC_Constant
, // 0x05 DW_FORM_data2
36 // --- These can be FC_SectionOffset in DWARF3 and below:
37 DWARFFormValue::FC_Constant
, // 0x06 DW_FORM_data4
38 DWARFFormValue::FC_Constant
, // 0x07 DW_FORM_data8
40 DWARFFormValue::FC_String
, // 0x08 DW_FORM_string
41 DWARFFormValue::FC_Block
, // 0x09 DW_FORM_block
42 DWARFFormValue::FC_Block
, // 0x0a DW_FORM_block1
43 DWARFFormValue::FC_Constant
, // 0x0b DW_FORM_data1
44 DWARFFormValue::FC_Flag
, // 0x0c DW_FORM_flag
45 DWARFFormValue::FC_Constant
, // 0x0d DW_FORM_sdata
46 DWARFFormValue::FC_String
, // 0x0e DW_FORM_strp
47 DWARFFormValue::FC_Constant
, // 0x0f DW_FORM_udata
48 DWARFFormValue::FC_Reference
, // 0x10 DW_FORM_ref_addr
49 DWARFFormValue::FC_Reference
, // 0x11 DW_FORM_ref1
50 DWARFFormValue::FC_Reference
, // 0x12 DW_FORM_ref2
51 DWARFFormValue::FC_Reference
, // 0x13 DW_FORM_ref4
52 DWARFFormValue::FC_Reference
, // 0x14 DW_FORM_ref8
53 DWARFFormValue::FC_Reference
, // 0x15 DW_FORM_ref_udata
54 DWARFFormValue::FC_Indirect
, // 0x16 DW_FORM_indirect
55 DWARFFormValue::FC_SectionOffset
, // 0x17 DW_FORM_sec_offset
56 DWARFFormValue::FC_Exprloc
, // 0x18 DW_FORM_exprloc
57 DWARFFormValue::FC_Flag
, // 0x19 DW_FORM_flag_present
58 DWARFFormValue::FC_String
, // 0x1a DW_FORM_strx
59 DWARFFormValue::FC_Address
, // 0x1b DW_FORM_addrx
60 DWARFFormValue::FC_Reference
, // 0x1c DW_FORM_ref_sup4
61 DWARFFormValue::FC_String
, // 0x1d DW_FORM_strp_sup
62 DWARFFormValue::FC_Constant
, // 0x1e DW_FORM_data16
63 DWARFFormValue::FC_String
, // 0x1f DW_FORM_line_strp
64 DWARFFormValue::FC_Reference
, // 0x20 DW_FORM_ref_sig8
65 DWARFFormValue::FC_Constant
, // 0x21 DW_FORM_implicit_const
66 DWARFFormValue::FC_SectionOffset
, // 0x22 DW_FORM_loclistx
67 DWARFFormValue::FC_SectionOffset
, // 0x23 DW_FORM_rnglistx
68 DWARFFormValue::FC_Reference
, // 0x24 DW_FORM_ref_sup8
69 DWARFFormValue::FC_String
, // 0x25 DW_FORM_strx1
70 DWARFFormValue::FC_String
, // 0x26 DW_FORM_strx2
71 DWARFFormValue::FC_String
, // 0x27 DW_FORM_strx3
72 DWARFFormValue::FC_String
, // 0x28 DW_FORM_strx4
73 DWARFFormValue::FC_Address
, // 0x29 DW_FORM_addrx1
74 DWARFFormValue::FC_Address
, // 0x2a DW_FORM_addrx2
75 DWARFFormValue::FC_Address
, // 0x2b DW_FORM_addrx3
76 DWARFFormValue::FC_Address
, // 0x2c DW_FORM_addrx4
77 DWARFFormValue::FC_Address
, // 0x2001 DW_FORM_addrx_offset
80 DWARFFormValue
DWARFFormValue::createFromSValue(dwarf::Form F
, int64_t V
) {
81 return DWARFFormValue(F
, ValueType(V
));
84 DWARFFormValue
DWARFFormValue::createFromUValue(dwarf::Form F
, uint64_t V
) {
85 return DWARFFormValue(F
, ValueType(V
));
88 DWARFFormValue
DWARFFormValue::createFromPValue(dwarf::Form F
, const char *V
) {
89 return DWARFFormValue(F
, ValueType(V
));
92 DWARFFormValue
DWARFFormValue::createFromBlockValue(dwarf::Form F
,
93 ArrayRef
<uint8_t> D
) {
97 return DWARFFormValue(F
, V
);
100 DWARFFormValue
DWARFFormValue::createFromUnit(dwarf::Form F
, const DWARFUnit
*U
,
101 uint64_t *OffsetPtr
) {
102 DWARFFormValue
FormValue(F
);
103 FormValue
.extractValue(U
->getDebugInfoExtractor(), OffsetPtr
,
104 U
->getFormParams(), U
);
108 bool DWARFFormValue::skipValue(dwarf::Form Form
, DataExtractor DebugInfoData
,
110 const dwarf::FormParams Params
) {
111 bool Indirect
= false;
114 // Blocks of inlined data that have a length field and the data bytes
115 // inlined in the .debug_info.
116 case DW_FORM_exprloc
:
117 case DW_FORM_block
: {
118 uint64_t size
= DebugInfoData
.getULEB128(OffsetPtr
);
122 case DW_FORM_block1
: {
123 uint8_t size
= DebugInfoData
.getU8(OffsetPtr
);
127 case DW_FORM_block2
: {
128 uint16_t size
= DebugInfoData
.getU16(OffsetPtr
);
132 case DW_FORM_block4
: {
133 uint32_t size
= DebugInfoData
.getU32(OffsetPtr
);
138 // Inlined NULL terminated C-strings.
140 DebugInfoData
.getCStr(OffsetPtr
);
144 case DW_FORM_ref_addr
:
145 case DW_FORM_flag_present
:
156 case DW_FORM_ref_sig8
:
157 case DW_FORM_ref_sup4
:
158 case DW_FORM_ref_sup8
:
165 case DW_FORM_sec_offset
:
167 case DW_FORM_strp_sup
:
168 case DW_FORM_line_strp
:
169 case DW_FORM_GNU_ref_alt
:
170 case DW_FORM_GNU_strp_alt
:
171 case DW_FORM_implicit_const
:
172 if (Optional
<uint8_t> FixedSize
=
173 dwarf::getFixedFormByteSize(Form
, Params
)) {
174 *OffsetPtr
+= *FixedSize
;
179 // signed or unsigned LEB 128 values.
181 DebugInfoData
.getSLEB128(OffsetPtr
);
185 case DW_FORM_ref_udata
:
188 case DW_FORM_loclistx
:
189 case DW_FORM_rnglistx
:
190 case DW_FORM_GNU_addr_index
:
191 case DW_FORM_GNU_str_index
:
192 DebugInfoData
.getULEB128(OffsetPtr
);
195 case DW_FORM_LLVM_addrx_offset
:
196 DebugInfoData
.getULEB128(OffsetPtr
);
200 case DW_FORM_indirect
:
202 Form
= static_cast<dwarf::Form
>(DebugInfoData
.getULEB128(OffsetPtr
));
212 bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC
) const {
213 // First, check DWARF5 form classes.
214 if (Form
< makeArrayRef(DWARF5FormClasses
).size() &&
215 DWARF5FormClasses
[Form
] == FC
)
217 // Check more forms from extensions and proposals.
219 case DW_FORM_GNU_ref_alt
:
220 return (FC
== FC_Reference
);
221 case DW_FORM_GNU_addr_index
:
222 return (FC
== FC_Address
);
223 case DW_FORM_GNU_str_index
:
224 case DW_FORM_GNU_strp_alt
:
225 return (FC
== FC_String
);
226 case DW_FORM_LLVM_addrx_offset
:
227 return (FC
== FC_Address
);
232 if (FC
== FC_SectionOffset
) {
233 if (Form
== DW_FORM_strp
|| Form
== DW_FORM_line_strp
)
235 // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section
236 // offset. If we don't have a DWARFUnit, default to the old behavior.
237 if (Form
== DW_FORM_data4
|| Form
== DW_FORM_data8
)
238 return !U
|| U
->getVersion() <= 3;
244 bool DWARFFormValue::extractValue(const DWARFDataExtractor
&Data
,
245 uint64_t *OffsetPtr
, dwarf::FormParams FP
,
246 const DWARFContext
*Ctx
,
247 const DWARFUnit
*CU
) {
249 Ctx
= &CU
->getContext();
253 bool Indirect
= false;
254 bool IsBlock
= false;
255 Value
.data
= nullptr;
256 // Read the value for the form into value and follow and DW_FORM_indirect
257 // instances we run into
258 Error Err
= Error::success();
263 case DW_FORM_ref_addr
: {
265 (Form
== DW_FORM_addr
) ? FP
.AddrSize
: FP
.getRefAddrByteSize();
267 Data
.getRelocatedValue(Size
, OffsetPtr
, &Value
.SectionIndex
, &Err
);
270 case DW_FORM_exprloc
:
272 Value
.uval
= Data
.getULEB128(OffsetPtr
, &Err
);
276 Value
.uval
= Data
.getU8(OffsetPtr
, &Err
);
280 Value
.uval
= Data
.getU16(OffsetPtr
, &Err
);
284 Value
.uval
= Data
.getU32(OffsetPtr
, &Err
);
292 Value
.uval
= Data
.getU8(OffsetPtr
, &Err
);
298 Value
.uval
= Data
.getU16(OffsetPtr
, &Err
);
301 Value
.uval
= Data
.getU24(OffsetPtr
, &Err
);
305 case DW_FORM_ref_sup4
:
308 Value
.uval
= Data
.getRelocatedValue(4, OffsetPtr
, nullptr, &Err
);
312 case DW_FORM_ref_sup8
:
313 Value
.uval
= Data
.getRelocatedValue(8, OffsetPtr
, nullptr, &Err
);
316 // Treat this like a 16-byte block.
321 Value
.sval
= Data
.getSLEB128(OffsetPtr
, &Err
);
324 case DW_FORM_ref_udata
:
325 case DW_FORM_rnglistx
:
326 case DW_FORM_loclistx
:
327 case DW_FORM_GNU_addr_index
:
328 case DW_FORM_GNU_str_index
:
331 Value
.uval
= Data
.getULEB128(OffsetPtr
, &Err
);
333 case DW_FORM_LLVM_addrx_offset
:
334 Value
.uval
= Data
.getULEB128(OffsetPtr
, &Err
) << 32;
335 Value
.uval
= Data
.getU32(OffsetPtr
, &Err
);
338 Value
.cstr
= Data
.getCStr(OffsetPtr
, &Err
);
340 case DW_FORM_indirect
:
341 Form
= static_cast<dwarf::Form
>(Data
.getULEB128(OffsetPtr
, &Err
));
345 case DW_FORM_sec_offset
:
346 case DW_FORM_GNU_ref_alt
:
347 case DW_FORM_GNU_strp_alt
:
348 case DW_FORM_line_strp
:
349 case DW_FORM_strp_sup
: {
350 Value
.uval
= Data
.getRelocatedValue(FP
.getDwarfOffsetByteSize(),
351 OffsetPtr
, nullptr, &Err
);
354 case DW_FORM_flag_present
:
357 case DW_FORM_ref_sig8
:
358 Value
.uval
= Data
.getU64(OffsetPtr
, &Err
);
360 case DW_FORM_implicit_const
:
361 // Value has been already set by DWARFFormValue::createFromSValue.
364 // DWARFFormValue::skipValue() will have caught this and caused all
365 // DWARF DIEs to fail to be parsed, so this code is not be reachable.
366 llvm_unreachable("unsupported form");
368 } while (Indirect
&& !Err
);
371 Value
.data
= Data
.getBytes(OffsetPtr
, Value
.uval
, &Err
).bytes_begin();
373 return !errorToBool(std::move(Err
));
376 void DWARFFormValue::dumpAddress(raw_ostream
&OS
, uint8_t AddressSize
,
378 uint8_t HexDigits
= AddressSize
* 2;
379 OS
<< format("0x%*.*" PRIx64
, HexDigits
, HexDigits
, Address
);
382 void DWARFFormValue::dumpSectionedAddress(raw_ostream
&OS
,
383 DIDumpOptions DumpOpts
,
384 object::SectionedAddress SA
) const {
385 dumpAddress(OS
, U
->getAddressByteSize(), SA
.Address
);
386 dumpAddressSection(U
->getContext().getDWARFObj(), OS
, DumpOpts
,
390 void DWARFFormValue::dumpAddressSection(const DWARFObject
&Obj
, raw_ostream
&OS
,
391 DIDumpOptions DumpOpts
,
392 uint64_t SectionIndex
) {
393 if (!DumpOpts
.Verbose
|| SectionIndex
== -1ULL)
395 ArrayRef
<SectionName
> SectionNames
= Obj
.getSectionNames();
396 const auto &SecRef
= SectionNames
[SectionIndex
];
398 OS
<< " \"" << SecRef
.Name
<< '\"';
400 // Print section index if name is not unique.
401 if (!SecRef
.IsNameUnique
)
402 OS
<< format(" [%" PRIu64
"]", SectionIndex
);
405 void DWARFFormValue::dump(raw_ostream
&OS
, DIDumpOptions DumpOpts
) const {
406 uint64_t UValue
= Value
.uval
;
407 bool CURelativeOffset
= false;
408 raw_ostream
&AddrOS
= DumpOpts
.ShowAddresses
409 ? WithColor(OS
, HighlightColor::Address
).get()
411 int OffsetDumpWidth
= 2 * dwarf::getDwarfOffsetByteSize(Format
);
414 dumpSectionedAddress(AddrOS
, DumpOpts
, {Value
.uval
, Value
.SectionIndex
});
421 case DW_FORM_GNU_addr_index
: {
423 OS
<< "<invalid dwarf unit>";
426 Optional
<object::SectionedAddress
> A
= U
->getAddrOffsetSectionItem(UValue
);
427 if (!A
|| DumpOpts
.Verbose
)
428 AddrOS
<< format("indexed (%8.8x) address = ", (uint32_t)UValue
);
430 dumpSectionedAddress(AddrOS
, DumpOpts
, *A
);
432 OS
<< "<unresolved>";
435 case DW_FORM_LLVM_addrx_offset
: {
437 OS
<< "<invalid dwarf unit>";
440 uint32_t Index
= UValue
>> 32;
441 uint32_t Offset
= UValue
& 0xffffffff;
442 Optional
<object::SectionedAddress
> A
= U
->getAddrOffsetSectionItem(Index
);
443 if (!A
|| DumpOpts
.Verbose
)
444 AddrOS
<< format("indexed (%8.8x) + 0x%x address = ", Index
, Offset
);
446 A
->Address
+= Offset
;
447 dumpSectionedAddress(AddrOS
, DumpOpts
, *A
);
449 OS
<< "<unresolved>";
452 case DW_FORM_flag_present
:
457 OS
<< format("0x%02x", (uint8_t)UValue
);
460 OS
<< format("0x%04x", (uint16_t)UValue
);
463 OS
<< format("0x%08x", (uint32_t)UValue
);
465 case DW_FORM_ref_sig8
:
466 AddrOS
<< format("0x%016" PRIx64
, UValue
);
469 OS
<< format("0x%016" PRIx64
, UValue
);
472 OS
<< format_bytes(ArrayRef
<uint8_t>(Value
.data
, 16), None
, 16, 16);
476 OS
.write_escaped(Value
.cstr
);
479 case DW_FORM_exprloc
:
486 case DW_FORM_exprloc
:
488 AddrOS
<< format("<0x%" PRIx64
"> ", UValue
);
491 AddrOS
<< format("<0x%2.2x> ", (uint8_t)UValue
);
494 AddrOS
<< format("<0x%4.4x> ", (uint16_t)UValue
);
497 AddrOS
<< format("<0x%8.8x> ", (uint32_t)UValue
);
503 const uint8_t *DataPtr
= Value
.data
;
505 // UValue contains size of block
506 const uint8_t *EndDataPtr
= DataPtr
+ UValue
;
507 while (DataPtr
< EndDataPtr
) {
508 AddrOS
<< format("%2.2x ", *DataPtr
);
517 case DW_FORM_implicit_const
:
524 if (DumpOpts
.Verbose
)
525 OS
<< format(" .debug_str[0x%0*" PRIx64
"] = ", OffsetDumpWidth
, UValue
);
528 case DW_FORM_line_strp
:
529 if (DumpOpts
.Verbose
)
530 OS
<< format(" .debug_line_str[0x%0*" PRIx64
"] = ", OffsetDumpWidth
,
539 case DW_FORM_GNU_str_index
:
540 if (DumpOpts
.Verbose
)
541 OS
<< format("indexed (%8.8x) string = ", (uint32_t)UValue
);
544 case DW_FORM_GNU_strp_alt
:
545 if (DumpOpts
.Verbose
)
546 OS
<< format("alt indirect string, offset: 0x%" PRIx64
"", UValue
);
549 case DW_FORM_ref_addr
:
550 AddrOS
<< format("0x%016" PRIx64
, UValue
);
553 CURelativeOffset
= true;
554 if (DumpOpts
.Verbose
)
555 AddrOS
<< format("cu + 0x%2.2x", (uint8_t)UValue
);
558 CURelativeOffset
= true;
559 if (DumpOpts
.Verbose
)
560 AddrOS
<< format("cu + 0x%4.4x", (uint16_t)UValue
);
563 CURelativeOffset
= true;
564 if (DumpOpts
.Verbose
)
565 AddrOS
<< format("cu + 0x%4.4x", (uint32_t)UValue
);
568 CURelativeOffset
= true;
569 if (DumpOpts
.Verbose
)
570 AddrOS
<< format("cu + 0x%8.8" PRIx64
, UValue
);
572 case DW_FORM_ref_udata
:
573 CURelativeOffset
= true;
574 if (DumpOpts
.Verbose
)
575 AddrOS
<< format("cu + 0x%" PRIx64
, UValue
);
577 case DW_FORM_GNU_ref_alt
:
578 AddrOS
<< format("<alt 0x%" PRIx64
">", UValue
);
581 // All DW_FORM_indirect attributes should be resolved prior to calling
583 case DW_FORM_indirect
:
584 OS
<< "DW_FORM_indirect";
587 case DW_FORM_rnglistx
:
588 OS
<< format("indexed (0x%x) rangelist = ", (uint32_t)UValue
);
591 case DW_FORM_loclistx
:
592 OS
<< format("indexed (0x%x) loclist = ", (uint32_t)UValue
);
595 case DW_FORM_sec_offset
:
596 AddrOS
<< format("0x%0*" PRIx64
, OffsetDumpWidth
, UValue
);
600 OS
<< format("DW_FORM(0x%4.4x)", Form
);
604 if (CURelativeOffset
) {
605 if (DumpOpts
.Verbose
)
607 if (DumpOpts
.ShowAddresses
)
608 WithColor(OS
, HighlightColor::Address
).get()
609 << format("0x%8.8" PRIx64
, UValue
+ (U
? U
->getOffset() : 0));
610 if (DumpOpts
.Verbose
)
615 void DWARFFormValue::dumpString(raw_ostream
&OS
) const {
616 Optional
<const char *> DbgStr
= getAsCString();
617 if (DbgStr
.hasValue()) {
618 auto COS
= WithColor(OS
, HighlightColor::String
);
620 COS
.get().write_escaped(DbgStr
.getValue());
625 Optional
<const char *> DWARFFormValue::getAsCString() const {
626 if (!isFormClass(FC_String
))
628 if (Form
== DW_FORM_string
)
630 // FIXME: Add support for DW_FORM_GNU_strp_alt
631 if (Form
== DW_FORM_GNU_strp_alt
|| C
== nullptr)
633 uint64_t Offset
= Value
.uval
;
634 if (Form
== DW_FORM_line_strp
) {
635 // .debug_line_str is tracked in the Context.
636 if (const char *Str
= C
->getLineStringExtractor().getCStr(&Offset
))
640 if (Form
== DW_FORM_GNU_str_index
|| Form
== DW_FORM_strx
||
641 Form
== DW_FORM_strx1
|| Form
== DW_FORM_strx2
|| Form
== DW_FORM_strx3
||
642 Form
== DW_FORM_strx4
) {
645 Optional
<uint64_t> StrOffset
= U
->getStringOffsetSectionItem(Offset
);
650 // Prefer the Unit's string extractor, because for .dwo it will point to
651 // .debug_str.dwo, while the Context's extractor always uses .debug_str.
653 if (const char *Str
= U
->getStringExtractor().getCStr(&Offset
))
657 if (const char *Str
= C
->getStringExtractor().getCStr(&Offset
))
662 Optional
<uint64_t> DWARFFormValue::getAsAddress() const {
663 if (auto SA
= getAsSectionedAddress())
668 Optional
<object::SectionedAddress
>
669 DWARFFormValue::getAsSectionedAddress() const {
670 if (!isFormClass(FC_Address
))
672 bool AddrOffset
= Form
== dwarf::DW_FORM_LLVM_addrx_offset
;
673 if (Form
== DW_FORM_GNU_addr_index
|| Form
== DW_FORM_addrx
|| AddrOffset
) {
675 uint32_t Index
= AddrOffset
? (Value
.uval
>> 32) : Value
.uval
;
678 Optional
<object::SectionedAddress
> SA
= U
->getAddrOffsetSectionItem(Index
);
682 SA
->Address
+= (Value
.uval
& 0xffffffff);
685 return {{Value
.uval
, Value
.SectionIndex
}};
688 Optional
<uint64_t> DWARFFormValue::getAsReference() const {
689 if (auto R
= getAsRelativeReference())
690 return R
->Unit
? R
->Unit
->getOffset() + R
->Offset
: R
->Offset
;
694 Optional
<DWARFFormValue::UnitOffset
> DWARFFormValue::getAsRelativeReference() const {
695 if (!isFormClass(FC_Reference
))
702 case DW_FORM_ref_udata
:
705 return UnitOffset
{const_cast<DWARFUnit
*>(U
), Value
.uval
};
706 case DW_FORM_ref_addr
:
707 case DW_FORM_ref_sig8
:
708 case DW_FORM_GNU_ref_alt
:
709 return UnitOffset
{nullptr, Value
.uval
};
715 Optional
<uint64_t> DWARFFormValue::getAsSectionOffset() const {
716 if (!isFormClass(FC_SectionOffset
))
721 Optional
<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
722 if ((!isFormClass(FC_Constant
) && !isFormClass(FC_Flag
)) ||
723 Form
== DW_FORM_sdata
)
728 Optional
<int64_t> DWARFFormValue::getAsSignedConstant() const {
729 if ((!isFormClass(FC_Constant
) && !isFormClass(FC_Flag
)) ||
730 (Form
== DW_FORM_udata
&&
731 uint64_t(std::numeric_limits
<int64_t>::max()) < Value
.uval
))
735 return int32_t(Value
.uval
);
737 return int16_t(Value
.uval
);
739 return int8_t(Value
.uval
);
747 Optional
<ArrayRef
<uint8_t>> DWARFFormValue::getAsBlock() const {
748 if (!isFormClass(FC_Block
) && !isFormClass(FC_Exprloc
) &&
749 Form
!= DW_FORM_data16
)
751 return makeArrayRef(Value
.data
, Value
.uval
);
754 Optional
<uint64_t> DWARFFormValue::getAsCStringOffset() const {
755 if (!isFormClass(FC_String
) && Form
== DW_FORM_string
)
760 Optional
<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
761 if (!isFormClass(FC_Reference
))