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"
19static llvm::ExitOnError
ExitOnErr(
"clang-doc error: ");
21using Record = llvm::SmallVector<uint64_t, 1024>;
26 llvm::StringRef Blob) {
27 Field.assign(Blob.begin(), Blob.end());
28 return llvm::Error::success();
32 llvm::StringRef Blob) {
34 return llvm::Error::success();
38 llvm::StringRef Blob) {
40 return llvm::createStringError(llvm::inconvertibleErrorCode(),
41 "incorrect USR size");
45 for (
int I = 0, E = R[0]; I < E; ++I)
47 return llvm::Error::success();
51 llvm::StringRef Blob) {
53 return llvm::Error::success();
57 llvm::StringRef Blob) {
63 Field = (AccessSpecifier)R[0];
64 return llvm::Error::success();
66 llvm_unreachable(
"invalid value for AccessSpecifier");
70 llvm::StringRef Blob) {
71 switch (
static_cast<TagTypeKind
>(R[0])) {
72 case TagTypeKind::Struct:
73 case TagTypeKind::Interface:
74 case TagTypeKind::Union:
75 case TagTypeKind::Class:
76 case TagTypeKind::Enum:
77 Field =
static_cast<TagTypeKind
>(R[0]);
78 return llvm::Error::success();
80 return llvm::createStringError(llvm::inconvertibleErrorCode(),
81 "invalid value for TagTypeKind");
85 llvm::StringRef Blob) {
87 return llvm::createStringError(llvm::inconvertibleErrorCode(),
88 "integer too large to parse");
89 Field.emplace(
static_cast<int>(R[0]),
static_cast<int>(R[1]), Blob,
90 static_cast<bool>(R[2]));
91 return llvm::Error::success();
95 llvm::StringRef Blob) {
96 switch (
auto IT =
static_cast<InfoType>(R[0])) {
107 return llvm::Error::success();
109 return llvm::createStringError(llvm::inconvertibleErrorCode(),
110 "invalid value for InfoType");
114 llvm::StringRef Blob) {
115 switch (
auto F =
static_cast<FieldId>(R[0])) {
126 return llvm::Error::success();
128 return llvm::createStringError(llvm::inconvertibleErrorCode(),
129 "invalid value for FieldId");
134 llvm::StringRef Blob) {
136 return llvm::createStringError(llvm::inconvertibleErrorCode(),
137 "integer too large to parse");
138 Field.emplace_back(
static_cast<int>(R[0]),
static_cast<int>(R[1]), Blob,
139 static_cast<bool>(R[2]));
140 return llvm::Error::success();
144 llvm::StringRef Blob,
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");
163 return llvm::createStringError(llvm::inconvertibleErrorCode(),
164 "invalid field for NamespaceInfo");
190 return llvm::createStringError(llvm::inconvertibleErrorCode(),
191 "invalid field for RecordInfo");
213 return llvm::createStringError(llvm::inconvertibleErrorCode(),
214 "invalid field for BaseRecordInfo");
219 llvm::StringRef Blob,
EnumInfo *I) {
232 return llvm::createStringError(llvm::inconvertibleErrorCode(),
233 "invalid field for EnumInfo");
249 return llvm::createStringError(llvm::inconvertibleErrorCode(),
250 "invalid field for TypedefInfo");
264 return llvm::createStringError(llvm::inconvertibleErrorCode(),
265 "invalid field for EnumValueInfo");
287 return llvm::createStringError(llvm::inconvertibleErrorCode(),
288 "invalid field for FunctionInfo");
293 llvm::StringRef Blob,
TypeInfo *I) {
300 return llvm::createStringError(llvm::inconvertibleErrorCode(),
301 "invalid field for TypeInfo");
317 return llvm::createStringError(llvm::inconvertibleErrorCode(),
318 "invalid field for TypeInfo");
336 return llvm::createStringError(llvm::inconvertibleErrorCode(),
337 "invalid field for MemberTypeInfo");
346 llvm::SmallString<16> KindStr;
352 return llvm::Error::success();
365 return llvm::Error::success();
368 return llvm::Error::success();
371 return llvm::Error::success();
377 return llvm::createStringError(llvm::inconvertibleErrorCode(),
378 "invalid field for CommentInfo");
382template <
typename T,
typename BlockBeginHandler,
typename BlockEndHandler,
383 typename RecordHandler>
385ClangDocBitcodeReader::parseBlock(
unsigned ID, T I, BlockBeginHandler &&BBH,
386 BlockEndHandler &&BEH, RecordHandler &&RH) {
387 llvm::TimeTraceScope(
"Reducing infos",
"readBlock");
388 if (llvm::Error Err = Stream.EnterSubBlock(ID))
392 unsigned BlockOrCode = 0;
393 llvm::Expected<Cursor> C = skipUntilRecordOrBlock(BlockOrCode);
395 return C.takeError();
398 case Cursor::BadBlock:
399 return llvm::createStringError(llvm::inconvertibleErrorCode(),
401 case Cursor::BlockEnd:
402 if (llvm::Error Err = BEH())
404 return llvm::Error::success();
405 case Cursor::BlockBegin: {
406 llvm::Expected<bool> Handled = BBH(BlockOrCode);
408 return Handled.takeError();
412 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
413 if (llvm::Error Skipped = Stream.SkipBlock())
414 return joinErrors(std::move(Err), std::move(Skipped));
423 if (llvm::Error Err = RH(BlockOrCode))
429llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
CommentInfo *I) {
430 llvm::SmallVector<CommentInfo> LocalChildren;
431 llvm::SmallVector<StringRef> AttrKeys;
432 llvm::SmallVector<StringRef> AttrValues;
433 llvm::SmallVector<StringRef> Args;
437 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
440 if (llvm::Error Err = readBlock(BlockOrCode, &Child))
441 return std::move(Err);
442 LocalChildren.push_back(std::move(Child));
447 [&]() -> llvm::Error {
448 if (!LocalChildren.empty())
451 if (!AttrKeys.empty()) {
454 std::uninitialized_copy(AttrKeys.begin(), AttrKeys.end(), KeysMem);
455 I->
AttrKeys = llvm::ArrayRef<StringRef>(KeysMem, AttrKeys.size());
457 if (!AttrValues.empty()) {
458 StringRef *ValuesMem =
460 std::uninitialized_copy(AttrValues.begin(), AttrValues.end(),
463 llvm::ArrayRef<StringRef>(ValuesMem, AttrValues.size());
466 StringRef *ArgsMem =
TransientArena.Allocate<StringRef>(Args.size());
467 std::uninitialized_copy(Args.begin(), Args.end(), ArgsMem);
468 I->
Args = llvm::ArrayRef<StringRef>(ArgsMem, Args.size());
470 return llvm::Error::success();
472 [&](
unsigned BlockOrCode) -> llvm::Error {
474 llvm::StringRef Blob;
475 llvm::Expected<unsigned> MaybeRecID =
476 Stream.readRecord(BlockOrCode, R, &Blob);
478 return MaybeRecID.takeError();
479 return parseRecord(R, MaybeRecID.get(), Blob, I, AttrKeys, AttrValues,
502 return llvm::createStringError(llvm::inconvertibleErrorCode(),
503 "invalid field for Reference");
510 return llvm::createStringError(llvm::inconvertibleErrorCode(),
511 "invalid field for TemplateParamInfo");
515 llvm::StringRef Blob,
519 return llvm::createStringError(llvm::inconvertibleErrorCode(),
520 "invalid field for TemplateParamInfo");
527 return llvm::createStringError(llvm::inconvertibleErrorCode(),
528 "invalid field for TemplateParamInfo");
545 llvm_unreachable(
"invalid field for ConceptInfo");
552 return llvm::createStringError(llvm::inconvertibleErrorCode(),
553 "invalid field for ConstraintInfo");
557 llvm::StringRef Blob,
VarInfo *I) {
568 return llvm::createStringError(llvm::inconvertibleErrorCode(),
569 "invalid field for VarInfo");
578 return llvm::createStringError(llvm::inconvertibleErrorCode(),
579 "invalid field for Friend");
583 return llvm::createStringError(llvm::inconvertibleErrorCode(),
584 "invalid type cannot contain CommentInfo");
630template <
typename T,
typename TTypeInfo>
632 return llvm::createStringError(llvm::inconvertibleErrorCode(),
633 "invalid type cannot contain TypeInfo");
637 I->
Members.emplace_back(std::move(T));
638 return llvm::Error::success();
642 I->
Members.emplace_back(std::move(T));
643 return llvm::Error::success();
648 return llvm::Error::success();
652 I->
Params.emplace_back(std::move(T));
653 return llvm::Error::success();
658 return llvm::Error::success();
663 return llvm::Error::success();
668 return llvm::Error::success();
672 I->
Type = std::move(T);
673 return llvm::Error::success();
678 return llvm::createStringError(llvm::inconvertibleErrorCode(),
679 "invalid type cannot contain Reference");
686 return llvm::Error::success();
688 return llvm::createStringError(llvm::inconvertibleErrorCode(),
689 "VarInfo cannot contain this Reference");
696 I->
Type = std::move(R);
697 return llvm::Error::success();
699 return llvm::createStringError(llvm::inconvertibleErrorCode(),
700 "invalid type cannot contain Reference");
708 I->
Type = std::move(R);
709 return llvm::Error::success();
711 return llvm::createStringError(llvm::inconvertibleErrorCode(),
712 "invalid type cannot contain Reference");
720 I->
Type = std::move(R);
721 return llvm::Error::success();
723 return llvm::createStringError(llvm::inconvertibleErrorCode(),
724 "invalid type cannot contain Reference");
732 return llvm::Error::success();
734 return llvm::createStringError(llvm::inconvertibleErrorCode(),
735 "invalid type cannot contain Reference");
743 return llvm::Error::success();
745 return llvm::createStringError(llvm::inconvertibleErrorCode(),
746 "invalid type cannot contain Reference");
755 return llvm::Error::success();
759 return llvm::Error::success();
763 return llvm::Error::success();
765 return llvm::createStringError(llvm::inconvertibleErrorCode(),
766 "invalid type cannot contain Reference");
775 return llvm::Error::success();
778 return llvm::Error::success();
780 return llvm::createStringError(llvm::inconvertibleErrorCode(),
781 "invalid type cannot contain Reference");
789 return llvm::Error::success();
791 I->
Parents.emplace_back(std::move(R));
792 return llvm::Error::success();
795 return llvm::Error::success();
798 return llvm::Error::success();
800 return llvm::createStringError(llvm::inconvertibleErrorCode(),
801 "invalid type cannot contain Reference");
809 return llvm::Error::success();
811 return llvm::createStringError(
812 llvm::inconvertibleErrorCode(),
813 "ConstraintInfo cannot contain this Reference");
819 Friend->
Ref = std::move(R);
820 return llvm::Error::success();
822 return llvm::createStringError(llvm::inconvertibleErrorCode(),
823 "Friend cannot contain this Reference");
826template <
typename T,
typename ChildInfoType>
828 ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
829 "invalid child type for info"));
860 I->
Friends.emplace_back(std::move(R));
865 I->
Members.emplace_back(std::move(R));
868 I->
Bases.emplace_back(std::move(R));
879 llvm::createStringError(llvm::inconvertibleErrorCode(),
880 "invalid container for template parameter"));
883 I->
Params.emplace_back(std::move(P));
887 I->
Params.emplace_back(std::move(P));
892 ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
893 "invalid container for template info"));
915 llvm::inconvertibleErrorCode(),
916 "invalid container for template specialization info"));
925 ExitOnErr(llvm::createStringError(llvm::inconvertibleErrorCode(),
926 "invalid container for constraint info"));
934llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID, T I) {
936 llvm::StringRef Blob;
937 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
939 return MaybeRecID.takeError();
944llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID,
Reference *I) {
945 llvm::TimeTraceScope(
"Reducing infos",
"readRecord");
947 llvm::StringRef Blob;
948 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(ID, R, &Blob);
950 return MaybeRecID.takeError();
951 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
956llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID, T I) {
958 ID, I, [](
unsigned BlockOrCode) -> llvm::Expected<bool> {
return false; },
959 []() -> llvm::Error {
return llvm::Error::success(); },
960 [&](
unsigned BlockOrCode) -> llvm::Error {
961 return readRecord(BlockOrCode, I);
966llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID,
FriendInfo *I) {
967 llvm::SmallVector<FieldTypeInfo, 4> LocalParams;
971 [&](
unsigned BlockOrCode) -> llvm::Expected<bool> {
974 if (
auto Err = readBlock(BlockOrCode, &FI))
975 return std::move(Err);
976 LocalParams.push_back(std::move(FI));
981 [&]() -> llvm::Error {
982 if (!LocalParams.empty())
984 return llvm::Error::success();
986 [&](
unsigned BlockOrCode) -> llvm::Error {
987 return readRecord(BlockOrCode, I);
993template <
typename InfoType,
typename T,
typename Callback>
994llvm::Error ClangDocBitcodeReader::handleSubBlock(
unsigned ID, T Parent,
997 if (
auto Err = readBlock(ID, &
Info))
999 Function(Parent, std::move(
Info));
1000 return llvm::Error::success();
1003template <
typename InfoType,
typename T,
typename Callback>
1004llvm::Error ClangDocBitcodeReader::handleTypeSubBlock(
unsigned ID, T Parent,
1005 Callback Function) {
1007 if (
auto Err = readBlock(ID, &
Info))
1009 if (
auto Err = Function(Parent, std::move(
Info)))
1011 return llvm::Error::success();
1014template <
typename T>
1015llvm::Error ClangDocBitcodeReader::readSubBlock(
unsigned ID, T I) {
1016 llvm::TimeTraceScope(
"Reducing infos",
"readSubBlock");
1018 static auto CreateAddFunc = [](
auto AddFunc) {
1019 return [AddFunc](
auto Parent,
auto Child) {
1020 return AddFunc(Parent, std::move(Child));
1029 return Comment.takeError();
1030 if (
auto Err = readBlock(ID, Comment.get()))
1032 return llvm::Error::success();
1035 return handleTypeSubBlock<TypeInfo>(
1039 return handleTypeSubBlock<FieldTypeInfo>(
1043 return handleTypeSubBlock<MemberTypeInfo>(
1048 if (
auto Err = readBlock(ID, &R))
1050 if (
auto Err =
addReference(I, std::move(R), CurrentReferenceField))
1052 return llvm::Error::success();
1055 return handleSubBlock<FunctionInfo>(
1059 return handleSubBlock<BaseRecordInfo>(
1063 return handleSubBlock<EnumInfo>(ID, I,
1067 return handleSubBlock<EnumValueInfo>(
1071 return handleSubBlock<TemplateInfo>(ID, I, CreateAddFunc(
addTemplate<T>));
1074 return handleSubBlock<TemplateSpecializationInfo>(
1078 return handleSubBlock<TemplateParamInfo>(
1082 return handleSubBlock<TypedefInfo>(ID, I,
1086 return handleSubBlock<ConstraintInfo>(ID, I,
1090 return handleSubBlock<ConceptInfo>(ID, I,
1097 return handleSubBlock<FriendInfo>(ID, I,
1101 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1102 "invalid subblock type");
1106llvm::Expected<ClangDocBitcodeReader::Cursor>
1107ClangDocBitcodeReader::skipUntilRecordOrBlock(
unsigned &BlockOrRecordID) {
1108 llvm::TimeTraceScope(
"Reducing infos",
"skipUntilRecordOrBlock");
1109 BlockOrRecordID = 0;
1111 while (!Stream.AtEndOfStream()) {
1112 Expected<unsigned> Code = Stream.ReadCode();
1114 return Code.takeError();
1116 if (*Code >=
static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
1117 BlockOrRecordID = *Code;
1118 return Cursor::Record;
1120 switch (
static_cast<llvm::bitc::FixedAbbrevIDs
>(*Code)) {
1121 case llvm::bitc::ENTER_SUBBLOCK:
1122 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
1123 BlockOrRecordID = MaybeID.get();
1125 return MaybeID.takeError();
1126 return Cursor::BlockBegin;
1127 case llvm::bitc::END_BLOCK:
1128 if (Stream.ReadBlockEnd())
1129 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1130 "error at end of block");
1131 return Cursor::BlockEnd;
1132 case llvm::bitc::DEFINE_ABBREV:
1133 if (llvm::Error Err = Stream.ReadAbbrevRecord())
1134 return std::move(Err);
1136 case llvm::bitc::UNABBREV_RECORD:
1137 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1138 "found unabbreviated record");
1139 case llvm::bitc::FIRST_APPLICATION_ABBREV:
1140 llvm_unreachable(
"Unexpected abbrev id.");
1143 llvm_unreachable(
"Premature stream end.");
1146llvm::Error ClangDocBitcodeReader::validateStream() {
1147 if (Stream.AtEndOfStream())
1148 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1149 "premature end of stream");
1152 for (
int Idx = 0; Idx != 4; ++Idx) {
1153 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
1155 return MaybeRead.takeError();
1157 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1158 "invalid bitcode signature");
1160 return llvm::Error::success();
1163llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
1164 llvm::TimeTraceScope(
"Reducing infos",
"readBlockInfoBlock");
1165 Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
1166 Stream.ReadBlockInfoBlock();
1167 if (!MaybeBlockInfo)
1168 return MaybeBlockInfo.takeError();
1169 BlockInfo = MaybeBlockInfo.get();
1171 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1172 "unable to parse BlockInfoBlock");
1173 Stream.setBlockInfo(&*BlockInfo);
1174 return llvm::Error::success();
1177template <
typename T>
1178llvm::Expected<OwnedPtr<Info>> ClangDocBitcodeReader::createInfo(
unsigned ID) {
1179 llvm::TimeTraceScope(
"Reducing infos",
"createInfo");
1181 if (
auto Err = readBlock(ID,
static_cast<T *
>(
getPtr(I))))
1182 return std::move(Err);
1186llvm::Expected<OwnedPtr<Info>>
1187ClangDocBitcodeReader::readBlockToInfo(
unsigned ID) {
1188 llvm::TimeTraceScope(
"Reducing infos",
"readBlockToInfo");
1191 return createInfo<NamespaceInfo>(ID);
1193 return createInfo<RecordInfo>(ID);
1195 return createInfo<EnumInfo>(ID);
1197 return createInfo<TypedefInfo>(ID);
1199 return createInfo<ConceptInfo>(ID);
1201 return createInfo<FunctionInfo>(ID);
1203 return createInfo<VarInfo>(ID);
1205 return createInfo<FriendInfo>(ID);
1207 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1208 "cannot create info");
1215 if (
auto Err = validateStream())
1216 return std::move(Err);
1219 while (!Stream.AtEndOfStream()) {
1220 Expected<unsigned> MaybeCode = Stream.ReadCode();
1222 return MaybeCode.takeError();
1223 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
1224 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1225 "no blocks in input");
1226 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
1228 return MaybeID.takeError();
1229 unsigned ID = MaybeID.get();
1237 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1238 "invalid top level block");
1247 auto InfoOrErr = readBlockToInfo(ID);
1249 return InfoOrErr.takeError();
1250 Infos.emplace_back(std::move(InfoOrErr.get()));
1255 return std::move(Err);
1257 case llvm::bitc::BLOCKINFO_BLOCK_ID:
1258 if (
auto Err = readBlockInfoBlock())
1259 return std::move(Err);
1262 if (llvm::Error Err = Stream.SkipBlock())
1263 return std::move(Err);
1267 return std::move(Infos);
static llvm::ExitOnError ExitOnErr
llvm::Expected< OwningPtrArray< Info > > readBitcode()
static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, const unsigned VersionNo)
static llvm::Expected< CommentInfo * > getCommentInfo(T I)
@ TEMPLATE_SPECIALIZATION_OF
@ MEMBER_TYPE_IS_TEMPLATE
@ TEMPLATE_PARAM_CONTENTS
@ CONCEPT_CONSTRAINT_EXPRESSION
llvm::SmallVector< uint64_t, 1024 > Record
std::unique_ptr< T > OwnedPtr
llvm::ArrayRef< T > allocateArray(llvm::ArrayRef< T > V, llvm::BumpPtrAllocator &Alloc)
static llvm::Error decodeRecord(const Record &R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)
T * getPtr(const OwnedPtr< T > &O)
static const unsigned VersionNumber
static void addChild(T I, ChildInfoType &&R)
CommentKind stringToCommentKind(llvm::StringRef KindStr)
std::vector< OwnedPtr< T > > OwningPtrArray
static llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
static void addTemplateSpecialization(T I, TemplateSpecializationInfo &&TSI)
static void addTemplate(T I, TemplateInfo &&P)
thread_local llvm::BumpPtrAllocator TransientArena
StringRef internString(const Twine &T)
OwnedPtr< T > allocatePtr(Args &&...args)
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::SmallVector< EnumValueInfo, 4 > Members
std::optional< TypeInfo > BaseType
OwningVec< CommentInfo > Description
Comment description of this field.
std::optional< TypeInfo > ReturnType
llvm::ArrayRef< FieldTypeInfo > Params
std::optional< TemplateInfo > Template
llvm::SmallVector< FieldTypeInfo, 4 > Params
std::optional< TemplateInfo > Template
OwningVec< CommentInfo > Description
llvm::SmallVector< Reference, 4 > Namespace
OwningVec< CommentInfo > Description
OwningVec< BaseRecordInfo > Bases
llvm::SmallVector< MemberTypeInfo, 4 > Members
std::optional< TemplateInfo > Template
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
OwningVec< FriendInfo > Friends
StringRef DocumentationFileName
OwningVec< FunctionInfo > Functions
OwningVec< TypedefInfo > Typedefs
OwningVec< EnumInfo > Enums
OwningVec< Reference > Records
OwningVec< ConceptInfo > Concepts
OwningVec< VarInfo > Variables
llvm::simple_ilist< Reference > Namespaces
llvm::SmallVector< Location, 2 > Loc
std::optional< Location > DefLoc
OwningVec< TemplateParamInfo > Params
OwningVec< ConstraintInfo > Constraints
std::optional< TemplateSpecializationInfo > Specialization
SymbolID SpecializationOf
OwningVec< TemplateParamInfo > Params
std::optional< TemplateInfo > Template