[Alignment][NFC] Migrate Instructions to Align
[llvm-core.git] / include / llvm / DebugInfo / DWARF / DWARFAbbreviationDeclaration.h
blob39ae53c4e7fe58e821151f621840b72f86b8dcda
1 //===- DWARFAbbreviationDeclaration.h ---------------------------*- C++ -*-===//
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 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
10 #define LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H
12 #include "llvm/ADT/Optional.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/iterator_range.h"
15 #include "llvm/BinaryFormat/Dwarf.h"
16 #include "llvm/Support/DataExtractor.h"
17 #include <cassert>
18 #include <cstddef>
19 #include <cstdint>
21 namespace llvm {
23 class DWARFFormValue;
24 class DWARFUnit;
25 class raw_ostream;
27 class DWARFAbbreviationDeclaration {
28 public:
29 struct AttributeSpec {
30 AttributeSpec(dwarf::Attribute A, dwarf::Form F, int64_t Value)
31 : Attr(A), Form(F), Value(Value) {
32 assert(isImplicitConst());
34 AttributeSpec(dwarf::Attribute A, dwarf::Form F, Optional<uint8_t> ByteSize)
35 : Attr(A), Form(F) {
36 assert(!isImplicitConst());
37 this->ByteSize.HasByteSize = ByteSize.hasValue();
38 if (this->ByteSize.HasByteSize)
39 this->ByteSize.ByteSize = *ByteSize;
42 dwarf::Attribute Attr;
43 dwarf::Form Form;
45 private:
46 /// The following field is used for ByteSize for non-implicit_const
47 /// attributes and as value for implicit_const ones, indicated by
48 /// Form == DW_FORM_implicit_const.
49 /// The following cases are distinguished:
50 /// * Form != DW_FORM_implicit_const and HasByteSize is true:
51 /// ByteSize contains the fixed size in bytes for the Form in this
52 /// object.
53 /// * Form != DW_FORM_implicit_const and HasByteSize is false:
54 /// byte size of Form either varies according to the DWARFUnit
55 /// that it is contained in or the value size varies and must be
56 /// decoded from the debug information in order to determine its size.
57 /// * Form == DW_FORM_implicit_const:
58 /// Value contains value for the implicit_const attribute.
59 struct ByteSizeStorage {
60 bool HasByteSize;
61 uint8_t ByteSize;
63 union {
64 ByteSizeStorage ByteSize;
65 int64_t Value;
68 public:
69 bool isImplicitConst() const {
70 return Form == dwarf::DW_FORM_implicit_const;
73 int64_t getImplicitConstValue() const {
74 assert(isImplicitConst());
75 return Value;
78 /// Get the fixed byte size of this Form if possible. This function might
79 /// use the DWARFUnit to calculate the size of the Form, like for
80 /// DW_AT_address and DW_AT_ref_addr, so this isn't just an accessor for
81 /// the ByteSize member.
82 Optional<int64_t> getByteSize(const DWARFUnit &U) const;
84 using AttributeSpecVector = SmallVector<AttributeSpec, 8>;
86 DWARFAbbreviationDeclaration();
88 uint32_t getCode() const { return Code; }
89 uint8_t getCodeByteSize() const { return CodeByteSize; }
90 dwarf::Tag getTag() const { return Tag; }
91 bool hasChildren() const { return HasChildren; }
93 using attr_iterator_range =
94 iterator_range<AttributeSpecVector::const_iterator>;
96 attr_iterator_range attributes() const {
97 return attr_iterator_range(AttributeSpecs.begin(), AttributeSpecs.end());
100 dwarf::Form getFormByIndex(uint32_t idx) const {
101 assert(idx < AttributeSpecs.size());
102 return AttributeSpecs[idx].Form;
105 size_t getNumAttributes() const {
106 return AttributeSpecs.size();
109 dwarf::Attribute getAttrByIndex(uint32_t idx) const {
110 assert(idx < AttributeSpecs.size());
111 return AttributeSpecs[idx].Attr;
114 /// Get the index of the specified attribute.
116 /// Searches the this abbreviation declaration for the index of the specified
117 /// attribute.
119 /// \param attr DWARF attribute to search for.
120 /// \returns Optional index of the attribute if found, None otherwise.
121 Optional<uint32_t> findAttributeIndex(dwarf::Attribute attr) const;
123 /// Extract a DWARF form value from a DIE specified by DIE offset.
125 /// Extract an attribute value for a DWARFUnit given the DIE offset and the
126 /// attribute.
128 /// \param DIEOffset the DIE offset that points to the ULEB128 abbreviation
129 /// code in the .debug_info data.
130 /// \param Attr DWARF attribute to search for.
131 /// \param U the DWARFUnit the contains the DIE.
132 /// \returns Optional DWARF form value if the attribute was extracted.
133 Optional<DWARFFormValue> getAttributeValue(const uint64_t DIEOffset,
134 const dwarf::Attribute Attr,
135 const DWARFUnit &U) const;
137 bool extract(DataExtractor Data, uint64_t* OffsetPtr);
138 void dump(raw_ostream &OS) const;
140 // Return an optional byte size of all attribute data in this abbreviation
141 // if a constant byte size can be calculated given a DWARFUnit. This allows
142 // DWARF parsing to be faster as many DWARF DIEs have a fixed byte size.
143 Optional<size_t> getFixedAttributesByteSize(const DWARFUnit &U) const;
145 private:
146 void clear();
148 /// A helper structure that can quickly determine the size in bytes of an
149 /// abbreviation declaration.
150 struct FixedSizeInfo {
151 /// The fixed byte size for fixed size forms.
152 uint16_t NumBytes = 0;
153 /// Number of DW_FORM_address forms in this abbrevation declaration.
154 uint8_t NumAddrs = 0;
155 /// Number of DW_FORM_ref_addr forms in this abbrevation declaration.
156 uint8_t NumRefAddrs = 0;
157 /// Number of 4 byte in DWARF32 and 8 byte in DWARF64 forms.
158 uint8_t NumDwarfOffsets = 0;
160 FixedSizeInfo() = default;
162 /// Calculate the fixed size in bytes given a DWARFUnit.
164 /// \param U the DWARFUnit to use when determing the byte size.
165 /// \returns the size in bytes for all attribute data in this abbreviation.
166 /// The returned size does not include bytes for the ULEB128 abbreviation
167 /// code
168 size_t getByteSize(const DWARFUnit &U) const;
171 uint32_t Code;
172 dwarf::Tag Tag;
173 uint8_t CodeByteSize;
174 bool HasChildren;
175 AttributeSpecVector AttributeSpecs;
176 /// If this abbreviation has a fixed byte size then FixedAttributeSize member
177 /// variable below will have a value.
178 Optional<FixedSizeInfo> FixedAttributeSize;
181 } // end namespace llvm
183 #endif // LLVM_DEBUGINFO_DWARFABBREVIATIONDECLARATION_H