10#include "llvm/Support/Error.h"
11#include "llvm/Support/ErrorHandling.h"
12#include "llvm/Support/TimeProfiler.h"
13#include "llvm/Support/raw_ostream.h"
20static llvm::ExitOnError
ExitOnErr(
"clang-doc error: ");
22using Record = llvm::SmallVector<uint64_t, 1024>;
27 llvm::StringRef Blob) {
28 Field.assign(Blob.begin(), Blob.end());
29 return llvm::Error::success();
33 llvm::StringRef Blob) {
35 return llvm::Error::success();
39 llvm::StringRef Blob) {
41 return llvm::createStringError(llvm::inconvertibleErrorCode(),
42 "empty record for SymbolID");
44 return llvm::createStringError(llvm::inconvertibleErrorCode(),
45 "incorrect USR size");
46 if (R.size() < R[0] + 1)
47 return llvm::createStringError(llvm::inconvertibleErrorCode(),
48 "record too short for SymbolID");
52 for (
int I = 0, E = R[0]; I < E; ++I)
54 return llvm::Error::success();
58 llvm::StringRef Blob) {
60 return llvm::createStringError(llvm::inconvertibleErrorCode(),
61 "empty record for bool");
63 return llvm::Error::success();
67 llvm::StringRef Blob) {
69 return llvm::createStringError(llvm::inconvertibleErrorCode(),
70 "empty record for AccessSpecifier");
76 Field = (AccessSpecifier)R[0];
77 return llvm::Error::success();
79 llvm_unreachable(
"invalid value for AccessSpecifier");
83 llvm::StringRef Blob) {
85 return llvm::createStringError(llvm::inconvertibleErrorCode(),
86 "empty record for TagTypeKind");
87 switch (
static_cast<TagTypeKind
>(R[0])) {
88 case TagTypeKind::Struct:
89 case TagTypeKind::Interface:
90 case TagTypeKind::Union:
91 case TagTypeKind::Class:
92 case TagTypeKind::Enum:
93 Field =
static_cast<TagTypeKind
>(R[0]);
94 return llvm::Error::success();
96 return llvm::createStringError(llvm::inconvertibleErrorCode(),
97 "invalid value for TagTypeKind");
101 llvm::StringRef Blob) {
103 return llvm::createStringError(llvm::inconvertibleErrorCode(),
104 "record too short for Location");
106 return llvm::createStringError(llvm::inconvertibleErrorCode(),
107 "integer too large to parse");
108 Field.emplace(
static_cast<int>(R[0]),
static_cast<int>(R[1]), Blob,
109 static_cast<bool>(R[2]));
110 return llvm::Error::success();
114 llvm::StringRef Blob) {
116 return llvm::createStringError(llvm::inconvertibleErrorCode(),
117 "empty record for InfoType");
118 switch (
auto IT =
static_cast<InfoType>(R[0])) {
129 return llvm::Error::success();
131 return llvm::createStringError(llvm::inconvertibleErrorCode(),
132 "invalid value for InfoType");
136 llvm::StringRef Blob) {
138 return llvm::createStringError(llvm::inconvertibleErrorCode(),
139 "empty record for FieldId");
140 switch (
auto F =
static_cast<FieldId>(R[0])) {
151 return llvm::Error::success();
153 return llvm::createStringError(llvm::inconvertibleErrorCode(),
154 "invalid value for FieldId");
158 llvm::StringRef Blob) {
160 return llvm::createStringError(llvm::inconvertibleErrorCode(),
161 "record too short for Location");
163 return llvm::createStringError(llvm::inconvertibleErrorCode(),
164 "integer too large to parse");
167 static_cast<int>(R[0]),
static_cast<int>(R[1]), Blob,
168 static_cast<bool>(R[2])));
169 return llvm::Error::success();
173 llvm::StringRef Blob,
const unsigned VersionNo) {
174 if (ID ==
VERSION && R[0] == VersionNo)
175 return llvm::Error::success();
176 return llvm::createStringError(llvm::inconvertibleErrorCode(),
177 "mismatched bitcode version number");
192 return llvm::createStringError(llvm::inconvertibleErrorCode(),
193 "invalid field for NamespaceInfo");
219 return llvm::createStringError(llvm::inconvertibleErrorCode(),
220 "invalid field for RecordInfo");
242 return llvm::createStringError(llvm::inconvertibleErrorCode(),
243 "invalid field for BaseRecordInfo");
248 llvm::StringRef Blob,
EnumInfo *I) {
261 return llvm::createStringError(llvm::inconvertibleErrorCode(),
262 "invalid field for EnumInfo");
278 return llvm::createStringError(llvm::inconvertibleErrorCode(),
279 "invalid field for TypedefInfo");
293 return llvm::createStringError(llvm::inconvertibleErrorCode(),
294 "invalid field for EnumValueInfo");
316 return llvm::createStringError(llvm::inconvertibleErrorCode(),
317 "invalid field for FunctionInfo");
322 llvm::StringRef Blob,
TypeInfo *I) {
329 return llvm::createStringError(llvm::inconvertibleErrorCode(),
330 "invalid field for TypeInfo");
346 return llvm::createStringError(llvm::inconvertibleErrorCode(),
347 "invalid field for TypeInfo");
365 return llvm::createStringError(llvm::inconvertibleErrorCode(),
366 "invalid field for MemberTypeInfo");
375 llvm::SmallString<16> KindStr;
381 return llvm::Error::success();
394 return llvm::Error::success();
397 return llvm::Error::success();
400 return llvm::Error::success();
406 return llvm::createStringError(llvm::inconvertibleErrorCode(),
407 "invalid field for CommentInfo");
411template <
typename T,
typename BlockBeginHandler,
typename BlockEndHandler,
412 typename RecordHandler>
414ClangDocBitcodeReader::parseBlock(
unsigned ID, T I, BlockBeginHandler &&BBH,
415 BlockEndHandler &&BEH, RecordHandler &&RH) {
416 llvm::TimeTraceScope(
"Reducing infos",
"readBlock");
417 if (llvm::Error Err = Stream.EnterSubBlock(ID))
421 unsigned BlockOrCode = 0;
422 llvm::Expected<Cursor> C = skipUntilRecordOrBlock(BlockOrCode);
424 return C.takeError();
427 case Cursor::BadBlock:
428 return llvm::createStringError(llvm::inconvertibleErrorCode(),
430 case Cursor::BlockEnd:
431 if (llvm::Error Err = BEH())
433 return llvm::Error::success();
434 case Cursor::BlockBegin: {
435 llvm::Expected<bool> Handled = BBH(BlockOrCode);
437 return Handled.takeError();
441 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
442 if (llvm::Error Skipped = Stream.SkipBlock())
443 return joinErrors(std::move(Err), std::move(Skipped));
452 if (llvm::Error Err = RH(BlockOrCode))
457template <
typename T,
typename BlockBeginHandler,
typename BlockEndHandler>
458llvm::Error ClangDocBitcodeReader::parseBlock(
unsigned ID, T I,
459 BlockBeginHandler &&BBH,
460 BlockEndHandler &&BEH) {
461 return parseBlock(ID, I, std::forward<BlockBeginHandler>(BBH),
462 std::forward<BlockEndHandler>(BEH),
463 [&](
unsigned Code) {
return readRecord(Code, I); });
466template <
typename ChildType>
467llvm::Expected<bool> ClangDocBitcodeReader::readSubBlockIfMatch(
468 unsigned ID,
unsigned TargetID, llvm::SmallVectorImpl<ChildType> &V) {
472 if (
auto Err = readBlock(ID, &Val))
473 return std::move(Err);
474 V.push_back(std::move(Val));
498template <
typename InfoT>
499llvm::Expected<bool> ClangDocBitcodeReader::routeReferenceBlock(
500 unsigned ID, llvm::SmallVectorImpl<Reference> &Namespaces, InfoT *I,
501 std::initializer_list<ReferenceMap> Mappings) {
505 if (
auto Err = readBlock(ID, &R))
506 return std::move(Err);
508 for (
const auto &Map : Mappings) {
509 if (CurrentReferenceField == Map.Field) {
510 Map.Vec->push_back(std::move(R));
516 Namespaces.push_back(std::move(R));
520 if (
auto Err =
addReference(I, std::move(R), CurrentReferenceField))
521 return std::move(Err);
527llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
CommentInfo *I);
529llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
FunctionInfo *I);
531llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
EnumInfo *I);
535llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
RecordInfo *I);
537llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
TemplateInfo *I);
539llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
542llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
VarInfo *I);
544llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
TypedefInfo *I);
548llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
FriendInfo *I);
551llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
CommentInfo *I) {
552 llvm::SmallVector<CommentInfo> LocalChildren;
553 llvm::SmallVector<StringRef> AttrKeys;
554 llvm::SmallVector<StringRef> AttrValues;
555 llvm::SmallVector<StringRef> Args;
559 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
562 if (llvm::Error Err = readBlock(BlockOrCode, &Child))
563 return std::move(Err);
564 LocalChildren.push_back(std::move(Child));
569 [&]() -> llvm::Error {
570 if (!LocalChildren.empty())
573 if (!AttrKeys.empty())
575 if (!AttrValues.empty())
580 return llvm::Error::success();
582 [&](
unsigned BlockOrCode) -> llvm::Error {
584 llvm::StringRef Blob;
585 llvm::Expected<unsigned> MaybeRecID =
586 Stream.readRecord(BlockOrCode, R, &Blob);
588 return MaybeRecID.takeError();
589 return parseRecord(R, MaybeRecID.get(), Blob, I, AttrKeys, AttrValues,
595llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
FunctionInfo *I) {
596 llvm::SmallVector<FieldTypeInfo, 4> LocalParams;
597 llvm::SmallVector<Reference> LocalNamespaces;
601 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
605 return B.takeError();
608 return routeReferenceBlock(BlockOrCode, LocalNamespaces, I);
610 [&]() -> llvm::Error {
612 if (!LocalNamespaces.empty())
614 return llvm::Error::success();
619llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
EnumInfo *I) {
620 llvm::SmallVector<EnumValueInfo, 4> LocalMembers;
621 llvm::SmallVector<Reference> LocalNamespaces;
625 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
629 return B.takeError();
632 return routeReferenceBlock(BlockOrCode, LocalNamespaces, I);
634 [&]() -> llvm::Error {
636 if (!LocalNamespaces.empty())
638 return llvm::Error::success();
645 llvm::SmallVector<BaseRecordInfo, 4> LocalBases;
646 llvm::SmallVector<FriendInfo, 4> LocalFriends;
647 llvm::SmallVector<MemberTypeInfo> LocalMembers;
648 llvm::SmallVector<Reference> LocalParents;
649 llvm::SmallVector<Reference> LocalVirtualParents;
653 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
657 return B.takeError();
664 return B.takeError();
670 return B.takeError();
674 llvm::SmallVector<Reference> Dummy;
675 return routeReferenceBlock(
676 BlockOrCode, Dummy, I,
680 [&]() -> llvm::Error {
681 if (!LocalMembers.empty())
683 if (!LocalParents.empty())
685 if (!LocalVirtualParents.empty())
690 return llvm::Error::success();
695llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
RecordInfo *I) {
696 llvm::SmallVector<BaseRecordInfo, 4> LocalBases;
697 llvm::SmallVector<FriendInfo, 4> LocalFriends;
698 llvm::SmallVector<MemberTypeInfo> LocalMembers;
699 llvm::SmallVector<Reference> LocalParents;
700 llvm::SmallVector<Reference> LocalVirtualParents;
701 llvm::SmallVector<Reference> LocalNamespaces;
705 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
709 return B.takeError();
716 return B.takeError();
722 return B.takeError();
726 return routeReferenceBlock(
727 BlockOrCode, LocalNamespaces, I,
731 [&]() -> llvm::Error {
732 if (!LocalMembers.empty())
734 if (!LocalParents.empty())
736 if (!LocalVirtualParents.empty())
739 if (!LocalNamespaces.empty())
743 return llvm::Error::success();
748llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
TemplateInfo *I) {
749 llvm::SmallVector<TemplateParamInfo> LocalParams;
750 llvm::SmallVector<ConstraintInfo> LocalConstraints;
754 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
758 return B.takeError();
765 return B.takeError();
771 [&]() -> llvm::Error {
774 return llvm::Error::success();
776 [&](
unsigned BlockOrCode) -> llvm::Error {
777 return readRecord(BlockOrCode, I);
782llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
784 llvm::SmallVector<TemplateParamInfo> LocalParams;
788 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
792 return B.takeError();
798 [&]() -> llvm::Error {
800 return llvm::Error::success();
802 [&](
unsigned BlockOrCode) -> llvm::Error {
803 return readRecord(BlockOrCode, I);
825 return llvm::createStringError(llvm::inconvertibleErrorCode(),
826 "invalid field for Reference");
833 return llvm::createStringError(llvm::inconvertibleErrorCode(),
834 "invalid field for TemplateParamInfo");
838 llvm::StringRef Blob,
842 return llvm::createStringError(llvm::inconvertibleErrorCode(),
843 "invalid field for TemplateParamInfo");
850 return llvm::createStringError(llvm::inconvertibleErrorCode(),
851 "invalid field for TemplateParamInfo");
868 llvm_unreachable(
"invalid field for ConceptInfo");
875 return llvm::createStringError(llvm::inconvertibleErrorCode(),
876 "invalid field for ConstraintInfo");
880 llvm::StringRef Blob,
VarInfo *I) {
891 return llvm::createStringError(llvm::inconvertibleErrorCode(),
892 "invalid field for VarInfo");
901 return llvm::createStringError(llvm::inconvertibleErrorCode(),
902 "invalid field for Friend");
905template <
typename,
typename =
void>
912 if constexpr (std::is_pointer_v<T>) {
913 using Pointee = std::remove_pointer_t<T>;
916 I->Description.push_back(*NewComment);
917 return NewComment->Ptr;
920 return llvm::createStringError(llvm::inconvertibleErrorCode(),
921 "invalid type cannot contain CommentInfo");
927template <
typename T,
typename TTypeInfo>
929 return llvm::createStringError(llvm::inconvertibleErrorCode(),
930 "invalid type cannot contain TypeInfo");
935 return llvm::Error::success();
940 return llvm::Error::success();
945 return llvm::Error::success();
950 return llvm::Error::success();
954 I->
Type = std::move(T);
955 return llvm::Error::success();
960 return llvm::createStringError(llvm::inconvertibleErrorCode(),
961 "invalid type cannot contain Reference");
965 return llvm::createStringError(llvm::inconvertibleErrorCode(),
966 "VarInfo cannot contain this Reference");
972 I->
Type = std::move(R);
973 return llvm::Error::success();
975 return llvm::createStringError(llvm::inconvertibleErrorCode(),
976 "invalid type cannot contain Reference");
984 I->
Type = std::move(R);
985 return llvm::Error::success();
987 return llvm::createStringError(llvm::inconvertibleErrorCode(),
988 "invalid type cannot contain Reference");
996 I->
Type = std::move(R);
997 return llvm::Error::success();
999 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1000 "invalid type cannot contain Reference");
1005 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1006 "invalid type cannot contain Reference");
1010 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1011 "invalid type cannot contain Reference");
1020 return llvm::Error::success();
1024 return llvm::Error::success();
1026 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1027 "invalid type cannot contain Reference");
1035 I->
Parent = std::move(R);
1036 return llvm::Error::success();
1038 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1039 "invalid type cannot contain Reference");
1048 return llvm::Error::success();
1050 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1051 "invalid type cannot contain Reference");
1059 return llvm::Error::success();
1061 return llvm::createStringError(
1062 llvm::inconvertibleErrorCode(),
1063 "ConstraintInfo cannot contain this Reference");
1069 Friend->
Ref = std::move(R);
1070 return llvm::Error::success();
1072 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1073 "Friend cannot contain this Reference");
1082template <
typename T,
typename =
void>
struct has_children : std::false_type {};
1083template <
typename T>
1085 : std::is_same<decltype(std::declval<T>().Children), ScopeChildren> {};
1087template <
typename TargetChild,
typename =
void>
1089template <
typename TargetChild>
1091 TargetChild, std::void_t<decltype(getList(std::declval<ScopeChildren &>(),
1092 std::declval<TargetChild *>()))>>
1093 : std::true_type {};
1095template <
typename Target,
typename Child>
1097 if constexpr (std::is_pointer_v<Target>) {
1098 using Pointee = std::remove_pointer_t<Target>;
1100 using BareChild = std::remove_cv_t<std::remove_reference_t<Child>>;
1104 getList(I->Children, Node->Ptr).push_back(*Node);
1109 ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
1110 "invalid child type for info"));
1113template <
typename Target,
typename Child>
1115 if constexpr (std::is_pointer_v<Target>) {
1116 using Pointee = std::remove_pointer_t<Target>;
1123 ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
1124 "invalid child type for info"));
1132 llvm::createStringError(llvm::inconvertibleErrorCode(),
1133 "invalid container for template parameter"));
1138 ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
1139 "invalid container for template info"));
1158template <
typename T>
1161 llvm::inconvertibleErrorCode(),
1162 "invalid container for template specialization info"));
1171 ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
1172 "invalid container for constraint info"));
1176template <
typename T>
1177llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID, T I) {
1179 llvm::StringRef Blob;
1180 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
1182 return MaybeRecID.takeError();
1187llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID,
Reference *I) {
1188 llvm::TimeTraceScope(
"Reducing infos",
"readRecord");
1190 llvm::StringRef Blob;
1191 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
1193 return MaybeRecID.takeError();
1194 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
1200llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
VarInfo *I) {
1201 return readBlockWithNamespace(ID, I);
1205llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
TypedefInfo *I) {
1206 return readBlockWithNamespace(ID, I);
1211 return readBlockWithNamespace(ID, I);
1214template <
typename T>
1215llvm::Error ClangDocBitcodeReader::readBlockWithNamespace(
unsigned ID, T I) {
1216 llvm::SmallVector<Reference> LocalNamespaces;
1219 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
1220 return routeReferenceBlock(BlockOrCode, LocalNamespaces, I);
1222 [&]() -> llvm::Error {
1223 if (!LocalNamespaces.empty())
1225 return llvm::Error::success();
1229template <
typename T>
1230llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID, T I) {
1232 ID, I, [](
unsigned BlockOrCode) -> llvm::Expected<bool> {
return false; },
1233 []() -> llvm::Error {
return llvm::Error::success(); },
1234 [&](
unsigned BlockOrCode) -> llvm::Error {
1235 return readRecord(BlockOrCode, I);
1240llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
FriendInfo *I) {
1241 llvm::SmallVector<FieldTypeInfo, 4> LocalParams;
1245 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
1249 return B.takeError();
1255 [&]() -> llvm::Error {
1256 if (!LocalParams.empty())
1258 return llvm::Error::success();
1260 [&](
unsigned BlockOrCode) -> llvm::Error {
1261 return readRecord(BlockOrCode, I);
1265template <
typename InfoType,
typename T,
typename Callback>
1266llvm::Error ClangDocBitcodeReader::handleSubBlock(
unsigned ID, T Parent,
1267 Callback Function) {
1269 if (
auto Err = readBlock(ID, &
Info))
1271 if constexpr (std::is_void_v<
1272 std::invoke_result_t<Callback, T, InfoType &&>>) {
1273 Function(Parent, std::move(
Info));
1274 return llvm::Error::success();
1276 return Function(Parent, std::move(
Info));
1280template <
typename InfoType,
typename T>
1281llvm::Error ClangDocBitcodeReader::handleSubBlock(
unsigned ID, T Parent) {
1283 if (
auto Err = readBlock(ID,
Info))
1286 return llvm::Error::success();
1289template <
typename T>
1290llvm::Error ClangDocBitcodeReader::readSubBlock(
unsigned ID, T I) {
1291 llvm::TimeTraceScope(
"Reducing infos",
"readSubBlock");
1293 static auto CreateAddFunc = [](
auto AddFunc) {
1294 return [AddFunc](
auto Parent,
auto Child) {
1295 return AddFunc(Parent, std::move(Child));
1304 return Comment.takeError();
1305 if (
auto Err = readBlock(ID, Comment.get()))
1307 return llvm::Error::success();
1310 return handleSubBlock<TypeInfo>(ID, I,
1314 return handleSubBlock<FieldTypeInfo>(
1318 return handleSubBlock<MemberTypeInfo>(
1323 if (
auto Err = readBlock(ID, &R))
1325 if (
auto Err =
addReference(I, std::move(R), CurrentReferenceField))
1327 return llvm::Error::success();
1330 return handleSubBlock<FunctionInfo>(ID, I);
1333 return handleSubBlock<BaseRecordInfo>(
1337 return handleSubBlock<EnumInfo>(ID, I);
1340 return handleSubBlock<EnumValueInfo>(
1344 return handleSubBlock<TemplateInfo>(ID, I, CreateAddFunc(
addTemplate<T>));
1347 return handleSubBlock<TemplateSpecializationInfo>(
1351 return handleSubBlock<TemplateParamInfo>(
1355 return handleSubBlock<TypedefInfo>(ID, I);
1358 return handleSubBlock<ConstraintInfo>(ID, I,
1362 return handleSubBlock<ConceptInfo>(ID, I);
1365 return handleSubBlock<VarInfo>(ID, I);
1368 return handleSubBlock<FriendInfo>(ID, I,
1372 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1373 "invalid subblock type");
1377llvm::Expected<ClangDocBitcodeReader::Cursor>
1378ClangDocBitcodeReader::skipUntilRecordOrBlock(
unsigned &BlockOrRecordID) {
1379 llvm::TimeTraceScope(
"Reducing infos",
"skipUntilRecordOrBlock");
1380 BlockOrRecordID = 0;
1382 while (!Stream.AtEndOfStream()) {
1383 Expected<unsigned> Code = Stream.ReadCode();
1385 return Code.takeError();
1387 if (*Code >=
static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
1388 BlockOrRecordID = *Code;
1389 return Cursor::Record;
1391 switch (
static_cast<llvm::bitc::FixedAbbrevIDs
>(*Code)) {
1392 case llvm::bitc::ENTER_SUBBLOCK:
1393 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
1394 BlockOrRecordID = MaybeID.get();
1396 return MaybeID.takeError();
1397 return Cursor::BlockBegin;
1398 case llvm::bitc::END_BLOCK:
1399 if (Stream.ReadBlockEnd())
1400 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1401 "error at end of block");
1402 return Cursor::BlockEnd;
1403 case llvm::bitc::DEFINE_ABBREV:
1404 if (llvm::Error Err = Stream.ReadAbbrevRecord())
1405 return std::move(Err);
1407 case llvm::bitc::UNABBREV_RECORD:
1408 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1409 "found unabbreviated record");
1410 case llvm::bitc::FIRST_APPLICATION_ABBREV:
1411 llvm_unreachable(
"Unexpected abbrev id.");
1414 llvm_unreachable(
"Premature stream end.");
1417llvm::Error ClangDocBitcodeReader::validateStream() {
1418 if (Stream.AtEndOfStream())
1419 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1420 "premature end of stream");
1423 for (
int Idx = 0; Idx != 4; ++Idx) {
1424 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
1426 return MaybeRead.takeError();
1428 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1429 "invalid bitcode signature");
1431 return llvm::Error::success();
1434llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
1435 llvm::TimeTraceScope(
"Reducing infos",
"readBlockInfoBlock");
1436 Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
1437 Stream.ReadBlockInfoBlock();
1438 if (!MaybeBlockInfo)
1439 return MaybeBlockInfo.takeError();
1440 BlockInfo = MaybeBlockInfo.get();
1442 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1443 "unable to parse BlockInfoBlock");
1444 Stream.setBlockInfo(&*BlockInfo);
1445 return llvm::Error::success();
1448template <
typename T>
1449llvm::Expected<Info *> ClangDocBitcodeReader::createInfo(
unsigned ID) {
1450 llvm::TimeTraceScope(
"Reducing infos",
"createInfo");
1452 if (
auto Err = readBlock(ID, I))
1453 return std::move(Err);
1457llvm::Expected<Info *> ClangDocBitcodeReader::readBlockToInfo(
unsigned ID) {
1458 llvm::TimeTraceScope(
"Reducing infos",
"readBlockToInfo");
1461 return createInfo<NamespaceInfo>(ID);
1463 return createInfo<RecordInfo>(ID);
1465 return createInfo<EnumInfo>(ID);
1467 return createInfo<TypedefInfo>(ID);
1469 return createInfo<ConceptInfo>(ID);
1471 return createInfo<FunctionInfo>(ID);
1473 return createInfo<VarInfo>(ID);
1475 return createInfo<FriendInfo>(ID);
1477 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1478 "cannot create info");
1484 std::vector<Info *> Infos;
1485 if (
auto Err = validateStream())
1486 return std::move(Err);
1489 while (!Stream.AtEndOfStream()) {
1490 Expected<unsigned> MaybeCode = Stream.ReadCode();
1492 return MaybeCode.takeError();
1493 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
1494 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1495 "no blocks in input");
1496 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
1498 return MaybeID.takeError();
1499 unsigned ID = MaybeID.get();
1507 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1508 "invalid top level block");
1517 auto InfoOrErr = readBlockToInfo(ID);
1519 return InfoOrErr.takeError();
1520 Infos.emplace_back(std::move(InfoOrErr.get()));
1525 return std::move(Err);
1527 case llvm::bitc::BLOCKINFO_BLOCK_ID:
1528 if (
auto Err = readBlockInfoBlock())
1529 return std::move(Err);
1532 if (llvm::Error Err = Stream.SkipBlock())
1533 return std::move(Err);
1537 return std::move(Infos);
static llvm::ExitOnError ExitOnErr
llvm::Expected< std::vector< Info * > > readBitcode()
static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, const unsigned VersionNo)
static llvm::Expected< CommentInfo * > getCommentInfo(T I)
llvm::simple_ilist< InfoNode< T > > DocList
@ TEMPLATE_SPECIALIZATION_OF
@ MEMBER_TYPE_IS_TEMPLATE
@ TEMPLATE_PARAM_CONTENTS
@ CONCEPT_CONSTRAINT_EXPRESSION
llvm::SmallVector< uint64_t, 1024 > Record
static llvm::Error decodeRecord(const Record &R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)
T * allocateTransient(Args &&...args)
static const unsigned VersionNumber
CommentKind stringToCommentKind(llvm::StringRef KindStr)
static llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
static void addTemplateSpecialization(T I, TemplateSpecializationInfo &&TSI)
static void addChildPtr(Target I, Child *Node)
static void addTemplate(T I, TemplateInfo &&P)
static void addChild(Target I, Child &&R)
thread_local llvm::BumpPtrAllocator TransientArena
StringRef internString(const Twine &T)
llvm::ArrayRef< T > allocateArray(llvm::SmallVectorImpl< T > &V, llvm::BumpPtrAllocator &Alloc)
InfoNode< T > * allocateListNodeTransient(Args &&...args)
static auto & getList(ScopeChildren &C, FunctionInfo *)
static llvm::Error addReference(T I, Reference &&R, FieldId F)
std::array< uint8_t, 20 > SymbolID
static void addTemplateParam(T I, TemplateParamInfo &&P)
@ BI_TEMPLATE_SPECIALIZATION_BLOCK_ID
@ BI_TEMPLATE_PARAM_BLOCK_ID
@ BI_MEMBER_TYPE_BLOCK_ID
@ BI_BASE_RECORD_BLOCK_ID
static void addConstraint(T I, ConstraintInfo &&C)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static constexpr int USRHashSize
static constexpr unsigned char Signature[4]
StringRef ConstraintExpression
llvm::ArrayRef< EnumValueInfo > Members
std::optional< TypeInfo > BaseType
std::optional< TypeInfo > ReturnType
llvm::ArrayRef< FieldTypeInfo > Params
std::optional< TemplateInfo > Template
llvm::ArrayRef< FieldTypeInfo > Params
std::optional< TemplateInfo > Template
llvm::ArrayRef< Reference > Namespace
llvm::ArrayRef< BaseRecordInfo > Bases
llvm::ArrayRef< FriendInfo > Friends
llvm::ArrayRef< Reference > VirtualParents
std::optional< TemplateInfo > Template
llvm::ArrayRef< Reference > Parents
llvm::ArrayRef< MemberTypeInfo > Members
StringRef DocumentationFileName
DocList< Reference > Records
DocList< Reference > Namespaces
std::optional< Location > DefLoc
llvm::ArrayRef< TemplateParamInfo > Params
llvm::ArrayRef< ConstraintInfo > Constraints
std::optional< TemplateSpecializationInfo > Specialization
SymbolID SpecializationOf
llvm::ArrayRef< TemplateParamInfo > Params
std::optional< TemplateInfo > Template