Bug Summary

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'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name BitcodeReader.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/tools/extra/clang-doc -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/tools/extra/clang-doc -I /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/clang/tools/extra/clang-doc -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/clang/tools/extra/clang-doc/BitcodeReader.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/tools/clang/tools/extra/clang-doc/BitcodeReader.cpp

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
16namespace clang {
17namespace doc {
18
19using Record = llvm::SmallVector<uint64_t, 1024>;
20
21llvm::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
27llvm::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
39llvm::Error decodeRecord(Record R, bool &Field, llvm::StringRef Blob) {
40 Field = R[0] != 0;
41 return llvm::Error::success();
42}
43
44llvm::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
52llvm::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
67llvm::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
82llvm::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
91llvm::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
105llvm::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
121llvm::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
128llvm::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
137llvm::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
145llvm::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
158llvm::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
177llvm::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
198llvm::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
219llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob,
220 TypeInfo *I) {
221 return llvm::Error::success();
222}
223
224llvm::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
235llvm::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
248llvm::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
279llvm::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
296template <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
302template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
303 I->Description.emplace_back();
304 return &I->Description.back();
305}
306
307template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
308 I->Description.emplace_back();
309 return &I->Description.back();
310}
311
312template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
313 I->Description.emplace_back();
314 return &I->Description.back();
315}
316
317template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
318 I->Description.emplace_back();
319 return &I->Description.back();
320}
321
322template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {
323 I->Children.emplace_back(llvm::make_unique<CommentInfo>());
324 return I->Children.back().get();
325}
326
327template <>
328llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
329 return getCommentInfo(I.get());
330}
331
332template <typename T, typename TTypeInfo>
333llvm::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
339template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
340 I->Members.emplace_back(std::move(T));
341 return llvm::Error::success();
342}
343
344template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
345 I->ReturnType = std::move(T);
346 return llvm::Error::success();
347}
348
349template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
350 I->Params.emplace_back(std::move(T));
351 return llvm::Error::success();
352}
353
354template <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
360template <> 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
372template <>
373llvm::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
385template <>
386llvm::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
398template <> 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
410template <>
411llvm::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
429template <>
430llvm::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
445template <> 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
466template <typename T, typename ChildInfoType>
467void addChild(T I, ChildInfoType &&R) {
468 llvm::errs() << "Invalid child type for info.\n";
469 exit(1);
470}
471
472template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
473 I->ChildFunctions.emplace_back(std::move(R));
474}
475
476template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
477 I->ChildEnums.emplace_back(std::move(R));
478}
479
480template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
481 I->ChildFunctions.emplace_back(std::move(R));
482}
483
484template <> 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.
489template <typename T>
490llvm::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
497template <>
498llvm::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.
506template <typename T>
507llvm::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
537template <typename T>
538llvm::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
602ClangDocBitcodeReader::Cursor
603ClangDocBitcodeReader::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
630llvm::Error ClangDocBitcodeReader::validateStream() {
631 if (Stream.AtEndOfStream())
2
Taking false branch
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] ||
3
Calling 'SimpleBitstreamCursor::Read'
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
645llvm::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
654template <typename T>
655llvm::Expected<std::unique_ptr<Info>>
656ClangDocBitcodeReader::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
663llvm::Expected<std::unique_ptr<Info>>
664ClangDocBitcodeReader::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
681llvm::Expected<std::vector<std::unique_ptr<Info>>>
682ClangDocBitcodeReader::readBitcode() {
683 std::vector<std::unique_ptr<Info>> Infos;
684 if (auto Err = validateStream())
1
Calling 'ClangDocBitcodeReader::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

/build/llvm-toolchain-snapshot-8~svn345461/include/llvm/Bitcode/BitstreamReader.h

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
35namespace llvm {
36
37/// This class maintains the abbreviations read from a block info block.
38class BitstreamBlockInfo {
39public:
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
49private:
50 std::vector<BlockInfo> BlockInfoRecords;
51
52public:
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.
81class SimpleBitstreamCursor {
82 ArrayRef<uint8_t> BitcodeBytes;
83 size_t NextChar = 0;
84
85public:
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
93private:
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
100public:
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;
4
'?' condition is true
189
190 // If the field is fully contained by CurWord, return it quickly.
191 if (BitsInCurWord >= NumBits) {
5
Assuming the condition is false
6
Taking false branch
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;
7
'?' condition is true
202 unsigned BitsLeft = NumBits - BitsInCurWord;
203
204 fillCurWord();
205
206 // If we run out of data, abort.
207 if (BitsLeft > BitsInCurWord)
8
Assuming the condition is false
9
Taking false branch
208 report_fatal_error("Unexpected end of file");
209
210 word_t R2 = CurWord & (~word_t(0) >> (BitsInWord - BitsLeft));
10
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'
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:
279struct 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.
312class 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
332public:
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
459private:
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
471public:
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