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/Support/Error.h" |
12 | #include "llvm/Support/raw_ostream.h" |
13 | #include <optional> |
14 | |
15 | namespace clang { |
16 | namespace doc { |
17 | |
18 | using Record = llvm::SmallVector<uint64_t, 1024>; |
19 | |
20 | // This implements decode for SmallString. |
21 | llvm::Error decodeRecord(const 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(const Record &R, SymbolID &Field, |
28 | llvm::StringRef Blob) { |
29 | if (R[0] != BitCodeConstants::USRHashSize) |
30 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
31 | "incorrect USR size" ); |
32 | |
33 | // First position in the record is the length of the following array, so we |
34 | // copy the following elements to the field. |
35 | for (int I = 0, E = R[0]; I < E; ++I) |
36 | Field[I] = R[I + 1]; |
37 | return llvm::Error::success(); |
38 | } |
39 | |
40 | llvm::Error decodeRecord(const Record &R, bool &Field, llvm::StringRef Blob) { |
41 | Field = R[0] != 0; |
42 | return llvm::Error::success(); |
43 | } |
44 | |
45 | llvm::Error decodeRecord(const Record &R, int &Field, llvm::StringRef Blob) { |
46 | if (R[0] > INT_MAX) |
47 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
48 | "integer too large to parse" ); |
49 | Field = (int)R[0]; |
50 | return llvm::Error::success(); |
51 | } |
52 | |
53 | llvm::Error decodeRecord(const Record &R, AccessSpecifier &Field, |
54 | llvm::StringRef Blob) { |
55 | switch (R[0]) { |
56 | case AS_public: |
57 | case AS_private: |
58 | case AS_protected: |
59 | case AS_none: |
60 | Field = (AccessSpecifier)R[0]; |
61 | return llvm::Error::success(); |
62 | default: |
63 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
64 | "invalid value for AccessSpecifier" ); |
65 | } |
66 | } |
67 | |
68 | llvm::Error decodeRecord(const Record &R, TagTypeKind &Field, |
69 | llvm::StringRef Blob) { |
70 | switch (R[0]) { |
71 | case TTK_Struct: |
72 | case TTK_Interface: |
73 | case TTK_Union: |
74 | case TTK_Class: |
75 | case TTK_Enum: |
76 | Field = (TagTypeKind)R[0]; |
77 | return llvm::Error::success(); |
78 | default: |
79 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
80 | "invalid value for TagTypeKind" ); |
81 | } |
82 | } |
83 | |
84 | llvm::Error decodeRecord(const Record &R, std::optional<Location> &Field, |
85 | llvm::StringRef Blob) { |
86 | if (R[0] > INT_MAX) |
87 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
88 | "integer too large to parse" ); |
89 | Field.emplace((int)R[0], Blob, (bool)R[1]); |
90 | return llvm::Error::success(); |
91 | } |
92 | |
93 | llvm::Error decodeRecord(const Record &R, InfoType &Field, |
94 | llvm::StringRef Blob) { |
95 | switch (auto IT = static_cast<InfoType>(R[0])) { |
96 | case InfoType::IT_namespace: |
97 | case InfoType::IT_record: |
98 | case InfoType::IT_function: |
99 | case InfoType::IT_default: |
100 | case InfoType::IT_enum: |
101 | case InfoType::IT_typedef: |
102 | Field = IT; |
103 | return llvm::Error::success(); |
104 | } |
105 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
106 | "invalid value for InfoType" ); |
107 | } |
108 | |
109 | llvm::Error decodeRecord(const Record &R, FieldId &Field, |
110 | llvm::StringRef Blob) { |
111 | switch (auto F = static_cast<FieldId>(R[0])) { |
112 | case FieldId::F_namespace: |
113 | case FieldId::F_parent: |
114 | case FieldId::F_vparent: |
115 | case FieldId::F_type: |
116 | case FieldId::F_child_namespace: |
117 | case FieldId::F_child_record: |
118 | case FieldId::F_default: |
119 | Field = F; |
120 | return llvm::Error::success(); |
121 | } |
122 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
123 | "invalid value for FieldId" ); |
124 | } |
125 | |
126 | llvm::Error decodeRecord(const Record &R, |
127 | llvm::SmallVectorImpl<llvm::SmallString<16>> &Field, |
128 | llvm::StringRef Blob) { |
129 | Field.push_back(Blob); |
130 | return llvm::Error::success(); |
131 | } |
132 | |
133 | llvm::Error decodeRecord(const Record &R, |
134 | llvm::SmallVectorImpl<Location> &Field, |
135 | llvm::StringRef Blob) { |
136 | if (R[0] > INT_MAX) |
137 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
138 | "integer too large to parse" ); |
139 | Field.emplace_back((int)R[0], Blob, (bool)R[1]); |
140 | return llvm::Error::success(); |
141 | } |
142 | |
143 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
144 | const unsigned VersionNo) { |
145 | if (ID == VERSION && R[0] == VersionNo) |
146 | return llvm::Error::success(); |
147 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
148 | "mismatched bitcode version number" ); |
149 | } |
150 | |
151 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
152 | NamespaceInfo *I) { |
153 | switch (ID) { |
154 | case NAMESPACE_USR: |
155 | return decodeRecord(R, I->USR, Blob); |
156 | case NAMESPACE_NAME: |
157 | return decodeRecord(R, I->Name, Blob); |
158 | case NAMESPACE_PATH: |
159 | return decodeRecord(R, I->Path, Blob); |
160 | default: |
161 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
162 | "invalid field for NamespaceInfo" ); |
163 | } |
164 | } |
165 | |
166 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
167 | RecordInfo *I) { |
168 | switch (ID) { |
169 | case RECORD_USR: |
170 | return decodeRecord(R, I->USR, Blob); |
171 | case RECORD_NAME: |
172 | return decodeRecord(R, I->Name, Blob); |
173 | case RECORD_PATH: |
174 | return decodeRecord(R, I->Path, Blob); |
175 | case RECORD_DEFLOCATION: |
176 | return decodeRecord(R, I->DefLoc, Blob); |
177 | case RECORD_LOCATION: |
178 | return decodeRecord(R, I->Loc, Blob); |
179 | case RECORD_TAG_TYPE: |
180 | return decodeRecord(R, I->TagType, Blob); |
181 | case RECORD_IS_TYPE_DEF: |
182 | return decodeRecord(R, I->IsTypeDef, Blob); |
183 | default: |
184 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
185 | "invalid field for RecordInfo" ); |
186 | } |
187 | } |
188 | |
189 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
190 | BaseRecordInfo *I) { |
191 | switch (ID) { |
192 | case BASE_RECORD_USR: |
193 | return decodeRecord(R, I->USR, Blob); |
194 | case BASE_RECORD_NAME: |
195 | return decodeRecord(R, I->Name, Blob); |
196 | case BASE_RECORD_PATH: |
197 | return decodeRecord(R, I->Path, Blob); |
198 | case BASE_RECORD_TAG_TYPE: |
199 | return decodeRecord(R, I->TagType, Blob); |
200 | case BASE_RECORD_IS_VIRTUAL: |
201 | return decodeRecord(R, I->IsVirtual, Blob); |
202 | case BASE_RECORD_ACCESS: |
203 | return decodeRecord(R, I->Access, Blob); |
204 | case BASE_RECORD_IS_PARENT: |
205 | return decodeRecord(R, I->IsParent, Blob); |
206 | default: |
207 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
208 | "invalid field for BaseRecordInfo" ); |
209 | } |
210 | } |
211 | |
212 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
213 | EnumInfo *I) { |
214 | switch (ID) { |
215 | case ENUM_USR: |
216 | return decodeRecord(R, I->USR, Blob); |
217 | case ENUM_NAME: |
218 | return decodeRecord(R, I->Name, Blob); |
219 | case ENUM_DEFLOCATION: |
220 | return decodeRecord(R, I->DefLoc, Blob); |
221 | case ENUM_LOCATION: |
222 | return decodeRecord(R, I->Loc, Blob); |
223 | case ENUM_SCOPED: |
224 | return decodeRecord(R, I->Scoped, Blob); |
225 | default: |
226 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
227 | "invalid field for EnumInfo" ); |
228 | } |
229 | } |
230 | |
231 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
232 | TypedefInfo *I) { |
233 | switch (ID) { |
234 | case TYPEDEF_USR: |
235 | return decodeRecord(R, I->USR, Blob); |
236 | case TYPEDEF_NAME: |
237 | return decodeRecord(R, I->Name, Blob); |
238 | case TYPEDEF_DEFLOCATION: |
239 | return decodeRecord(R, I->DefLoc, Blob); |
240 | case TYPEDEF_IS_USING: |
241 | return decodeRecord(R, I->IsUsing, Blob); |
242 | default: |
243 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
244 | "invalid field for TypedefInfo" ); |
245 | } |
246 | } |
247 | |
248 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
249 | EnumValueInfo *I) { |
250 | switch (ID) { |
251 | case ENUM_VALUE_NAME: |
252 | return decodeRecord(R, I->Name, Blob); |
253 | case ENUM_VALUE_VALUE: |
254 | return decodeRecord(R, I->Value, Blob); |
255 | case ENUM_VALUE_EXPR: |
256 | return decodeRecord(R, I->ValueExpr, Blob); |
257 | default: |
258 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
259 | "invalid field for EnumValueInfo" ); |
260 | } |
261 | } |
262 | |
263 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
264 | FunctionInfo *I) { |
265 | switch (ID) { |
266 | case FUNCTION_USR: |
267 | return decodeRecord(R, I->USR, Blob); |
268 | case FUNCTION_NAME: |
269 | return decodeRecord(R, I->Name, Blob); |
270 | case FUNCTION_DEFLOCATION: |
271 | return decodeRecord(R, I->DefLoc, Blob); |
272 | case FUNCTION_LOCATION: |
273 | return decodeRecord(R, I->Loc, Blob); |
274 | case FUNCTION_ACCESS: |
275 | return decodeRecord(R, I->Access, Blob); |
276 | case FUNCTION_IS_METHOD: |
277 | return decodeRecord(R, I->IsMethod, Blob); |
278 | default: |
279 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
280 | "invalid field for FunctionInfo" ); |
281 | } |
282 | } |
283 | |
284 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
285 | TypeInfo *I) { |
286 | return llvm::Error::success(); |
287 | } |
288 | |
289 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
290 | FieldTypeInfo *I) { |
291 | switch (ID) { |
292 | case FIELD_TYPE_NAME: |
293 | return decodeRecord(R, I->Name, Blob); |
294 | case FIELD_DEFAULT_VALUE: |
295 | return decodeRecord(R, I->DefaultValue, Blob); |
296 | default: |
297 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
298 | "invalid field for TypeInfo" ); |
299 | } |
300 | } |
301 | |
302 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
303 | MemberTypeInfo *I) { |
304 | switch (ID) { |
305 | case MEMBER_TYPE_NAME: |
306 | return decodeRecord(R, I->Name, Blob); |
307 | case MEMBER_TYPE_ACCESS: |
308 | return decodeRecord(R, I->Access, Blob); |
309 | default: |
310 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
311 | "invalid field for MemberTypeInfo" ); |
312 | } |
313 | } |
314 | |
315 | llvm::Error (const Record &R, unsigned ID, llvm::StringRef Blob, |
316 | CommentInfo *I) { |
317 | switch (ID) { |
318 | case COMMENT_KIND: |
319 | return decodeRecord(R, I->Kind, Blob); |
320 | case COMMENT_TEXT: |
321 | return decodeRecord(R, I->Text, Blob); |
322 | case COMMENT_NAME: |
323 | return decodeRecord(R, I->Name, Blob); |
324 | case COMMENT_DIRECTION: |
325 | return decodeRecord(R, I->Direction, Blob); |
326 | case COMMENT_PARAMNAME: |
327 | return decodeRecord(R, I->ParamName, Blob); |
328 | case COMMENT_CLOSENAME: |
329 | return decodeRecord(R, I->CloseName, Blob); |
330 | case COMMENT_ATTRKEY: |
331 | return decodeRecord(R, I->AttrKeys, Blob); |
332 | case COMMENT_ATTRVAL: |
333 | return decodeRecord(R, I->AttrValues, Blob); |
334 | case COMMENT_ARG: |
335 | return decodeRecord(R, I->Args, Blob); |
336 | case COMMENT_SELFCLOSING: |
337 | return decodeRecord(R, I->SelfClosing, Blob); |
338 | case COMMENT_EXPLICIT: |
339 | return decodeRecord(R, I->Explicit, Blob); |
340 | default: |
341 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
342 | "invalid field for CommentInfo" ); |
343 | } |
344 | } |
345 | |
346 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
347 | Reference *I, FieldId &F) { |
348 | switch (ID) { |
349 | case REFERENCE_USR: |
350 | return decodeRecord(R, I->USR, Blob); |
351 | case REFERENCE_NAME: |
352 | return decodeRecord(R, I->Name, Blob); |
353 | case REFERENCE_QUAL_NAME: |
354 | return decodeRecord(R, I->QualName, Blob); |
355 | case REFERENCE_TYPE: |
356 | return decodeRecord(R, I->RefType, Blob); |
357 | case REFERENCE_PATH: |
358 | return decodeRecord(R, I->Path, Blob); |
359 | case REFERENCE_FIELD: |
360 | return decodeRecord(R, F, Blob); |
361 | default: |
362 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
363 | "invalid field for Reference" ); |
364 | } |
365 | } |
366 | |
367 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
368 | TemplateInfo *I) { |
369 | // Currently there are no child records of TemplateInfo (only child blocks). |
370 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
371 | "invalid field for TemplateParamInfo" ); |
372 | } |
373 | |
374 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
375 | TemplateSpecializationInfo *I) { |
376 | if (ID == TEMPLATE_SPECIALIZATION_OF) |
377 | return decodeRecord(R, I->SpecializationOf, Blob); |
378 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
379 | "invalid field for TemplateParamInfo" ); |
380 | } |
381 | |
382 | llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, |
383 | TemplateParamInfo *I) { |
384 | if (ID == TEMPLATE_PARAM_CONTENTS) |
385 | return decodeRecord(R, I->Contents, Blob); |
386 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
387 | "invalid field for TemplateParamInfo" ); |
388 | } |
389 | |
390 | template <typename T> llvm::Expected<CommentInfo *> (T I) { |
391 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
392 | "invalid type cannot contain CommentInfo" ); |
393 | } |
394 | |
395 | template <> llvm::Expected<CommentInfo *> (FunctionInfo *I) { |
396 | return &I->Description.emplace_back(); |
397 | } |
398 | |
399 | template <> llvm::Expected<CommentInfo *> (NamespaceInfo *I) { |
400 | return &I->Description.emplace_back(); |
401 | } |
402 | |
403 | template <> llvm::Expected<CommentInfo *> (RecordInfo *I) { |
404 | return &I->Description.emplace_back(); |
405 | } |
406 | |
407 | template <> llvm::Expected<CommentInfo *> (MemberTypeInfo *I) { |
408 | return &I->Description.emplace_back(); |
409 | } |
410 | |
411 | template <> llvm::Expected<CommentInfo *> (EnumInfo *I) { |
412 | return &I->Description.emplace_back(); |
413 | } |
414 | |
415 | template <> llvm::Expected<CommentInfo *> (TypedefInfo *I) { |
416 | return &I->Description.emplace_back(); |
417 | } |
418 | |
419 | template <> llvm::Expected<CommentInfo *> (CommentInfo *I) { |
420 | I->Children.emplace_back(std::make_unique<CommentInfo>()); |
421 | return I->Children.back().get(); |
422 | } |
423 | |
424 | template <> |
425 | llvm::Expected<CommentInfo *> (std::unique_ptr<CommentInfo> &I) { |
426 | return getCommentInfo(I.get()); |
427 | } |
428 | |
429 | // When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on |
430 | // the parent block to set it. The template specializations define what to do |
431 | // for each supported parent block. |
432 | template <typename T, typename TTypeInfo> |
433 | llvm::Error addTypeInfo(T I, TTypeInfo &&TI) { |
434 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
435 | "invalid type cannot contain TypeInfo" ); |
436 | } |
437 | |
438 | template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) { |
439 | I->Members.emplace_back(std::move(T)); |
440 | return llvm::Error::success(); |
441 | } |
442 | |
443 | template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) { |
444 | I->Members.emplace_back(std::move(T)); |
445 | return llvm::Error::success(); |
446 | } |
447 | |
448 | template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) { |
449 | I->ReturnType = std::move(T); |
450 | return llvm::Error::success(); |
451 | } |
452 | |
453 | template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) { |
454 | I->Params.emplace_back(std::move(T)); |
455 | return llvm::Error::success(); |
456 | } |
457 | |
458 | template <> llvm::Error addTypeInfo(EnumInfo *I, TypeInfo &&T) { |
459 | I->BaseType = std::move(T); |
460 | return llvm::Error::success(); |
461 | } |
462 | |
463 | template <> llvm::Error addTypeInfo(TypedefInfo *I, TypeInfo &&T) { |
464 | I->Underlying = std::move(T); |
465 | return llvm::Error::success(); |
466 | } |
467 | |
468 | template <typename T> llvm::Error addReference(T I, Reference &&R, FieldId F) { |
469 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
470 | "invalid type cannot contain Reference" ); |
471 | } |
472 | |
473 | template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) { |
474 | switch (F) { |
475 | case FieldId::F_type: |
476 | I->Type = std::move(R); |
477 | return llvm::Error::success(); |
478 | default: |
479 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
480 | "invalid type cannot contain Reference" ); |
481 | } |
482 | } |
483 | |
484 | template <> |
485 | llvm::Error addReference(FieldTypeInfo *I, Reference &&R, FieldId F) { |
486 | switch (F) { |
487 | case FieldId::F_type: |
488 | I->Type = std::move(R); |
489 | return llvm::Error::success(); |
490 | default: |
491 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
492 | "invalid type cannot contain Reference" ); |
493 | } |
494 | } |
495 | |
496 | template <> |
497 | llvm::Error addReference(MemberTypeInfo *I, Reference &&R, FieldId F) { |
498 | switch (F) { |
499 | case FieldId::F_type: |
500 | I->Type = std::move(R); |
501 | return llvm::Error::success(); |
502 | default: |
503 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
504 | "invalid type cannot contain Reference" ); |
505 | } |
506 | } |
507 | |
508 | template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) { |
509 | switch (F) { |
510 | case FieldId::F_namespace: |
511 | I->Namespace.emplace_back(std::move(R)); |
512 | return llvm::Error::success(); |
513 | default: |
514 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
515 | "invalid type cannot contain Reference" ); |
516 | } |
517 | } |
518 | |
519 | template <> llvm::Error addReference(TypedefInfo *I, Reference &&R, FieldId F) { |
520 | switch (F) { |
521 | case FieldId::F_namespace: |
522 | I->Namespace.emplace_back(std::move(R)); |
523 | return llvm::Error::success(); |
524 | default: |
525 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
526 | "invalid type cannot contain Reference" ); |
527 | } |
528 | } |
529 | |
530 | template <> |
531 | llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) { |
532 | switch (F) { |
533 | case FieldId::F_namespace: |
534 | I->Namespace.emplace_back(std::move(R)); |
535 | return llvm::Error::success(); |
536 | case FieldId::F_child_namespace: |
537 | I->Children.Namespaces.emplace_back(std::move(R)); |
538 | return llvm::Error::success(); |
539 | case FieldId::F_child_record: |
540 | I->Children.Records.emplace_back(std::move(R)); |
541 | return llvm::Error::success(); |
542 | default: |
543 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
544 | "invalid type cannot contain Reference" ); |
545 | } |
546 | } |
547 | |
548 | template <> |
549 | llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) { |
550 | switch (F) { |
551 | case FieldId::F_namespace: |
552 | I->Namespace.emplace_back(std::move(R)); |
553 | return llvm::Error::success(); |
554 | case FieldId::F_parent: |
555 | I->Parent = std::move(R); |
556 | return llvm::Error::success(); |
557 | default: |
558 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
559 | "invalid type cannot contain Reference" ); |
560 | } |
561 | } |
562 | |
563 | template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) { |
564 | switch (F) { |
565 | case FieldId::F_namespace: |
566 | I->Namespace.emplace_back(std::move(R)); |
567 | return llvm::Error::success(); |
568 | case FieldId::F_parent: |
569 | I->Parents.emplace_back(std::move(R)); |
570 | return llvm::Error::success(); |
571 | case FieldId::F_vparent: |
572 | I->VirtualParents.emplace_back(std::move(R)); |
573 | return llvm::Error::success(); |
574 | case FieldId::F_child_record: |
575 | I->Children.Records.emplace_back(std::move(R)); |
576 | return llvm::Error::success(); |
577 | default: |
578 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
579 | "invalid type cannot contain Reference" ); |
580 | } |
581 | } |
582 | |
583 | template <typename T, typename ChildInfoType> |
584 | void addChild(T I, ChildInfoType &&R) { |
585 | llvm::errs() << "invalid child type for info" ; |
586 | exit(1); |
587 | } |
588 | |
589 | // Namespace children: |
590 | template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) { |
591 | I->Children.Functions.emplace_back(std::move(R)); |
592 | } |
593 | template <> void addChild(NamespaceInfo *I, EnumInfo &&R) { |
594 | I->Children.Enums.emplace_back(std::move(R)); |
595 | } |
596 | template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) { |
597 | I->Children.Typedefs.emplace_back(std::move(R)); |
598 | } |
599 | |
600 | // Record children: |
601 | template <> void addChild(RecordInfo *I, FunctionInfo &&R) { |
602 | I->Children.Functions.emplace_back(std::move(R)); |
603 | } |
604 | template <> void addChild(RecordInfo *I, EnumInfo &&R) { |
605 | I->Children.Enums.emplace_back(std::move(R)); |
606 | } |
607 | template <> void addChild(RecordInfo *I, TypedefInfo &&R) { |
608 | I->Children.Typedefs.emplace_back(std::move(R)); |
609 | } |
610 | |
611 | // Other types of children: |
612 | template <> void addChild(EnumInfo *I, EnumValueInfo &&R) { |
613 | I->Members.emplace_back(std::move(R)); |
614 | } |
615 | template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) { |
616 | I->Bases.emplace_back(std::move(R)); |
617 | } |
618 | template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) { |
619 | I->Children.Functions.emplace_back(std::move(R)); |
620 | } |
621 | |
622 | // TemplateParam children. These go into either a TemplateInfo (for template |
623 | // parameters) or TemplateSpecializationInfo (for the specialization's |
624 | // parameters). |
625 | template <typename T> void addTemplateParam(T I, TemplateParamInfo &&P) { |
626 | llvm::errs() << "invalid container for template parameter" ; |
627 | exit(1); |
628 | } |
629 | template <> void addTemplateParam(TemplateInfo *I, TemplateParamInfo &&P) { |
630 | I->Params.emplace_back(std::move(P)); |
631 | } |
632 | template <> |
633 | void addTemplateParam(TemplateSpecializationInfo *I, TemplateParamInfo &&P) { |
634 | I->Params.emplace_back(std::move(P)); |
635 | } |
636 | |
637 | // Template info. These apply to either records or functions. |
638 | template <typename T> void addTemplate(T I, TemplateInfo &&P) { |
639 | llvm::errs() << "invalid container for template info" ; |
640 | exit(1); |
641 | } |
642 | template <> void addTemplate(RecordInfo *I, TemplateInfo &&P) { |
643 | I->Template.emplace(std::move(P)); |
644 | } |
645 | template <> void addTemplate(FunctionInfo *I, TemplateInfo &&P) { |
646 | I->Template.emplace(std::move(P)); |
647 | } |
648 | |
649 | // Template specializations go only into template records. |
650 | template <typename T> |
651 | void addTemplateSpecialization(T I, TemplateSpecializationInfo &&TSI) { |
652 | llvm::errs() << "invalid container for template specialization info" ; |
653 | exit(1); |
654 | } |
655 | template <> |
656 | void addTemplateSpecialization(TemplateInfo *I, |
657 | TemplateSpecializationInfo &&TSI) { |
658 | I->Specialization.emplace(std::move(TSI)); |
659 | } |
660 | |
661 | // Read records from bitcode into a given info. |
662 | template <typename T> |
663 | llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) { |
664 | Record R; |
665 | llvm::StringRef Blob; |
666 | llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob); |
667 | if (!MaybeRecID) |
668 | return MaybeRecID.takeError(); |
669 | return parseRecord(R, MaybeRecID.get(), Blob, I); |
670 | } |
671 | |
672 | template <> |
673 | llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) { |
674 | Record R; |
675 | llvm::StringRef Blob; |
676 | llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob); |
677 | if (!MaybeRecID) |
678 | return MaybeRecID.takeError(); |
679 | return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField); |
680 | } |
681 | |
682 | // Read a block of records into a single info. |
683 | template <typename T> |
684 | llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) { |
685 | if (llvm::Error Err = Stream.EnterSubBlock(ID)) |
686 | return Err; |
687 | |
688 | while (true) { |
689 | unsigned BlockOrCode = 0; |
690 | Cursor Res = skipUntilRecordOrBlock(BlockOrCode); |
691 | |
692 | switch (Res) { |
693 | case Cursor::BadBlock: |
694 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
695 | "bad block found" ); |
696 | case Cursor::BlockEnd: |
697 | return llvm::Error::success(); |
698 | case Cursor::BlockBegin: |
699 | if (llvm::Error Err = readSubBlock(BlockOrCode, I)) { |
700 | if (llvm::Error Skipped = Stream.SkipBlock()) |
701 | return joinErrors(std::move(Err), std::move(Skipped)); |
702 | return Err; |
703 | } |
704 | continue; |
705 | case Cursor::Record: |
706 | break; |
707 | } |
708 | if (auto Err = readRecord(BlockOrCode, I)) |
709 | return Err; |
710 | } |
711 | } |
712 | |
713 | template <typename T> |
714 | llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { |
715 | switch (ID) { |
716 | // Blocks can only have certain types of sub blocks. |
717 | case BI_COMMENT_BLOCK_ID: { |
718 | auto = getCommentInfo(I); |
719 | if (!Comment) |
720 | return Comment.takeError(); |
721 | if (auto Err = readBlock(ID, Comment.get())) |
722 | return Err; |
723 | return llvm::Error::success(); |
724 | } |
725 | case BI_TYPE_BLOCK_ID: { |
726 | TypeInfo TI; |
727 | if (auto Err = readBlock(ID, &TI)) |
728 | return Err; |
729 | if (auto Err = addTypeInfo(I, std::move(TI))) |
730 | return Err; |
731 | return llvm::Error::success(); |
732 | } |
733 | case BI_FIELD_TYPE_BLOCK_ID: { |
734 | FieldTypeInfo TI; |
735 | if (auto Err = readBlock(ID, &TI)) |
736 | return Err; |
737 | if (auto Err = addTypeInfo(I, std::move(TI))) |
738 | return Err; |
739 | return llvm::Error::success(); |
740 | } |
741 | case BI_MEMBER_TYPE_BLOCK_ID: { |
742 | MemberTypeInfo TI; |
743 | if (auto Err = readBlock(ID, &TI)) |
744 | return Err; |
745 | if (auto Err = addTypeInfo(I, std::move(TI))) |
746 | return Err; |
747 | return llvm::Error::success(); |
748 | } |
749 | case BI_REFERENCE_BLOCK_ID: { |
750 | Reference R; |
751 | if (auto Err = readBlock(ID, &R)) |
752 | return Err; |
753 | if (auto Err = addReference(I, std::move(R), CurrentReferenceField)) |
754 | return Err; |
755 | return llvm::Error::success(); |
756 | } |
757 | case BI_FUNCTION_BLOCK_ID: { |
758 | FunctionInfo F; |
759 | if (auto Err = readBlock(ID, &F)) |
760 | return Err; |
761 | addChild(I, std::move(F)); |
762 | return llvm::Error::success(); |
763 | } |
764 | case BI_BASE_RECORD_BLOCK_ID: { |
765 | BaseRecordInfo BR; |
766 | if (auto Err = readBlock(ID, &BR)) |
767 | return Err; |
768 | addChild(I, std::move(BR)); |
769 | return llvm::Error::success(); |
770 | } |
771 | case BI_ENUM_BLOCK_ID: { |
772 | EnumInfo E; |
773 | if (auto Err = readBlock(ID, &E)) |
774 | return Err; |
775 | addChild(I, std::move(E)); |
776 | return llvm::Error::success(); |
777 | } |
778 | case BI_ENUM_VALUE_BLOCK_ID: { |
779 | EnumValueInfo EV; |
780 | if (auto Err = readBlock(ID, &EV)) |
781 | return Err; |
782 | addChild(I, std::move(EV)); |
783 | return llvm::Error::success(); |
784 | } |
785 | case BI_TEMPLATE_BLOCK_ID: { |
786 | TemplateInfo TI; |
787 | if (auto Err = readBlock(ID, &TI)) |
788 | return Err; |
789 | addTemplate(I, std::move(TI)); |
790 | return llvm::Error::success(); |
791 | } |
792 | case BI_TEMPLATE_SPECIALIZATION_BLOCK_ID: { |
793 | TemplateSpecializationInfo TSI; |
794 | if (auto Err = readBlock(ID, &TSI)) |
795 | return Err; |
796 | addTemplateSpecialization(I, std::move(TSI)); |
797 | return llvm::Error::success(); |
798 | } |
799 | case BI_TEMPLATE_PARAM_BLOCK_ID: { |
800 | TemplateParamInfo TPI; |
801 | if (auto Err = readBlock(ID, &TPI)) |
802 | return Err; |
803 | addTemplateParam(I, std::move(TPI)); |
804 | return llvm::Error::success(); |
805 | } |
806 | case BI_TYPEDEF_BLOCK_ID: { |
807 | TypedefInfo TI; |
808 | if (auto Err = readBlock(ID, &TI)) |
809 | return Err; |
810 | addChild(I, std::move(TI)); |
811 | return llvm::Error::success(); |
812 | } |
813 | default: |
814 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
815 | "invalid subblock type" ); |
816 | } |
817 | } |
818 | |
819 | ClangDocBitcodeReader::Cursor |
820 | ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) { |
821 | BlockOrRecordID = 0; |
822 | |
823 | while (!Stream.AtEndOfStream()) { |
824 | Expected<unsigned> MaybeCode = Stream.ReadCode(); |
825 | if (!MaybeCode) { |
826 | // FIXME this drops the error on the floor. |
827 | consumeError(MaybeCode.takeError()); |
828 | return Cursor::BadBlock; |
829 | } |
830 | |
831 | unsigned Code = MaybeCode.get(); |
832 | if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) { |
833 | BlockOrRecordID = Code; |
834 | return Cursor::Record; |
835 | } |
836 | switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) { |
837 | case llvm::bitc::ENTER_SUBBLOCK: |
838 | if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID()) |
839 | BlockOrRecordID = MaybeID.get(); |
840 | else { |
841 | // FIXME this drops the error on the floor. |
842 | consumeError(MaybeID.takeError()); |
843 | } |
844 | return Cursor::BlockBegin; |
845 | case llvm::bitc::END_BLOCK: |
846 | if (Stream.ReadBlockEnd()) |
847 | return Cursor::BadBlock; |
848 | return Cursor::BlockEnd; |
849 | case llvm::bitc::DEFINE_ABBREV: |
850 | if (llvm::Error Err = Stream.ReadAbbrevRecord()) { |
851 | // FIXME this drops the error on the floor. |
852 | consumeError(std::move(Err)); |
853 | } |
854 | continue; |
855 | case llvm::bitc::UNABBREV_RECORD: |
856 | return Cursor::BadBlock; |
857 | case llvm::bitc::FIRST_APPLICATION_ABBREV: |
858 | llvm_unreachable("Unexpected abbrev id." ); |
859 | } |
860 | } |
861 | llvm_unreachable("Premature stream end." ); |
862 | } |
863 | |
864 | llvm::Error ClangDocBitcodeReader::validateStream() { |
865 | if (Stream.AtEndOfStream()) |
866 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
867 | "premature end of stream" ); |
868 | |
869 | // Sniff for the signature. |
870 | for (int Idx = 0; Idx != 4; ++Idx) { |
871 | Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8); |
872 | if (!MaybeRead) |
873 | return MaybeRead.takeError(); |
874 | else if (MaybeRead.get() != BitCodeConstants::Signature[Idx]) |
875 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
876 | "invalid bitcode signature" ); |
877 | } |
878 | return llvm::Error::success(); |
879 | } |
880 | |
881 | llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() { |
882 | Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo = |
883 | Stream.ReadBlockInfoBlock(); |
884 | if (!MaybeBlockInfo) |
885 | return MaybeBlockInfo.takeError(); |
886 | else |
887 | BlockInfo = MaybeBlockInfo.get(); |
888 | if (!BlockInfo) |
889 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
890 | "unable to parse BlockInfoBlock" ); |
891 | Stream.setBlockInfo(&*BlockInfo); |
892 | return llvm::Error::success(); |
893 | } |
894 | |
895 | template <typename T> |
896 | llvm::Expected<std::unique_ptr<Info>> |
897 | ClangDocBitcodeReader::createInfo(unsigned ID) { |
898 | std::unique_ptr<Info> I = std::make_unique<T>(); |
899 | if (auto Err = readBlock(ID, static_cast<T *>(I.get()))) |
900 | return std::move(Err); |
901 | return std::unique_ptr<Info>{std::move(I)}; |
902 | } |
903 | |
904 | llvm::Expected<std::unique_ptr<Info>> |
905 | ClangDocBitcodeReader::readBlockToInfo(unsigned ID) { |
906 | switch (ID) { |
907 | case BI_NAMESPACE_BLOCK_ID: |
908 | return createInfo<NamespaceInfo>(ID); |
909 | case BI_RECORD_BLOCK_ID: |
910 | return createInfo<RecordInfo>(ID); |
911 | case BI_ENUM_BLOCK_ID: |
912 | return createInfo<EnumInfo>(ID); |
913 | case BI_TYPEDEF_BLOCK_ID: |
914 | return createInfo<TypedefInfo>(ID); |
915 | case BI_FUNCTION_BLOCK_ID: |
916 | return createInfo<FunctionInfo>(ID); |
917 | default: |
918 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
919 | "cannot create info" ); |
920 | } |
921 | } |
922 | |
923 | // Entry point |
924 | llvm::Expected<std::vector<std::unique_ptr<Info>>> |
925 | ClangDocBitcodeReader::readBitcode() { |
926 | std::vector<std::unique_ptr<Info>> Infos; |
927 | if (auto Err = validateStream()) |
928 | return std::move(Err); |
929 | |
930 | // Read the top level blocks. |
931 | while (!Stream.AtEndOfStream()) { |
932 | Expected<unsigned> MaybeCode = Stream.ReadCode(); |
933 | if (!MaybeCode) |
934 | return MaybeCode.takeError(); |
935 | if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK) |
936 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
937 | "no blocks in input" ); |
938 | Expected<unsigned> MaybeID = Stream.ReadSubBlockID(); |
939 | if (!MaybeID) |
940 | return MaybeID.takeError(); |
941 | unsigned ID = MaybeID.get(); |
942 | switch (ID) { |
943 | // NamedType and Comment blocks should not appear at the top level |
944 | case BI_TYPE_BLOCK_ID: |
945 | case BI_FIELD_TYPE_BLOCK_ID: |
946 | case BI_MEMBER_TYPE_BLOCK_ID: |
947 | case BI_COMMENT_BLOCK_ID: |
948 | case BI_REFERENCE_BLOCK_ID: |
949 | return llvm::createStringError(llvm::inconvertibleErrorCode(), |
950 | "invalid top level block" ); |
951 | case BI_NAMESPACE_BLOCK_ID: |
952 | case BI_RECORD_BLOCK_ID: |
953 | case BI_ENUM_BLOCK_ID: |
954 | case BI_TYPEDEF_BLOCK_ID: |
955 | case BI_FUNCTION_BLOCK_ID: { |
956 | auto InfoOrErr = readBlockToInfo(ID); |
957 | if (!InfoOrErr) |
958 | return InfoOrErr.takeError(); |
959 | Infos.emplace_back(std::move(InfoOrErr.get())); |
960 | continue; |
961 | } |
962 | case BI_VERSION_BLOCK_ID: |
963 | if (auto Err = readBlock(ID, VersionNumber)) |
964 | return std::move(Err); |
965 | continue; |
966 | case llvm::bitc::BLOCKINFO_BLOCK_ID: |
967 | if (auto Err = readBlockInfoBlock()) |
968 | return std::move(Err); |
969 | continue; |
970 | default: |
971 | if (llvm::Error Err = Stream.SkipBlock()) { |
972 | // FIXME this drops the error on the floor. |
973 | consumeError(std::move(Err)); |
974 | } |
975 | continue; |
976 | } |
977 | } |
978 | return std::move(Infos); |
979 | } |
980 | |
981 | } // namespace doc |
982 | } // namespace clang |
983 | |