Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- RecordSerialization.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
//===----------------------------------------------------------------------===//
8
 
9
#ifndef LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H
10
#define LLVM_DEBUGINFO_CODEVIEW_RECORDSERIALIZATION_H
11
 
12
#include "llvm/ADT/ArrayRef.h"
13
#include "llvm/ADT/StringRef.h"
14
#include "llvm/DebugInfo/CodeView/CodeView.h"
15
#include "llvm/DebugInfo/CodeView/CodeViewError.h"
16
#include "llvm/Support/BinaryStreamReader.h"
17
#include "llvm/Support/Endian.h"
18
#include "llvm/Support/Error.h"
19
#include <cinttypes>
20
 
21
namespace llvm {
22
class APSInt;
23
namespace codeview {
24
using llvm::support::little32_t;
25
using llvm::support::ulittle16_t;
26
using llvm::support::ulittle32_t;
27
 
28
/// Limit on the size of all codeview symbol and type records, including the
29
/// RecordPrefix. MSVC does not emit any records larger than this.
30
enum : unsigned { MaxRecordLength = 0xFF00 };
31
 
32
struct RecordPrefix {
33
  RecordPrefix() = default;
34
  explicit RecordPrefix(uint16_t Kind) : RecordLen(2), RecordKind(Kind) {}
35
 
36
  ulittle16_t RecordLen;  // Record length, starting from &RecordKind.
37
  ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
38
};
39
 
40
/// Reinterpret a byte array as an array of characters. Does not interpret as
41
/// a C string, as StringRef has several helpers (split) that make that easy.
42
StringRef getBytesAsCharacters(ArrayRef<uint8_t> LeafData);
43
StringRef getBytesAsCString(ArrayRef<uint8_t> LeafData);
44
 
45
inline Error consume(BinaryStreamReader &Reader) { return Error::success(); }
46
 
47
/// Decodes a numeric "leaf" value. These are integer literals encountered in
48
/// the type stream. If the value is positive and less than LF_NUMERIC (1 <<
49
/// 15), it is emitted directly in Data. Otherwise, it has a tag like LF_CHAR
50
/// that indicates the bitwidth and sign of the numeric data.
51
Error consume(BinaryStreamReader &Reader, APSInt &Num);
52
 
53
/// Decodes a numeric leaf value that is known to be a particular type.
54
Error consume_numeric(BinaryStreamReader &Reader, uint64_t &Value);
55
 
56
/// Decodes signed and unsigned fixed-length integers.
57
Error consume(BinaryStreamReader &Reader, uint32_t &Item);
58
Error consume(BinaryStreamReader &Reader, int32_t &Item);
59
 
60
/// Decodes a null terminated string.
61
Error consume(BinaryStreamReader &Reader, StringRef &Item);
62
 
63
Error consume(StringRef &Data, APSInt &Num);
64
Error consume(StringRef &Data, uint32_t &Item);
65
 
66
/// Decodes an arbitrary object whose layout matches that of the underlying
67
/// byte sequence, and returns a pointer to the object.
68
template <typename T> Error consume(BinaryStreamReader &Reader, T *&Item) {
69
  return Reader.readObject(Item);
70
}
71
 
72
template <typename T, typename U> struct serialize_conditional_impl {
73
  serialize_conditional_impl(T &Item, U Func) : Item(Item), Func(Func) {}
74
 
75
  Error deserialize(BinaryStreamReader &Reader) const {
76
    if (!Func())
77
      return Error::success();
78
    return consume(Reader, Item);
79
  }
80
 
81
  T &Item;
82
  U Func;
83
};
84
 
85
template <typename T, typename U>
86
serialize_conditional_impl<T, U> serialize_conditional(T &Item, U Func) {
87
  return serialize_conditional_impl<T, U>(Item, Func);
88
}
89
 
90
template <typename T, typename U> struct serialize_array_impl {
91
  serialize_array_impl(ArrayRef<T> &Item, U Func) : Item(Item), Func(Func) {}
92
 
93
  Error deserialize(BinaryStreamReader &Reader) const {
94
    return Reader.readArray(Item, Func());
95
  }
96
 
97
  ArrayRef<T> &Item;
98
  U Func;
99
};
100
 
101
template <typename T> struct serialize_vector_tail_impl {
102
  serialize_vector_tail_impl(std::vector<T> &Item) : Item(Item) {}
103
 
104
  Error deserialize(BinaryStreamReader &Reader) const {
105
    T Field;
106
    // Stop when we run out of bytes or we hit record padding bytes.
107
    while (!Reader.empty() && Reader.peek() < LF_PAD0) {
108
      if (auto EC = consume(Reader, Field))
109
        return EC;
110
      Item.push_back(Field);
111
    }
112
    return Error::success();
113
  }
114
 
115
  std::vector<T> &Item;
116
};
117
 
118
struct serialize_null_term_string_array_impl {
119
  serialize_null_term_string_array_impl(std::vector<StringRef> &Item)
120
      : Item(Item) {}
121
 
122
  Error deserialize(BinaryStreamReader &Reader) const {
123
    if (Reader.empty())
124
      return make_error<CodeViewError>(cv_error_code::insufficient_buffer,
125
                                       "Null terminated string is empty!");
126
 
127
    while (Reader.peek() != 0) {
128
      StringRef Field;
129
      if (auto EC = Reader.readCString(Field))
130
        return EC;
131
      Item.push_back(Field);
132
    }
133
    return Reader.skip(1);
134
  }
135
 
136
  std::vector<StringRef> &Item;
137
};
138
 
139
template <typename T> struct serialize_arrayref_tail_impl {
140
  serialize_arrayref_tail_impl(ArrayRef<T> &Item) : Item(Item) {}
141
 
142
  Error deserialize(BinaryStreamReader &Reader) const {
143
    uint32_t Count = Reader.bytesRemaining() / sizeof(T);
144
    return Reader.readArray(Item, Count);
145
  }
146
 
147
  ArrayRef<T> &Item;
148
};
149
 
150
template <typename T> struct serialize_numeric_impl {
151
  serialize_numeric_impl(T &Item) : Item(Item) {}
152
 
153
  Error deserialize(BinaryStreamReader &Reader) const {
154
    return consume_numeric(Reader, Item);
155
  }
156
 
157
  T &Item;
158
};
159
 
160
template <typename T, typename U>
161
serialize_array_impl<T, U> serialize_array(ArrayRef<T> &Item, U Func) {
162
  return serialize_array_impl<T, U>(Item, Func);
163
}
164
 
165
inline serialize_null_term_string_array_impl
166
serialize_null_term_string_array(std::vector<StringRef> &Item) {
167
  return serialize_null_term_string_array_impl(Item);
168
}
169
 
170
template <typename T>
171
serialize_vector_tail_impl<T> serialize_array_tail(std::vector<T> &Item) {
172
  return serialize_vector_tail_impl<T>(Item);
173
}
174
 
175
template <typename T>
176
serialize_arrayref_tail_impl<T> serialize_array_tail(ArrayRef<T> &Item) {
177
  return serialize_arrayref_tail_impl<T>(Item);
178
}
179
 
180
template <typename T> serialize_numeric_impl<T> serialize_numeric(T &Item) {
181
  return serialize_numeric_impl<T>(Item);
182
}
183
 
184
template <typename T, typename U>
185
Error consume(BinaryStreamReader &Reader,
186
              const serialize_conditional_impl<T, U> &Item) {
187
  return Item.deserialize(Reader);
188
}
189
 
190
template <typename T, typename U>
191
Error consume(BinaryStreamReader &Reader,
192
              const serialize_array_impl<T, U> &Item) {
193
  return Item.deserialize(Reader);
194
}
195
 
196
inline Error consume(BinaryStreamReader &Reader,
197
                     const serialize_null_term_string_array_impl &Item) {
198
  return Item.deserialize(Reader);
199
}
200
 
201
template <typename T>
202
Error consume(BinaryStreamReader &Reader,
203
              const serialize_vector_tail_impl<T> &Item) {
204
  return Item.deserialize(Reader);
205
}
206
 
207
template <typename T>
208
Error consume(BinaryStreamReader &Reader,
209
              const serialize_arrayref_tail_impl<T> &Item) {
210
  return Item.deserialize(Reader);
211
}
212
 
213
template <typename T>
214
Error consume(BinaryStreamReader &Reader,
215
              const serialize_numeric_impl<T> &Item) {
216
  return Item.deserialize(Reader);
217
}
218
 
219
template <typename T, typename U, typename... Args>
220
Error consume(BinaryStreamReader &Reader, T &&X, U &&Y, Args &&... Rest) {
221
  if (auto EC = consume(Reader, X))
222
    return EC;
223
  return consume(Reader, Y, std::forward<Args>(Rest)...);
224
}
225
 
226
}
227
}
228
 
229
#endif