[llvm-branch-commits] [clang-tools-extra] [clang-doc] add support for concepts (PR #144430)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jun 17 09:46:11 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra
Author: Erick Velez (evelez7)
<details>
<summary>Changes</summary>
---
Patch is 40.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/144430.diff
19 Files Affected:
- (modified) clang-tools-extra/clang-doc/BitcodeReader.cpp (+72)
- (modified) clang-tools-extra/clang-doc/BitcodeWriter.cpp (+41-3)
- (modified) clang-tools-extra/clang-doc/BitcodeWriter.h (+11-1)
- (modified) clang-tools-extra/clang-doc/HTMLGenerator.cpp (+4)
- (modified) clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp (+2)
- (modified) clang-tools-extra/clang-doc/JSONGenerator.cpp (+46)
- (modified) clang-tools-extra/clang-doc/MDGenerator.cpp (+5)
- (modified) clang-tools-extra/clang-doc/Mapper.cpp (+4)
- (modified) clang-tools-extra/clang-doc/Mapper.h (+1)
- (modified) clang-tools-extra/clang-doc/Representation.cpp (+13)
- (modified) clang-tools-extra/clang-doc/Representation.h (+25-1)
- (modified) clang-tools-extra/clang-doc/Serialize.cpp (+91-1)
- (modified) clang-tools-extra/clang-doc/Serialize.h (+4)
- (modified) clang-tools-extra/clang-doc/YAMLGenerator.cpp (+2)
- (modified) clang-tools-extra/test/clang-doc/json/class-requires.cpp (+9-9)
- (added) clang-tools-extra/test/clang-doc/json/compound-constraints.cpp (+121)
- (modified) clang-tools-extra/test/clang-doc/json/concept.cpp (+24-24)
- (modified) clang-tools-extra/test/clang-doc/json/function-requires.cpp (+18-18)
- (modified) clang-tools-extra/unittests/clang-doc/BitcodeTest.cpp (+2)
``````````diff
diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp
index 35058abab0663..5b70280e7dba8 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->Expression, 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,18 @@ template <> llvm::Error addReference(RecordInfo *I, Reference &&R, FieldId F) {
}
}
+template <>
+llvm::Error addReference(ConstraintInfo *I, Reference &&R, FieldId F) {
+ switch (F) {
+ case FieldId::F_concept:
+ I->ConceptRef = std::move(R);
+ return llvm::Error::success();
+ default:
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid type cannot contain Reference");
+ }
+}
+
template <typename T, typename ChildInfoType>
static void addChild(T I, ChildInfoType &&R) {
llvm::errs() << "invalid child type for info";
@@ -600,6 +641,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 +693,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 +709,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) {
@@ -817,6 +872,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 +991,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 +1033,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)
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
index f8a6859169b01..330b919140343 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp
@@ -128,7 +128,9 @@ static const llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor>
{BI_REFERENCE_BLOCK_ID, "ReferenceBlock"},
{BI_TEMPLATE_BLOCK_ID, "TemplateBlock"},
{BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, "TemplateSpecializationBlock"},
- {BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"}};
+ {BI_TEMPLATE_PARAM_BLOCK_ID, "TemplateParamBlock"},
+ {BI_CONSTRAINT_BLOCK_ID, "ConstraintBlock"},
+ {BI_CONCEPT_BLOCK_ID, "ConceptBlock"}};
assert(Inits.size() == BlockIdCount);
for (const auto &Init : Inits)
BlockIdNameMap[Init.first] = Init.second;
@@ -205,7 +207,13 @@ static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
{TYPEDEF_USR, {"USR", &genSymbolIdAbbrev}},
{TYPEDEF_NAME, {"Name", &genStringAbbrev}},
{TYPEDEF_DEFLOCATION, {"DefLocation", &genLocationAbbrev}},
- {TYPEDEF_IS_USING, {"IsUsing", &genBoolAbbrev}}};
+ {TYPEDEF_IS_USING, {"IsUsing", &genBoolAbbrev}},
+ {CONCEPT_USR, {"USR", &genSymbolIdAbbrev}},
+ {CONCEPT_NAME, {"Name", &genStringAbbrev}},
+ {CONCEPT_IS_TYPE, {"IsType", &genBoolAbbrev}},
+ {CONCEPT_CONSTRAINT_EXPRESSION,
+ {"ConstraintExpression", &genStringAbbrev}},
+ {CONSTRAINT_EXPRESSION, {"Expression", &genStringAbbrev}}};
assert(Inits.size() == RecordIdCount);
for (const auto &Init : Inits) {
RecordIdNameMap[Init.first] = Init.second;
@@ -263,7 +271,13 @@ static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
// Template Blocks.
{BI_TEMPLATE_BLOCK_ID, {}},
{BI_TEMPLATE_PARAM_BLOCK_ID, {TEMPLATE_PARAM_CONTENTS}},
- {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, {TEMPLATE_SPECIALIZATION_OF}}};
+ {BI_TEMPLATE_SPECIALIZATION_BLOCK_ID, {TEMPLATE_SPECIALIZATION_OF}},
+ // Concept Block
+ {BI_CONCEPT_BLOCK_ID,
+ {CONCEPT_USR, CONCEPT_NAME, CONCEPT_IS_TYPE,
+ CONCEPT_CONSTRAINT_EXPRESSION}},
+ // Constraint Block
+ {BI_CONSTRAINT_BLOCK_ID, {CONSTRAINT_EXPRESSION}}};
// AbbreviationMap
@@ -524,6 +538,8 @@ void ClangDocBitcodeWriter::emitBlock(const NamespaceInfo &I) {
emitBlock(C);
for (const auto &C : I.Children.Typedefs)
emitBlock(C);
+ for (const auto &C : I.Children.Concepts)
+ emitBlock(C);
}
void ClangDocBitcodeWriter::emitBlock(const EnumInfo &I) {
@@ -627,12 +643,25 @@ void ClangDocBitcodeWriter::emitBlock(const FunctionInfo &I) {
emitBlock(*I.Template);
}
+void ClangDocBitcodeWriter::emitBlock(const ConceptInfo &I) {
+ StreamSubBlockGuard Block(Stream, BI_CONCEPT_BLOCK_ID);
+ emitRecord(I.USR, CONCEPT_USR);
+ emitRecord(I.Name, CONCEPT_NAME);
+ for (const auto &CI : I.Description)
+ emitBlock(CI);
+ emitRecord(I.IsType, CONCEPT_IS_TYPE);
+ emitRecord(I.ConstraintExpression, CONCEPT_CONSTRAINT_EXPRESSION);
+ emitBlock(I.Template);
+}
+
void ClangDocBitcodeWriter::emitBlock(const TemplateInfo &T) {
StreamSubBlockGuard Block(Stream, BI_TEMPLATE_BLOCK_ID);
for (const auto &P : T.Params)
emitBlock(P);
if (T.Specialization)
emitBlock(*T.Specialization);
+ for (const auto &C : T.Constraints)
+ emitBlock(C);
}
void ClangDocBitcodeWriter::emitBlock(const TemplateSpecializationInfo &T) {
@@ -647,6 +676,12 @@ void ClangDocBitcodeWriter::emitBlock(const TemplateParamInfo &T) {
emitRecord(T.Contents, TEMPLATE_PARAM_CONTENTS);
}
+void ClangDocBitcodeWriter::emitBlock(const ConstraintInfo &C) {
+ StreamSubBlockGuard Block(Stream, BI_CONSTRAINT_BLOCK_ID);
+ emitRecord(C.Expression, CONSTRAINT_EXPRESSION);
+ emitBlock(C.ConceptRef, FieldId::F_concept);
+}
+
bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) {
switch (I->IT) {
case InfoType::IT_namespace:
@@ -664,6 +699,9 @@ bool ClangDocBitcodeWriter::dispatchInfoForWrite(Info *I) {
case InfoType::IT_typedef:
emitBlock(*static_cast<clang::doc::TypedefInfo *>(I));
break;
+ case InfoType::IT_concept:
+ emitBlock(*static_cast<clang::doc::ConceptInfo *>(I));
+ break;
case InfoType::IT_default:
llvm::errs() << "Unexpected info, unable to write.\n";
return true;
diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.h b/clang-tools-extra/clang-doc/BitcodeWriter.h
index e33a1aece883c..4d0c0c07805e7 100644
--- a/clang-tools-extra/clang-doc/BitcodeWriter.h
+++ b/clang-tools-extra/clang-doc/BitcodeWriter.h
@@ -66,7 +66,9 @@ enum BlockId {
BI_TEMPLATE_BLOCK_ID,
BI_TEMPLATE_SPECIALIZATION_BLOCK_ID,
BI_TEMPLATE_PARAM_BLOCK_ID,
+ BI_CONSTRAINT_BLOCK_ID,
BI_TYPEDEF_BLOCK_ID,
+ BI_CONCEPT_BLOCK_ID,
BI_LAST,
BI_FIRST = BI_VERSION_BLOCK_ID
};
@@ -135,6 +137,11 @@ enum RecordId {
TYPEDEF_NAME,
TYPEDEF_DEFLOCATION,
TYPEDEF_IS_USING,
+ CONCEPT_USR,
+ CONCEPT_NAME,
+ CONCEPT_IS_TYPE,
+ CONCEPT_CONSTRAINT_EXPRESSION,
+ CONSTRAINT_EXPRESSION,
RI_LAST,
RI_FIRST = VERSION
};
@@ -150,7 +157,8 @@ enum class FieldId {
F_vparent,
F_type,
F_child_namespace,
- F_child_record
+ F_child_record,
+ F_concept
};
class ClangDocBitcodeWriter {
@@ -179,6 +187,8 @@ class ClangDocBitcodeWriter {
void emitBlock(const TemplateInfo &T);
void emitBlock(const TemplateSpecializationInfo &T);
void emitBlock(const TemplateParamInfo &T);
+ void emitBlock(const ConceptInfo &T);
+ void emitBlock(const ConstraintInfo &T);
void emitBlock(const Reference &B, FieldId F);
private:
diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
index 7293a129177c9..935bbfee7a9b1 100644
--- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp
@@ -985,6 +985,8 @@ llvm::Error HTMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
MainContentNodes =
genHTML(*static_cast<clang::doc::TypedefInfo *>(I), CDCtx, InfoTitle);
break;
+ case InfoType::IT_concept:
+ break;
case InfoType::IT_default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"unexpected info type");
@@ -1011,6 +1013,8 @@ static std::string getRefType(InfoType IT) {
return "enum";
case InfoType::IT_typedef:
return "typedef";
+ case InfoType::IT_concept:
+ return "concept";
}
llvm_unreachable("Unknown InfoType");
}
diff --git a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
index 69c670b208440..81ba99c21e374 100644
--- a/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
+++ b/clang-tools-extra/clang-doc/HTMLMustacheGenerator.cpp
@@ -585,6 +585,8 @@ Error MustacheHTMLGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
case InfoType::IT_typedef:
OS << "IT_typedef\n";
break;
+ case InfoType::IT_concept:
+ break;
case InfoType::IT_default:
return createStringError(inconvertibleErrorCode(), "unexpected InfoType");
}
diff --git a/clang-tools-extra/clang-doc/JSONGenerator.cpp b/clang-tools-extra/clang-doc/JSONGenerator.cpp
index 0f7cbafcf5135..60dbd4def6780 100644
--- a/clang-tools-extra/clang-doc/JSONGenerator.cpp
+++ b/clang-tools-extra/clang-doc/JSONGenerator.cpp
@@ -248,6 +248,26 @@ static void serializeCommonChildren(const ScopeChildren &Children,
}
}
+template <typename T>
+static void serializeArray(const std::vector<T> &Records, Object &Obj,
+ const std::string &Key) {
+ json::Value RecordsArray = Array();
+ auto &RecordsArrayRef = *RecordsArray.getAsArray();
+ RecordsArrayRef.reserve(Records.size());
+ for (const auto &Item : Records) {
+ json::Value ItemVal = Object();
+ auto &ItemObj = *ItemVal.getAsObject();
+ serializeInfo(Item, ItemObj);
+ RecordsArrayRef.push_back(ItemVal);
+ }
+ Obj[Key] = RecordsArray;
+}
+
+static void serializeInfo(const ConstraintInfo &I, Object &Obj) {
+ serializeReference(I.ConceptRef, Obj);
+ Obj["Expression"] = I.Expression;
+}
+
static void serializeInfo(const TemplateInfo &Template, Object &Obj) {
json::Value TemplateVal = Object();
auto &TemplateObj = *TemplateVal.getAsObject();
@@ -277,9 +297,21 @@ static void serializeInfo(const TemplateInfo &Template, Object &Obj) {
TemplateObj["Parameters"] = ParamsArray;
}
+ if (!Template.Constraints.empty()) {
+ serializeArray(Template.Constraints, TemplateObj, "Constraints");
+ }
+
Obj["Template"] = TemplateVal;
}
+static void serializeInfo(const ConceptInfo &I, Object &Obj,
+ std::optional<StringRef> RepositoryUrl) {
+ serializeCommonAttributes(I, Obj, RepositoryUrl);
+ Obj["IsType"] = I.IsType;
+ Obj["ConstraintExpression"] = I.ConstraintExpression;
+ serializeInfo(I.Template, Obj);
+}
+
static void serializeInfo(const TypeInfo &I, Object &Obj) {
Obj["Name"] = I.Type.Name;
Obj["QualName"] = I.Type.QualName;
@@ -470,6 +502,19 @@ static void serializeInfo(const NamespaceInfo &I, json::Object &Obj,
Obj["Functions"] = FunctionsArray;
}
+ if (!I.Children.Concepts.empty()) {
+ json::Value ConceptsArray = Array();
+ auto &ConceptsArrayRef = *ConceptsArray.getAsArray();
+ ConceptsArrayRef.reserve(I.Children.Concepts.size());
+ for (const auto &Concept : I.Children.Concepts) {
+ json::Value ConceptVal = Object();
+ auto &ConceptObj = *ConceptVal.getAsObject();
+ serializeInfo(Concept, ConceptObj, RepositoryUrl);
+ ConceptsArrayRef.push_back(ConceptVal);
+ }
+ Obj["Concepts"] = ConceptsArray;
+ }
+
serializeCommonChildren(I.Children, Obj, RepositoryUrl);
}
@@ -520,6 +565,7 @@ Error JSONGenerator::generateDocForInfo(Info *I, raw_ostream &OS,
case InfoType::IT_record:
serializeInfo(*static_cast<RecordInfo *>(I), Obj, CDCtx.RepositoryUrl);
break;
+ case InfoType::IT_concept:
case InfoType::IT_enum:
case InfoType::IT_function:
case InfoType::IT_typedef:
diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp
index 2becccf8b07da..6e68e09cfa2a6 100644
--- a/clang-tools-extra/clang-doc/MDGenerator.cpp
+++ b/clang-tools-extra/clang-doc/MDGenerator.cpp
@@ -372,6 +372,9 @@ static llvm::Error genIndex(ClangDocContext &CDCtx) {
case InfoType::IT_typedef:
Type = "Typedef";
break;
+ case InfoType::IT_concept:
+ Type = "Concept";
+ break;
case InfoType::IT_default:
Type = "Other";
}
@@ -464,6 +467,8 @@ llvm::Error MDGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS,
case InfoType::IT_typedef:
genMarkdown(CDCtx, *static_cast<clang::doc::TypedefInfo *>(I), OS);
break;
+ case InfoType::IT_concept:
+ break;
case InfoType::IT_default:
return createStringError(llvm::inconvertibleErrorCode(),
"unexpected InfoType");
diff --git a/clang-tools-extra/clang-doc/Mapper.cpp b/clang-tools-extra/clang-doc/Mapper.cpp
index 9f640b5325da4..6021e17b4696d 100644
--- a/clang-tools-extra/clang-doc/Mapper.cpp
+++ b/clang-tools-extra/clang-doc/Mapper.cpp
@@ -134,6 +134,10 @@ bool MapASTVisitor::VisitTypeAliasDecl(const TypeAliasDecl *D) {
return mapDecl(D, /*isDefinition=*/true);
}
+bool MapASTVisitor::VisitConceptDecl(const ConceptDecl *D) {
+ return mapDecl(D, true);
+}
+
comments::FullComment *
MapASTVisitor::getComment(const NamedDecl *D, const ASTContext &Context) const {
RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
diff --git a/clang-tools-extra/clang-doc/Mapper.h b/clang-tools-extra/clang-doc/Mapper.h
index 36322ea2bfb77..04dc5450c8ba3 100644
--- a/clang-tools-extra/clang-doc/Mapper.h
+++ b/clang-tools-extra/clang-doc/Mapper.h
@@ -41,6 +41,7 @@ class MapASTVisitor : public clang::RecursiveASTVisitor<MapASTVisitor>,
bool VisitFunctionDecl(const FunctionDecl *D);
bool VisitTypedefDecl(const TypedefDecl *D);
bool VisitTypeAliasDecl(const TypeAliasDecl *D);
+ bool VisitConceptDecl(const ConceptDecl *D);
private:
template <typename T> bool mapDecl(const T *D, bool IsDefinition);
diff --git a/clang-tools-extra/clang-doc/Representation.cpp b/clang-tools-extra/clang-doc/Representation.cpp
index 820d644ef8b83..320048aa0fbf8 100644
--- a/clang-tools-extra/clang-doc/Representation.cpp
+++ b/clang-tools-extra/clang-doc/Representation.cpp
@@ -143,6 +143,8 @@ mergeInfos(std::vector<std::unique_ptr<Info>> &Values) {
return reduce<FunctionInfo>(Values);
case InfoType::IT_typedef:
return reduce<TypedefInfo>(Values);
+ case InfoType::IT_concept:
+ return reduce<ConceptInfo>(Values);
case InfoType::IT_default:
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"unexpected info type");
@@ -287,6 +289,7 @@ void NamespaceInfo::merge(NamespaceInfo &&Other) {
reduceChildren(Children.Functions, std::move(Other.Children.Functions));
reduceChildren(Children.Enums, std::move(Other.Children.Enums));
reduceChildren(Children.Typedefs, std::move(Other.Children.Typedefs));
+ reduceChildren(Children.Concepts, std::move(Other.Children.Concepts));
mergeBase(std::move(Other));
}
@@ -351,6 +354,13 @@ void TypedefInfo::merge(TypedefInfo &&Other) {
SymbolInfo::merge(std::move(Other));
}
+void ConceptInfo::merge(ConceptInfo &&Other) {
+ assert(mergeable(Other));
+ if (!IsType)
+ IsType = Other.IsType;
+ SymbolInfo::merge(std::move(Other));
+}
+
BaseRecordInfo::BaseRecordInfo() : RecordInfo() {}
BaseRecordInfo::BaseRecordInfo(SymbolID USR, StringRef Name, StringRef Path,
@@ -387,6 +397,9 @@ llvm::SmallString<16> Info::extractName() const {
case InfoType::IT_function:
return llvm::SmallString<16>("@nonymous_function_" +
toHex(llvm::toStringRef(USR)));
+ case InfoType::IT_concept:
+ return llvm::SmallString<16>("@nonymous_concept_" +
+ toHex(llvm::toStringRef(USR)));
case InfoType::IT_default:
return llvm::SmallString<16>("@nonymous_" + toHex(llvm::toStringRef(USR)));
}
diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h
index 75da500645819..b7be2d23cbc45 100644
--- a/clang-tools-extra/clang-doc/Representation.h
+++ b/clang-tools-extra/clang-doc/Representation.h
@@ -35,6 +35,7 @@ struct EnumInfo;
struct FunctionInfo;
struct Info;
struct TypedefInfo;
+struct ConceptI...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/144430
More information about the llvm-branch-commits
mailing list