diff options
Diffstat (limited to 'clang-tools-extra/clang-doc/BitcodeReader.cpp')
-rw-r--r-- | clang-tools-extra/clang-doc/BitcodeReader.cpp | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 35058ab..6685293 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -92,6 +92,7 @@ static llvm::Error decodeRecord(const Record &R, InfoType &Field, case InfoType::IT_default: case InfoType::IT_enum: case InfoType::IT_typedef: + case InfoType::IT_concept: Field = IT; return llvm::Error::success(); } @@ -108,6 +109,7 @@ static llvm::Error decodeRecord(const Record &R, FieldId &Field, case FieldId::F_type: case FieldId::F_child_namespace: case FieldId::F_child_record: + case FieldId::F_concept: case FieldId::F_default: Field = F; return llvm::Error::success(); @@ -391,6 +393,29 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, "invalid field for TemplateParamInfo"); } +static llvm::Error parseRecord(const Record &R, unsigned ID, + llvm::StringRef Blob, ConceptInfo *I) { + switch (ID) { + case CONCEPT_USR: + return decodeRecord(R, I->USR, Blob); + case CONCEPT_NAME: + return decodeRecord(R, I->Name, Blob); + case CONCEPT_IS_TYPE: + return decodeRecord(R, I->IsType, Blob); + case CONCEPT_CONSTRAINT_EXPRESSION: + return decodeRecord(R, I->ConstraintExpression, Blob); + } + llvm_unreachable("invalid field for ConceptInfo"); +} + +static llvm::Error parseRecord(const Record &R, unsigned ID, + llvm::StringRef Blob, ConstraintInfo *I) { + if (ID == CONSTRAINT_EXPRESSION) + return decodeRecord(R, I->ConstraintExpr, Blob); + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "invalid field for ConstraintInfo"); +} + template <typename T> static llvm::Expected<CommentInfo *> getCommentInfo(T I) { return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid type cannot contain CommentInfo"); @@ -429,6 +454,10 @@ template <> llvm::Expected<CommentInfo *> getCommentInfo(CommentInfo *I) { return I->Children.back().get(); } +template <> llvm::Expected<CommentInfo *> getCommentInfo(ConceptInfo *I) { + return &I->Description.emplace_back(); +} + // When readSubBlock encounters a TypeInfo sub-block, it calls addTypeInfo on // the parent block to set it. The template specializations define what to do // for each supported parent block. @@ -584,6 +613,17 @@ template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) { } } +template <> +llvm::Error addReference(ConstraintInfo *I, Reference &&R, FieldId F) { + if (F == FieldId::F_concept) { + I->ConceptRef = std::move(R); + return llvm::Error::success(); + } + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "ConstraintInfo cannot contain this Reference"); +} + template <typename T, typename ChildInfoType> static void addChild(T I, ChildInfoType &&R) { llvm::errs() << "invalid child type for info"; @@ -600,6 +640,9 @@ template <> void addChild(NamespaceInfo *I, EnumInfo &&R) { template <> void addChild(NamespaceInfo *I, TypedefInfo &&R) { I->Children.Typedefs.emplace_back(std::move(R)); } +template <> void addChild(NamespaceInfo *I, ConceptInfo &&R) { + I->Children.Concepts.emplace_back(std::move(R)); +} // Record children: template <> void addChild(RecordInfo *I, FunctionInfo &&R) { @@ -649,6 +692,9 @@ template <> void addTemplate(RecordInfo *I, TemplateInfo &&P) { template <> void addTemplate(FunctionInfo *I, TemplateInfo &&P) { I->Template.emplace(std::move(P)); } +template <> void addTemplate(ConceptInfo *I, TemplateInfo &&P) { + I->Template = std::move(P); +} // Template specializations go only into template records. template <typename T> @@ -662,6 +708,14 @@ void addTemplateSpecialization(TemplateInfo *I, I->Specialization.emplace(std::move(TSI)); } +template <typename T> static void addConstraint(T I, ConstraintInfo &&C) { + llvm::errs() << "invalid container for constraint info"; + exit(1); +} +template <> void addConstraint(TemplateInfo *I, ConstraintInfo &&C) { + I->Constraints.emplace_back(std::move(C)); +} + // Read records from bitcode into a given info. template <typename T> llvm::Error ClangDocBitcodeReader::readRecord(unsigned ID, T I) { @@ -716,6 +770,8 @@ llvm::Error ClangDocBitcodeReader::readBlock(unsigned ID, T I) { } } +// TODO: Create a helper that can receive a function to reduce repetition for +// most blocks. template <typename T> llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { llvm::TimeTraceScope("Reducing infos", "readSubBlock"); @@ -817,6 +873,20 @@ llvm::Error ClangDocBitcodeReader::readSubBlock(unsigned ID, T I) { addChild(I, std::move(TI)); return llvm::Error::success(); } + case BI_CONSTRAINT_BLOCK_ID: { + ConstraintInfo CI; + if (auto Err = readBlock(ID, &CI)) + return Err; + addConstraint(I, std::move(CI)); + return llvm::Error::success(); + } + case BI_CONCEPT_BLOCK_ID: { + ConceptInfo CI; + if (auto Err = readBlock(ID, &CI)) + return Err; + addChild(I, std::move(CI)); + return llvm::Error::success(); + } default: return llvm::createStringError(llvm::inconvertibleErrorCode(), "invalid subblock type"); @@ -922,6 +992,8 @@ ClangDocBitcodeReader::readBlockToInfo(unsigned ID) { return createInfo<EnumInfo>(ID); case BI_TYPEDEF_BLOCK_ID: return createInfo<TypedefInfo>(ID); + case BI_CONCEPT_BLOCK_ID: + return createInfo<ConceptInfo>(ID); case BI_FUNCTION_BLOCK_ID: return createInfo<FunctionInfo>(ID); default: @@ -962,6 +1034,7 @@ ClangDocBitcodeReader::readBitcode() { case BI_RECORD_BLOCK_ID: case BI_ENUM_BLOCK_ID: case BI_TYPEDEF_BLOCK_ID: + case BI_CONCEPT_BLOCK_ID: case BI_FUNCTION_BLOCK_ID: { auto InfoOrErr = readBlockToInfo(ID); if (!InfoOrErr) |