diff options
author | Erick Velez <erickvelez7@gmail.com> | 2023-08-18 12:03:44 -0700 |
---|---|---|
committer | Erick Velez <erickvelez7@gmail.com> | 2023-08-18 13:40:22 -0700 |
commit | 7ba37f4e46a5bbb1dc42f1ea1722296ea32034d5 (patch) | |
tree | 5055e36eb713043d9955821c0b755633067363a2 /clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | |
parent | d8900f661a6e451be0ca253df3065254008dd93a (diff) | |
download | llvm-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.cpp | 114 |
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); |