150
|
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"
|
252
|
13 #include <optional>
|
150
|
14
|
|
15 namespace clang {
|
|
16 namespace doc {
|
|
17
|
|
18 using Record = llvm::SmallVector<uint64_t, 1024>;
|
|
19
|
236
|
20 // This implements decode for SmallString.
|
|
21 llvm::Error decodeRecord(const Record &R, llvm::SmallVectorImpl<char> &Field,
|
150
|
22 llvm::StringRef Blob) {
|
|
23 Field.assign(Blob.begin(), Blob.end());
|
|
24 return llvm::Error::success();
|
|
25 }
|
|
26
|
236
|
27 llvm::Error decodeRecord(const Record &R, SymbolID &Field,
|
|
28 llvm::StringRef Blob) {
|
150
|
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
|
236
|
40 llvm::Error decodeRecord(const Record &R, bool &Field, llvm::StringRef Blob) {
|
150
|
41 Field = R[0] != 0;
|
|
42 return llvm::Error::success();
|
|
43 }
|
|
44
|
236
|
45 llvm::Error decodeRecord(const Record &R, int &Field, llvm::StringRef Blob) {
|
150
|
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
|
236
|
53 llvm::Error decodeRecord(const Record &R, AccessSpecifier &Field,
|
150
|
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
|
236
|
68 llvm::Error decodeRecord(const Record &R, TagTypeKind &Field,
|
|
69 llvm::StringRef Blob) {
|
150
|
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
|
252
|
84 llvm::Error decodeRecord(const Record &R, std::optional<Location> &Field,
|
150
|
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
|
236
|
93 llvm::Error decodeRecord(const Record &R, InfoType &Field,
|
|
94 llvm::StringRef Blob) {
|
150
|
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:
|
236
|
101 case InfoType::IT_typedef:
|
150
|
102 Field = IT;
|
|
103 return llvm::Error::success();
|
|
104 }
|
|
105 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
106 "invalid value for InfoType");
|
|
107 }
|
|
108
|
236
|
109 llvm::Error decodeRecord(const Record &R, FieldId &Field,
|
|
110 llvm::StringRef Blob) {
|
150
|
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
|
236
|
126 llvm::Error decodeRecord(const Record &R,
|
150
|
127 llvm::SmallVectorImpl<llvm::SmallString<16>> &Field,
|
|
128 llvm::StringRef Blob) {
|
|
129 Field.push_back(Blob);
|
|
130 return llvm::Error::success();
|
|
131 }
|
|
132
|
236
|
133 llvm::Error decodeRecord(const Record &R,
|
|
134 llvm::SmallVectorImpl<Location> &Field,
|
150
|
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
|
236
|
143 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
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
|
236
|
151 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
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
|
236
|
166 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
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
|
236
|
189 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
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
|
236
|
212 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
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
|
236
|
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,
|
150
|
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
|
236
|
284 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
285 TypeInfo *I) {
|
|
286 return llvm::Error::success();
|
|
287 }
|
|
288
|
236
|
289 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
290 FieldTypeInfo *I) {
|
|
291 switch (ID) {
|
|
292 case FIELD_TYPE_NAME:
|
|
293 return decodeRecord(R, I->Name, Blob);
|
236
|
294 case FIELD_DEFAULT_VALUE:
|
|
295 return decodeRecord(R, I->DefaultValue, Blob);
|
150
|
296 default:
|
|
297 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
298 "invalid field for TypeInfo");
|
|
299 }
|
|
300 }
|
|
301
|
236
|
302 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
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
|
236
|
315 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
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
|
236
|
346 llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob,
|
150
|
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);
|
252
|
353 case REFERENCE_QUAL_NAME:
|
|
354 return decodeRecord(R, I->QualName, Blob);
|
150
|
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
|
252
|
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
|
150
|
390 template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) {
|
|
391 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
392 "invalid type cannot contain CommentInfo");
|
|
393 }
|
|
394
|
|
395 template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
|
236
|
396 return &I->Description.emplace_back();
|
150
|
397 }
|
|
398
|
|
399 template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
|
236
|
400 return &I->Description.emplace_back();
|
150
|
401 }
|
|
402
|
|
403 template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
|
236
|
404 return &I->Description.emplace_back();
|
|
405 }
|
|
406
|
|
407 template <> llvm::Expected<CommentInfo *> getCommentInfo(MemberTypeInfo *I) {
|
|
408 return &I->Description.emplace_back();
|
150
|
409 }
|
|
410
|
|
411 template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
|
236
|
412 return &I->Description.emplace_back();
|
|
413 }
|
|
414
|
|
415 template <> llvm::Expected<CommentInfo *> getCommentInfo(TypedefInfo *I) {
|
|
416 return &I->Description.emplace_back();
|
150
|
417 }
|
|
418
|
|
419 template <> llvm::Expected<CommentInfo *> getCommentInfo(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 *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
|
|
426 return getCommentInfo(I.get());
|
|
427 }
|
|
428
|
236
|
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.
|
150
|
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
|
236
|
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
|
150
|
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
|
236
|
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
|
150
|
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:
|
236
|
537 I->Children.Namespaces.emplace_back(std::move(R));
|
150
|
538 return llvm::Error::success();
|
|
539 case FieldId::F_child_record:
|
236
|
540 I->Children.Records.emplace_back(std::move(R));
|
150
|
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:
|
236
|
575 I->Children.Records.emplace_back(std::move(R));
|
150
|
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
|
236
|
589 // Namespace children:
|
150
|
590 template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
|
236
|
591 I->Children.Functions.emplace_back(std::move(R));
|
150
|
592 }
|
|
593 template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
|
236
|
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));
|
150
|
598 }
|
|
599
|
236
|
600 // Record children:
|
150
|
601 template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
|
236
|
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));
|
150
|
609 }
|
|
610
|
236
|
611 // Other types of children:
|
|
612 template <> void addChild(EnumInfo *I, EnumValueInfo &&R) {
|
|
613 I->Members.emplace_back(std::move(R));
|
150
|
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) {
|
236
|
619 I->Children.Functions.emplace_back(std::move(R));
|
150
|
620 }
|
|
621
|
252
|
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
|
150
|
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) {
|
236
|
716 // Blocks can only have certain types of sub blocks.
|
150
|
717 case BI_COMMENT_BLOCK_ID: {
|
|
718 auto Comment = 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 }
|
236
|
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 }
|
252
|
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 }
|
236
|
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 }
|
150
|
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() {
|
252
|
882 Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
|
150
|
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);
|
236
|
913 case BI_TYPEDEF_BLOCK_ID:
|
|
914 return createInfo<TypedefInfo>(ID);
|
150
|
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:
|
236
|
954 case BI_TYPEDEF_BLOCK_ID:
|
150
|
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
|