diff options
author | Erick Velez <erickvelez7@gmail.com> | 2023-08-04 07:16:59 -0700 |
---|---|---|
committer | Erick Velez <erickvelez7@gmail.com> | 2023-08-04 07:19:24 -0700 |
commit | 75f55eb331e0e9d8edb60115739b1b4794188df8 (patch) | |
tree | c2b81854aa418798195d87ed17178e77e51f0b3f /clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | |
parent | 5d492766a8fbfadb39c9830ebb64137edddfe0e5 (diff) | |
download | llvm-75f55eb331e0e9d8edb60115739b1b4794188df8.zip llvm-75f55eb331e0e9d8edb60115739b1b4794188df8.tar.gz llvm-75f55eb331e0e9d8edb60115739b1b4794188df8.tar.bz2 |
[clang][ExtractAPI] Add support for C++ classes with fix
Reintroduce D153557 with fix for use-after-free from f4de606ef271 and minor changes.
Reviewed By: dang
Differential Revision: https://reviews.llvm.org/D157007
Diffstat (limited to 'clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp')
-rw-r--r-- | clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp | 101 |
1 files changed, 96 insertions, 5 deletions
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index 534e928..c9fbf0d 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -38,6 +38,14 @@ void serializeObject(Object &Paren, StringRef Key, std::optional<Object> Obj) { Paren[Key] = std::move(*Obj); } +/// Helper function to inject a StringRef \p String into an object \p Paren at +/// position \p Key +void serializeString(Object &Paren, StringRef Key, + std::optional<std::string> String) { + if (String) + Paren[Key] = std::move(*String); +} + /// Helper function to inject a JSON array \p Array into object \p Paren at /// position \p Key. void serializeArray(Object &Paren, StringRef Key, std::optional<Array> Array) { @@ -189,9 +197,10 @@ StringRef getLanguageName(Language Lang) { return "c"; case Language::ObjC: return "objective-c"; + case Language::CXX: + return "c++"; // Unsupported language currently - case Language::CXX: case Language::ObjCXX: case Language::OpenCL: case Language::OpenCLCXX: @@ -366,6 +375,38 @@ Object serializeSymbolKind(APIRecord::RecordKind RK, Language Lang) { Kind["identifier"] = AddLangPrefix("struct"); Kind["displayName"] = "Structure"; break; + case APIRecord::RK_CXXField: + Kind["identifier"] = AddLangPrefix("property"); + Kind["displayName"] = "Instance Property"; + break; + case APIRecord::RK_Union: + Kind["identifier"] = AddLangPrefix("union"); + Kind["displayName"] = "Union"; + break; + case APIRecord::RK_StaticField: + Kind["identifier"] = AddLangPrefix("type.property"); + Kind["displayName"] = "Type Property"; + break; + case APIRecord::RK_CXXClass: + Kind["identifier"] = AddLangPrefix("class"); + Kind["displayName"] = "Class"; + break; + case APIRecord::RK_CXXStaticMethod: + Kind["identifier"] = AddLangPrefix("type.method"); + Kind["displayName"] = "Static Method"; + break; + case APIRecord::RK_CXXInstanceMethod: + Kind["identifier"] = AddLangPrefix("method"); + Kind["displayName"] = "Instance Method"; + break; + case APIRecord::RK_CXXConstructorMethod: + Kind["identifier"] = AddLangPrefix("method"); + Kind["displayName"] = "Constructor"; + break; + case APIRecord::RK_CXXDestructorMethod: + Kind["identifier"] = AddLangPrefix("method"); + Kind["displayName"] = "Destructor"; + break; case APIRecord::RK_ObjCIvar: Kind["identifier"] = AddLangPrefix("ivar"); Kind["displayName"] = "Instance Variable"; @@ -470,6 +511,31 @@ void serializeFunctionSignatureMixin(Object &Paren, const RecordTy &Record) { Record, has_function_signature<RecordTy>())); } +template <typename RecordTy> +std::optional<std::string> serializeAccessMixinImpl(const RecordTy &Record, + std::true_type) { + const auto &AccessControl = Record.Access; + std::string Access; + if (AccessControl.empty()) + return std::nullopt; + Access = AccessControl.getAccess(); + return Access; +} + +template <typename RecordTy> +std::optional<std::string> serializeAccessMixinImpl(const RecordTy &Record, + std::false_type) { + return std::nullopt; +} + +template <typename RecordTy> +void serializeAccessMixin(Object &Paren, const RecordTy &Record) { + auto accessLevel = serializeAccessMixinImpl(Record, has_access<RecordTy>()); + if (!accessLevel.has_value()) + accessLevel = "public"; + serializeString(Paren, "accessLevel", accessLevel); +} + struct PathComponent { StringRef USR; StringRef Name; @@ -543,7 +609,6 @@ Array generateParentContexts(const RecordTy &Record, const APISet &API, return ParentContexts; } - } // namespace /// Defines the format version emitted by SymbolGraphSerializer. @@ -602,9 +667,6 @@ SymbolGraphSerializer::serializeAPIRecord(const RecordTy &Record) const { serializeObject(Obj, "docComment", serializeDocComment(Record.Comment)); serializeArray(Obj, "declarationFragments", serializeDeclarationFragments(Record.Declaration)); - // TODO: Once we keep track of symbol access information serialize it - // correctly here. - Obj["accessLevel"] = "public"; SmallVector<StringRef, 4> PathComponentsNames; // If this returns true it indicates that we couldn't find a symbol in the // hierarchy. @@ -617,6 +679,7 @@ SymbolGraphSerializer::serializeAPIRecord(const RecordTy &Record) const { serializeArray(Obj, "pathComponents", Array(PathComponentsNames)); serializeFunctionSignatureMixin(Obj, Record); + serializeAccessMixin(Obj, Record); return Obj; } @@ -698,6 +761,28 @@ void SymbolGraphSerializer::visitStructRecord(const StructRecord &Record) { serializeMembers(Record, Record.Fields); } +void SymbolGraphSerializer::visitStaticFieldRecord( + const StaticFieldRecord &Record) { + auto StaticField = serializeAPIRecord(Record); + if (!StaticField) + return; + Symbols.emplace_back(std::move(*StaticField)); + serializeRelationship(RelationshipKind::MemberOf, Record, Record.Context); +} + +void SymbolGraphSerializer::visitCXXClassRecord(const CXXClassRecord &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::visitObjCContainerRecord( const ObjCContainerRecord &Record) { auto ObjCContainer = serializeAPIRecord(Record); @@ -761,6 +846,12 @@ void SymbolGraphSerializer::serializeSingleRecord(const APIRecord *Record) { case APIRecord::RK_Struct: visitStructRecord(*cast<StructRecord>(Record)); break; + case APIRecord::RK_StaticField: + visitStaticFieldRecord(*cast<StaticFieldRecord>(Record)); + break; + case APIRecord::RK_CXXClass: + visitCXXClassRecord(*cast<CXXClassRecord>(Record)); + break; case APIRecord::RK_ObjCInterface: visitObjCContainerRecord(*cast<ObjCInterfaceRecord>(Record)); break; |