aboutsummaryrefslogtreecommitdiff
path: root/clang-tools-extra/clang-doc/BitcodeReader.cpp
diff options
context:
space:
mode:
authorErick Velez <erickvelez7@gmail.com>2025-06-20 17:39:31 -0700
committerGitHub <noreply@github.com>2025-06-20 17:39:31 -0700
commit8050a6e0732c6614ce3e5296fdeb5a3c36bde26d (patch)
treec77d7ad9bb5120657cd4e9ee21bd44067669430e /clang-tools-extra/clang-doc/BitcodeReader.cpp
parent2dfcc4375faa5e3692bd82a022d33bdd6fe55f10 (diff)
downloadllvm-8050a6e0732c6614ce3e5296fdeb5a3c36bde26d.zip
llvm-8050a6e0732c6614ce3e5296fdeb5a3c36bde26d.tar.gz
llvm-8050a6e0732c6614ce3e5296fdeb5a3c36bde26d.tar.bz2
[clang-doc] add support for concepts (#144430)
Add support for documenting concepts. This handles concepts and constraints on function and class templates. Atomic constraints are not considered yet. We don't order constraints based on their conjunctive or disjunctive properties.
Diffstat (limited to 'clang-tools-extra/clang-doc/BitcodeReader.cpp')
-rw-r--r--clang-tools-extra/clang-doc/BitcodeReader.cpp73
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)