Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / include / llvm / DebugInfo / CodeView / CodeViewRecordIO.h
blobb2476f16d1002b22e34a3a90488c7426efce8447
1 //===- CodeViewRecordIO.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_CODEVIEW_CODEVIEWRECORDIO_H
10 #define LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H
12 #include "llvm/ADT/APSInt.h"
13 #include "llvm/ADT/None.h"
14 #include "llvm/ADT/Optional.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
18 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
19 #include "llvm/Support/BinaryStreamReader.h"
20 #include "llvm/Support/BinaryStreamWriter.h"
21 #include "llvm/Support/Error.h"
22 #include <cassert>
23 #include <cstdint>
24 #include <type_traits>
26 namespace llvm {
27 namespace codeview {
29 class CodeViewRecordIO {
30 uint32_t getCurrentOffset() const {
31 return (isWriting()) ? Writer->getOffset() : Reader->getOffset();
34 public:
35 explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
36 explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {}
38 Error beginRecord(Optional<uint32_t> MaxLength);
39 Error endRecord();
41 Error mapInteger(TypeIndex &TypeInd);
43 bool isReading() const { return Reader != nullptr; }
44 bool isWriting() const { return !isReading(); }
46 uint32_t maxFieldLength() const;
48 template <typename T> Error mapObject(T &Value) {
49 if (isWriting())
50 return Writer->writeObject(Value);
52 const T *ValuePtr;
53 if (auto EC = Reader->readObject(ValuePtr))
54 return EC;
55 Value = *ValuePtr;
56 return Error::success();
59 template <typename T> Error mapInteger(T &Value) {
60 if (isWriting())
61 return Writer->writeInteger(Value);
63 return Reader->readInteger(Value);
66 template <typename T> Error mapEnum(T &Value) {
67 if (sizeof(Value) > maxFieldLength())
68 return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
70 using U = typename std::underlying_type<T>::type;
71 U X;
72 if (isWriting())
73 X = static_cast<U>(Value);
75 if (auto EC = mapInteger(X))
76 return EC;
77 if (isReading())
78 Value = static_cast<T>(X);
79 return Error::success();
82 Error mapEncodedInteger(int64_t &Value);
83 Error mapEncodedInteger(uint64_t &Value);
84 Error mapEncodedInteger(APSInt &Value);
85 Error mapStringZ(StringRef &Value);
86 Error mapGuid(GUID &Guid);
88 Error mapStringZVectorZ(std::vector<StringRef> &Value);
90 template <typename SizeType, typename T, typename ElementMapper>
91 Error mapVectorN(T &Items, const ElementMapper &Mapper) {
92 SizeType Size;
93 if (isWriting()) {
94 Size = static_cast<SizeType>(Items.size());
95 if (auto EC = Writer->writeInteger(Size))
96 return EC;
98 for (auto &X : Items) {
99 if (auto EC = Mapper(*this, X))
100 return EC;
102 } else {
103 if (auto EC = Reader->readInteger(Size))
104 return EC;
105 for (SizeType I = 0; I < Size; ++I) {
106 typename T::value_type Item;
107 if (auto EC = Mapper(*this, Item))
108 return EC;
109 Items.push_back(Item);
113 return Error::success();
116 template <typename T, typename ElementMapper>
117 Error mapVectorTail(T &Items, const ElementMapper &Mapper) {
118 if (isWriting()) {
119 for (auto &Item : Items) {
120 if (auto EC = Mapper(*this, Item))
121 return EC;
123 } else {
124 typename T::value_type Field;
125 // Stop when we run out of bytes or we hit record padding bytes.
126 while (!Reader->empty() && Reader->peek() < 0xf0 /* LF_PAD0 */) {
127 if (auto EC = Mapper(*this, Field))
128 return EC;
129 Items.push_back(Field);
132 return Error::success();
135 Error mapByteVectorTail(ArrayRef<uint8_t> &Bytes);
136 Error mapByteVectorTail(std::vector<uint8_t> &Bytes);
138 Error padToAlignment(uint32_t Align);
139 Error skipPadding();
141 private:
142 Error writeEncodedSignedInteger(const int64_t &Value);
143 Error writeEncodedUnsignedInteger(const uint64_t &Value);
145 struct RecordLimit {
146 uint32_t BeginOffset;
147 Optional<uint32_t> MaxLength;
149 Optional<uint32_t> bytesRemaining(uint32_t CurrentOffset) const {
150 if (!MaxLength.hasValue())
151 return None;
152 assert(CurrentOffset >= BeginOffset);
154 uint32_t BytesUsed = CurrentOffset - BeginOffset;
155 if (BytesUsed >= *MaxLength)
156 return 0;
157 return *MaxLength - BytesUsed;
161 SmallVector<RecordLimit, 2> Limits;
163 BinaryStreamReader *Reader = nullptr;
164 BinaryStreamWriter *Writer = nullptr;
167 } // end namespace codeview
168 } // end namespace llvm
170 #endif // LLVM_DEBUGINFO_CODEVIEW_CODEVIEWRECORDIO_H