From: Argyrios Kyrtzidis Date: Thu, 3 Mar 2016 05:33:54 +0000 (+0000) Subject: [index] Report references of ObjC super class/protocols in interfaces and protocols. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e85a1ce36280e358ad450b05a5c1cada0766d73e;p=clang [index] Report references of ObjC super class/protocols in interfaces and protocols. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@262584 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp index 76f68e564c..af438f3684 100644 --- a/lib/Index/IndexDecl.cpp +++ b/lib/Index/IndexDecl.cpp @@ -14,6 +14,12 @@ using namespace clang; using namespace index; +#define TRY_TO(CALL_EXPR) \ + do { \ + if (!CALL_EXPR) \ + return false; \ + } while (0) + namespace { class IndexingDeclVisitor : public ConstDeclVisitor { @@ -196,11 +202,30 @@ public: return true; } + bool handleReferencedProtocols(const ObjCProtocolList &ProtList, + const ObjCContainerDecl *ContD) { + ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin(); + for (ObjCInterfaceDecl::protocol_iterator + I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) { + SourceLocation Loc = *LI; + ObjCProtocolDecl *PD = *I; + TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, + SymbolRoleSet(), + SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD})); + } + return true; + } + bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { if (D->isThisDeclarationADefinition()) { - if (!IndexCtx.handleDecl(D)) - return false; - IndexCtx.indexDeclContext(D); + TRY_TO(IndexCtx.handleDecl(D)); + if (auto *SuperD = D->getSuperClass()) { + TRY_TO(IndexCtx.handleReference(SuperD, D->getSuperClassLoc(), D, D, + SymbolRoleSet(), + SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D})); + } + TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D)); + TRY_TO(IndexCtx.indexDeclContext(D)); } else { return IndexCtx.handleReference(D, D->getLocation(), nullptr, nullptr, SymbolRoleSet()); @@ -210,9 +235,9 @@ public: bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { if (D->isThisDeclarationADefinition()) { - if (!IndexCtx.handleDecl(D)) - return false; - IndexCtx.indexDeclContext(D); + TRY_TO(IndexCtx.handleDecl(D)); + TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D)); + TRY_TO(IndexCtx.indexDeclContext(D)); } else { return IndexCtx.handleReference(D, D->getLocation(), nullptr, nullptr, SymbolRoleSet()); diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m index c2604f6754..766b6b198f 100644 --- a/test/Index/Core/index-source.m +++ b/test/Index/Core/index-source.m @@ -18,3 +18,23 @@ void goo(Base *b) { // CHECK-NEXT: RelRec | Base | c:objc(cs)Base [b meth]; } + +// CHECK: [[@LINE+1]]:11 | objc-protocol/ObjC | Prot1 | c:objc(pl)Prot1 | | Decl | rel: 0 +@protocol Prot1 +@end + +// CHECK: [[@LINE+3]]:11 | objc-protocol/ObjC | Prot2 | c:objc(pl)Prot2 | | Decl | rel: 0 +// CHECK: [[@LINE+2]]:17 | objc-protocol/ObjC | Prot1 | c:objc(pl)Prot1 | | Ref,RelBase | rel: 1 +// CHECK-NEXT: RelBase | Prot2 | c:objc(pl)Prot2 +@protocol Prot2 +@end + +// CHECK: [[@LINE+7]]:12 | objc-class/ObjC | Sub | c:objc(cs)Sub | _OBJC_CLASS_$_Sub | Decl | rel: 0 +// CHECK: [[@LINE+6]]:18 | objc-class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelBase | rel: 1 +// CHECK-NEXT: RelBase | Sub | c:objc(cs)Sub +// CHECK: [[@LINE+4]]:23 | objc-protocol/ObjC | Prot2 | c:objc(pl)Prot2 | | Ref,RelBase | rel: 1 +// CHECK-NEXT: RelBase | Sub | c:objc(cs)Sub +// CHECK: [[@LINE+2]]:30 | objc-protocol/ObjC | Prot1 | c:objc(pl)Prot1 | | Ref,RelBase | rel: 1 +// CHECK-NEXT: RelBase | Sub | c:objc(cs)Sub +@interface Sub : Base +@end