aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/ExtractAPI
diff options
context:
space:
mode:
authorZixu Wang <zixu_wang@apple.com>2022-03-25 15:15:08 -0700
committerZixu Wang <zixu_wang@apple.com>2022-03-29 14:44:49 -0700
commitd1d34bafef56b732b461e12032eaf030e609f55a (patch)
tree8360785bdf0fa068133c2916679cbb5550af3b8c /clang/lib/ExtractAPI
parent122638d97d913edcdfa8ccf921eb5929498166c7 (diff)
downloadllvm-d1d34bafef56b732b461e12032eaf030e609f55a.zip
llvm-d1d34bafef56b732b461e12032eaf030e609f55a.tar.gz
llvm-d1d34bafef56b732b461e12032eaf030e609f55a.tar.bz2
[clang][extract-api] Add Objective-C protocol support
Add support for Objective-C protocol declarations in ExtractAPI. Depends on D122446 Differential Revision: https://reviews.llvm.org/D122511
Diffstat (limited to 'clang/lib/ExtractAPI')
-rw-r--r--clang/lib/ExtractAPI/API.cpp15
-rw-r--r--clang/lib/ExtractAPI/DeclarationFragments.cpp29
-rw-r--r--clang/lib/ExtractAPI/ExtractAPIConsumer.cpp32
-rw-r--r--clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp8
4 files changed, 84 insertions, 0 deletions
diff --git a/clang/lib/ExtractAPI/API.cpp b/clang/lib/ExtractAPI/API.cpp
index 2456022..1c9314c 100644
--- a/clang/lib/ExtractAPI/API.cpp
+++ b/clang/lib/ExtractAPI/API.cpp
@@ -161,6 +161,20 @@ ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable(
return Container->Ivars.emplace_back(std::move(Record)).get();
}
+ObjCProtocolRecord *APISet::addObjCProtocol(
+ StringRef Name, StringRef USR, PresumedLoc Loc,
+ const AvailabilityInfo &Availability, const DocComment &Comment,
+ DeclarationFragments Declaration, DeclarationFragments SubHeading) {
+ auto Result = ObjCProtocols.insert({Name, nullptr});
+ if (Result.second) {
+ // Create the record if it does not already exist.
+ auto Record = std::make_unique<ObjCProtocolRecord>(
+ Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
+ Result.first->second = std::move(Record);
+ }
+ return Result.first->second.get();
+}
+
StringRef APISet::recordUSR(const Decl *D) {
SmallString<128> USR;
index::generateUSRForDecl(D, USR);
@@ -193,3 +207,4 @@ void ObjCPropertyRecord::anchor() {}
void ObjCInstanceVariableRecord::anchor() {}
void ObjCMethodRecord::anchor() {}
void ObjCInterfaceRecord::anchor() {}
+void ObjCProtocolRecord::anchor() {}
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index b35388e..7c6c9dc 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -621,6 +621,35 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProperty(
.append(std::move(After));
}
+DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(
+ const ObjCProtocolDecl *Protocol) {
+ DeclarationFragments Fragments;
+ // Build basic protocol declaration.
+ Fragments.append("@protocol", DeclarationFragments::FragmentKind::Keyword)
+ .appendSpace()
+ .append(Protocol->getName(),
+ DeclarationFragments::FragmentKind::Identifier);
+
+ // If this protocol conforms to other protocols, build the conformance list.
+ if (!Protocol->protocols().empty()) {
+ Fragments.append(" <", DeclarationFragments::FragmentKind::Text);
+ for (ObjCProtocolDecl::protocol_iterator It = Protocol->protocol_begin();
+ It != Protocol->protocol_end(); It++) {
+ // Add a leading comma if this is not the first protocol rendered.
+ if (It != Protocol->protocol_begin())
+ Fragments.append(", ", DeclarationFragments::FragmentKind::Text);
+
+ SmallString<128> USR;
+ index::generateUSRForDecl(*It, USR);
+ Fragments.append((*It)->getName(),
+ DeclarationFragments::FragmentKind::TypeIdentifier, USR);
+ }
+ Fragments.append(">", DeclarationFragments::FragmentKind::Text);
+ }
+
+ return Fragments;
+}
+
template <typename FunctionT>
FunctionSignature
DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
index f8b1c9b..bcc01db 100644
--- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
+++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
@@ -260,6 +260,38 @@ public:
return true;
}
+ bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl) {
+ // Skip forward declaration for protocols (@protocol).
+ if (!Decl->isThisDeclarationADefinition())
+ return true;
+
+ // Collect symbol information.
+ StringRef Name = Decl->getName();
+ StringRef USR = API.recordUSR(Decl);
+ PresumedLoc Loc =
+ Context.getSourceManager().getPresumedLoc(Decl->getLocation());
+ AvailabilityInfo Availability = getAvailability(Decl);
+ DocComment Comment;
+ if (auto *RawComment = Context.getRawCommentForDeclNoCache(Decl))
+ Comment = RawComment->getFormattedLines(Context.getSourceManager(),
+ Context.getDiagnostics());
+
+ // Build declaration fragments and sub-heading for the protocol.
+ DeclarationFragments Declaration =
+ DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(Decl);
+ DeclarationFragments SubHeading =
+ DeclarationFragmentsBuilder::getSubHeading(Decl);
+
+ ObjCProtocolRecord *ObjCProtocolRecord = API.addObjCProtocol(
+ Name, USR, Loc, Availability, Comment, Declaration, SubHeading);
+
+ recordObjCMethods(ObjCProtocolRecord, Decl->methods());
+ recordObjCProperties(ObjCProtocolRecord, Decl->properties());
+ recordObjCProtocols(ObjCProtocolRecord, Decl->protocols());
+
+ return true;
+ }
+
private:
/// Get availability information of the declaration \p D.
AvailabilityInfo getAvailability(const Decl *D) const {
diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
index 3faf9cd..1acb67a 100644
--- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
+++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp
@@ -393,6 +393,10 @@ Object serializeSymbolKind(const APIRecord &Record, Language Lang) {
Kind["identifier"] = AddLangPrefix("class");
Kind["displayName"] = "Class";
break;
+ case APIRecord::RK_ObjCProtocol:
+ Kind["identifier"] = AddLangPrefix("protocol");
+ Kind["displayName"] = "Protocol";
+ break;
}
return Kind;
@@ -593,6 +597,10 @@ Object SymbolGraphSerializer::serialize() {
for (const auto &ObjCInterface : API.getObjCInterfaces())
serializeObjCContainerRecord(*ObjCInterface.second);
+ // Serialize Objective-C protocol records in the API set.
+ for (const auto &ObjCProtocol : API.getObjCProtocols())
+ serializeObjCContainerRecord(*ObjCProtocol.second);
+
Root["symbols"] = std::move(Symbols);
Root["relationhips"] = std::move(Relationships);