Mercurial > hg > CbC > CbC_llvm
comparison clang-tools-extra/clang-doc/BitcodeReader.cpp @ 150:1d019706d866
LLVM10
author | anatofuz |
---|---|
date | Thu, 13 Feb 2020 15:10:13 +0900 |
parents | |
children | c4bab56944e8 |
comparison
equal
deleted
inserted
replaced
147:c2174574ed3a | 150:1d019706d866 |
---|---|
1 //===-- BitcodeReader.cpp - ClangDoc Bitcode Reader ------------*- C++ -*-===// | |
2 // | |
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
4 // See https://llvm.org/LICENSE.txt for license information. | |
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
6 // | |
7 //===----------------------------------------------------------------------===// | |
8 | |
9 #include "BitcodeReader.h" | |
10 #include "llvm/ADT/IndexedMap.h" | |
11 #include "llvm/ADT/Optional.h" | |
12 #include "llvm/Support/Error.h" | |
13 #include "llvm/Support/raw_ostream.h" | |
14 | |
15 namespace clang { | |
16 namespace doc { | |
17 | |
18 using Record = llvm::SmallVector<uint64_t, 1024>; | |
19 | |
20 llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl<char> &Field, | |
21 llvm::StringRef Blob) { | |
22 Field.assign(Blob.begin(), Blob.end()); | |
23 return llvm::Error::success(); | |
24 } | |
25 | |
26 llvm::Error decodeRecord(Record R, SymbolID &Field, llvm::StringRef Blob) { | |
27 if (R[0] != BitCodeConstants::USRHashSize) | |
28 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
29 "incorrect USR size"); | |
30 | |
31 // First position in the record is the length of the following array, so we | |
32 // copy the following elements to the field. | |
33 for (int I = 0, E = R[0]; I < E; ++I) | |
34 Field[I] = R[I + 1]; | |
35 return llvm::Error::success(); | |
36 } | |
37 | |
38 llvm::Error decodeRecord(Record R, bool &Field, llvm::StringRef Blob) { | |
39 Field = R[0] != 0; | |
40 return llvm::Error::success(); | |
41 } | |
42 | |
43 llvm::Error decodeRecord(Record R, int &Field, llvm::StringRef Blob) { | |
44 if (R[0] > INT_MAX) | |
45 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
46 "integer too large to parse"); | |
47 Field = (int)R[0]; | |
48 return llvm::Error::success(); | |
49 } | |
50 | |
51 llvm::Error decodeRecord(Record R, AccessSpecifier &Field, | |
52 llvm::StringRef Blob) { | |
53 switch (R[0]) { | |
54 case AS_public: | |
55 case AS_private: | |
56 case AS_protected: | |
57 case AS_none: | |
58 Field = (AccessSpecifier)R[0]; | |
59 return llvm::Error::success(); | |
60 default: | |
61 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
62 "invalid value for AccessSpecifier"); | |
63 } | |
64 } | |
65 | |
66 llvm::Error decodeRecord(Record R, TagTypeKind &Field, llvm::StringRef Blob) { | |
67 switch (R[0]) { | |
68 case TTK_Struct: | |
69 case TTK_Interface: | |
70 case TTK_Union: | |
71 case TTK_Class: | |
72 case TTK_Enum: | |
73 Field = (TagTypeKind)R[0]; | |
74 return llvm::Error::success(); | |
75 default: | |
76 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
77 "invalid value for TagTypeKind"); | |
78 } | |
79 } | |
80 | |
81 llvm::Error decodeRecord(Record R, llvm::Optional<Location> &Field, | |
82 llvm::StringRef Blob) { | |
83 if (R[0] > INT_MAX) | |
84 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
85 "integer too large to parse"); | |
86 Field.emplace((int)R[0], Blob, (bool)R[1]); | |
87 return llvm::Error::success(); | |
88 } | |
89 | |
90 llvm::Error decodeRecord(Record R, InfoType &Field, llvm::StringRef Blob) { | |
91 switch (auto IT = static_cast<InfoType>(R[0])) { | |
92 case InfoType::IT_namespace: | |
93 case InfoType::IT_record: | |
94 case InfoType::IT_function: | |
95 case InfoType::IT_default: | |
96 case InfoType::IT_enum: | |
97 Field = IT; | |
98 return llvm::Error::success(); | |
99 } | |
100 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
101 "invalid value for InfoType"); | |
102 } | |
103 | |
104 llvm::Error decodeRecord(Record R, FieldId &Field, llvm::StringRef Blob) { | |
105 switch (auto F = static_cast<FieldId>(R[0])) { | |
106 case FieldId::F_namespace: | |
107 case FieldId::F_parent: | |
108 case FieldId::F_vparent: | |
109 case FieldId::F_type: | |
110 case FieldId::F_child_namespace: | |
111 case FieldId::F_child_record: | |
112 case FieldId::F_default: | |
113 Field = F; | |
114 return llvm::Error::success(); | |
115 } | |
116 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
117 "invalid value for FieldId"); | |
118 } | |
119 | |
120 llvm::Error decodeRecord(Record R, | |
121 llvm::SmallVectorImpl<llvm::SmallString<16>> &Field, | |
122 llvm::StringRef Blob) { | |
123 Field.push_back(Blob); | |
124 return llvm::Error::success(); | |
125 } | |
126 | |
127 llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl<Location> &Field, | |
128 llvm::StringRef Blob) { | |
129 if (R[0] > INT_MAX) | |
130 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
131 "integer too large to parse"); | |
132 Field.emplace_back((int)R[0], Blob, (bool)R[1]); | |
133 return llvm::Error::success(); | |
134 } | |
135 | |
136 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
137 const unsigned VersionNo) { | |
138 if (ID == VERSION && R[0] == VersionNo) | |
139 return llvm::Error::success(); | |
140 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
141 "mismatched bitcode version number"); | |
142 } | |
143 | |
144 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
145 NamespaceInfo *I) { | |
146 switch (ID) { | |
147 case NAMESPACE_USR: | |
148 return decodeRecord(R, I->USR, Blob); | |
149 case NAMESPACE_NAME: | |
150 return decodeRecord(R, I->Name, Blob); | |
151 case NAMESPACE_PATH: | |
152 return decodeRecord(R, I->Path, Blob); | |
153 default: | |
154 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
155 "invalid field for NamespaceInfo"); | |
156 } | |
157 } | |
158 | |
159 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
160 RecordInfo *I) { | |
161 switch (ID) { | |
162 case RECORD_USR: | |
163 return decodeRecord(R, I->USR, Blob); | |
164 case RECORD_NAME: | |
165 return decodeRecord(R, I->Name, Blob); | |
166 case RECORD_PATH: | |
167 return decodeRecord(R, I->Path, Blob); | |
168 case RECORD_DEFLOCATION: | |
169 return decodeRecord(R, I->DefLoc, Blob); | |
170 case RECORD_LOCATION: | |
171 return decodeRecord(R, I->Loc, Blob); | |
172 case RECORD_TAG_TYPE: | |
173 return decodeRecord(R, I->TagType, Blob); | |
174 case RECORD_IS_TYPE_DEF: | |
175 return decodeRecord(R, I->IsTypeDef, Blob); | |
176 default: | |
177 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
178 "invalid field for RecordInfo"); | |
179 } | |
180 } | |
181 | |
182 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
183 BaseRecordInfo *I) { | |
184 switch (ID) { | |
185 case BASE_RECORD_USR: | |
186 return decodeRecord(R, I->USR, Blob); | |
187 case BASE_RECORD_NAME: | |
188 return decodeRecord(R, I->Name, Blob); | |
189 case BASE_RECORD_PATH: | |
190 return decodeRecord(R, I->Path, Blob); | |
191 case BASE_RECORD_TAG_TYPE: | |
192 return decodeRecord(R, I->TagType, Blob); | |
193 case BASE_RECORD_IS_VIRTUAL: | |
194 return decodeRecord(R, I->IsVirtual, Blob); | |
195 case BASE_RECORD_ACCESS: | |
196 return decodeRecord(R, I->Access, Blob); | |
197 case BASE_RECORD_IS_PARENT: | |
198 return decodeRecord(R, I->IsParent, Blob); | |
199 default: | |
200 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
201 "invalid field for BaseRecordInfo"); | |
202 } | |
203 } | |
204 | |
205 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
206 EnumInfo *I) { | |
207 switch (ID) { | |
208 case ENUM_USR: | |
209 return decodeRecord(R, I->USR, Blob); | |
210 case ENUM_NAME: | |
211 return decodeRecord(R, I->Name, Blob); | |
212 case ENUM_DEFLOCATION: | |
213 return decodeRecord(R, I->DefLoc, Blob); | |
214 case ENUM_LOCATION: | |
215 return decodeRecord(R, I->Loc, Blob); | |
216 case ENUM_MEMBER: | |
217 return decodeRecord(R, I->Members, Blob); | |
218 case ENUM_SCOPED: | |
219 return decodeRecord(R, I->Scoped, Blob); | |
220 default: | |
221 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
222 "invalid field for EnumInfo"); | |
223 } | |
224 } | |
225 | |
226 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
227 FunctionInfo *I) { | |
228 switch (ID) { | |
229 case FUNCTION_USR: | |
230 return decodeRecord(R, I->USR, Blob); | |
231 case FUNCTION_NAME: | |
232 return decodeRecord(R, I->Name, Blob); | |
233 case FUNCTION_DEFLOCATION: | |
234 return decodeRecord(R, I->DefLoc, Blob); | |
235 case FUNCTION_LOCATION: | |
236 return decodeRecord(R, I->Loc, Blob); | |
237 case FUNCTION_ACCESS: | |
238 return decodeRecord(R, I->Access, Blob); | |
239 case FUNCTION_IS_METHOD: | |
240 return decodeRecord(R, I->IsMethod, Blob); | |
241 default: | |
242 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
243 "invalid field for FunctionInfo"); | |
244 } | |
245 } | |
246 | |
247 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
248 TypeInfo *I) { | |
249 return llvm::Error::success(); | |
250 } | |
251 | |
252 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
253 FieldTypeInfo *I) { | |
254 switch (ID) { | |
255 case FIELD_TYPE_NAME: | |
256 return decodeRecord(R, I->Name, Blob); | |
257 default: | |
258 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
259 "invalid field for TypeInfo"); | |
260 } | |
261 } | |
262 | |
263 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
264 MemberTypeInfo *I) { | |
265 switch (ID) { | |
266 case MEMBER_TYPE_NAME: | |
267 return decodeRecord(R, I->Name, Blob); | |
268 case MEMBER_TYPE_ACCESS: | |
269 return decodeRecord(R, I->Access, Blob); | |
270 default: | |
271 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
272 "invalid field for MemberTypeInfo"); | |
273 } | |
274 } | |
275 | |
276 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
277 CommentInfo *I) { | |
278 switch (ID) { | |
279 case COMMENT_KIND: | |
280 return decodeRecord(R, I->Kind, Blob); | |
281 case COMMENT_TEXT: | |
282 return decodeRecord(R, I->Text, Blob); | |
283 case COMMENT_NAME: | |
284 return decodeRecord(R, I->Name, Blob); | |
285 case COMMENT_DIRECTION: | |
286 return decodeRecord(R, I->Direction, Blob); | |
287 case COMMENT_PARAMNAME: | |
288 return decodeRecord(R, I->ParamName, Blob); | |
289 case COMMENT_CLOSENAME: | |
290 return decodeRecord(R, I->CloseName, Blob); | |
291 case COMMENT_ATTRKEY: | |
292 return decodeRecord(R, I->AttrKeys, Blob); | |
293 case COMMENT_ATTRVAL: | |
294 return decodeRecord(R, I->AttrValues, Blob); | |
295 case COMMENT_ARG: | |
296 return decodeRecord(R, I->Args, Blob); | |
297 case COMMENT_SELFCLOSING: | |
298 return decodeRecord(R, I->SelfClosing, Blob); | |
299 case COMMENT_EXPLICIT: | |
300 return decodeRecord(R, I->Explicit, Blob); | |
301 default: | |
302 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
303 "invalid field for CommentInfo"); | |
304 } | |
305 } | |
306 | |
307 llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, | |
308 Reference *I, FieldId &F) { | |
309 switch (ID) { | |
310 case REFERENCE_USR: | |
311 return decodeRecord(R, I->USR, Blob); | |
312 case REFERENCE_NAME: | |
313 return decodeRecord(R, I->Name, Blob); | |
314 case REFERENCE_TYPE: | |
315 return decodeRecord(R, I->RefType, Blob); | |
316 case REFERENCE_PATH: | |
317 return decodeRecord(R, I->Path, Blob); | |
318 case REFERENCE_IS_IN_GLOBAL_NAMESPACE: | |
319 return decodeRecord(R, I->IsInGlobalNamespace, Blob); | |
320 case REFERENCE_FIELD: | |
321 return decodeRecord(R, F, Blob); | |
322 default: | |
323 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
324 "invalid field for Reference"); | |
325 } | |
326 } | |
327 | |
328 template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) { | |
329 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
330 "invalid type cannot contain CommentInfo"); | |
331 } | |
332 | |
333 template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) { | |
334 I->Description.emplace_back(); | |
335 return &I->Description.back(); | |
336 } | |
337 | |
338 template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) { | |
339 I->Description.emplace_back(); | |
340 return &I->Description.back(); | |
341 } | |
342 | |
343 template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) { | |
344 I->Description.emplace_back(); | |
345 return &I->Description.back(); | |
346 } | |
347 | |
348 template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) { | |
349 I->Description.emplace_back(); | |
350 return &I->Description.back(); | |
351 } | |
352 | |
353 template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) { | |
354 I->Children.emplace_back(std::make_unique<CommentInfo>()); | |
355 return I->Children.back().get(); | |
356 } | |
357 | |
358 template <> | |
359 llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) { | |
360 return getCommentInfo(I.get()); | |
361 } | |
362 | |
363 template <typename T, typename TTypeInfo> | |
364 llvm::Error addTypeInfo(T I, TTypeInfo &&TI) { | |
365 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
366 "invalid type cannot contain TypeInfo"); | |
367 } | |
368 | |
369 template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) { | |
370 I->Members.emplace_back(std::move(T)); | |
371 return llvm::Error::success(); | |
372 } | |
373 | |
374 template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) { | |
375 I->Members.emplace_back(std::move(T)); | |
376 return llvm::Error::success(); | |
377 } | |
378 | |
379 template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) { | |
380 I->ReturnType = std::move(T); | |
381 return llvm::Error::success(); | |
382 } | |
383 | |
384 template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) { | |
385 I->Params.emplace_back(std::move(T)); | |
386 return llvm::Error::success(); | |
387 } | |
388 | |
389 template <typename T> llvm::Error addReference(T I, Reference &&R, FieldId F) { | |
390 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
391 "invalid type cannot contain Reference"); | |
392 } | |
393 | |
394 template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) { | |
395 switch (F) { | |
396 case FieldId::F_type: | |
397 I->Type = std::move(R); | |
398 return llvm::Error::success(); | |
399 default: | |
400 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
401 "invalid type cannot contain Reference"); | |
402 } | |
403 } | |
404 | |
405 template <> | |
406 llvm::Error addReference(FieldTypeInfo *I, Reference &&R, FieldId F) { | |
407 switch (F) { | |
408 case FieldId::F_type: | |
409 I->Type = std::move(R); | |
410 return llvm::Error::success(); | |
411 default: | |
412 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
413 "invalid type cannot contain Reference"); | |
414 } | |
415 } | |
416 | |
417 template <> | |
418 llvm::Error addReference(MemberTypeInfo *I, Reference &&R, FieldId F) { | |
419 switch (F) { | |
420 case FieldId::F_type: | |
421 I->Type = std::move(R); | |
422 return llvm::Error::success(); | |
423 default: | |
424 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
425 "invalid type cannot contain Reference"); | |
426 } | |
427 } | |
428 | |
429 template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) { | |
430 switch (F) { | |
431 case FieldId::F_namespace: | |
432 I->Namespace.emplace_back(std::move(R)); | |
433 return llvm::Error::success(); | |
434 default: | |
435 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
436 "invalid type cannot contain Reference"); | |
437 } | |
438 } | |
439 | |
440 template <> | |
441 llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) { | |
442 switch (F) { | |
443 case FieldId::F_namespace: | |
444 I->Namespace.emplace_back(std::move(R)); | |
445 return llvm::Error::success(); | |
446 case FieldId::F_child_namespace: | |
447 I->ChildNamespaces.emplace_back(std::move(R)); | |
448 return llvm::Error::success(); | |
449 case FieldId::F_child_record: | |
450 I->ChildRecords.emplace_back(std::move(R)); | |
451 return llvm::Error::success(); | |
452 default: | |
453 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
454 "invalid type cannot contain Reference"); | |
455 } | |
456 } | |
457 | |
458 template <> | |
459 llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) { | |
460 switch (F) { | |
461 case FieldId::F_namespace: | |
462 I->Namespace.emplace_back(std::move(R)); | |
463 return llvm::Error::success(); | |
464 case FieldId::F_parent: | |
465 I->Parent = std::move(R); | |
466 return llvm::Error::success(); | |
467 default: | |
468 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
469 "invalid type cannot contain Reference"); | |
470 } | |
471 } | |
472 | |
473 template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) { | |
474 switch (F) { | |
475 case FieldId::F_namespace: | |
476 I->Namespace.emplace_back(std::move(R)); | |
477 return llvm::Error::success(); | |
478 case FieldId::F_parent: | |
479 I->Parents.emplace_back(std::move(R)); | |
480 return llvm::Error::success(); | |
481 case FieldId::F_vparent: | |
482 I->VirtualParents.emplace_back(std::move(R)); | |
483 return llvm::Error::success(); | |
484 case FieldId::F_child_record: | |
485 I->ChildRecords.emplace_back(std::move(R)); | |
486 return llvm::Error::success(); | |
487 default: | |
488 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
489 "invalid type cannot contain Reference"); | |
490 } | |
491 } | |
492 | |
493 template <typename T, typename ChildInfoType> | |
494 void addChild(T I, ChildInfoType &&R) { | |
495 llvm::errs() << "invalid child type for info"; | |
496 exit(1); | |
497 } | |
498 | |
499 template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) { | |
500 I->ChildFunctions.emplace_back(std::move(R)); | |
501 } | |
502 | |
503 template <> void addChild(NamespaceInfo *I, EnumInfo &&R) { | |
504 I->ChildEnums.emplace_back(std::move(R)); | |
505 } | |
506 | |
507 template <> void addChild(RecordInfo *I, FunctionInfo &&R) { | |
508 I->ChildFunctions.emplace_back(std::move(R)); | |
509 } | |
510 | |
511 template <> void addChild(RecordInfo *I, EnumInfo &&R) { | |
512 I->ChildEnums.emplace_back(std::move(R)); | |
513 } | |
514 | |
515 template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) { | |
516 I->Bases.emplace_back(std::move(R)); | |
517 } | |
518 | |
519 template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) { | |
520 I->ChildFunctions.emplace_back(std::move(R)); | |
521 } | |
522 | |
523 // Read records from bitcode into a given info. | |
524 template <typename T> | |
525 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) { | |
526 Record R; | |
527 llvm::StringRef Blob; | |
528 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob); | |
529 if (!MaybeRecID) | |
530 return MaybeRecID.takeError(); | |
531 return parseRecord(R, MaybeRecID.get(), Blob, I); | |
532 } | |
533 | |
534 template <> | |
535 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) { | |
536 Record R; | |
537 llvm::StringRef Blob; | |
538 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob); | |
539 if (!MaybeRecID) | |
540 return MaybeRecID.takeError(); | |
541 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField); | |
542 } | |
543 | |
544 // Read a block of records into a single info. | |
545 template <typename T> | |
546 llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) { | |
547 if (llvm::Error Err = Stream.EnterSubBlock(ID)) | |
548 return Err; | |
549 | |
550 while (true) { | |
551 unsigned BlockOrCode = 0; | |
552 Cursor Res = skipUntilRecordOrBlock(BlockOrCode); | |
553 | |
554 switch (Res) { | |
555 case Cursor::BadBlock: | |
556 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
557 "bad block found"); | |
558 case Cursor::BlockEnd: | |
559 return llvm::Error::success(); | |
560 case Cursor::BlockBegin: | |
561 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) { | |
562 if (llvm::Error Skipped = Stream.SkipBlock()) | |
563 return joinErrors(std::move(Err), std::move(Skipped)); | |
564 return Err; | |
565 } | |
566 continue; | |
567 case Cursor::Record: | |
568 break; | |
569 } | |
570 if (auto Err = readRecord(BlockOrCode, I)) | |
571 return Err; | |
572 } | |
573 } | |
574 | |
575 template <typename T> | |
576 llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { | |
577 switch (ID) { | |
578 // Blocks can only have Comment, Reference, TypeInfo, FunctionInfo, or | |
579 // EnumInfo subblocks | |
580 case BI_COMMENT_BLOCK_ID: { | |
581 auto Comment = getCommentInfo(I); | |
582 if (!Comment) | |
583 return Comment.takeError(); | |
584 if (auto Err = readBlock(ID, Comment.get())) | |
585 return Err; | |
586 return llvm::Error::success(); | |
587 } | |
588 case BI_TYPE_BLOCK_ID: { | |
589 TypeInfo TI; | |
590 if (auto Err = readBlock(ID, &TI)) | |
591 return Err; | |
592 if (auto Err = addTypeInfo(I, std::move(TI))) | |
593 return Err; | |
594 return llvm::Error::success(); | |
595 } | |
596 case BI_FIELD_TYPE_BLOCK_ID: { | |
597 FieldTypeInfo TI; | |
598 if (auto Err = readBlock(ID, &TI)) | |
599 return Err; | |
600 if (auto Err = addTypeInfo(I, std::move(TI))) | |
601 return Err; | |
602 return llvm::Error::success(); | |
603 } | |
604 case BI_MEMBER_TYPE_BLOCK_ID: { | |
605 MemberTypeInfo TI; | |
606 if (auto Err = readBlock(ID, &TI)) | |
607 return Err; | |
608 if (auto Err = addTypeInfo(I, std::move(TI))) | |
609 return Err; | |
610 return llvm::Error::success(); | |
611 } | |
612 case BI_REFERENCE_BLOCK_ID: { | |
613 Reference R; | |
614 if (auto Err = readBlock(ID, &R)) | |
615 return Err; | |
616 if (auto Err = addReference(I, std::move(R), CurrentReferenceField)) | |
617 return Err; | |
618 return llvm::Error::success(); | |
619 } | |
620 case BI_FUNCTION_BLOCK_ID: { | |
621 FunctionInfo F; | |
622 if (auto Err = readBlock(ID, &F)) | |
623 return Err; | |
624 addChild(I, std::move(F)); | |
625 return llvm::Error::success(); | |
626 } | |
627 case BI_BASE_RECORD_BLOCK_ID: { | |
628 BaseRecordInfo BR; | |
629 if (auto Err = readBlock(ID, &BR)) | |
630 return Err; | |
631 addChild(I, std::move(BR)); | |
632 return llvm::Error::success(); | |
633 } | |
634 case BI_ENUM_BLOCK_ID: { | |
635 EnumInfo E; | |
636 if (auto Err = readBlock(ID, &E)) | |
637 return Err; | |
638 addChild(I, std::move(E)); | |
639 return llvm::Error::success(); | |
640 } | |
641 default: | |
642 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
643 "invalid subblock type"); | |
644 } | |
645 } | |
646 | |
647 ClangDocBitcodeReader::Cursor | |
648 ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) { | |
649 BlockOrRecordID = 0; | |
650 | |
651 while (!Stream.AtEndOfStream()) { | |
652 Expected<unsigned> MaybeCode = Stream.ReadCode(); | |
653 if (!MaybeCode) { | |
654 // FIXME this drops the error on the floor. | |
655 consumeError(MaybeCode.takeError()); | |
656 return Cursor::BadBlock; | |
657 } | |
658 | |
659 unsigned Code = MaybeCode.get(); | |
660 if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) { | |
661 BlockOrRecordID = Code; | |
662 return Cursor::Record; | |
663 } | |
664 switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) { | |
665 case llvm::bitc::ENTER_SUBBLOCK: | |
666 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID()) | |
667 BlockOrRecordID = MaybeID.get(); | |
668 else { | |
669 // FIXME this drops the error on the floor. | |
670 consumeError(MaybeID.takeError()); | |
671 } | |
672 return Cursor::BlockBegin; | |
673 case llvm::bitc::END_BLOCK: | |
674 if (Stream.ReadBlockEnd()) | |
675 return Cursor::BadBlock; | |
676 return Cursor::BlockEnd; | |
677 case llvm::bitc::DEFINE_ABBREV: | |
678 if (llvm::Error Err = Stream.ReadAbbrevRecord()) { | |
679 // FIXME this drops the error on the floor. | |
680 consumeError(std::move(Err)); | |
681 } | |
682 continue; | |
683 case llvm::bitc::UNABBREV_RECORD: | |
684 return Cursor::BadBlock; | |
685 case llvm::bitc::FIRST_APPLICATION_ABBREV: | |
686 llvm_unreachable("Unexpected abbrev id."); | |
687 } | |
688 } | |
689 llvm_unreachable("Premature stream end."); | |
690 } | |
691 | |
692 llvm::Error ClangDocBitcodeReader::validateStream() { | |
693 if (Stream.AtEndOfStream()) | |
694 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
695 "premature end of stream"); | |
696 | |
697 // Sniff for the signature. | |
698 for (int Idx = 0; Idx != 4; ++Idx) { | |
699 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8); | |
700 if (!MaybeRead) | |
701 return MaybeRead.takeError(); | |
702 else if (MaybeRead.get() != BitCodeConstants::Signature[Idx]) | |
703 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
704 "invalid bitcode signature"); | |
705 } | |
706 return llvm::Error::success(); | |
707 } | |
708 | |
709 llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() { | |
710 Expected<Optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo = | |
711 Stream.ReadBlockInfoBlock(); | |
712 if (!MaybeBlockInfo) | |
713 return MaybeBlockInfo.takeError(); | |
714 else | |
715 BlockInfo = MaybeBlockInfo.get(); | |
716 if (!BlockInfo) | |
717 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
718 "unable to parse BlockInfoBlock"); | |
719 Stream.setBlockInfo(&*BlockInfo); | |
720 return llvm::Error::success(); | |
721 } | |
722 | |
723 template <typename T> | |
724 llvm::Expected<std::unique_ptr<Info>> | |
725 ClangDocBitcodeReader::createInfo(unsigned ID) { | |
726 std::unique_ptr<Info> I = std::make_unique<T>(); | |
727 if (auto Err = readBlock(ID, static_cast<T *>(I.get()))) | |
728 return std::move(Err); | |
729 return std::unique_ptr<Info>{std::move(I)}; | |
730 } | |
731 | |
732 llvm::Expected<std::unique_ptr<Info>> | |
733 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) { | |
734 switch (ID) { | |
735 case BI_NAMESPACE_BLOCK_ID: | |
736 return createInfo<NamespaceInfo>(ID); | |
737 case BI_RECORD_BLOCK_ID: | |
738 return createInfo<RecordInfo>(ID); | |
739 case BI_ENUM_BLOCK_ID: | |
740 return createInfo<EnumInfo>(ID); | |
741 case BI_FUNCTION_BLOCK_ID: | |
742 return createInfo<FunctionInfo>(ID); | |
743 default: | |
744 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
745 "cannot create info"); | |
746 } | |
747 } | |
748 | |
749 // Entry point | |
750 llvm::Expected<std::vector<std::unique_ptr<Info>>> | |
751 ClangDocBitcodeReader::readBitcode() { | |
752 std::vector<std::unique_ptr<Info>> Infos; | |
753 if (auto Err = validateStream()) | |
754 return std::move(Err); | |
755 | |
756 // Read the top level blocks. | |
757 while (!Stream.AtEndOfStream()) { | |
758 Expected<unsigned> MaybeCode = Stream.ReadCode(); | |
759 if (!MaybeCode) | |
760 return MaybeCode.takeError(); | |
761 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK) | |
762 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
763 "no blocks in input"); | |
764 Expected<unsigned> MaybeID = Stream.ReadSubBlockID(); | |
765 if (!MaybeID) | |
766 return MaybeID.takeError(); | |
767 unsigned ID = MaybeID.get(); | |
768 switch (ID) { | |
769 // NamedType and Comment blocks should not appear at the top level | |
770 case BI_TYPE_BLOCK_ID: | |
771 case BI_FIELD_TYPE_BLOCK_ID: | |
772 case BI_MEMBER_TYPE_BLOCK_ID: | |
773 case BI_COMMENT_BLOCK_ID: | |
774 case BI_REFERENCE_BLOCK_ID: | |
775 return llvm::createStringError(llvm::inconvertibleErrorCode(), | |
776 "invalid top level block"); | |
777 case BI_NAMESPACE_BLOCK_ID: | |
778 case BI_RECORD_BLOCK_ID: | |
779 case BI_ENUM_BLOCK_ID: | |
780 case BI_FUNCTION_BLOCK_ID: { | |
781 auto InfoOrErr = readBlockToInfo(ID); | |
782 if (!InfoOrErr) | |
783 return InfoOrErr.takeError(); | |
784 Infos.emplace_back(std::move(InfoOrErr.get())); | |
785 continue; | |
786 } | |
787 case BI_VERSION_BLOCK_ID: | |
788 if (auto Err = readBlock(ID, VersionNumber)) | |
789 return std::move(Err); | |
790 continue; | |
791 case llvm::bitc::BLOCKINFO_BLOCK_ID: | |
792 if (auto Err = readBlockInfoBlock()) | |
793 return std::move(Err); | |
794 continue; | |
795 default: | |
796 if (llvm::Error Err = Stream.SkipBlock()) { | |
797 // FIXME this drops the error on the floor. | |
798 consumeError(std::move(Err)); | |
799 } | |
800 continue; | |
801 } | |
802 } | |
803 return std::move(Infos); | |
804 } | |
805 | |
806 } // namespace doc | |
807 } // namespace clang |