LLVM: lib/DebugInfo/CodeView/CodeViewRecordIO.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
17
18using namespace llvm;
20
22 RecordLimit Limit;
23 Limit.MaxLength = MaxLength;
24 Limit.BeginOffset = getCurrentOffset();
25 Limits.push_back(Limit);
27}
28
30 assert(!Limits.empty() && "Not in a record!");
31 Limits.pop_back();
32
33
34
35
36
37
38
39
40
42
43
47
48 int PaddingBytes = 4 - Align;
49 while (PaddingBytes > 0) {
50 char Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
52 Streamer->emitBytes(BytesSR);
53 --PaddingBytes;
54 }
55 resetStreamedLen();
56 }
58}
59
62 return 0;
63
64 assert(!Limits.empty() && "Not in a record!");
65
66
67
68
69
71 std::optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
72 for (auto X : ArrayRef(Limits).drop_front()) {
73 std::optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
74 if (ThisMin)
75 Min = Min ? std::min(*Min, *ThisMin) : *ThisMin;
76 }
77 assert(Min && "Every field must have a maximum length!");
78
79 return *Min;
80}
81
84 return Reader->padToAlignment(Align);
85 return Writer->padToAlignment(Align);
86}
87
89 assert(() && "Cannot skip padding while writing!");
90
91 if (Reader->bytesRemaining() == 0)
93
94 uint8_t Leaf = Reader->peek();
95 if (Leaf < LF_PAD0)
97
98
99 unsigned BytesToAdvance = Leaf & 0x0F;
100 return Reader->skip(BytesToAdvance);
101}
102
104 const Twine &Comment) {
106 emitComment(Comment);
107 Streamer->emitBinaryData(toStringRef(Bytes));
108 incrStreamedLen(Bytes.size());
110 if (auto EC = Writer->writeBytes(Bytes))
111 return EC;
112 } else {
113 if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
114 return EC;
115 }
117}
118
120 const Twine &Comment) {
123 return EC;
125 Bytes.assign(BytesRef.begin(), BytesRef.end());
126
128}
129
132 std::string TypeNameStr = Streamer->getTypeName(TypeInd);
133 if (!TypeNameStr.empty())
134 emitComment(Comment + ": " + TypeNameStr);
135 else
136 emitComment(Comment);
137 Streamer->emitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
138 incrStreamedLen(sizeof(TypeInd.getIndex()));
140 if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
141 return EC;
142 } else {
144 if (auto EC = Reader->readInteger(I))
145 return EC;
147 }
149}
150
152 const Twine &Comment) {
155 emitEncodedUnsignedInteger(static_cast<uint64_t>(Value), Comment);
156 else
157 emitEncodedSignedInteger(Value, Comment);
159 if (Value >= 0) {
160 if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value)))
161 return EC;
162 } else {
163 if (auto EC = writeEncodedSignedInteger(Value))
164 return EC;
165 }
166 } else {
169 return EC;
171 }
172
174}
175
177 const Twine &Comment) {
179 emitEncodedUnsignedInteger(Value, Comment);
181 if (auto EC = writeEncodedUnsignedInteger(Value))
182 return EC;
183 } else {
186 return EC;
188 }
190}
191
194
195
196 if (Value.isSigned())
197 emitEncodedSignedInteger(Value.getSExtValue(), Comment);
198 else
199 emitEncodedUnsignedInteger(Value.getZExtValue(), Comment);
201 if (Value.isSigned())
202 return writeEncodedSignedInteger(
204 return writeEncodedUnsignedInteger(Value.getLimitedValue());
205 } else
208}
209
213 emitComment(Comment);
214 Streamer->emitBytes(NullTerminatedString);
215 incrStreamedLen(NullTerminatedString.size());
217
219 if (auto EC = Writer->writeCString(S))
220 return EC;
221 } else {
222 if (auto EC = Reader->readCString(Value))
223 return EC;
224 }
226}
227
229 constexpr uint32_t GuidSize = 16;
230
233 StringRef((reinterpret_cast<const char *>(&Guid)), GuidSize);
234 emitComment(Comment);
235 Streamer->emitBytes(GuidSR);
236 incrStreamedLen(GuidSize);
238 }
239
242
244 if (auto EC = Writer->writeBytes(Guid.Guid))
245 return EC;
246 } else {
248 if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
249 return EC;
250 memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
251 }
253}
254
256 const Twine &Comment) {
257
259 emitComment(Comment);
260 for (auto V : Value) {
262 return EC;
263 }
266 return EC;
267 } else {
270 return EC;
271 while (!S.empty()) {
272 Value.push_back(S);
274 return EC;
275 };
276 }
278}
279
280void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
281 const Twine &Comment) {
282
283
284
286 emitComment(Comment);
288 incrStreamedLen(2);
289 } else if (Value >= std::numeric_limits<int8_t>::min() &&
290 Value <= std::numeric_limits<int8_t>::max()) {
292 emitComment(Comment);
294 incrStreamedLen(3);
295 } else if (Value >= std::numeric_limits<int16_t>::min() &&
296 Value <= std::numeric_limits<int16_t>::max()) {
298 emitComment(Comment);
300 incrStreamedLen(4);
301 } else if (Value >= std::numeric_limits<int32_t>::min() &&
302 Value <= std::numeric_limits<int32_t>::max()) {
303 Streamer->emitIntValue(LF_LONG, 2);
304 emitComment(Comment);
305 Streamer->emitIntValue(Value, 4);
306 incrStreamedLen(6);
307 } else {
308 Streamer->emitIntValue(LF_QUADWORD, 2);
309 emitComment(Comment);
310 Streamer->emitIntValue(Value, 4);
311 incrStreamedLen(6);
312 }
313}
314
315void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value,
316 const Twine &Comment) {
317 if (Value < LF_NUMERIC) {
318 emitComment(Comment);
319 Streamer->emitIntValue(Value, 2);
320 incrStreamedLen(2);
321 } else if (Value <= std::numeric_limits<uint16_t>::max()) {
322 Streamer->emitIntValue(LF_USHORT, 2);
323 emitComment(Comment);
324 Streamer->emitIntValue(Value, 2);
325 incrStreamedLen(4);
326 } else if (Value <= std::numeric_limits<uint32_t>::max()) {
327 Streamer->emitIntValue(LF_ULONG, 2);
328 emitComment(Comment);
329 Streamer->emitIntValue(Value, 4);
330 incrStreamedLen(6);
331 } else {
332
333 Streamer->emitIntValue(LF_UQUADWORD, 2);
334 emitComment(Comment);
335 Streamer->emitIntValue(Value, 8);
336 incrStreamedLen(6);
337 }
338}
339
340Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) {
342 if (auto EC = Writer->writeInteger<int16_t>(Value))
343 return EC;
344 } else if (Value >= std::numeric_limits<int8_t>::min() &&
345 Value <= std::numeric_limits<int8_t>::max()) {
346 if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
347 return EC;
348 if (auto EC = Writer->writeInteger<int8_t>(Value))
349 return EC;
350 } else if (Value >= std::numeric_limits<int16_t>::min() &&
351 Value <= std::numeric_limits<int16_t>::max()) {
352 if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
353 return EC;
354 if (auto EC = Writer->writeInteger<int16_t>(Value))
355 return EC;
356 } else if (Value >= std::numeric_limits<int32_t>::min() &&
357 Value <= std::numeric_limits<int32_t>::max()) {
358 if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
359 return EC;
360 if (auto EC = Writer->writeInteger<int32_t>(Value))
361 return EC;
362 } else {
363 if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
364 return EC;
365 if (auto EC = Writer->writeInteger(Value))
366 return EC;
367 }
369}
370
371Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
372 if (Value < LF_NUMERIC) {
373 if (auto EC = Writer->writeInteger<uint16_t>(Value))
374 return EC;
375 } else if (Value <= std::numeric_limits<uint16_t>::max()) {
376 if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
377 return EC;
378 if (auto EC = Writer->writeInteger<uint16_t>(Value))
379 return EC;
380 } else if (Value <= std::numeric_limits<uint32_t>::max()) {
381 if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
382 return EC;
383 if (auto EC = Writer->writeInteger<uint32_t>(Value))
384 return EC;
385 } else {
386 if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
387 return EC;
388 if (auto EC = Writer->writeInteger(Value))
389 return EC;
390 }
391
393}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
An arbitrary precision integer that knows its signedness.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM Value Representation.
LLVM_ABI Error padToAlignment(uint32_t Align)
Definition CodeViewRecordIO.cpp:82
LLVM_ABI Error endRecord()
Definition CodeViewRecordIO.cpp:29
LLVM_ABI Error mapInteger(TypeIndex &TypeInd, const Twine &Comment="")
Definition CodeViewRecordIO.cpp:130
LLVM_ABI Error mapGuid(GUID &Guid, const Twine &Comment="")
Definition CodeViewRecordIO.cpp:228
LLVM_ABI Error mapStringZVectorZ(std::vector< StringRef > &Value, const Twine &Comment="")
Definition CodeViewRecordIO.cpp:255
LLVM_ABI Error skipPadding()
Definition CodeViewRecordIO.cpp:88
LLVM_ABI Error mapStringZ(StringRef &Value, const Twine &Comment="")
Definition CodeViewRecordIO.cpp:210
uint64_t getStreamedLen()
LLVM_ABI Error mapEncodedInteger(int64_t &Value, const Twine &Comment="")
Definition CodeViewRecordIO.cpp:151
LLVM_ABI Error beginRecord(std::optional< uint32_t > MaxLength)
Definition CodeViewRecordIO.cpp:21
LLVM_ABI Error mapByteVectorTail(ArrayRef< uint8_t > &Bytes, const Twine &Comment="")
Definition CodeViewRecordIO.cpp:103
LLVM_ABI uint32_t maxFieldLength() const
Definition CodeViewRecordIO.cpp:60
virtual void emitIntValue(uint64_t Value, unsigned Size)=0
void setIndex(uint32_t I)
uint32_t getIndex() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
ArrayRef(const T &OneElt) -> ArrayRef< T >
StringRef toStringRef(bool B)
Construct a string ref from a boolean.
This struct is a compact representation of a valid (non-zero power of two) alignment.
This represents the 'GUID' type from windows.h.