aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
diff options
context:
space:
mode:
authorErick Velez <erickvelez7@gmail.com>2023-08-18 12:03:44 -0700
committerErick Velez <erickvelez7@gmail.com>2023-08-18 13:40:22 -0700
commit7ba37f4e46a5bbb1dc42f1ea1722296ea32034d5 (patch)
tree5055e36eb713043d9955821c0b755633067363a2 /clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
parentd8900f661a6e451be0ca253df3065254008dd93a (diff)
downloadllvm-7ba37f4e46a5bbb1dc42f1ea1722296ea32034d5.zip
llvm-7ba37f4e46a5bbb1dc42f1ea1722296ea32034d5.tar.gz
llvm-7ba37f4e46a5bbb1dc42f1ea1722296ea32034d5.tar.bz2
[clang][ExtractAPI] Add support for C++ class templates and concepts
Add has_template template, DeclarationFragmentBuilder functions, and tests for class templates, specializations/partial specs, and concepts. Depends on D157007 Reviewed By: dang Differential Revision: https://reviews.llvm.org/D157076
Diffstat (limited to 'clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp')
-rw-r--r--clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp114
1 files changed, 114 insertions, 0 deletions
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index af52abe..6c7a037 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -393,10 +393,17 @@ Object serializeSymbolKind(APIRecord::RecordKind RK, Language Lang) {
Kind["identifier"] = AddLangPrefix("type.property");
Kind["displayName"] = "Type Property";
break;
+ case APIRecord::RK_ClassTemplate:
+ case APIRecord::RK_ClassTemplateSpecialization:
+ case APIRecord::RK_ClassTemplatePartialSpecialization:
case APIRecord::RK_CXXClass:
Kind["identifier"] = AddLangPrefix("class");
Kind["displayName"] = "Class";
break;
+ case APIRecord::RK_Concept:
+ Kind["identifier"] = AddLangPrefix("concept");
+ Kind["displayName"] = "Concept";
+ break;
case APIRecord::RK_CXXStaticMethod:
Kind["identifier"] = AddLangPrefix("type.method");
Kind["displayName"] = "Static Method";
@@ -545,6 +552,52 @@ void serializeAccessMixin(Object &Paren, const RecordTy &Record) {
serializeString(Paren, "accessLevel", accessLevel);
}
+template <typename RecordTy>
+std::optional<Object> serializeTemplateMixinImpl(const RecordTy &Record,
+ std::true_type) {
+ const auto &Template = Record.Templ;
+ if (Template.empty())
+ return std::nullopt;
+
+ Object Generics;
+ Array GenericParameters;
+ for (const auto Param : Template.getParameters()) {
+ Object Parameter;
+ Parameter["name"] = Param.Name;
+ Parameter["index"] = Param.Index;
+ Parameter["depth"] = Param.Depth;
+ GenericParameters.emplace_back(std::move(Parameter));
+ }
+ if (!GenericParameters.empty())
+ Generics["parameters"] = std::move(GenericParameters);
+
+ Array GenericConstraints;
+ for (const auto Constr : Template.getConstraints()) {
+ Object Constraint;
+ Constraint["kind"] = Constr.Kind;
+ Constraint["lhs"] = Constr.LHS;
+ Constraint["rhs"] = Constr.RHS;
+ GenericConstraints.emplace_back(std::move(Constraint));
+ }
+
+ if (!GenericConstraints.empty())
+ Generics["constraints"] = std::move(GenericConstraints);
+
+ return Generics;
+}
+
+template <typename RecordTy>
+std::optional<Object> serializeTemplateMixinImpl(const RecordTy &Record,
+ std::false_type) {
+ return std::nullopt;
+}
+
+template <typename RecordTy>
+void serializeTemplateMixin(Object &Paren, const RecordTy &Record) {
+ serializeObject(Paren, "swiftGenerics",
+ serializeTemplateMixinImpl(Record, has_template<RecordTy>()));
+}
+
struct PathComponent {
StringRef USR;
StringRef Name;
@@ -691,6 +744,7 @@ SymbolGraphSerializer::serializeAPIRecord(const RecordTy &Record) const {
serializeFunctionSignatureMixin(Obj, Record);
serializeAccessMixin(Obj, Record);
+ serializeTemplateMixin(Obj, Record);
return Obj;
}
@@ -726,6 +780,16 @@ StringRef SymbolGraphSerializer::getRelationshipString(RelationshipKind Kind) {
llvm_unreachable("Unhandled relationship kind");
}
+StringRef SymbolGraphSerializer::getConstraintString(ConstraintKind Kind) {
+ switch (Kind) {
+ case ConstraintKind::Conformance:
+ return "conformance";
+ case ConstraintKind::ConditionalConformance:
+ return "conditionalConformance";
+ }
+ llvm_unreachable("Unhandled constraint kind");
+}
+
void SymbolGraphSerializer::serializeRelationship(RelationshipKind Kind,
SymbolReference Source,
SymbolReference Target) {
@@ -796,6 +860,56 @@ void SymbolGraphSerializer::visitCXXClassRecord(const CXXClassRecord &Record) {
serializeRelationship(RelationshipKind::InheritsFrom, Record, Base);
}
+void SymbolGraphSerializer::visitClassTemplateRecord(
+ const ClassTemplateRecord &Record) {
+ auto Class = serializeAPIRecord(Record);
+ if (!Class)
+ return;
+
+ Symbols.emplace_back(std::move(*Class));
+ serializeMembers(Record, Record.Fields);
+ serializeMembers(Record, Record.Methods);
+
+ for (const auto Base : Record.Bases)
+ serializeRelationship(RelationshipKind::InheritsFrom, Record, Base);
+}
+
+void SymbolGraphSerializer::visitClassTemplateSpecializationRecord(
+ const ClassTemplateSpecializationRecord &Record) {
+ auto Class = serializeAPIRecord(Record);
+ if (!Class)
+ return;
+
+ Symbols.emplace_back(std::move(*Class));
+ serializeMembers(Record, Record.Fields);
+ serializeMembers(Record, Record.Methods);
+
+ for (const auto Base : Record.Bases)
+ serializeRelationship(RelationshipKind::InheritsFrom, Record, Base);
+}
+
+void SymbolGraphSerializer::visitClassTemplatePartialSpecializationRecord(
+ const ClassTemplatePartialSpecializationRecord &Record) {
+ auto Class = serializeAPIRecord(Record);
+ if (!Class)
+ return;
+
+ Symbols.emplace_back(std::move(*Class));
+ serializeMembers(Record, Record.Fields);
+ serializeMembers(Record, Record.Methods);
+
+ for (const auto Base : Record.Bases)
+ serializeRelationship(RelationshipKind::InheritsFrom, Record, Base);
+}
+
+void SymbolGraphSerializer::visitConceptRecord(const ConceptRecord &Record) {
+ auto Concept = serializeAPIRecord(Record);
+ if (!Concept)
+ return;
+
+ Symbols.emplace_back(std::move(*Concept));
+}
+
void SymbolGraphSerializer::visitObjCContainerRecord(
const ObjCContainerRecord &Record) {
auto ObjCContainer = serializeAPIRecord(Record);