11 #include "llvm/ADT/IndexedMap.h" 12 #include "llvm/ADT/Optional.h" 13 #include "llvm/Support/Error.h" 14 #include "llvm/Support/raw_ostream.h" 19 using Record = llvm::SmallVector<uint64_t, 1024>;
22 llvm::StringRef Blob) {
23 Field.assign(Blob.begin(), Blob.end());
24 return llvm::Error::success();
29 return llvm::make_error<llvm::StringError>(
"Incorrect USR size.\n",
30 llvm::inconvertibleErrorCode());
34 for (
int I = 0, E = R[0]; I < E; ++I)
36 return llvm::Error::success();
41 return llvm::Error::success();
46 return llvm::make_error<llvm::StringError>(
"Integer too large to parse.\n",
47 llvm::inconvertibleErrorCode());
49 return llvm::Error::success();
53 llvm::StringRef Blob) {
59 Field = (AccessSpecifier)R[0];
60 return llvm::Error::success();
62 return llvm::make_error<llvm::StringError>(
63 "Invalid value for AccessSpecifier.\n", llvm::inconvertibleErrorCode());
74 Field = (TagTypeKind)R[0];
75 return llvm::Error::success();
77 return llvm::make_error<llvm::StringError>(
78 "Invalid value for TagTypeKind.\n", llvm::inconvertibleErrorCode());
83 llvm::StringRef Blob) {
85 return llvm::make_error<llvm::StringError>(
"Integer too large to parse.\n",
86 llvm::inconvertibleErrorCode());
87 Field.emplace((
int)R[0], Blob);
88 return llvm::Error::success();
92 switch (
auto IT = static_cast<InfoType>(R[0])) {
99 return llvm::Error::success();
101 return llvm::make_error<llvm::StringError>(
"Invalid value for InfoType.\n",
102 llvm::inconvertibleErrorCode());
106 switch (
auto F = static_cast<FieldId>(R[0])) {
115 return llvm::Error::success();
117 return llvm::make_error<llvm::StringError>(
"Invalid value for FieldId.\n",
118 llvm::inconvertibleErrorCode());
122 llvm::SmallVectorImpl<llvm::SmallString<16>> &Field,
123 llvm::StringRef Blob) {
124 Field.push_back(Blob);
125 return llvm::Error::success();
129 llvm::StringRef Blob) {
131 return llvm::make_error<llvm::StringError>(
"Integer too large to parse.\n",
132 llvm::inconvertibleErrorCode());
133 Field.emplace_back((
int)R[0], Blob);
134 return llvm::Error::success();
138 const unsigned VersionNo) {
139 if (ID ==
VERSION && R[0] == VersionNo)
140 return llvm::Error::success();
141 return llvm::make_error<llvm::StringError>(
142 "Mismatched bitcode version number.\n", llvm::inconvertibleErrorCode());
153 return llvm::make_error<llvm::StringError>(
154 "Invalid field for NamespaceInfo.\n", llvm::inconvertibleErrorCode());
172 return llvm::make_error<llvm::StringError>(
173 "Invalid field for RecordInfo.\n", llvm::inconvertibleErrorCode());
193 return llvm::make_error<llvm::StringError>(
"Invalid field for EnumInfo.\n",
194 llvm::inconvertibleErrorCode());
214 return llvm::make_error<llvm::StringError>(
215 "Invalid field for FunctionInfo.\n", llvm::inconvertibleErrorCode());
221 return llvm::Error::success();
230 return llvm::make_error<llvm::StringError>(
"Invalid field for TypeInfo.\n",
231 llvm::inconvertibleErrorCode());
243 return llvm::make_error<llvm::StringError>(
244 "Invalid field for MemberTypeInfo.\n", llvm::inconvertibleErrorCode());
274 return llvm::make_error<llvm::StringError>(
275 "Invalid field for CommentInfo.\n", llvm::inconvertibleErrorCode());
291 return llvm::make_error<llvm::StringError>(
"Invalid field for Reference.\n",
292 llvm::inconvertibleErrorCode());
297 return llvm::make_error<llvm::StringError>(
298 "Invalid type cannot contain CommentInfo.\n",
299 llvm::inconvertibleErrorCode());
323 I->
Children.emplace_back(llvm::make_unique<CommentInfo>());
332 template <
typename T,
typename TTypeInfo>
334 return llvm::make_error<llvm::StringError>(
335 "Invalid type cannot contain TypeInfo.\n",
336 llvm::inconvertibleErrorCode());
340 I->
Members.emplace_back(std::move(T));
341 return llvm::Error::success();
346 return llvm::Error::success();
350 I->
Params.emplace_back(std::move(T));
351 return llvm::Error::success();
355 return llvm::make_error<llvm::StringError>(
356 "Invalid type cannot contain Reference\n",
357 llvm::inconvertibleErrorCode());
363 I->
Type = std::move(R);
364 return llvm::Error::success();
366 return llvm::make_error<llvm::StringError>(
367 "Invalid type cannot contain Reference.\n",
368 llvm::inconvertibleErrorCode());
376 I->
Type = std::move(R);
377 return llvm::Error::success();
379 return llvm::make_error<llvm::StringError>(
380 "Invalid type cannot contain Reference.\n",
381 llvm::inconvertibleErrorCode());
389 I->
Type = std::move(R);
390 return llvm::Error::success();
392 return llvm::make_error<llvm::StringError>(
393 "Invalid type cannot contain Reference.\n",
394 llvm::inconvertibleErrorCode());
402 return llvm::Error::success();
404 return llvm::make_error<llvm::StringError>(
405 "Invalid type cannot contain Reference.\n",
406 llvm::inconvertibleErrorCode());
415 return llvm::Error::success();
418 return llvm::Error::success();
421 return llvm::Error::success();
423 return llvm::make_error<llvm::StringError>(
424 "Invalid type cannot contain Reference.\n",
425 llvm::inconvertibleErrorCode());
434 return llvm::Error::success();
437 return llvm::Error::success();
439 return llvm::make_error<llvm::StringError>(
440 "Invalid type cannot contain Reference.\n",
441 llvm::inconvertibleErrorCode());
449 return llvm::Error::success();
451 I->
Parents.emplace_back(std::move(R));
452 return llvm::Error::success();
455 return llvm::Error::success();
458 return llvm::Error::success();
460 return llvm::make_error<llvm::StringError>(
461 "Invalid type cannot contain Reference.\n",
462 llvm::inconvertibleErrorCode());
466 template <
typename T,
typename ChildInfoType>
468 llvm::errs() <<
"Invalid child type for info.\n";
489 template <
typename T>
490 llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID, T I) {
492 llvm::StringRef Blob;
493 unsigned RecID = Stream.readRecord(ID, R, &Blob);
498 llvm::Error ClangDocBitcodeReader::readRecord(
unsigned ID,
Reference *I) {
500 llvm::StringRef Blob;
501 unsigned RecID = Stream.readRecord(ID, R, &Blob);
502 return parseRecord(R, RecID, Blob, I, CurrentReferenceField);
506 template <
typename T>
507 llvm::Error ClangDocBitcodeReader::readBlock(
unsigned ID, T I) {
508 if (Stream.EnterSubBlock(ID))
509 return llvm::make_error<llvm::StringError>(
"Unable to enter subblock.\n",
510 llvm::inconvertibleErrorCode());
513 unsigned BlockOrCode = 0;
514 Cursor Res = skipUntilRecordOrBlock(BlockOrCode);
517 case Cursor::BadBlock:
518 return llvm::make_error<llvm::StringError>(
519 "Bad block found.\n", llvm::inconvertibleErrorCode());
520 case Cursor::BlockEnd:
521 return llvm::Error::success();
522 case Cursor::BlockBegin:
523 if (
auto Err = readSubBlock(BlockOrCode, I)) {
524 if (!Stream.SkipBlock())
532 if (
auto Err = readRecord(BlockOrCode, I))
537 template <
typename T>
538 llvm::Error ClangDocBitcodeReader::readSubBlock(
unsigned ID, T I) {
545 return Comment.takeError();
546 if (
auto Err = readBlock(ID, Comment.get()))
548 return llvm::Error::success();
552 if (
auto Err = readBlock(ID, &TI))
556 return llvm::Error::success();
560 if (
auto Err = readBlock(ID, &TI))
564 return llvm::Error::success();
568 if (
auto Err = readBlock(ID, &TI))
572 return llvm::Error::success();
576 if (
auto Err = readBlock(ID, &R))
578 if (
auto Err =
addReference(I, std::move(R), CurrentReferenceField))
580 return llvm::Error::success();
584 if (
auto Err = readBlock(ID, &F))
587 return llvm::Error::success();
591 if (
auto Err = readBlock(ID, &E))
594 return llvm::Error::success();
597 return llvm::make_error<llvm::StringError>(
"Invalid subblock type.\n",
598 llvm::inconvertibleErrorCode());
602 ClangDocBitcodeReader::Cursor
603 ClangDocBitcodeReader::skipUntilRecordOrBlock(
unsigned &BlockOrRecordID) {
606 while (!Stream.AtEndOfStream()) {
607 unsigned Code = Stream.ReadCode();
609 switch ((llvm::bitc::FixedAbbrevIDs)Code) {
610 case llvm::bitc::ENTER_SUBBLOCK:
611 BlockOrRecordID = Stream.ReadSubBlockID();
612 return Cursor::BlockBegin;
613 case llvm::bitc::END_BLOCK:
614 if (Stream.ReadBlockEnd())
615 return Cursor::BadBlock;
616 return Cursor::BlockEnd;
617 case llvm::bitc::DEFINE_ABBREV:
618 Stream.ReadAbbrevRecord();
620 case llvm::bitc::UNABBREV_RECORD:
621 return Cursor::BadBlock;
623 BlockOrRecordID = Code;
624 return Cursor::Record;
627 llvm_unreachable(
"Premature stream end.");
630 llvm::Error ClangDocBitcodeReader::validateStream() {
631 if (Stream.AtEndOfStream())
632 return llvm::make_error<llvm::StringError>(
"Premature end of stream.\n",
633 llvm::inconvertibleErrorCode());
640 return llvm::make_error<llvm::StringError>(
"Invalid bitcode signature.\n",
641 llvm::inconvertibleErrorCode());
642 return llvm::Error::success();
645 llvm::Error ClangDocBitcodeReader::readBlockInfoBlock() {
646 BlockInfo = Stream.ReadBlockInfoBlock();
648 return llvm::make_error<llvm::StringError>(
649 "Unable to parse BlockInfoBlock.\n", llvm::inconvertibleErrorCode());
650 Stream.setBlockInfo(&*BlockInfo);
651 return llvm::Error::success();
654 template <
typename T>
655 llvm::Expected<std::unique_ptr<Info>>
656 ClangDocBitcodeReader::createInfo(
unsigned ID) {
657 std::unique_ptr<Info> I = llvm::make_unique<T>();
658 if (
auto Err = readBlock(ID, static_cast<T *>(I.get())))
659 return std::move(Err);
660 return std::unique_ptr<Info>{std::move(I)};;
663 llvm::Expected<std::unique_ptr<Info>>
664 ClangDocBitcodeReader::readBlockToInfo(
unsigned ID) {
667 return createInfo<NamespaceInfo>(ID);
669 return createInfo<RecordInfo>(ID);
671 return createInfo<EnumInfo>(ID);
673 return createInfo<FunctionInfo>(ID);
675 return llvm::make_error<llvm::StringError>(
"Cannot create info.\n",
676 llvm::inconvertibleErrorCode());
681 llvm::Expected<std::vector<std::unique_ptr<Info>>>
683 std::vector<std::unique_ptr<Info>> Infos;
684 if (
auto Err = validateStream())
685 return std::move(Err);
688 while (!Stream.AtEndOfStream()) {
689 unsigned Code = Stream.ReadCode();
690 if (Code != llvm::bitc::ENTER_SUBBLOCK)
691 return llvm::make_error<llvm::StringError>(
692 "No blocks in input.\n", llvm::inconvertibleErrorCode());
693 unsigned ID = Stream.ReadSubBlockID();
701 return llvm::make_error<llvm::StringError>(
702 "Invalid top level block.\n", llvm::inconvertibleErrorCode());
707 auto InfoOrErr = readBlockToInfo(ID);
709 return InfoOrErr.takeError();
710 Infos.emplace_back(std::move(InfoOrErr.get()));
715 return std::move(Err);
717 case llvm::bitc::BLOCKINFO_BLOCK_ID:
718 if (
auto Err = readBlockInfoBlock())
719 return std::move(Err);
722 if (!Stream.SkipBlock())
726 return std::move(Infos);
llvm::SmallVector< Reference, 4 > Namespace
static const unsigned VersionNumber
llvm::Error addTypeInfo(T I, TTypeInfo &&TI)
llvm::SmallVector< uint64_t, 1024 > Record
llvm::Optional< Location > DefLoc
std::vector< FunctionInfo > ChildFunctions
llvm::Error parseRecord(Record R, unsigned ID, llvm::StringRef Blob, const unsigned VersionNo)
llvm::SmallVector< Location, 2 > Loc
std::vector< FunctionInfo > ChildFunctions
std::vector< EnumInfo > ChildEnums
std::vector< Reference > ChildRecords
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< FieldTypeInfo, 4 > Params
static constexpr char Signature[4]
llvm::SmallVector< SmallString< 16 >, 4 > Members
std::vector< CommentInfo > Description
static constexpr int USRHashSize
llvm::Expected< std::vector< std::unique_ptr< Info > > > readBitcode()
llvm::SmallVector< Reference, 4 > Parents
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< Reference > ChildNamespaces
std::vector< Reference > ChildRecords
std::vector< EnumInfo > ChildEnums
llvm::Expected< CommentInfo * > getCommentInfo(T I)
llvm::SmallVector< MemberTypeInfo, 4 > Members
void addChild(T I, ChildInfoType &&R)
std::array< uint8_t, 20 > SymbolID
llvm::Error addReference(T I, Reference &&R, FieldId F)
llvm::Error decodeRecord(Record R, llvm::SmallVectorImpl< char > &Field, llvm::StringRef Blob)