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/ADT/Optional.h"
|
|
12 #include "llvm/Support/Error.h"
|
|
13 #include "llvm/Support/raw_ostream.h"
|
|
14
|
|
15 namespace clang {
|
|
16 namespace doc {
|
|
17
|
|
18 using Record = llvm::SmallVector<uint64_t, 1024>;
|
|
19
|
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
|
236
|
84 llvm::Error decodeRecord(const Record &R, llvm::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);
|
|
353 case REFERENCE_TYPE:
|
|
354 return decodeRecord(R, I->RefType, Blob);
|
|
355 case REFERENCE_PATH:
|
|
356 return decodeRecord(R, I->Path, Blob);
|
|
357 case REFERENCE_FIELD:
|
|
358 return decodeRecord(R, F, Blob);
|
|
359 default:
|
|
360 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
361 "invalid field for Reference");
|
|
362 }
|
|
363 }
|
|
364
|
|
365 template <typename T> llvm::Expected<CommentInfo *> getCommentInfo(T I) {
|
|
366 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
367 "invalid type cannot contain CommentInfo");
|
|
368 }
|
|
369
|
|
370 template <> llvm::Expected<CommentInfo *> getCommentInfo(FunctionInfo *I) {
|
236
|
371 return &I->Description.emplace_back();
|
150
|
372 }
|
|
373
|
|
374 template <> llvm::Expected<CommentInfo *> getCommentInfo(NamespaceInfo *I) {
|
236
|
375 return &I->Description.emplace_back();
|
150
|
376 }
|
|
377
|
|
378 template <> llvm::Expected<CommentInfo *> getCommentInfo(RecordInfo *I) {
|
236
|
379 return &I->Description.emplace_back();
|
|
380 }
|
|
381
|
|
382 template <> llvm::Expected<CommentInfo *> getCommentInfo(MemberTypeInfo *I) {
|
|
383 return &I->Description.emplace_back();
|
150
|
384 }
|
|
385
|
|
386 template <> llvm::Expected<CommentInfo *> getCommentInfo(EnumInfo *I) {
|
236
|
387 return &I->Description.emplace_back();
|
|
388 }
|
|
389
|
|
390 template <> llvm::Expected<CommentInfo *> getCommentInfo(TypedefInfo *I) {
|
|
391 return &I->Description.emplace_back();
|
150
|
392 }
|
|
393
|
|
394 template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) {
|
|
395 I->Children.emplace_back(std::make_unique<CommentInfo>());
|
|
396 return I->Children.back().get();
|
|
397 }
|
|
398
|
|
399 template <>
|
|
400 llvm::Expected<CommentInfo *> getCommentInfo(std::unique_ptr<CommentInfo> &I) {
|
|
401 return getCommentInfo(I.get());
|
|
402 }
|
|
403
|
236
|
404 // When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on
|
|
405 // the parent block to set it. The template specializations define what to do
|
|
406 // for each supported parent block.
|
150
|
407 template <typename T, typename TTypeInfo>
|
|
408 llvm::Error addTypeInfo(T I, TTypeInfo &&TI) {
|
|
409 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
410 "invalid type cannot contain TypeInfo");
|
|
411 }
|
|
412
|
|
413 template <> llvm::Error addTypeInfo(RecordInfo *I, MemberTypeInfo &&T) {
|
|
414 I->Members.emplace_back(std::move(T));
|
|
415 return llvm::Error::success();
|
|
416 }
|
|
417
|
|
418 template <> llvm::Error addTypeInfo(BaseRecordInfo *I, MemberTypeInfo &&T) {
|
|
419 I->Members.emplace_back(std::move(T));
|
|
420 return llvm::Error::success();
|
|
421 }
|
|
422
|
|
423 template <> llvm::Error addTypeInfo(FunctionInfo *I, TypeInfo &&T) {
|
|
424 I->ReturnType = std::move(T);
|
|
425 return llvm::Error::success();
|
|
426 }
|
|
427
|
|
428 template <> llvm::Error addTypeInfo(FunctionInfo *I, FieldTypeInfo &&T) {
|
|
429 I->Params.emplace_back(std::move(T));
|
|
430 return llvm::Error::success();
|
|
431 }
|
|
432
|
236
|
433 template <> llvm::Error addTypeInfo(EnumInfo *I, TypeInfo &&T) {
|
|
434 I->BaseType = std::move(T);
|
|
435 return llvm::Error::success();
|
|
436 }
|
|
437
|
|
438 template <> llvm::Error addTypeInfo(TypedefInfo *I, TypeInfo &&T) {
|
|
439 I->Underlying = std::move(T);
|
|
440 return llvm::Error::success();
|
|
441 }
|
|
442
|
150
|
443 template <typename T> llvm::Error addReference(T I, Reference &&R, FieldId F) {
|
|
444 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
445 "invalid type cannot contain Reference");
|
|
446 }
|
|
447
|
|
448 template <> llvm::Error addReference(TypeInfo *I, Reference &&R, FieldId F) {
|
|
449 switch (F) {
|
|
450 case FieldId::F_type:
|
|
451 I->Type = std::move(R);
|
|
452 return llvm::Error::success();
|
|
453 default:
|
|
454 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
455 "invalid type cannot contain Reference");
|
|
456 }
|
|
457 }
|
|
458
|
|
459 template <>
|
|
460 llvm::Error addReference(FieldTypeInfo *I, Reference &&R, FieldId F) {
|
|
461 switch (F) {
|
|
462 case FieldId::F_type:
|
|
463 I->Type = std::move(R);
|
|
464 return llvm::Error::success();
|
|
465 default:
|
|
466 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
467 "invalid type cannot contain Reference");
|
|
468 }
|
|
469 }
|
|
470
|
|
471 template <>
|
|
472 llvm::Error addReference(MemberTypeInfo *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(llvm::inconvertibleErrorCode(),
|
|
479 "invalid type cannot contain Reference");
|
|
480 }
|
|
481 }
|
|
482
|
|
483 template <> llvm::Error addReference(EnumInfo *I, Reference &&R, FieldId F) {
|
|
484 switch (F) {
|
|
485 case FieldId::F_namespace:
|
|
486 I->Namespace.emplace_back(std::move(R));
|
|
487 return llvm::Error::success();
|
|
488 default:
|
|
489 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
490 "invalid type cannot contain Reference");
|
|
491 }
|
|
492 }
|
|
493
|
236
|
494 template <> llvm::Error addReference(TypedefInfo *I, Reference &&R, FieldId F) {
|
|
495 switch (F) {
|
|
496 case FieldId::F_namespace:
|
|
497 I->Namespace.emplace_back(std::move(R));
|
|
498 return llvm::Error::success();
|
|
499 default:
|
|
500 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
501 "invalid type cannot contain Reference");
|
|
502 }
|
|
503 }
|
|
504
|
150
|
505 template <>
|
|
506 llvm::Error addReference(NamespaceInfo *I, Reference &&R, FieldId F) {
|
|
507 switch (F) {
|
|
508 case FieldId::F_namespace:
|
|
509 I->Namespace.emplace_back(std::move(R));
|
|
510 return llvm::Error::success();
|
|
511 case FieldId::F_child_namespace:
|
236
|
512 I->Children.Namespaces.emplace_back(std::move(R));
|
150
|
513 return llvm::Error::success();
|
|
514 case FieldId::F_child_record:
|
236
|
515 I->Children.Records.emplace_back(std::move(R));
|
150
|
516 return llvm::Error::success();
|
|
517 default:
|
|
518 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
519 "invalid type cannot contain Reference");
|
|
520 }
|
|
521 }
|
|
522
|
|
523 template <>
|
|
524 llvm::Error addReference(FunctionInfo *I, Reference &&R, FieldId F) {
|
|
525 switch (F) {
|
|
526 case FieldId::F_namespace:
|
|
527 I->Namespace.emplace_back(std::move(R));
|
|
528 return llvm::Error::success();
|
|
529 case FieldId::F_parent:
|
|
530 I->Parent = std::move(R);
|
|
531 return llvm::Error::success();
|
|
532 default:
|
|
533 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
534 "invalid type cannot contain Reference");
|
|
535 }
|
|
536 }
|
|
537
|
|
538 template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
|
|
539 switch (F) {
|
|
540 case FieldId::F_namespace:
|
|
541 I->Namespace.emplace_back(std::move(R));
|
|
542 return llvm::Error::success();
|
|
543 case FieldId::F_parent:
|
|
544 I->Parents.emplace_back(std::move(R));
|
|
545 return llvm::Error::success();
|
|
546 case FieldId::F_vparent:
|
|
547 I->VirtualParents.emplace_back(std::move(R));
|
|
548 return llvm::Error::success();
|
|
549 case FieldId::F_child_record:
|
236
|
550 I->Children.Records.emplace_back(std::move(R));
|
150
|
551 return llvm::Error::success();
|
|
552 default:
|
|
553 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
554 "invalid type cannot contain Reference");
|
|
555 }
|
|
556 }
|
|
557
|
|
558 template <typename T, typename ChildInfoType>
|
|
559 void addChild(T I, ChildInfoType &&R) {
|
|
560 llvm::errs() << "invalid child type for info";
|
|
561 exit(1);
|
|
562 }
|
|
563
|
236
|
564 // Namespace children:
|
150
|
565 template <> void addChild(NamespaceInfo *I, FunctionInfo &&R) {
|
236
|
566 I->Children.Functions.emplace_back(std::move(R));
|
150
|
567 }
|
|
568 template <> void addChild(NamespaceInfo *I, EnumInfo &&R) {
|
236
|
569 I->Children.Enums.emplace_back(std::move(R));
|
|
570 }
|
|
571 template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) {
|
|
572 I->Children.Typedefs.emplace_back(std::move(R));
|
150
|
573 }
|
|
574
|
236
|
575 // Record children:
|
150
|
576 template <> void addChild(RecordInfo *I, FunctionInfo &&R) {
|
236
|
577 I->Children.Functions.emplace_back(std::move(R));
|
|
578 }
|
|
579 template <> void addChild(RecordInfo *I, EnumInfo &&R) {
|
|
580 I->Children.Enums.emplace_back(std::move(R));
|
|
581 }
|
|
582 template <> void addChild(RecordInfo *I, TypedefInfo &&R) {
|
|
583 I->Children.Typedefs.emplace_back(std::move(R));
|
150
|
584 }
|
|
585
|
236
|
586 // Other types of children:
|
|
587 template <> void addChild(EnumInfo *I, EnumValueInfo &&R) {
|
|
588 I->Members.emplace_back(std::move(R));
|
150
|
589 }
|
|
590 template <> void addChild(RecordInfo *I, BaseRecordInfo &&R) {
|
|
591 I->Bases.emplace_back(std::move(R));
|
|
592 }
|
|
593 template <> void addChild(BaseRecordInfo *I, FunctionInfo &&R) {
|
236
|
594 I->Children.Functions.emplace_back(std::move(R));
|
150
|
595 }
|
|
596
|
|
597 // Read records from bitcode into a given info.
|
|
598 template <typename T>
|
|
599 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) {
|
|
600 Record R;
|
|
601 llvm::StringRef Blob;
|
|
602 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
|
|
603 if (!MaybeRecID)
|
|
604 return MaybeRecID.takeError();
|
|
605 return parseRecord(R, MaybeRecID.get(), Blob, I);
|
|
606 }
|
|
607
|
|
608 template <>
|
|
609 llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, Reference *I) {
|
|
610 Record R;
|
|
611 llvm::StringRef Blob;
|
|
612 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
|
|
613 if (!MaybeRecID)
|
|
614 return MaybeRecID.takeError();
|
|
615 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
|
|
616 }
|
|
617
|
|
618 // Read a block of records into a single info.
|
|
619 template <typename T>
|
|
620 llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) {
|
|
621 if (llvm::Error Err = Stream.EnterSubBlock(ID))
|
|
622 return Err;
|
|
623
|
|
624 while (true) {
|
|
625 unsigned BlockOrCode = 0;
|
|
626 Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
|
|
627
|
|
628 switch (Res) {
|
|
629 case Cursor::BadBlock:
|
|
630 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
631 "bad block found");
|
|
632 case Cursor::BlockEnd:
|
|
633 return llvm::Error::success();
|
|
634 case Cursor::BlockBegin:
|
|
635 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
|
|
636 if (llvm::Error Skipped = Stream.SkipBlock())
|
|
637 return joinErrors(std::move(Err), std::move(Skipped));
|
|
638 return Err;
|
|
639 }
|
|
640 continue;
|
|
641 case Cursor::Record:
|
|
642 break;
|
|
643 }
|
|
644 if (auto Err = readRecord(BlockOrCode, I))
|
|
645 return Err;
|
|
646 }
|
|
647 }
|
|
648
|
|
649 template <typename T>
|
|
650 llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) {
|
|
651 switch (ID) {
|
236
|
652 // Blocks can only have certain types of sub blocks.
|
150
|
653 case BI_COMMENT_BLOCK_ID: {
|
|
654 auto Comment = getCommentInfo(I);
|
|
655 if (!Comment)
|
|
656 return Comment.takeError();
|
|
657 if (auto Err = readBlock(ID, Comment.get()))
|
|
658 return Err;
|
|
659 return llvm::Error::success();
|
|
660 }
|
|
661 case BI_TYPE_BLOCK_ID: {
|
|
662 TypeInfo TI;
|
|
663 if (auto Err = readBlock(ID, &TI))
|
|
664 return Err;
|
|
665 if (auto Err = addTypeInfo(I, std::move(TI)))
|
|
666 return Err;
|
|
667 return llvm::Error::success();
|
|
668 }
|
|
669 case BI_FIELD_TYPE_BLOCK_ID: {
|
|
670 FieldTypeInfo TI;
|
|
671 if (auto Err = readBlock(ID, &TI))
|
|
672 return Err;
|
|
673 if (auto Err = addTypeInfo(I, std::move(TI)))
|
|
674 return Err;
|
|
675 return llvm::Error::success();
|
|
676 }
|
|
677 case BI_MEMBER_TYPE_BLOCK_ID: {
|
|
678 MemberTypeInfo TI;
|
|
679 if (auto Err = readBlock(ID, &TI))
|
|
680 return Err;
|
|
681 if (auto Err = addTypeInfo(I, std::move(TI)))
|
|
682 return Err;
|
|
683 return llvm::Error::success();
|
|
684 }
|
|
685 case BI_REFERENCE_BLOCK_ID: {
|
|
686 Reference R;
|
|
687 if (auto Err = readBlock(ID, &R))
|
|
688 return Err;
|
|
689 if (auto Err = addReference(I, std::move(R), CurrentReferenceField))
|
|
690 return Err;
|
|
691 return llvm::Error::success();
|
|
692 }
|
|
693 case BI_FUNCTION_BLOCK_ID: {
|
|
694 FunctionInfo F;
|
|
695 if (auto Err = readBlock(ID, &F))
|
|
696 return Err;
|
|
697 addChild(I, std::move(F));
|
|
698 return llvm::Error::success();
|
|
699 }
|
|
700 case BI_BASE_RECORD_BLOCK_ID: {
|
|
701 BaseRecordInfo BR;
|
|
702 if (auto Err = readBlock(ID, &BR))
|
|
703 return Err;
|
|
704 addChild(I, std::move(BR));
|
|
705 return llvm::Error::success();
|
|
706 }
|
|
707 case BI_ENUM_BLOCK_ID: {
|
|
708 EnumInfo E;
|
|
709 if (auto Err = readBlock(ID, &E))
|
|
710 return Err;
|
|
711 addChild(I, std::move(E));
|
|
712 return llvm::Error::success();
|
|
713 }
|
236
|
714 case BI_ENUM_VALUE_BLOCK_ID: {
|
|
715 EnumValueInfo EV;
|
|
716 if (auto Err = readBlock(ID, &EV))
|
|
717 return Err;
|
|
718 addChild(I, std::move(EV));
|
|
719 return llvm::Error::success();
|
|
720 }
|
|
721 case BI_TYPEDEF_BLOCK_ID: {
|
|
722 TypedefInfo TI;
|
|
723 if (auto Err = readBlock(ID, &TI))
|
|
724 return Err;
|
|
725 addChild(I, std::move(TI));
|
|
726 return llvm::Error::success();
|
|
727 }
|
150
|
728 default:
|
|
729 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
730 "invalid subblock type");
|
|
731 }
|
|
732 }
|
|
733
|
|
734 ClangDocBitcodeReader::Cursor
|
|
735 ClangDocBitcodeReader::skipUntilRecordOrBlock(unsigned &BlockOrRecordID) {
|
|
736 BlockOrRecordID = 0;
|
|
737
|
|
738 while (!Stream.AtEndOfStream()) {
|
|
739 Expected<unsigned> MaybeCode = Stream.ReadCode();
|
|
740 if (!MaybeCode) {
|
|
741 // FIXME this drops the error on the floor.
|
|
742 consumeError(MaybeCode.takeError());
|
|
743 return Cursor::BadBlock;
|
|
744 }
|
|
745
|
|
746 unsigned Code = MaybeCode.get();
|
|
747 if (Code >= static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
|
|
748 BlockOrRecordID = Code;
|
|
749 return Cursor::Record;
|
|
750 }
|
|
751 switch (static_cast<llvm::bitc::FixedAbbrevIDs>(Code)) {
|
|
752 case llvm::bitc::ENTER_SUBBLOCK:
|
|
753 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
|
|
754 BlockOrRecordID = MaybeID.get();
|
|
755 else {
|
|
756 // FIXME this drops the error on the floor.
|
|
757 consumeError(MaybeID.takeError());
|
|
758 }
|
|
759 return Cursor::BlockBegin;
|
|
760 case llvm::bitc::END_BLOCK:
|
|
761 if (Stream.ReadBlockEnd())
|
|
762 return Cursor::BadBlock;
|
|
763 return Cursor::BlockEnd;
|
|
764 case llvm::bitc::DEFINE_ABBREV:
|
|
765 if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
|
|
766 // FIXME this drops the error on the floor.
|
|
767 consumeError(std::move(Err));
|
|
768 }
|
|
769 continue;
|
|
770 case llvm::bitc::UNABBREV_RECORD:
|
|
771 return Cursor::BadBlock;
|
|
772 case llvm::bitc::FIRST_APPLICATION_ABBREV:
|
|
773 llvm_unreachable("Unexpected abbrev id.");
|
|
774 }
|
|
775 }
|
|
776 llvm_unreachable("Premature stream end.");
|
|
777 }
|
|
778
|
|
779 llvm::Error ClangDocBitcodeReader::validateStream() {
|
|
780 if (Stream.AtEndOfStream())
|
|
781 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
782 "premature end of stream");
|
|
783
|
|
784 // Sniff for the signature.
|
|
785 for (int Idx = 0; Idx != 4; ++Idx) {
|
|
786 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
|
|
787 if (!MaybeRead)
|
|
788 return MaybeRead.takeError();
|
|
789 else if (MaybeRead.get() != BitCodeConstants::Signature[Idx])
|
|
790 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
791 "invalid bitcode signature");
|
|
792 }
|
|
793 return llvm::Error::success();
|
|
794 }
|
|
795
|
|
796 llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
|
|
797 Expected<Optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
|
|
798 Stream.ReadBlockInfoBlock();
|
|
799 if (!MaybeBlockInfo)
|
|
800 return MaybeBlockInfo.takeError();
|
|
801 else
|
|
802 BlockInfo = MaybeBlockInfo.get();
|
|
803 if (!BlockInfo)
|
|
804 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
805 "unable to parse BlockInfoBlock");
|
|
806 Stream.setBlockInfo(&*BlockInfo);
|
|
807 return llvm::Error::success();
|
|
808 }
|
|
809
|
|
810 template <typename T>
|
|
811 llvm::Expected<std::unique_ptr<Info>>
|
|
812 ClangDocBitcodeReader::createInfo(unsigned ID) {
|
|
813 std::unique_ptr<Info> I = std::make_unique<T>();
|
|
814 if (auto Err = readBlock(ID, static_cast<T *>(I.get())))
|
|
815 return std::move(Err);
|
|
816 return std::unique_ptr<Info>{std::move(I)};
|
|
817 }
|
|
818
|
|
819 llvm::Expected<std::unique_ptr<Info>>
|
|
820 ClangDocBitcodeReader::readBlockToInfo(unsigned ID) {
|
|
821 switch (ID) {
|
|
822 case BI_NAMESPACE_BLOCK_ID:
|
|
823 return createInfo<NamespaceInfo>(ID);
|
|
824 case BI_RECORD_BLOCK_ID:
|
|
825 return createInfo<RecordInfo>(ID);
|
|
826 case BI_ENUM_BLOCK_ID:
|
|
827 return createInfo<EnumInfo>(ID);
|
236
|
828 case BI_TYPEDEF_BLOCK_ID:
|
|
829 return createInfo<TypedefInfo>(ID);
|
150
|
830 case BI_FUNCTION_BLOCK_ID:
|
|
831 return createInfo<FunctionInfo>(ID);
|
|
832 default:
|
|
833 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
834 "cannot create info");
|
|
835 }
|
|
836 }
|
|
837
|
|
838 // Entry point
|
|
839 llvm::Expected<std::vector<std::unique_ptr<Info>>>
|
|
840 ClangDocBitcodeReader::readBitcode() {
|
|
841 std::vector<std::unique_ptr<Info>> Infos;
|
|
842 if (auto Err = validateStream())
|
|
843 return std::move(Err);
|
|
844
|
|
845 // Read the top level blocks.
|
|
846 while (!Stream.AtEndOfStream()) {
|
|
847 Expected<unsigned> MaybeCode = Stream.ReadCode();
|
|
848 if (!MaybeCode)
|
|
849 return MaybeCode.takeError();
|
|
850 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
|
|
851 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
852 "no blocks in input");
|
|
853 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
|
|
854 if (!MaybeID)
|
|
855 return MaybeID.takeError();
|
|
856 unsigned ID = MaybeID.get();
|
|
857 switch (ID) {
|
|
858 // NamedType and Comment blocks should not appear at the top level
|
|
859 case BI_TYPE_BLOCK_ID:
|
|
860 case BI_FIELD_TYPE_BLOCK_ID:
|
|
861 case BI_MEMBER_TYPE_BLOCK_ID:
|
|
862 case BI_COMMENT_BLOCK_ID:
|
|
863 case BI_REFERENCE_BLOCK_ID:
|
|
864 return llvm::createStringError(llvm::inconvertibleErrorCode(),
|
|
865 "invalid top level block");
|
|
866 case BI_NAMESPACE_BLOCK_ID:
|
|
867 case BI_RECORD_BLOCK_ID:
|
|
868 case BI_ENUM_BLOCK_ID:
|
236
|
869 case BI_TYPEDEF_BLOCK_ID:
|
150
|
870 case BI_FUNCTION_BLOCK_ID: {
|
|
871 auto InfoOrErr = readBlockToInfo(ID);
|
|
872 if (!InfoOrErr)
|
|
873 return InfoOrErr.takeError();
|
|
874 Infos.emplace_back(std::move(InfoOrErr.get()));
|
|
875 continue;
|
|
876 }
|
|
877 case BI_VERSION_BLOCK_ID:
|
|
878 if (auto Err = readBlock(ID, VersionNumber))
|
|
879 return std::move(Err);
|
|
880 continue;
|
|
881 case llvm::bitc::BLOCKINFO_BLOCK_ID:
|
|
882 if (auto Err = readBlockInfoBlock())
|
|
883 return std::move(Err);
|
|
884 continue;
|
|
885 default:
|
|
886 if (llvm::Error Err = Stream.SkipBlock()) {
|
|
887 // FIXME this drops the error on the floor.
|
|
888 consumeError(std::move(Err));
|
|
889 }
|
|
890 continue;
|
|
891 }
|
|
892 }
|
|
893 return std::move(Infos);
|
|
894 }
|
|
895
|
|
896 } // namespace doc
|
|
897 } // namespace clang
|