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");
423 I->
Children.emplace_back(std::make_unique<CommentInfo>());
435template <
typename T,
typename TTypeInfo>
437 return llvm::createStringError(llvm::inconvertibleErrorCode(),
438 "invalid type cannot contain TypeInfo");
442 I->
Members.emplace_back(std::move(T));
443 return llvm::Error::success();
447 I->
Members.emplace_back(std::move(T));
448 return llvm::Error::success();
453 return llvm::Error::success();
457 I->
Params.emplace_back(std::move(T));
458 return llvm::Error::success();
463 return llvm::Error::success();
468 return llvm::Error::success();
472 return llvm::createStringError(llvm::inconvertibleErrorCode(),
473 "invalid type cannot contain Reference");
479 I->
Type = std::move(R);
480 return llvm::Error::success();
482 return llvm::createStringError(llvm::inconvertibleErrorCode(),
483 "invalid type cannot contain Reference");
491 I->
Type = std::move(R);
492 return llvm::Error::success();
494 return llvm::createStringError(llvm::inconvertibleErrorCode(),
495 "invalid type cannot contain Reference");
503 I->
Type = std::move(R);
504 return llvm::Error::success();
506 return llvm::createStringError(llvm::inconvertibleErrorCode(),
507 "invalid type cannot contain Reference");
515 return llvm::Error::success();
517 return llvm::createStringError(llvm::inconvertibleErrorCode(),
518 "invalid type cannot contain Reference");
526 return llvm::Error::success();
528 return llvm::createStringError(llvm::inconvertibleErrorCode(),
529 "invalid type cannot contain Reference");
538 return llvm::Error::success();
541 return llvm::Error::success();
544 return llvm::Error::success();
546 return llvm::createStringError(llvm::inconvertibleErrorCode(),
547 "invalid type cannot contain Reference");
556 return llvm::Error::success();
559 return llvm::Error::success();
561 return llvm::createStringError(llvm::inconvertibleErrorCode(),
562 "invalid type cannot contain Reference");
570 return llvm::Error::success();
572 I->
Parents.emplace_back(std::move(R));
573 return llvm::Error::success();
576 return llvm::Error::success();
579 return llvm::Error::success();
581 return llvm::createStringError(llvm::inconvertibleErrorCode(),
582 "invalid type cannot contain Reference");
586template <
typename T,
typename ChildInfoType>
588 llvm::errs() <<
"invalid child type for info";
616 I->
Members.emplace_back(std::move(R));
619 I->
Bases.emplace_back(std::move(R));
629 llvm::errs() <<
"invalid container for template parameter";
633 I->
Params.emplace_back(std::move(P));
637 I->
Params.emplace_back(std::move(P));
642 llvm::errs() <<
"invalid container for template info";
655 llvm::errs() <<
"invalid container for template specialization info";
666llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID, T I) {
668 llvm::StringRef Blob;
669 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(
ID, R, &Blob);
671 return MaybeRecID.takeError();
676llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID,
Reference *I) {
678 llvm::StringRef Blob;
679 llvm::Expected<unsigned> MaybeRecID = Stream.readRecord(
ID, R, &Blob);
681 return MaybeRecID.takeError();
682 return parseRecord(R, MaybeRecID.get(), Blob, I, CurrentReferenceField);
687llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID, T I) {
688 if (llvm::Error Err = Stream.EnterSubBlock(
ID))
692 unsigned BlockOrCode = 0;
693 Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
696 case Cursor::BadBlock:
697 return llvm::createStringError(llvm::inconvertibleErrorCode(),
699 case Cursor::BlockEnd:
700 return llvm::Error::success();
701 case Cursor::BlockBegin:
702 if (llvm::Error Err = readSubBlock(BlockOrCode, I)) {
703 if (llvm::Error Skipped = Stream.SkipBlock())
704 return joinErrors(std::move(Err), std::move(Skipped));
711 if (
auto Err = readRecord(BlockOrCode, I))
717llvm::Error ClangDocBitcodeReader::readSubBlock(
unsigned ID, T I) {
723 return Comment.takeError();
724 if (
auto Err = readBlock(
ID, Comment.get()))
726 return llvm::Error::success();
730 if (
auto Err = readBlock(
ID, &TI))
734 return llvm::Error::success();
738 if (
auto Err = readBlock(
ID, &TI))
742 return llvm::Error::success();
746 if (
auto Err = readBlock(
ID, &TI))
750 return llvm::Error::success();
754 if (
auto Err = readBlock(
ID, &R))
756 if (
auto Err =
addReference(I, std::move(R), CurrentReferenceField))
758 return llvm::Error::success();
762 if (
auto Err = readBlock(
ID, &F))
765 return llvm::Error::success();
769 if (
auto Err = readBlock(
ID, &BR))
772 return llvm::Error::success();
776 if (
auto Err = readBlock(
ID, &
E))
779 return llvm::Error::success();
783 if (
auto Err = readBlock(
ID, &EV))
786 return llvm::Error::success();
790 if (
auto Err = readBlock(
ID, &TI))
793 return llvm::Error::success();
796 TemplateSpecializationInfo TSI;
797 if (
auto Err = readBlock(
ID, &TSI))
800 return llvm::Error::success();
803 TemplateParamInfo TPI;
804 if (
auto Err = readBlock(
ID, &TPI))
807 return llvm::Error::success();
811 if (
auto Err = readBlock(
ID, &TI))
814 return llvm::Error::success();
817 return llvm::createStringError(llvm::inconvertibleErrorCode(),
818 "invalid subblock type");
822ClangDocBitcodeReader::Cursor
823ClangDocBitcodeReader::skipUntilRecordOrBlock(
unsigned &BlockOrRecordID) {
826 while (!Stream.AtEndOfStream()) {
827 Expected<unsigned> MaybeCode = Stream.ReadCode();
830 consumeError(MaybeCode.takeError());
831 return Cursor::BadBlock;
834 unsigned Code = MaybeCode.get();
835 if (
Code >=
static_cast<unsigned>(llvm::bitc::FIRST_APPLICATION_ABBREV)) {
836 BlockOrRecordID =
Code;
837 return Cursor::Record;
839 switch (
static_cast<llvm::bitc::FixedAbbrevIDs
>(
Code)) {
840 case llvm::bitc::ENTER_SUBBLOCK:
841 if (Expected<unsigned> MaybeID = Stream.ReadSubBlockID())
842 BlockOrRecordID = MaybeID.get();
845 consumeError(MaybeID.takeError());
847 return Cursor::BlockBegin;
848 case llvm::bitc::END_BLOCK:
849 if (Stream.ReadBlockEnd())
850 return Cursor::BadBlock;
851 return Cursor::BlockEnd;
852 case llvm::bitc::DEFINE_ABBREV:
853 if (llvm::Error Err = Stream.ReadAbbrevRecord()) {
855 consumeError(std::move(Err));
858 case llvm::bitc::UNABBREV_RECORD:
859 return Cursor::BadBlock;
860 case llvm::bitc::FIRST_APPLICATION_ABBREV:
861 llvm_unreachable(
"Unexpected abbrev id.");
864 llvm_unreachable(
"Premature stream end.");
867llvm::Error ClangDocBitcodeReader::validateStream() {
868 if (Stream.AtEndOfStream())
869 return llvm::createStringError(llvm::inconvertibleErrorCode(),
870 "premature end of stream");
873 for (
int Idx = 0; Idx != 4; ++Idx) {
874 Expected<llvm::SimpleBitstreamCursor::word_t> MaybeRead = Stream.Read(8);
876 return MaybeRead.takeError();
878 return llvm::createStringError(llvm::inconvertibleErrorCode(),
879 "invalid bitcode signature");
881 return llvm::Error::success();
884llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
885 Expected<std::optional<llvm::BitstreamBlockInfo>> MaybeBlockInfo =
886 Stream.ReadBlockInfoBlock();
888 return MaybeBlockInfo.takeError();
890 BlockInfo = MaybeBlockInfo.get();
892 return llvm::createStringError(llvm::inconvertibleErrorCode(),
893 "unable to parse BlockInfoBlock");
894 Stream.setBlockInfo(&*BlockInfo);
895 return llvm::Error::success();
899llvm::Expected<std::unique_ptr<Info>>
900ClangDocBitcodeReader::createInfo(
unsigned ID) {
901 std::unique_ptr<Info> I = std::make_unique<T>();
902 if (
auto Err = readBlock(
ID,
static_cast<T *
>(I.get())))
903 return std::move(Err);
904 return std::unique_ptr<Info>{std::move(I)};
907llvm::Expected<std::unique_ptr<Info>>
908ClangDocBitcodeReader::readBlockToInfo(
unsigned ID) {
911 return createInfo<NamespaceInfo>(
ID);
913 return createInfo<RecordInfo>(
ID);
915 return createInfo<EnumInfo>(
ID);
917 return createInfo<TypedefInfo>(
ID);
919 return createInfo<FunctionInfo>(
ID);
921 return llvm::createStringError(llvm::inconvertibleErrorCode(),
922 "cannot create info");
927llvm::Expected<std::vector<std::unique_ptr<Info>>>
929 std::vector<std::unique_ptr<Info>> Infos;
930 if (
auto Err = validateStream())
931 return std::move(Err);
934 while (!Stream.AtEndOfStream()) {
935 Expected<unsigned> MaybeCode = Stream.ReadCode();
937 return MaybeCode.takeError();
938 if (MaybeCode.get() != llvm::bitc::ENTER_SUBBLOCK)
939 return llvm::createStringError(llvm::inconvertibleErrorCode(),
940 "no blocks in input");
941 Expected<unsigned> MaybeID = Stream.ReadSubBlockID();
943 return MaybeID.takeError();
944 unsigned ID = MaybeID.get();
952 return llvm::createStringError(llvm::inconvertibleErrorCode(),
953 "invalid top level block");
959 auto InfoOrErr = readBlockToInfo(
ID);
961 return InfoOrErr.takeError();
962 Infos.emplace_back(std::move(InfoOrErr.get()));
967 return std::move(Err);
969 case llvm::bitc::BLOCKINFO_BLOCK_ID:
970 if (
auto Err = readBlockInfoBlock())
971 return std::move(Err);
974 if (llvm::Error Err = Stream.SkipBlock()) {
976 consumeError(std::move(Err));
981 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
std::vector< CommentInfo > Description
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