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