[llvm-exegesis][NFC] Fix typo
[llvm-complete.git] / lib / DebugInfo / CodeView / RecordSerialization.cpp
blobbff9a619a846139642c16f69eb4c0b5c1c162e23
1 //===-- RecordSerialization.cpp -------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Utilities for serializing and deserializing CodeView records.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/APSInt.h"
17 #include "llvm/DebugInfo/CodeView/CodeViewError.h"
18 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
19 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
20 #include "llvm/Support/BinaryByteStream.h"
22 using namespace llvm;
23 using namespace llvm::codeview;
24 using namespace llvm::support;
26 /// Reinterpret a byte array as an array of characters. Does not interpret as
27 /// a C string, as StringRef has several helpers (split) that make that easy.
28 StringRef llvm::codeview::getBytesAsCharacters(ArrayRef<uint8_t> LeafData) {
29 return StringRef(reinterpret_cast<const char *>(LeafData.data()),
30 LeafData.size());
33 StringRef llvm::codeview::getBytesAsCString(ArrayRef<uint8_t> LeafData) {
34 return getBytesAsCharacters(LeafData).split('\0').first;
37 Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
38 // Used to avoid overload ambiguity on APInt construtor.
39 bool FalseVal = false;
40 uint16_t Short;
41 if (auto EC = Reader.readInteger(Short))
42 return EC;
44 if (Short < LF_NUMERIC) {
45 Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
46 /*isUnsigned=*/true);
47 return Error::success();
50 switch (Short) {
51 case LF_CHAR: {
52 int8_t N;
53 if (auto EC = Reader.readInteger(N))
54 return EC;
55 Num = APSInt(APInt(8, N, true), false);
56 return Error::success();
58 case LF_SHORT: {
59 int16_t N;
60 if (auto EC = Reader.readInteger(N))
61 return EC;
62 Num = APSInt(APInt(16, N, true), false);
63 return Error::success();
65 case LF_USHORT: {
66 uint16_t N;
67 if (auto EC = Reader.readInteger(N))
68 return EC;
69 Num = APSInt(APInt(16, N, false), true);
70 return Error::success();
72 case LF_LONG: {
73 int32_t N;
74 if (auto EC = Reader.readInteger(N))
75 return EC;
76 Num = APSInt(APInt(32, N, true), false);
77 return Error::success();
79 case LF_ULONG: {
80 uint32_t N;
81 if (auto EC = Reader.readInteger(N))
82 return EC;
83 Num = APSInt(APInt(32, N, FalseVal), true);
84 return Error::success();
86 case LF_QUADWORD: {
87 int64_t N;
88 if (auto EC = Reader.readInteger(N))
89 return EC;
90 Num = APSInt(APInt(64, N, true), false);
91 return Error::success();
93 case LF_UQUADWORD: {
94 uint64_t N;
95 if (auto EC = Reader.readInteger(N))
96 return EC;
97 Num = APSInt(APInt(64, N, false), true);
98 return Error::success();
101 return make_error<CodeViewError>(cv_error_code::corrupt_record,
102 "Buffer contains invalid APSInt type");
105 Error llvm::codeview::consume(StringRef &Data, APSInt &Num) {
106 ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
107 BinaryByteStream S(Bytes, llvm::support::little);
108 BinaryStreamReader SR(S);
109 auto EC = consume(SR, Num);
110 Data = Data.take_back(SR.bytesRemaining());
111 return EC;
114 /// Decode a numeric leaf value that is known to be a uint64_t.
115 Error llvm::codeview::consume_numeric(BinaryStreamReader &Reader,
116 uint64_t &Num) {
117 APSInt N;
118 if (auto EC = consume(Reader, N))
119 return EC;
120 if (N.isSigned() || !N.isIntN(64))
121 return make_error<CodeViewError>(cv_error_code::corrupt_record,
122 "Data is not a numeric value!");
123 Num = N.getLimitedValue();
124 return Error::success();
127 Error llvm::codeview::consume(BinaryStreamReader &Reader, uint32_t &Item) {
128 return Reader.readInteger(Item);
131 Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
132 ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
133 BinaryByteStream S(Bytes, llvm::support::little);
134 BinaryStreamReader SR(S);
135 auto EC = consume(SR, Item);
136 Data = Data.take_back(SR.bytesRemaining());
137 return EC;
140 Error llvm::codeview::consume(BinaryStreamReader &Reader, int32_t &Item) {
141 return Reader.readInteger(Item);
144 Error llvm::codeview::consume(BinaryStreamReader &Reader, StringRef &Item) {
145 if (Reader.empty())
146 return make_error<CodeViewError>(cv_error_code::corrupt_record,
147 "Null terminated string buffer is empty!");
149 return Reader.readCString(Item);
152 Expected<CVSymbol> llvm::codeview::readSymbolFromStream(BinaryStreamRef Stream,
153 uint32_t Offset) {
154 return readCVRecordFromStream<SymbolKind>(Stream, Offset);