File: | include/llvm/Bitcode/BitstreamReader.h |
Warning: | line 210, column 39 The result of the right shift is undefined due to shifting by '64', which is greater or equal to the width of type 'llvm::SimpleBitstreamCursor::word_t' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- BitcodeReader.cpp - ClangDoc Bitcode Reader ------------*- C++ -*-===// | |||
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 | #include "BitcodeReader.h" | |||
11 | #include "llvm/ADT/IndexedMap.h" | |||
12 | #include "llvm/ADT/Optional.h" | |||
13 | #include "llvm/Support/Error.h" | |||
14 | #include "llvm/Support/raw_ostream.h" | |||
15 | ||||
16 | namespace clang { | |||
17 | namespace doc { | |||
18 | ||||
19 | using Record = llvm::SmallVector<uint64_t, 1024>; | |||
20 | ||||
21 | llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl<char> &Field, | |||
22 | llvm::StringRef Blob) { | |||
23 | Field.assign(Blob.begin(), Blob.end()); | |||
24 | return llvm::Error::success(); | |||
25 | } | |||
26 | ||||
27 | llvm::Error decodeRecord(Record R, SymbolID &Field, llvm::StringRef Blob) { | |||
28 | if (R[0] != BitCodeConstants::USRHashSize) | |||
29 | return llvm::make_error<llvm::StringError>("Incorrect USR size.\n", | |||
30 | llvm::inconvertibleErrorCode()); | |||
31 | ||||
32 | // First position in the record is the length of the following array, so we | |||
33 | // copy the following elements to the field. | |||
34 | for (int I = 0, E = R[0]; I < E; ++I) | |||
35 | Field[I] = R[I + 1]; | |||
36 | return llvm::Error::success(); | |||
37 | } | |||
38 | ||||
39 | llvm::Error decodeRecord(Record R, bool &Field, llvm::StringRef Blob) { | |||
40 | Field = R[0] != 0; | |||
41 | return llvm::Error::success(); | |||
42 | } | |||
43 | ||||
44 | llvm::Error decodeRecord(Record R, int &Field, llvm::StringRef Blob) { | |||
45 | if (R[0] > INT_MAX2147483647) | |||
46 | return llvm::make_error<llvm::StringError>("Integer too large to parse.\n", | |||
47 | llvm::inconvertibleErrorCode()); | |||
48 | Field = (int)R[0]; | |||
49 | return llvm::Error::success(); | |||
50 | } | |||
51 | ||||
52 | llvm::Error decodeRecord(Record R, AccessSpecifier &Field, | |||
53 | llvm::StringRef Blob) { | |||
54 | switch (R[0]) { | |||
55 | case AS_public: | |||
56 | case AS_private: | |||
57 | case AS_protected: | |||
58 | case AS_none: | |||
59 | Field = (AccessSpecifier)R[0]; | |||
60 | return llvm::Error::success(); | |||
61 | default: | |||
62 | return llvm::make_error<llvm::StringError>( | |||
63 | "Invalid value for AccessSpecifier.\n", llvm::inconvertibleErrorCode()); | |||
64 | } | |||
65 | } | |||
66 | ||||
67 | llvm::Error decodeRecord(Record R, TagTypeKind &Field, llvm::StringRef Blob) { | |||
68 | switch (R[0]) { | |||
69 | case TTK_Struct: | |||
70 | case TTK_Interface: | |||
71 | case TTK_Union: | |||
72 | case TTK_Class: | |||
73 | case TTK_Enum: | |||
74 | Field = (TagTypeKind)R[0]; | |||
75 | return llvm::Error::success(); | |||
76 | default: | |||
77 | return llvm::make_error<llvm::StringError>( | |||
78 | "Invalid value for TagTypeKind.\n", llvm::inconvertibleErrorCode()); | |||
79 | } | |||
80 | } | |||
81 | ||||
82 | llvm::Error decodeRecord(Record R, llvm::Optional<Location> &Field, | |||
83 | llvm::StringRef Blob) { | |||
84 | if (R[0] > INT_MAX2147483647) | |||
85 | return llvm::make_error<llvm::StringError>("Integer too large to parse.\n", | |||
86 | llvm::inconvertibleErrorCode()); | |||
87 | Field.emplace((int)R[0], Blob); | |||
88 | return llvm::Error::success(); | |||
89 | } | |||
90 | ||||
91 | llvm::Error decodeRecord(Record R, InfoType &Field, llvm::StringRef Blob) { | |||
92 | switch (auto IT = static_cast<InfoType>(R[0])) { | |||
93 | case InfoType::IT_namespace: | |||
94 | case InfoType::IT_record: | |||
95 | case InfoType::IT_function: | |||
96 | case InfoType::IT_default: | |||
97 | case InfoType::IT_enum: | |||
98 | Field = IT; | |||
99 | return llvm::Error::success(); | |||
100 | } | |||
101 | return llvm::make_error<llvm::StringError>("Invalid value for InfoType.\n", | |||
102 | llvm::inconvertibleErrorCode()); | |||
103 | } | |||
104 | ||||
105 | llvm::Error decodeRecord(Record R, FieldId &Field, llvm::StringRef Blob) { | |||
106 | switch (auto F = static_cast<FieldId>(R[0])) { | |||
107 | case FieldId::F_namespace: | |||
108 | case FieldId::F_parent: | |||
109 | case FieldId::F_vparent: | |||
110 | case FieldId::F_type: | |||
111 | case FieldId::F_child_namespace: | |||
112 | case FieldId::F_child_record: | |||
113 | case FieldId::F_default: | |||
114 | Field = F; | |||
115 | return llvm::Error::success(); | |||
116 | } | |||
117 | return llvm::make_error<llvm::StringError>("Invalid value for FieldId.\n", | |||
118 | llvm::inconvertibleErrorCode()); | |||
119 | } | |||
120 | ||||
121 | llvm::Error decodeRecord(Record R, | |||
122 | llvm::SmallVectorImpl<llvm::SmallString<16>> &Field, | |||
123 | llvm::StringRef Blob) { | |||
124 | Field.push_back(Blob); | |||
125 | return llvm::Error::success(); | |||
126 | } | |||
127 | ||||
128 | llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl<Location> &Field, | |||
129 | llvm::StringRef Blob) { | |||
130 | if (R[0] > INT_MAX2147483647) | |||
131 | return llvm::make_error<llvm::StringError>("Integer too large to parse.\n", | |||
132 | llvm::inconvertibleErrorCode()); | |||
133 | Field.emplace_back((int)R[0], Blob); | |||
134 | return llvm::Error::success(); | |||
135 | } | |||
136 | ||||
137 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
138 | const unsigned VersionNo) { | |||
139 | if (ID == VERSION && R[0] == VersionNo) | |||
140 | return llvm::Error::success(); | |||
141 | return llvm::make_error<llvm::StringError>( | |||
142 | "Mismatched bitcode version number.\n", llvm::inconvertibleErrorCode()); | |||
143 | } | |||
144 | ||||
145 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
146 | NamespaceInfo *I) { | |||
147 | switch (ID) { | |||
148 | case NAMESPACE_USR: | |||
149 | return decodeRecord(R, I->USR, Blob); | |||
150 | case NAMESPACE_NAME: | |||
151 | return decodeRecord(R, I->Name, Blob); | |||
152 | default: | |||
153 | return llvm::make_error<llvm::StringError>( | |||
154 | "Invalid field for NamespaceInfo.\n", llvm::inconvertibleErrorCode()); | |||
155 | } | |||
156 | } | |||
157 | ||||
158 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
159 | RecordInfo *I) { | |||
160 | switch (ID) { | |||
161 | case RECORD_USR: | |||
162 | return decodeRecord(R, I->USR, Blob); | |||
163 | case RECORD_NAME: | |||
164 | return decodeRecord(R, I->Name, Blob); | |||
165 | case RECORD_DEFLOCATION: | |||
166 | return decodeRecord(R, I->DefLoc, Blob); | |||
167 | case RECORD_LOCATION: | |||
168 | return decodeRecord(R, I->Loc, Blob); | |||
169 | case RECORD_TAG_TYPE: | |||
170 | return decodeRecord(R, I->TagType, Blob); | |||
171 | default: | |||
172 | return llvm::make_error<llvm::StringError>( | |||
173 | "Invalid field for RecordInfo.\n", llvm::inconvertibleErrorCode()); | |||
174 | } | |||
175 | } | |||
176 | ||||
177 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
178 | EnumInfo *I) { | |||
179 | switch (ID) { | |||
180 | case ENUM_USR: | |||
181 | return decodeRecord(R, I->USR, Blob); | |||
182 | case ENUM_NAME: | |||
183 | return decodeRecord(R, I->Name, Blob); | |||
184 | case ENUM_DEFLOCATION: | |||
185 | return decodeRecord(R, I->DefLoc, Blob); | |||
186 | case ENUM_LOCATION: | |||
187 | return decodeRecord(R, I->Loc, Blob); | |||
188 | case ENUM_MEMBER: | |||
189 | return decodeRecord(R, I->Members, Blob); | |||
190 | case ENUM_SCOPED: | |||
191 | return decodeRecord(R, I->Scoped, Blob); | |||
192 | default: | |||
193 | return llvm::make_error<llvm::StringError>("Invalid field for EnumInfo.\n", | |||
194 | llvm::inconvertibleErrorCode()); | |||
195 | } | |||
196 | } | |||
197 | ||||
198 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
199 | FunctionInfo *I) { | |||
200 | switch (ID) { | |||
201 | case FUNCTION_USR: | |||
202 | return decodeRecord(R, I->USR, Blob); | |||
203 | case FUNCTION_NAME: | |||
204 | return decodeRecord(R, I->Name, Blob); | |||
205 | case FUNCTION_DEFLOCATION: | |||
206 | return decodeRecord(R, I->DefLoc, Blob); | |||
207 | case FUNCTION_LOCATION: | |||
208 | return decodeRecord(R, I->Loc, Blob); | |||
209 | case FUNCTION_ACCESS: | |||
210 | return decodeRecord(R, I->Access, Blob); | |||
211 | case FUNCTION_IS_METHOD: | |||
212 | return decodeRecord(R, I->IsMethod, Blob); | |||
213 | default: | |||
214 | return llvm::make_error<llvm::StringError>( | |||
215 | "Invalid field for FunctionInfo.\n", llvm::inconvertibleErrorCode()); | |||
216 | } | |||
217 | } | |||
218 | ||||
219 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
220 | TypeInfo *I) { | |||
221 | return llvm::Error::success(); | |||
222 | } | |||
223 | ||||
224 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
225 | FieldTypeInfo *I) { | |||
226 | switch (ID) { | |||
227 | case FIELD_TYPE_NAME: | |||
228 | return decodeRecord(R, I->Name, Blob); | |||
229 | default: | |||
230 | return llvm::make_error<llvm::StringError>("Invalid field for TypeInfo.\n", | |||
231 | llvm::inconvertibleErrorCode()); | |||
232 | } | |||
233 | } | |||
234 | ||||
235 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
236 | MemberTypeInfo *I) { | |||
237 | switch (ID) { | |||
238 | case MEMBER_TYPE_NAME: | |||
239 | return decodeRecord(R, I->Name, Blob); | |||
240 | case MEMBER_TYPE_ACCESS: | |||
241 | return decodeRecord(R, I->Access, Blob); | |||
242 | default: | |||
243 | return llvm::make_error<llvm::StringError>( | |||
244 | "Invalid field for MemberTypeInfo.\n", llvm::inconvertibleErrorCode()); | |||
245 | } | |||
246 | } | |||
247 | ||||
248 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
249 | CommentInfo *I) { | |||
250 | switch (ID) { | |||
251 | case COMMENT_KIND: | |||
252 | return decodeRecord(R, I->Kind, Blob); | |||
253 | case COMMENT_TEXT: | |||
254 | return decodeRecord(R, I->Text, Blob); | |||
255 | case COMMENT_NAME: | |||
256 | return decodeRecord(R, I->Name, Blob); | |||
257 | case COMMENT_DIRECTION: | |||
258 | return decodeRecord(R, I->Direction, Blob); | |||
259 | case COMMENT_PARAMNAME: | |||
260 | return decodeRecord(R, I->ParamName, Blob); | |||
261 | case COMMENT_CLOSENAME: | |||
262 | return decodeRecord(R, I->CloseName, Blob); | |||
263 | case COMMENT_ATTRKEY: | |||
264 | return decodeRecord(R, I->AttrKeys, Blob); | |||
265 | case COMMENT_ATTRVAL: | |||
266 | return decodeRecord(R, I->AttrValues, Blob); | |||
267 | case COMMENT_ARG: | |||
268 | return decodeRecord(R, I->Args, Blob); | |||
269 | case COMMENT_SELFCLOSING: | |||
270 | return decodeRecord(R, I->SelfClosing, Blob); | |||
271 | case COMMENT_EXPLICIT: | |||
272 | return decodeRecord(R, I->Explicit, Blob); | |||
273 | default: | |||
274 | return llvm::make_error<llvm::StringError>( | |||
275 | "Invalid field for CommentInfo.\n", llvm::inconvertibleErrorCode()); | |||
276 | } | |||
277 | } | |||
278 | ||||
279 | llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |||
280 | Reference *I, FieldId &F) { | |||
281 | switch (ID) { | |||
282 | case REFERENCE_USR: | |||
283 | return decodeRecord(R, I->USR, Blob); | |||
284 | case REFERENCE_NAME: | |||
285 | return decodeRecord(R, I->Name, Blob); | |||
286 | case REFERENCE_TYPE: | |||
287 | return decodeRecord(R, I->RefType, Blob); | |||
288 | case REFERENCE_FIELD: | |||
289 | return decodeRecord(R, F, Blob); | |||
290 | default: | |||
291 | return llvm::make_error<llvm::StringError>("Invalid field for Reference.\n", | |||
292 | llvm::inconvertibleErrorCode()); | |||
293 | } | |||
294 | } | |||
295 | ||||
296 | template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) { | |||
297 | return llvm::make_error<llvm::StringError>( | |||
298 | "Invalid type cannot contain CommentInfo.\n", | |||
299 | llvm::inconvertibleErrorCode()); | |||
300 | } | |||
301 | ||||
302 | template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) { | |||
303 | I->Description.emplace_back(); | |||
304 | return &I->Description.back(); | |||
305 | } | |||
306 | ||||
307 | template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) { | |||
308 | I->Description.emplace_back(); | |||
309 | return &I->Description.back(); | |||
310 | } | |||
311 | ||||
312 | template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) { | |||
313 | I->Description.emplace_back(); | |||
314 | return &I->Description.back(); | |||
315 | } | |||
316 | ||||
317 | template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) { | |||
318 | I->Description.emplace_back(); | |||
319 | return &I->Description.back(); | |||
320 | } | |||
321 | ||||
322 | template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) { | |||
323 | I->Children.emplace_back(llvm::make_unique<CommentInfo>()); | |||
324 | return I->Children.back().get(); | |||
325 | } | |||
326 | ||||
327 | template <> | |||
328 | llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) { | |||
329 | return getCommentInfo(I.get()); | |||
330 | } | |||
331 | ||||
332 | template <typename T, typename TTypeInfo> | |||
333 | llvm::Error addTypeInfo(T I, TTypeInfo &&TI) { | |||
334 | return llvm::make_error<llvm::StringError>( | |||
335 | "Invalid type cannot contain TypeInfo.\n", | |||
336 | llvm::inconvertibleErrorCode()); | |||
337 | } | |||
338 | ||||
339 | template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) { | |||
340 | I->Members.emplace_back(std::move(T)); | |||
341 | return llvm::Error::success(); | |||
342 | } | |||
343 | ||||
344 | template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) { | |||
345 | I->ReturnType = std::move(T); | |||
346 | return llvm::Error::success(); | |||
347 | } | |||
348 | ||||
349 | template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) { | |||
350 | I->Params.emplace_back(std::move(T)); | |||
351 | return llvm::Error::success(); | |||
352 | } | |||
353 | ||||
354 | template <typename T> llvm::Error addReference(T I, Reference &&R, FieldId F) { | |||
355 | return llvm::make_error<llvm::StringError>( | |||
356 | "Invalid type cannot contain Reference\n", | |||
357 | llvm::inconvertibleErrorCode()); | |||
358 | } | |||
359 | ||||
360 | template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) { | |||
361 | switch (F) { | |||
362 | case FieldId::F_type: | |||
363 | I->Type = std::move(R); | |||
364 | return llvm::Error::success(); | |||
365 | default: | |||
366 | return llvm::make_error<llvm::StringError>( | |||
367 | "Invalid type cannot contain Reference.\n", | |||
368 | llvm::inconvertibleErrorCode()); | |||
369 | } | |||
370 | } | |||
371 | ||||
372 | template <> | |||
373 | llvm::Error addReference(FieldTypeInfo *I, Reference &&R, FieldId F) { | |||
374 | switch (F) { | |||
375 | case FieldId::F_type: | |||
376 | I->Type = std::move(R); | |||
377 | return llvm::Error::success(); | |||
378 | default: | |||
379 | return llvm::make_error<llvm::StringError>( | |||
380 | "Invalid type cannot contain Reference.\n", | |||
381 | llvm::inconvertibleErrorCode()); | |||
382 | } | |||
383 | } | |||
384 | ||||
385 | template <> | |||
386 | llvm::Error addReference(MemberTypeInfo *I, Reference &&R, FieldId F) { | |||
387 | switch (F) { | |||
388 | case FieldId::F_type: | |||
389 | I->Type = std::move(R); | |||
390 | return llvm::Error::success(); | |||
391 | default: | |||
392 | return llvm::make_error<llvm::StringError>( | |||
393 | "Invalid type cannot contain Reference.\n", | |||
394 | llvm::inconvertibleErrorCode()); | |||
395 | } | |||
396 | } | |||
397 | ||||
398 | template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) { | |||
399 | switch (F) { | |||
400 | case FieldId::F_namespace: | |||
401 | I->Namespace.emplace_back(std::move(R)); | |||
402 | return llvm::Error::success(); | |||
403 | default: | |||
404 | return llvm::make_error<llvm::StringError>( | |||
405 | "Invalid type cannot contain Reference.\n", | |||
406 | llvm::inconvertibleErrorCode()); | |||
407 | } | |||
408 | } | |||
409 | ||||
410 | template <> | |||
411 | llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) { | |||
412 | switch (F) { | |||
413 | case FieldId::F_namespace: | |||
414 | I->Namespace.emplace_back(std::move(R)); | |||
415 | return llvm::Error::success(); | |||
416 | case FieldId::F_child_namespace: | |||
417 | I->ChildNamespaces.emplace_back(std::move(R)); | |||
418 | return llvm::Error::success(); | |||
419 | case FieldId::F_child_record: | |||
420 | I->ChildRecords.emplace_back(std::move(R)); | |||
421 | return llvm::Error::success(); | |||
422 | default: | |||
423 | return llvm::make_error<llvm::StringError>( | |||
424 | "Invalid type cannot contain Reference.\n", | |||
425 | llvm::inconvertibleErrorCode()); | |||
426 | } | |||
427 | } | |||
428 | ||||
429 | template <> | |||
430 | llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) { | |||
431 | switch (F) { | |||
432 | case FieldId::F_namespace: | |||
433 | I->Namespace.emplace_back(std::move(R)); | |||
434 | return llvm::Error::success(); | |||
435 | case FieldId::F_parent: | |||
436 | I->Parent = std::move(R); | |||
437 | return llvm::Error::success(); | |||
438 | default: | |||
439 | return llvm::make_error<llvm::StringError>( | |||
440 | "Invalid type cannot contain Reference.\n", | |||
441 | llvm::inconvertibleErrorCode()); | |||
442 | } | |||
443 | } | |||
444 | ||||
445 | template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) { | |||
446 | switch (F) { | |||
447 | case FieldId::F_namespace: | |||
448 | I->Namespace.emplace_back(std::move(R)); | |||
449 | return llvm::Error::success(); | |||
450 | case FieldId::F_parent: | |||
451 | I->Parents.emplace_back(std::move(R)); | |||
452 | return llvm::Error::success(); | |||
453 | case FieldId::F_vparent: | |||
454 | I->VirtualParents.emplace_back(std::move(R)); | |||
455 | return llvm::Error::success(); | |||
456 | case FieldId::F_child_record: | |||
457 | I->ChildRecords.emplace_back(std::move(R)); | |||
458 | return llvm::Error::success(); | |||
459 | default: | |||
460 | return llvm::make_error<llvm::StringError>( | |||
461 | "Invalid type cannot contain Reference.\n", | |||
462 | llvm::inconvertibleErrorCode()); | |||
463 | } | |||
464 | } | |||
465 | ||||
466 | template <typename T, typename ChildInfoType> | |||
467 | void addChild(T I, ChildInfoType &&R) { | |||
468 | llvm::errs() << "Invalid child type for info.\n"; | |||
469 | exit(1); | |||
470 | } | |||
471 | ||||
472 | template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) { | |||
473 | I->ChildFunctions.emplace_back(std::move(R)); | |||
474 | } | |||
475 | ||||
476 | template <> void addChild(NamespaceInfo *I, EnumInfo &&R) { | |||
477 | I->ChildEnums.emplace_back(std::move(R)); | |||
478 | } | |||
479 | ||||
480 | template <> void addChild(RecordInfo *I, FunctionInfo &&R) { | |||
481 | I->ChildFunctions.emplace_back(std::move(R)); | |||
482 | } | |||
483 | ||||
484 | template <> void addChild(RecordInfo *I, EnumInfo &&R) { | |||
485 | I->ChildEnums.emplace_back(std::move(R)); | |||
486 | } | |||
487 | ||||
488 | // Read records from bitcode into a given info. | |||
489 | template <typename T> | |||
490 | llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) { | |||
491 | Record R; | |||
492 | llvm::StringRef Blob; | |||
493 | unsigned RecID = Stream.readRecord(ID, R, &Blob); | |||
494 | return parseRecord(R, RecID, Blob, I); | |||
495 | } | |||
496 | ||||
497 | template <> | |||
498 | llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) { | |||
499 | Record R; | |||
500 | llvm::StringRef Blob; | |||
501 | unsigned RecID = Stream.readRecord(ID, R, &Blob); | |||
502 | return parseRecord(R, RecID, Blob, I, CurrentReferenceField); | |||
503 | } | |||
504 | ||||
505 | // Read a block of records into a single info. | |||
506 | template <typename T> | |||
507 | llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) { | |||
508 | if (Stream.EnterSubBlock(ID)) | |||
509 | return llvm::make_error<llvm::StringError>("Unable to enter subblock.\n", | |||
510 | llvm::inconvertibleErrorCode()); | |||
511 | ||||
512 | while (true) { | |||
513 | unsigned BlockOrCode = 0; | |||
514 | Cursor Res = skipUntilRecordOrBlock(BlockOrCode); | |||
515 | ||||
516 | switch (Res) { | |||
517 | case Cursor::BadBlock: | |||
518 | return llvm::make_error<llvm::StringError>( | |||
519 | "Bad block found.\n", llvm::inconvertibleErrorCode()); | |||
520 | case Cursor::BlockEnd: | |||
521 | return llvm::Error::success(); | |||
522 | case Cursor::BlockBegin: | |||
523 | if (auto Err = readSubBlock(BlockOrCode, I)) { | |||
524 | if (!Stream.SkipBlock()) | |||
525 | continue; | |||
526 | return Err; | |||
527 | } | |||
528 | continue; | |||
529 | case Cursor::Record: | |||
530 | break; | |||
531 | } | |||
532 | if (auto Err = readRecord(BlockOrCode, I)) | |||
533 | return Err; | |||
534 | } | |||
535 | } | |||
536 | ||||
537 | template <typename T> | |||
538 | llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { | |||
539 | switch (ID) { | |||
540 | // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or | |||
541 | // EnumInfo subblocks | |||
542 | case BI_COMMENT_BLOCK_ID: { | |||
543 | auto Comment = getCommentInfo(I); | |||
544 | if (!Comment) | |||
545 | return Comment.takeError(); | |||
546 | if (auto Err = readBlock(ID, Comment.get())) | |||
547 | return Err; | |||
548 | return llvm::Error::success(); | |||
549 | } | |||
550 | case BI_TYPE_BLOCK_ID: { | |||
551 | TypeInfo TI; | |||
552 | if (auto Err = readBlock(ID, &TI)) | |||
553 | return Err; | |||
554 | if (auto Err = addTypeInfo(I, std::move(TI))) | |||
555 | return Err; | |||
556 | return llvm::Error::success(); | |||
557 | } | |||
558 | case BI_FIELD_TYPE_BLOCK_ID: { | |||
559 | FieldTypeInfo TI; | |||
560 | if (auto Err = readBlock(ID, &TI)) | |||
561 | return Err; | |||
562 | if (auto Err = addTypeInfo(I, std::move(TI))) | |||
563 | return Err; | |||
564 | return llvm::Error::success(); | |||
565 | } | |||
566 | case BI_MEMBER_TYPE_BLOCK_ID: { | |||
567 | MemberTypeInfo TI; | |||
568 | if (auto Err = readBlock(ID, &TI)) | |||
569 | return Err; | |||
570 | if (auto Err = addTypeInfo(I, std::move(TI))) | |||
571 | return Err; | |||
572 | return llvm::Error::success(); | |||
573 | } | |||
574 | case BI_REFERENCE_BLOCK_ID: { | |||
575 | Reference R; | |||
576 | if (auto Err = readBlock(ID, &R)) | |||
577 | return Err; | |||
578 | if (auto Err = addReference(I, std::move(R), CurrentReferenceField)) | |||
579 | return Err; | |||
580 | return llvm::Error::success(); | |||
581 | } | |||
582 | case BI_FUNCTION_BLOCK_ID: { | |||
583 | FunctionInfo F; | |||
584 | if (auto Err = readBlock(ID, &F)) | |||
585 | return Err; | |||
586 | addChild(I, std::move(F)); | |||
587 | return llvm::Error::success(); | |||
588 | } | |||
589 | case BI_ENUM_BLOCK_ID: { | |||
590 | EnumInfo E; | |||
591 | if (auto Err = readBlock(ID, &E)) | |||
592 | return Err; | |||
593 | addChild(I, std::move(E)); | |||
594 | return llvm::Error::success(); | |||
595 | } | |||
596 | default: | |||
597 | return llvm::make_error<llvm::StringError>("Invalid subblock type.\n", | |||
598 | llvm::inconvertibleErrorCode()); | |||
599 | } | |||
600 | } | |||
601 | ||||
602 | ClangDocBitcodeReader::Cursor | |||
603 | ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) { | |||
604 | BlockOrRecordID = 0; | |||
605 | ||||
606 | while (!Stream.AtEndOfStream()) { | |||
607 | unsigned Code = Stream.ReadCode(); | |||
608 | ||||
609 | switch ((llvm::bitc::FixedAbbrevIDs)Code) { | |||
610 | case llvm::bitc::ENTER_SUBBLOCK: | |||
611 | BlockOrRecordID = Stream.ReadSubBlockID(); | |||
612 | return Cursor::BlockBegin; | |||
613 | case llvm::bitc::END_BLOCK: | |||
614 | if (Stream.ReadBlockEnd()) | |||
615 | return Cursor::BadBlock; | |||
616 | return Cursor::BlockEnd; | |||
617 | case llvm::bitc::DEFINE_ABBREV: | |||
618 | Stream.ReadAbbrevRecord(); | |||
619 | continue; | |||
620 | case llvm::bitc::UNABBREV_RECORD: | |||
621 | return Cursor::BadBlock; | |||
622 | default: | |||
623 | BlockOrRecordID = Code; | |||
624 | return Cursor::Record; | |||
625 | } | |||
626 | } | |||
627 | llvm_unreachable("Premature stream end.")::llvm::llvm_unreachable_internal("Premature stream end.", "/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/tools/extra/clang-doc/BitcodeReader.cpp" , 627); | |||
628 | } | |||
629 | ||||
630 | llvm::Error ClangDocBitcodeReader::validateStream() { | |||
631 | if (Stream.AtEndOfStream()) | |||
632 | return llvm::make_error<llvm::StringError>("Premature end of stream.\n", | |||
633 | llvm::inconvertibleErrorCode()); | |||
634 | ||||
635 | // Sniff for the signature. | |||
636 | if (Stream.Read(8) != BitCodeConstants::Signature[0] || | |||
637 | Stream.Read(8) != BitCodeConstants::Signature[1] || | |||
638 | Stream.Read(8) != BitCodeConstants::Signature[2] || | |||
639 | Stream.Read(8) != BitCodeConstants::Signature[3]) | |||
640 | return llvm::make_error<llvm::StringError>("Invalid bitcode signature.\n", | |||
641 | llvm::inconvertibleErrorCode()); | |||
642 | return llvm::Error::success(); | |||
643 | } | |||
644 | ||||
645 | llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() { | |||
646 | BlockInfo = Stream.ReadBlockInfoBlock(); | |||
647 | if (!BlockInfo) | |||
648 | return llvm::make_error<llvm::StringError>( | |||
649 | "Unable to parse BlockInfoBlock.\n", llvm::inconvertibleErrorCode()); | |||
650 | Stream.setBlockInfo(&*BlockInfo); | |||
651 | return llvm::Error::success(); | |||
652 | } | |||
653 | ||||
654 | template <typename T> | |||
655 | llvm::Expected<std::unique_ptr<Info>> | |||
656 | ClangDocBitcodeReader::createInfo(unsigned ID) { | |||
657 | std::unique_ptr<Info> I = llvm::make_unique<T>(); | |||
658 | if (auto Err = readBlock(ID, static_cast<T *>(I.get()))) | |||
659 | return std::move(Err); | |||
660 | return std::unique_ptr<Info>{std::move(I)};; | |||
661 | } | |||
662 | ||||
663 | llvm::Expected<std::unique_ptr<Info>> | |||
664 | ClangDocBitcodeReader::readBlockToInfo(unsigned ID) { | |||
665 | switch (ID) { | |||
666 | case BI_NAMESPACE_BLOCK_ID: | |||
667 | return createInfo<NamespaceInfo>(ID); | |||
668 | case BI_RECORD_BLOCK_ID: | |||
669 | return createInfo<RecordInfo>(ID); | |||
670 | case BI_ENUM_BLOCK_ID: | |||
671 | return createInfo<EnumInfo>(ID); | |||
672 | case BI_FUNCTION_BLOCK_ID: | |||
673 | return createInfo<FunctionInfo>(ID); | |||
674 | default: | |||
675 | return llvm::make_error<llvm::StringError>("Cannot create info.\n", | |||
676 | llvm::inconvertibleErrorCode()); | |||
677 | } | |||
678 | } | |||
679 | ||||
680 | // Entry point | |||
681 | llvm::Expected<std::vector<std::unique_ptr<Info>>> | |||
682 | ClangDocBitcodeReader::readBitcode() { | |||
683 | std::vector<std::unique_ptr<Info>> Infos; | |||
684 | if (auto Err = validateStream()) | |||
| ||||
685 | return std::move(Err); | |||
686 | ||||
687 | // Read the top level blocks. | |||
688 | while (!Stream.AtEndOfStream()) { | |||
689 | unsigned Code = Stream.ReadCode(); | |||
690 | if (Code != llvm::bitc::ENTER_SUBBLOCK) | |||
691 | return llvm::make_error<llvm::StringError>( | |||
692 | "No blocks in input.\n", llvm::inconvertibleErrorCode()); | |||
693 | unsigned ID = Stream.ReadSubBlockID(); | |||
694 | switch (ID) { | |||
695 | // NamedType and Comment blocks should not appear at the top level | |||
696 | case BI_TYPE_BLOCK_ID: | |||
697 | case BI_FIELD_TYPE_BLOCK_ID: | |||
698 | case BI_MEMBER_TYPE_BLOCK_ID: | |||
699 | case BI_COMMENT_BLOCK_ID: | |||
700 | case BI_REFERENCE_BLOCK_ID: | |||
701 | return llvm::make_error<llvm::StringError>( | |||
702 | "Invalid top level block.\n", llvm::inconvertibleErrorCode()); | |||
703 | case BI_NAMESPACE_BLOCK_ID: | |||
704 | case BI_RECORD_BLOCK_ID: | |||
705 | case BI_ENUM_BLOCK_ID: | |||
706 | case BI_FUNCTION_BLOCK_ID: { | |||
707 | auto InfoOrErr = readBlockToInfo(ID); | |||
708 | if (!InfoOrErr) | |||
709 | return InfoOrErr.takeError(); | |||
710 | Infos.emplace_back(std::move(InfoOrErr.get())); | |||
711 | continue; | |||
712 | } | |||
713 | case BI_VERSION_BLOCK_ID: | |||
714 | if (auto Err = readBlock(ID, VersionNumber)) | |||
715 | return std::move(Err); | |||
716 | continue; | |||
717 | case llvm::bitc::BLOCKINFO_BLOCK_ID: | |||
718 | if (auto Err = readBlockInfoBlock()) | |||
719 | return std::move(Err); | |||
720 | continue; | |||
721 | default: | |||
722 | if (!Stream.SkipBlock()) | |||
723 | continue; | |||
724 | } | |||
725 | } | |||
726 | return std::move(Infos); | |||
727 | } | |||
728 | ||||
729 | } // namespace doc | |||
730 | } // namespace clang |
1 | //===- BitstreamReader.h - Low-level bitstream reader interface -*- C++ -*-===// | |||
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 | // This header defines the BitstreamReader class. This class can be used to | |||
11 | // read an arbitrary bitstream, regardless of its contents. | |||
12 | // | |||
13 | //===----------------------------------------------------------------------===// | |||
14 | ||||
15 | #ifndef LLVM_BITCODE_BITSTREAMREADER_H | |||
16 | #define LLVM_BITCODE_BITSTREAMREADER_H | |||
17 | ||||
18 | #include "llvm/ADT/ArrayRef.h" | |||
19 | #include "llvm/ADT/SmallVector.h" | |||
20 | #include "llvm/Bitcode/BitCodes.h" | |||
21 | #include "llvm/Support/Endian.h" | |||
22 | #include "llvm/Support/ErrorHandling.h" | |||
23 | #include "llvm/Support/MathExtras.h" | |||
24 | #include "llvm/Support/MemoryBuffer.h" | |||
25 | #include <algorithm> | |||
26 | #include <cassert> | |||
27 | #include <climits> | |||
28 | #include <cstddef> | |||
29 | #include <cstdint> | |||
30 | #include <memory> | |||
31 | #include <string> | |||
32 | #include <utility> | |||
33 | #include <vector> | |||
34 | ||||
35 | namespace llvm { | |||
36 | ||||
37 | /// This class maintains the abbreviations read from a block info block. | |||
38 | class BitstreamBlockInfo { | |||
39 | public: | |||
40 | /// This contains information emitted to BLOCKINFO_BLOCK blocks. These | |||
41 | /// describe abbreviations that all blocks of the specified ID inherit. | |||
42 | struct BlockInfo { | |||
43 | unsigned BlockID; | |||
44 | std::vector<std::shared_ptr<BitCodeAbbrev>> Abbrevs; | |||
45 | std::string Name; | |||
46 | std::vector<std::pair<unsigned, std::string>> RecordNames; | |||
47 | }; | |||
48 | ||||
49 | private: | |||
50 | std::vector<BlockInfo> BlockInfoRecords; | |||
51 | ||||
52 | public: | |||
53 | /// If there is block info for the specified ID, return it, otherwise return | |||
54 | /// null. | |||
55 | const BlockInfo *getBlockInfo(unsigned BlockID) const { | |||
56 | // Common case, the most recent entry matches BlockID. | |||
57 | if (!BlockInfoRecords.empty() && BlockInfoRecords.back().BlockID == BlockID) | |||
58 | return &BlockInfoRecords.back(); | |||
59 | ||||
60 | for (unsigned i = 0, e = static_cast<unsigned>(BlockInfoRecords.size()); | |||
61 | i != e; ++i) | |||
62 | if (BlockInfoRecords[i].BlockID == BlockID) | |||
63 | return &BlockInfoRecords[i]; | |||
64 | return nullptr; | |||
65 | } | |||
66 | ||||
67 | BlockInfo &getOrCreateBlockInfo(unsigned BlockID) { | |||
68 | if (const BlockInfo *BI = getBlockInfo(BlockID)) | |||
69 | return *const_cast<BlockInfo*>(BI); | |||
70 | ||||
71 | // Otherwise, add a new record. | |||
72 | BlockInfoRecords.emplace_back(); | |||
73 | BlockInfoRecords.back().BlockID = BlockID; | |||
74 | return BlockInfoRecords.back(); | |||
75 | } | |||
76 | }; | |||
77 | ||||
78 | /// This represents a position within a bitstream. There may be multiple | |||
79 | /// independent cursors reading within one bitstream, each maintaining their | |||
80 | /// own local state. | |||
81 | class SimpleBitstreamCursor { | |||
82 | ArrayRef<uint8_t> BitcodeBytes; | |||
83 | size_t NextChar = 0; | |||
84 | ||||
85 | public: | |||
86 | /// This is the current data we have pulled from the stream but have not | |||
87 | /// returned to the client. This is specifically and intentionally defined to | |||
88 | /// follow the word size of the host machine for efficiency. We use word_t in | |||
89 | /// places that are aware of this to make it perfectly explicit what is going | |||
90 | /// on. | |||
91 | using word_t = size_t; | |||
92 | ||||
93 | private: | |||
94 | word_t CurWord = 0; | |||
95 | ||||
96 | /// This is the number of bits in CurWord that are valid. This is always from | |||
97 | /// [0...bits_of(size_t)-1] inclusive. | |||
98 | unsigned BitsInCurWord = 0; | |||
99 | ||||
100 | public: | |||
101 | static const size_t MaxChunkSize = sizeof(word_t) * 8; | |||
102 | ||||
103 | SimpleBitstreamCursor() = default; | |||
104 | explicit SimpleBitstreamCursor(ArrayRef<uint8_t> BitcodeBytes) | |||
105 | : BitcodeBytes(BitcodeBytes) {} | |||
106 | explicit SimpleBitstreamCursor(StringRef BitcodeBytes) | |||
107 | : BitcodeBytes(reinterpret_cast<const uint8_t *>(BitcodeBytes.data()), | |||
108 | BitcodeBytes.size()) {} | |||
109 | explicit SimpleBitstreamCursor(MemoryBufferRef BitcodeBytes) | |||
110 | : SimpleBitstreamCursor(BitcodeBytes.getBuffer()) {} | |||
111 | ||||
112 | bool canSkipToPos(size_t pos) const { | |||
113 | // pos can be skipped to if it is a valid address or one byte past the end. | |||
114 | return pos <= BitcodeBytes.size(); | |||
115 | } | |||
116 | ||||
117 | bool AtEndOfStream() { | |||
118 | return BitsInCurWord == 0 && BitcodeBytes.size() <= NextChar; | |||
119 | } | |||
120 | ||||
121 | /// Return the bit # of the bit we are reading. | |||
122 | uint64_t GetCurrentBitNo() const { | |||
123 | return NextChar*CHAR_BIT8 - BitsInCurWord; | |||
124 | } | |||
125 | ||||
126 | // Return the byte # of the current bit. | |||
127 | uint64_t getCurrentByteNo() const { return GetCurrentBitNo() / 8; } | |||
128 | ||||
129 | ArrayRef<uint8_t> getBitcodeBytes() const { return BitcodeBytes; } | |||
130 | ||||
131 | /// Reset the stream to the specified bit number. | |||
132 | void JumpToBit(uint64_t BitNo) { | |||
133 | size_t ByteNo = size_t(BitNo/8) & ~(sizeof(word_t)-1); | |||
134 | unsigned WordBitNo = unsigned(BitNo & (sizeof(word_t)*8-1)); | |||
135 | assert(canSkipToPos(ByteNo) && "Invalid location")((canSkipToPos(ByteNo) && "Invalid location") ? static_cast <void> (0) : __assert_fail ("canSkipToPos(ByteNo) && \"Invalid location\"" , "/build/llvm-toolchain-snapshot-8~svn345461/include/llvm/Bitcode/BitstreamReader.h" , 135, __PRETTY_FUNCTION__)); | |||
136 | ||||
137 | // Move the cursor to the right word. | |||
138 | NextChar = ByteNo; | |||
139 | BitsInCurWord = 0; | |||
140 | ||||
141 | // Skip over any bits that are already consumed. | |||
142 | if (WordBitNo) | |||
143 | Read(WordBitNo); | |||
144 | } | |||
145 | ||||
146 | /// Get a pointer into the bitstream at the specified byte offset. | |||
147 | const uint8_t *getPointerToByte(uint64_t ByteNo, uint64_t NumBytes) { | |||
148 | return BitcodeBytes.data() + ByteNo; | |||
149 | } | |||
150 | ||||
151 | /// Get a pointer into the bitstream at the specified bit offset. | |||
152 | /// | |||
153 | /// The bit offset must be on a byte boundary. | |||
154 | const uint8_t *getPointerToBit(uint64_t BitNo, uint64_t NumBytes) { | |||
155 | assert(!(BitNo % 8) && "Expected bit on byte boundary")((!(BitNo % 8) && "Expected bit on byte boundary") ? static_cast <void> (0) : __assert_fail ("!(BitNo % 8) && \"Expected bit on byte boundary\"" , "/build/llvm-toolchain-snapshot-8~svn345461/include/llvm/Bitcode/BitstreamReader.h" , 155, __PRETTY_FUNCTION__)); | |||
156 | return getPointerToByte(BitNo / 8, NumBytes); | |||
157 | } | |||
158 | ||||
159 | void fillCurWord() { | |||
160 | if (NextChar >= BitcodeBytes.size()) | |||
161 | report_fatal_error("Unexpected end of file"); | |||
162 | ||||
163 | // Read the next word from the stream. | |||
164 | const uint8_t *NextCharPtr = BitcodeBytes.data() + NextChar; | |||
165 | unsigned BytesRead; | |||
166 | if (BitcodeBytes.size() >= NextChar + sizeof(word_t)) { | |||
167 | BytesRead = sizeof(word_t); | |||
168 | CurWord = | |||
169 | support::endian::read<word_t, support::little, support::unaligned>( | |||
170 | NextCharPtr); | |||
171 | } else { | |||
172 | // Short read. | |||
173 | BytesRead = BitcodeBytes.size() - NextChar; | |||
174 | CurWord = 0; | |||
175 | for (unsigned B = 0; B != BytesRead; ++B) | |||
176 | CurWord |= uint64_t(NextCharPtr[B]) << (B * 8); | |||
177 | } | |||
178 | NextChar += BytesRead; | |||
179 | BitsInCurWord = BytesRead * 8; | |||
180 | } | |||
181 | ||||
182 | word_t Read(unsigned NumBits) { | |||
183 | static const unsigned BitsInWord = MaxChunkSize; | |||
184 | ||||
185 | assert(NumBits && NumBits <= BitsInWord &&((NumBits && NumBits <= BitsInWord && "Cannot return zero or more than BitsInWord bits!" ) ? static_cast<void> (0) : __assert_fail ("NumBits && NumBits <= BitsInWord && \"Cannot return zero or more than BitsInWord bits!\"" , "/build/llvm-toolchain-snapshot-8~svn345461/include/llvm/Bitcode/BitstreamReader.h" , 186, __PRETTY_FUNCTION__)) | |||
186 | "Cannot return zero or more than BitsInWord bits!")((NumBits && NumBits <= BitsInWord && "Cannot return zero or more than BitsInWord bits!" ) ? static_cast<void> (0) : __assert_fail ("NumBits && NumBits <= BitsInWord && \"Cannot return zero or more than BitsInWord bits!\"" , "/build/llvm-toolchain-snapshot-8~svn345461/include/llvm/Bitcode/BitstreamReader.h" , 186, __PRETTY_FUNCTION__)); | |||
187 | ||||
188 | static const unsigned Mask = sizeof(word_t) > 4 ? 0x3f : 0x1f; | |||
189 | ||||
190 | // If the field is fully contained by CurWord, return it quickly. | |||
191 | if (BitsInCurWord >= NumBits) { | |||
192 | word_t R = CurWord & (~word_t(0) >> (BitsInWord - NumBits)); | |||
193 | ||||
194 | // Use a mask to avoid undefined behavior. | |||
195 | CurWord >>= (NumBits & Mask); | |||
196 | ||||
197 | BitsInCurWord -= NumBits; | |||
198 | return R; | |||
199 | } | |||
200 | ||||
201 | word_t R = BitsInCurWord ? CurWord : 0; | |||
202 | unsigned BitsLeft = NumBits - BitsInCurWord; | |||
203 | ||||
204 | fillCurWord(); | |||
205 | ||||
206 | // If we run out of data, abort. | |||
207 | if (BitsLeft > BitsInCurWord) | |||
208 | report_fatal_error("Unexpected end of file"); | |||
209 | ||||
210 | word_t R2 = CurWord & (~word_t(0) >> (BitsInWord - BitsLeft)); | |||
| ||||
211 | ||||
212 | // Use a mask to avoid undefined behavior. | |||
213 | CurWord >>= (BitsLeft & Mask); | |||
214 | ||||
215 | BitsInCurWord -= BitsLeft; | |||
216 | ||||
217 | R |= R2 << (NumBits - BitsLeft); | |||
218 | ||||
219 | return R; | |||
220 | } | |||
221 | ||||
222 | uint32_t ReadVBR(unsigned NumBits) { | |||
223 | uint32_t Piece = Read(NumBits); | |||
224 | if ((Piece & (1U << (NumBits-1))) == 0) | |||
225 | return Piece; | |||
226 | ||||
227 | uint32_t Result = 0; | |||
228 | unsigned NextBit = 0; | |||
229 | while (true) { | |||
230 | Result |= (Piece & ((1U << (NumBits-1))-1)) << NextBit; | |||
231 | ||||
232 | if ((Piece & (1U << (NumBits-1))) == 0) | |||
233 | return Result; | |||
234 | ||||
235 | NextBit += NumBits-1; | |||
236 | Piece = Read(NumBits); | |||
237 | } | |||
238 | } | |||
239 | ||||
240 | // Read a VBR that may have a value up to 64-bits in size. The chunk size of | |||
241 | // the VBR must still be <= 32 bits though. | |||
242 | uint64_t ReadVBR64(unsigned NumBits) { | |||
243 | uint32_t Piece = Read(NumBits); | |||
244 | if ((Piece & (1U << (NumBits-1))) == 0) | |||
245 | return uint64_t(Piece); | |||
246 | ||||
247 | uint64_t Result = 0; | |||
248 | unsigned NextBit = 0; | |||
249 | while (true) { | |||
250 | Result |= uint64_t(Piece & ((1U << (NumBits-1))-1)) << NextBit; | |||
251 | ||||
252 | if ((Piece & (1U << (NumBits-1))) == 0) | |||
253 | return Result; | |||
254 | ||||
255 | NextBit += NumBits-1; | |||
256 | Piece = Read(NumBits); | |||
257 | } | |||
258 | } | |||
259 | ||||
260 | void SkipToFourByteBoundary() { | |||
261 | // If word_t is 64-bits and if we've read less than 32 bits, just dump | |||
262 | // the bits we have up to the next 32-bit boundary. | |||
263 | if (sizeof(word_t) > 4 && | |||
264 | BitsInCurWord >= 32) { | |||
265 | CurWord >>= BitsInCurWord-32; | |||
266 | BitsInCurWord = 32; | |||
267 | return; | |||
268 | } | |||
269 | ||||
270 | BitsInCurWord = 0; | |||
271 | } | |||
272 | ||||
273 | /// Skip to the end of the file. | |||
274 | void skipToEnd() { NextChar = BitcodeBytes.size(); } | |||
275 | }; | |||
276 | ||||
277 | /// When advancing through a bitstream cursor, each advance can discover a few | |||
278 | /// different kinds of entries: | |||
279 | struct BitstreamEntry { | |||
280 | enum { | |||
281 | Error, // Malformed bitcode was found. | |||
282 | EndBlock, // We've reached the end of the current block, (or the end of the | |||
283 | // file, which is treated like a series of EndBlock records. | |||
284 | SubBlock, // This is the start of a new subblock of a specific ID. | |||
285 | Record // This is a record with a specific AbbrevID. | |||
286 | } Kind; | |||
287 | ||||
288 | unsigned ID; | |||
289 | ||||
290 | static BitstreamEntry getError() { | |||
291 | BitstreamEntry E; E.Kind = Error; return E; | |||
292 | } | |||
293 | ||||
294 | static BitstreamEntry getEndBlock() { | |||
295 | BitstreamEntry E; E.Kind = EndBlock; return E; | |||
296 | } | |||
297 | ||||
298 | static BitstreamEntry getSubBlock(unsigned ID) { | |||
299 | BitstreamEntry E; E.Kind = SubBlock; E.ID = ID; return E; | |||
300 | } | |||
301 | ||||
302 | static BitstreamEntry getRecord(unsigned AbbrevID) { | |||
303 | BitstreamEntry E; E.Kind = Record; E.ID = AbbrevID; return E; | |||
304 | } | |||
305 | }; | |||
306 | ||||
307 | /// This represents a position within a bitcode file, implemented on top of a | |||
308 | /// SimpleBitstreamCursor. | |||
309 | /// | |||
310 | /// Unlike iterators, BitstreamCursors are heavy-weight objects that should not | |||
311 | /// be passed by value. | |||
312 | class BitstreamCursor : SimpleBitstreamCursor { | |||
313 | // This is the declared size of code values used for the current block, in | |||
314 | // bits. | |||
315 | unsigned CurCodeSize = 2; | |||
316 | ||||
317 | /// Abbrevs installed at in this block. | |||
318 | std::vector<std::shared_ptr<BitCodeAbbrev>> CurAbbrevs; | |||
319 | ||||
320 | struct Block { | |||
321 | unsigned PrevCodeSize; | |||
322 | std::vector<std::shared_ptr<BitCodeAbbrev>> PrevAbbrevs; | |||
323 | ||||
324 | explicit Block(unsigned PCS) : PrevCodeSize(PCS) {} | |||
325 | }; | |||
326 | ||||
327 | /// This tracks the codesize of parent blocks. | |||
328 | SmallVector<Block, 8> BlockScope; | |||
329 | ||||
330 | BitstreamBlockInfo *BlockInfo = nullptr; | |||
331 | ||||
332 | public: | |||
333 | static const size_t MaxChunkSize = sizeof(word_t) * 8; | |||
334 | ||||
335 | BitstreamCursor() = default; | |||
336 | explicit BitstreamCursor(ArrayRef<uint8_t> BitcodeBytes) | |||
337 | : SimpleBitstreamCursor(BitcodeBytes) {} | |||
338 | explicit BitstreamCursor(StringRef BitcodeBytes) | |||
339 | : SimpleBitstreamCursor(BitcodeBytes) {} | |||
340 | explicit BitstreamCursor(MemoryBufferRef BitcodeBytes) | |||
341 | : SimpleBitstreamCursor(BitcodeBytes) {} | |||
342 | ||||
343 | using SimpleBitstreamCursor::canSkipToPos; | |||
344 | using SimpleBitstreamCursor::AtEndOfStream; | |||
345 | using SimpleBitstreamCursor::getBitcodeBytes; | |||
346 | using SimpleBitstreamCursor::GetCurrentBitNo; | |||
347 | using SimpleBitstreamCursor::getCurrentByteNo; | |||
348 | using SimpleBitstreamCursor::getPointerToByte; | |||
349 | using SimpleBitstreamCursor::JumpToBit; | |||
350 | using SimpleBitstreamCursor::fillCurWord; | |||
351 | using SimpleBitstreamCursor::Read; | |||
352 | using SimpleBitstreamCursor::ReadVBR; | |||
353 | using SimpleBitstreamCursor::ReadVBR64; | |||
354 | ||||
355 | /// Return the number of bits used to encode an abbrev #. | |||
356 | unsigned getAbbrevIDWidth() const { return CurCodeSize; } | |||
357 | ||||
358 | /// Flags that modify the behavior of advance(). | |||
359 | enum { | |||
360 | /// If this flag is used, the advance() method does not automatically pop | |||
361 | /// the block scope when the end of a block is reached. | |||
362 | AF_DontPopBlockAtEnd = 1, | |||
363 | ||||
364 | /// If this flag is used, abbrev entries are returned just like normal | |||
365 | /// records. | |||
366 | AF_DontAutoprocessAbbrevs = 2 | |||
367 | }; | |||
368 | ||||
369 | /// Advance the current bitstream, returning the next entry in the stream. | |||
370 | BitstreamEntry advance(unsigned Flags = 0) { | |||
371 | while (true) { | |||
372 | if (AtEndOfStream()) | |||
373 | return BitstreamEntry::getError(); | |||
374 | ||||
375 | unsigned Code = ReadCode(); | |||
376 | if (Code == bitc::END_BLOCK) { | |||
377 | // Pop the end of the block unless Flags tells us not to. | |||
378 | if (!(Flags & AF_DontPopBlockAtEnd) && ReadBlockEnd()) | |||
379 | return BitstreamEntry::getError(); | |||
380 | return BitstreamEntry::getEndBlock(); | |||
381 | } | |||
382 | ||||
383 | if (Code == bitc::ENTER_SUBBLOCK) | |||
384 | return BitstreamEntry::getSubBlock(ReadSubBlockID()); | |||
385 | ||||
386 | if (Code == bitc::DEFINE_ABBREV && | |||
387 | !(Flags & AF_DontAutoprocessAbbrevs)) { | |||
388 | // We read and accumulate abbrev's, the client can't do anything with | |||
389 | // them anyway. | |||
390 | ReadAbbrevRecord(); | |||
391 | continue; | |||
392 | } | |||
393 | ||||
394 | return BitstreamEntry::getRecord(Code); | |||
395 | } | |||
396 | } | |||
397 | ||||
398 | /// This is a convenience function for clients that don't expect any | |||
399 | /// subblocks. This just skips over them automatically. | |||
400 | BitstreamEntry advanceSkippingSubblocks(unsigned Flags = 0) { | |||
401 | while (true) { | |||
402 | // If we found a normal entry, return it. | |||
403 | BitstreamEntry Entry = advance(Flags); | |||
404 | if (Entry.Kind != BitstreamEntry::SubBlock) | |||
405 | return Entry; | |||
406 | ||||
407 | // If we found a sub-block, just skip over it and check the next entry. | |||
408 | if (SkipBlock()) | |||
409 | return BitstreamEntry::getError(); | |||
410 | } | |||
411 | } | |||
412 | ||||
413 | unsigned ReadCode() { | |||
414 | return Read(CurCodeSize); | |||
415 | } | |||
416 | ||||
417 | // Block header: | |||
418 | // [ENTER_SUBBLOCK, blockid, newcodelen, <align4bytes>, blocklen] | |||
419 | ||||
420 | /// Having read the ENTER_SUBBLOCK code, read the BlockID for the block. | |||
421 | unsigned ReadSubBlockID() { | |||
422 | return ReadVBR(bitc::BlockIDWidth); | |||
423 | } | |||
424 | ||||
425 | /// Having read the ENTER_SUBBLOCK abbrevid and a BlockID, skip over the body | |||
426 | /// of this block. If the block record is malformed, return true. | |||
427 | bool SkipBlock() { | |||
428 | // Read and ignore the codelen value. Since we are skipping this block, we | |||
429 | // don't care what code widths are used inside of it. | |||
430 | ReadVBR(bitc::CodeLenWidth); | |||
431 | SkipToFourByteBoundary(); | |||
432 | size_t NumFourBytes = Read(bitc::BlockSizeWidth); | |||
433 | ||||
434 | // Check that the block wasn't partially defined, and that the offset isn't | |||
435 | // bogus. | |||
436 | size_t SkipTo = GetCurrentBitNo() + NumFourBytes*4*8; | |||
437 | if (AtEndOfStream() || !canSkipToPos(SkipTo/8)) | |||
438 | return true; | |||
439 | ||||
440 | JumpToBit(SkipTo); | |||
441 | return false; | |||
442 | } | |||
443 | ||||
444 | /// Having read the ENTER_SUBBLOCK abbrevid, enter the block, and return true | |||
445 | /// if the block has an error. | |||
446 | bool EnterSubBlock(unsigned BlockID, unsigned *NumWordsP = nullptr); | |||
447 | ||||
448 | bool ReadBlockEnd() { | |||
449 | if (BlockScope.empty()) return true; | |||
450 | ||||
451 | // Block tail: | |||
452 | // [END_BLOCK, <align4bytes>] | |||
453 | SkipToFourByteBoundary(); | |||
454 | ||||
455 | popBlockScope(); | |||
456 | return false; | |||
457 | } | |||
458 | ||||
459 | private: | |||
460 | void popBlockScope() { | |||
461 | CurCodeSize = BlockScope.back().PrevCodeSize; | |||
462 | ||||
463 | CurAbbrevs = std::move(BlockScope.back().PrevAbbrevs); | |||
464 | BlockScope.pop_back(); | |||
465 | } | |||
466 | ||||
467 | //===--------------------------------------------------------------------===// | |||
468 | // Record Processing | |||
469 | //===--------------------------------------------------------------------===// | |||
470 | ||||
471 | public: | |||
472 | /// Return the abbreviation for the specified AbbrevId. | |||
473 | const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) { | |||
474 | unsigned AbbrevNo = AbbrevID - bitc::FIRST_APPLICATION_ABBREV; | |||
475 | if (AbbrevNo >= CurAbbrevs.size()) | |||
476 | report_fatal_error("Invalid abbrev number"); | |||
477 | return CurAbbrevs[AbbrevNo].get(); | |||
478 | } | |||
479 | ||||
480 | /// Read the current record and discard it, returning the code for the record. | |||
481 | unsigned skipRecord(unsigned AbbrevID); | |||
482 | ||||
483 | unsigned readRecord(unsigned AbbrevID, SmallVectorImpl<uint64_t> &Vals, | |||
484 | StringRef *Blob = nullptr); | |||
485 | ||||
486 | //===--------------------------------------------------------------------===// | |||
487 | // Abbrev Processing | |||
488 | //===--------------------------------------------------------------------===// | |||
489 | void ReadAbbrevRecord(); | |||
490 | ||||
491 | /// Read and return a block info block from the bitstream. If an error was | |||
492 | /// encountered, return None. | |||
493 | /// | |||
494 | /// \param ReadBlockInfoNames Whether to read block/record name information in | |||
495 | /// the BlockInfo block. Only llvm-bcanalyzer uses this. | |||
496 | Optional<BitstreamBlockInfo> | |||
497 | ReadBlockInfoBlock(bool ReadBlockInfoNames = false); | |||
498 | ||||
499 | /// Set the block info to be used by this BitstreamCursor to interpret | |||
500 | /// abbreviated records. | |||
501 | void setBlockInfo(BitstreamBlockInfo *BI) { BlockInfo = BI; } | |||
502 | }; | |||
503 | ||||
504 | } // end llvm namespace | |||
505 | ||||
506 | #endif // LLVM_BITCODE_BITSTREAMREADER_H |