10#include "llvm/ADT/IndexedMap.h"
11#include "llvm/Support/Error.h"
12#include "llvm/Support/raw_ostream.h"
18using Record = llvm::SmallVector<uint64_t, 1024>;
22 llvm::StringRef Blob) {
23 Field.assign(Blob.begin(), Blob.end());
24 return llvm::Error::success();
28 llvm::StringRef Blob) {
30 return llvm::createStringError(llvm::inconvertibleErrorCode(),
31 "incorrect USR size");
35 for (
int I = 0,
E = R[0]; I <
E; ++I)
37 return llvm::Error::success();
42 return llvm::Error::success();
47 return llvm::createStringError(llvm::inconvertibleErrorCode(),
48 "integer too large to parse");
50 return llvm::Error::success();
54 llvm::StringRef Blob) {
60 Field = (AccessSpecifier)R[0];
61 return llvm::Error::success();
63 return llvm::createStringError(llvm::inconvertibleErrorCode(),
64 "invalid value for AccessSpecifier");
69 llvm::StringRef Blob) {
70 switch (
static_cast<TagTypeKind
>(R[0])) {
71 case TagTypeKind::Struct:
72 case TagTypeKind::Interface:
73 case TagTypeKind::Union:
74 case TagTypeKind::Class:
75 case TagTypeKind::Enum:
76 Field =
static_cast<TagTypeKind
>(R[0]);
77 return llvm::Error::success();
79 return llvm::createStringError(llvm::inconvertibleErrorCode(),
80 "invalid value for TagTypeKind");
84 llvm::StringRef Blob) {
86 return llvm::createStringError(llvm::inconvertibleErrorCode(),
87 "integer too large to parse");
88 Field.emplace((
int)R[0], Blob, (
bool)R[1]);
89 return llvm::Error::success();
93 llvm::StringRef Blob) {
94 switch (
auto IT =
static_cast<InfoType>(R[0])) {
102 return llvm::Error::success();
104 return llvm::createStringError(llvm::inconvertibleErrorCode(),
105 "invalid value for InfoType");
109 llvm::StringRef Blob) {
110 switch (
auto F =
static_cast<FieldId>(R[0])) {
119 return llvm::Error::success();
121 return llvm::createStringError(llvm::inconvertibleErrorCode(),
122 "invalid value for FieldId");
127 llvm::StringRef Blob) {
128 Field.push_back(Blob);
129 return llvm::Error::success();
134 llvm::StringRef Blob) {
136 return llvm::createStringError(llvm::inconvertibleErrorCode(),
137 "integer too large to parse");
138 Field.emplace_back((
int)R[0], Blob, (
bool)R[1]);
139 return llvm::Error::success();
143 const unsigned VersionNo) {
145 return llvm::Error::success();
146 return llvm::createStringError(llvm::inconvertibleErrorCode(),
147 "mismatched bitcode version number");
160 return llvm::createStringError(llvm::inconvertibleErrorCode(),
161 "invalid field for NamespaceInfo");
183 return llvm::createStringError(llvm::inconvertibleErrorCode(),
184 "invalid field for RecordInfo");
206 return llvm::createStringError(llvm::inconvertibleErrorCode(),
207 "invalid field for BaseRecordInfo");
225 return llvm::createStringError(llvm::inconvertibleErrorCode(),
226 "invalid field for EnumInfo");
242 return llvm::createStringError(llvm::inconvertibleErrorCode(),
243 "invalid field for TypedefInfo");
257 return llvm::createStringError(llvm::inconvertibleErrorCode(),
258 "invalid field for EnumValueInfo");
278 return llvm::createStringError(llvm::inconvertibleErrorCode(),
279 "invalid field for FunctionInfo");
285 return llvm::Error::success();
296 return llvm::createStringError(llvm::inconvertibleErrorCode(),
297 "invalid field for TypeInfo");
309 return llvm::createStringError(llvm::inconvertibleErrorCode(),
310 "invalid field for MemberTypeInfo");
340 return llvm::createStringError(llvm::inconvertibleErrorCode(),
341 "invalid field for CommentInfo");
361 return llvm::createStringError(llvm::inconvertibleErrorCode(),
362 "invalid field for Reference");
369 return llvm::createStringError(llvm::inconvertibleErrorCode(),
370 "invalid field for TemplateParamInfo");
377 return llvm::createStringError(llvm::inconvertibleErrorCode(),
378 "invalid field for TemplateParamInfo");
385 return llvm::createStringError(llvm::inconvertibleErrorCode(),
386 "invalid field for TemplateParamInfo");
390 return llvm::createStringError(llvm::inconvertibleErrorCode(),
391 "invalid type cannot contain CommentInfo");
419 I->
Children.emplace_back(std::make_unique<CommentInfo>());
431template <
typename T,
typename TTypeInfo>
433 return llvm::createStringError(llvm::inconvertibleErrorCode(),
434 "invalid type cannot contain TypeInfo");
438 I->
Members.emplace_back(std::move(T));
439 return llvm::Error::success();
443 I->
Members.emplace_back(std::move(T));
444 return llvm::Error::success();
449 return llvm::Error::success();
453 I->
Params.emplace_back(std::move(T));
454 return llvm::Error::success();
459 return llvm::Error::success();
464 return llvm::Error::success();
468 return llvm::createStringError(llvm::inconvertibleErrorCode(),
469 "invalid type cannot contain Reference");
475 I->
Type = std::move(R);
476 return llvm::Error::success();
478 return llvm::createStringError(llvm::inconvertibleErrorCode(),
479 "invalid type cannot contain Reference");
487 I->
Type = std::move(R);
488 return llvm::Error::success();
490 return llvm::createStringError(llvm::inconvertibleErrorCode(),
491 "invalid type cannot contain Reference");
499 I->
Type = std::move(R);
500 return llvm::Error::success();
502 return llvm::createStringError(llvm::inconvertibleErrorCode(),
503 "invalid type cannot contain Reference");
511 return llvm::Error::success();
513 return llvm::createStringError(llvm::inconvertibleErrorCode(),
514 "invalid type cannot contain Reference");
522 return llvm::Error::success();
524 return llvm::createStringError(llvm::inconvertibleErrorCode(),
525 "invalid type cannot contain Reference");
534 return llvm::Error::success();
537 return llvm::Error::success();
540 return llvm::Error::success();
542 return llvm::createStringError(llvm::inconvertibleErrorCode(),
543 "invalid type cannot contain Reference");
552 return llvm::Error::success();
555 return llvm::Error::success();
557 return llvm::createStringError(llvm::inconvertibleErrorCode(),
558 "invalid type cannot contain Reference");
566 return llvm::Error::success();
568 I->
Parents.emplace_back(std::move(R));
569 return llvm::Error::success();
572 return llvm::Error::success();
575 return llvm::Error::success();
577 return llvm::createStringError(llvm::inconvertibleErrorCode(),
578 "invalid type cannot contain Reference");
582template <
typename T,
typename ChildInfoType>
584 llvm::errs() <<
"invalid child type for info";
612 I->
Members.emplace_back(std::move(R));
615 I->
Bases.emplace_back(std::move(R));
625 llvm::errs() <<
"invalid container for template parameter";
629 I->
Params.emplace_back(std::move(P));
633 I->
Params.emplace_back(std::move(P));
638 llvm::errs() <<
"invalid container for template info";
651 llvm::errs() <<
"invalid container for template specialization info";
662llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID, T I) {
664 llvm::StringRef Blob;
665 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(
ID, R, &Blob);
667 return MaybeRecID.takeError();
672llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID,
Reference *I) {
674 llvm::StringRef Blob;
675 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(
ID, R, &Blob);
677 return MaybeRecID.takeError();
678 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
683llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID, T I) {
684 if (llvm::Error Err = Stream.EnterSubBlock(
ID))
688 unsigned BlockOrCode = 0;
689 Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
692 case Cursor::BadBlock:
693 return llvm::createStringError(llvm::inconvertibleErrorCode(),
695 case Cursor::BlockEnd:
696 return llvm::Error::success();
697 case Cursor::BlockBegin:
698 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
699 if (llvm::Error Skipped = Stream.SkipBlock())
700 return joinErrors(std::move(Err), std::move(Skipped));
707 if (
auto Err = readRecord(BlockOrCode, I))
713llvm::Error ClangDocBitcodeReader::readSubBlock(
unsigned ID, T I) {
719 return Comment.takeError();
720 if (
auto Err = readBlock(
ID, Comment.get()))
722 return llvm::Error::success();
726 if (
auto Err = readBlock(
ID, &TI))
730 return llvm::Error::success();
734 if (
auto Err = readBlock(
ID, &TI))
738 return llvm::Error::success();
742 if (
auto Err = readBlock(
ID, &TI))
746 return llvm::Error::success();
750 if (
auto Err = readBlock(
ID, &R))
752 if (
auto Err =
addReference(I, std::move(R), CurrentReferenceField))
754 return llvm::Error::success();
758 if (
auto Err = readBlock(
ID, &F))
761 return llvm::Error::success();
765 if (
auto Err = readBlock(
ID, &BR))
768 return llvm::Error::success();
772 if (
auto Err = readBlock(
ID, &
E))
775 return llvm::Error::success();
779 if (
auto Err = readBlock(
ID, &EV))
782 return llvm::Error::success();
786 if (
auto Err = readBlock(
ID, &TI))
789 return llvm::Error::success();
792 TemplateSpecializationInfo TSI;
793 if (
auto Err = readBlock(
ID, &TSI))
796 return llvm::Error::success();
799 TemplateParamInfo TPI;
800 if (
auto Err = readBlock(
ID, &TPI))
803 return llvm::Error::success();
807 if (
auto Err = readBlock(
ID, &TI))
810 return llvm::Error::success();
813 return llvm::createStringError(llvm::inconvertibleErrorCode(),
814 "invalid subblock type");
818ClangDocBitcodeReader::Cursor
819ClangDocBitcodeReader::skipUntilRecordOrBlock(
unsigned &BlockOrRecordID) {
822 while (!Stream.AtEndOfStream()) {
823 Expected<unsigned> MaybeCode = Stream.ReadCode();
826 consumeError(MaybeCode.takeError());
827 return Cursor::BadBlock;
830 unsigned Code = MaybeCode.get();
831 if (
Code >=
static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
832 BlockOrRecordID =
Code;
833 return Cursor::Record;
835 switch (
static_cast<llvm::bitc::FixedAbbrevIDs
>(
Code)) {
836 case llvm::bitc::ENTER_SUBBLOCK:
837 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
838 BlockOrRecordID = MaybeID.get();
841 consumeError(MaybeID.takeError());
843 return Cursor::BlockBegin;
844 case llvm::bitc::END_BLOCK:
845 if (Stream.ReadBlockEnd())
846 return Cursor::BadBlock;
847 return Cursor::BlockEnd;
848 case llvm::bitc::DEFINE_ABBREV:
849 if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
851 consumeError(std::move(Err));
854 case llvm::bitc::UNABBREV_RECORD:
855 return Cursor::BadBlock;
856 case llvm::bitc::FIRST_APPLICATION_ABBREV:
857 llvm_unreachable(
"Unexpected abbrev id.");
860 llvm_unreachable(
"Premature stream end.");
863llvm::Error ClangDocBitcodeReader::validateStream() {
864 if (Stream.AtEndOfStream())
865 return llvm::createStringError(llvm::inconvertibleErrorCode(),
866 "premature end of stream");
869 for (
int Idx = 0; Idx != 4; ++Idx) {
870 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
872 return MaybeRead.takeError();
874 return llvm::createStringError(llvm::inconvertibleErrorCode(),
875 "invalid bitcode signature");
877 return llvm::Error::success();
880llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
881 Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
882 Stream.ReadBlockInfoBlock();
884 return MaybeBlockInfo.takeError();
886 BlockInfo = MaybeBlockInfo.get();
888 return llvm::createStringError(llvm::inconvertibleErrorCode(),
889 "unable to parse BlockInfoBlock");
890 Stream.setBlockInfo(&*BlockInfo);
891 return llvm::Error::success();
895llvm::Expected<std::unique_ptr<Info>>
896ClangDocBitcodeReader::createInfo(
unsigned ID) {
897 std::unique_ptr<Info> I = std::make_unique<T>();
898 if (
auto Err = readBlock(
ID,
static_cast<T *
>(I.get())))
899 return std::move(Err);
900 return std::unique_ptr<Info>{std::move(I)};
903llvm::Expected<std::unique_ptr<Info>>
904ClangDocBitcodeReader::readBlockToInfo(
unsigned ID) {
907 return createInfo<NamespaceInfo>(
ID);
909 return createInfo<RecordInfo>(
ID);
911 return createInfo<EnumInfo>(
ID);
913 return createInfo<TypedefInfo>(
ID);
915 return createInfo<FunctionInfo>(
ID);
917 return llvm::createStringError(llvm::inconvertibleErrorCode(),
918 "cannot create info");
923llvm::Expected<std::vector<std::unique_ptr<Info>>>
925 std::vector<std::unique_ptr<Info>> Infos;
926 if (
auto Err = validateStream())
927 return std::move(Err);
930 while (!Stream.AtEndOfStream()) {
931 Expected<unsigned> MaybeCode = Stream.ReadCode();
933 return MaybeCode.takeError();
934 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
935 return llvm::createStringError(llvm::inconvertibleErrorCode(),
936 "no blocks in input");
937 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
939 return MaybeID.takeError();
940 unsigned ID = MaybeID.get();
948 return llvm::createStringError(llvm::inconvertibleErrorCode(),
949 "invalid top level block");
955 auto InfoOrErr = readBlockToInfo(
ID);
957 return InfoOrErr.takeError();
958 Infos.emplace_back(std::move(InfoOrErr.get()));
963 return std::move(Err);
965 case llvm::bitc::BLOCKINFO_BLOCK_ID:
966 if (
auto Err = readBlockInfoBlock())
967 return std::move(Err);
970 if (llvm::Error Err = Stream.SkipBlock()) {
972 consumeError(std::move(Err));
977 return std::move(Infos);
llvm::Expected< std::vector< std::unique_ptr< Info > > > readBitcode()
llvm::SmallVector< uint64_t, 1024 > Record
llvm::Error addReference(T I, Reference &&R, FieldId F)
void addTemplateSpecialization(T I, TemplateSpecializationInfo &&TSI)
void addTemplateParam(T I, TemplateParamInfo &&P)
@ TEMPLATE_SPECIALIZATION_OF
@ TEMPLATE_PARAM_CONTENTS
void addTemplate(T I, TemplateInfo &&P)
llvm::Expected< CommentInfo * > getCommentInfo(T I)
static const unsigned VersionNumber
llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, const unsigned VersionNo)
llvm::Error decodeRecord(const Record &R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)
void addChild(T I, ChildInfoType &&R)
llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
std::array< uint8_t, 20 > SymbolID
@ BI_TEMPLATE_SPECIALIZATION_BLOCK_ID
@ BI_TEMPLATE_PARAM_BLOCK_ID
@ BI_MEMBER_TYPE_BLOCK_ID
@ BI_BASE_RECORD_BLOCK_ID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static constexpr unsigned char Signature[4]
static constexpr int USRHashSize
llvm::SmallVector< EnumValueInfo, 4 > Members
std::optional< TypeInfo > BaseType
SmallString< 16 > ValueExpr
SmallString< 16 > DefaultValue
llvm::SmallVector< FieldTypeInfo, 4 > Params
std::optional< TemplateInfo > Template
std::vector< CommentInfo > Description
llvm::SmallString< 128 > Path
llvm::SmallVector< Reference, 4 > Namespace
std::vector< CommentInfo > Description
llvm::SmallVector< MemberTypeInfo, 4 > Members
std::optional< TemplateInfo > Template
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
std::vector< BaseRecordInfo > Bases
SmallString< 16 > QualName
llvm::SmallString< 128 > Path
std::vector< Reference > Records
std::vector< TypedefInfo > Typedefs
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< EnumInfo > Enums
llvm::SmallVector< Location, 2 > Loc
std::optional< Location > DefLoc
std::vector< TemplateParamInfo > Params
std::optional< TemplateSpecializationInfo > Specialization
SmallString< 16 > Contents
SymbolID SpecializationOf
std::vector< TemplateParamInfo > Params