}
bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
- const ObjCContainerDecl *ContD) {
+ const ObjCContainerDecl *ContD,
+ SourceLocation SuperLoc) {
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(),
+ SymbolRoleSet roles{};
+ if (Loc == SuperLoc)
+ roles |= (SymbolRoleSet)SymbolRole::Implicit;
+ TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
}
return true;
bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
if (D->isThisDeclarationADefinition()) {
TRY_TO(IndexCtx.handleDecl(D));
+ SourceLocation SuperLoc = D->getSuperClassLoc();
if (auto *SuperD = D->getSuperClass()) {
- TRY_TO(IndexCtx.handleReference(SuperD, D->getSuperClassLoc(), D, D,
- SymbolRoleSet(),
+ bool hasSuperTypedef = false;
+ if (auto *TInfo = D->getSuperClassTInfo()) {
+ if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
+ if (auto *TD = TT->getDecl()) {
+ hasSuperTypedef = true;
+ TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
+ SymbolRoleSet()));
+ }
+ }
+ }
+ SymbolRoleSet superRoles{};
+ if (hasSuperTypedef)
+ superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
+ TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
}
- TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+ TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+ SuperLoc));
TRY_TO(IndexCtx.indexDeclContext(D));
} else {
return IndexCtx.handleReference(D, D->getLocation(), nullptr,
bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
if (D->isThisDeclarationADefinition()) {
TRY_TO(IndexCtx.handleDecl(D));
- TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+ TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+ /*superLoc=*/SourceLocation()));
TRY_TO(IndexCtx.indexDeclContext(D));
} else {
return IndexCtx.handleReference(D, D->getLocation(), nullptr,
if (!CategoryLoc.isValid())
CategoryLoc = D->getLocation();
TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
- TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+ TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+ /*superLoc=*/SourceLocation()));
TRY_TO(IndexCtx.indexDeclContext(D));
return true;
}
@protocol MyEnumerating
@end
-// CHECK: [[@LINE+4]]:41 | type-alias/C | MyEnumerator | c:index-source.m@T@MyEnumerator | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+4]]:41 | type-alias/C | MyEnumerator | [[MyEnumerator_USR:.*]] | <no-cgname> | Def | rel: 0
// CHECK: [[@LINE+3]]:26 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,RelCont | rel: 1
// CHECK: [[@LINE+2]]:9 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,RelCont | rel: 1
// CHECK: [[@LINE+1]]:18 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
typedef MyGenCls<Base *><MyEnumerating> MyEnumerator;
-// CHECK: [[@LINE+5]]:12 | class/ObjC | PermanentEnumerator | c:objc(cs)PermanentEnumerator | _OBJC_CLASS_$_PermanentEnumerator | Decl | rel: 0
-// CHECK: [[@LINE+4]]:34 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,RelBase,RelCont | rel: 1
-// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | c:objc(cs)PermanentEnumerator
-// CHECK: [[@LINE+2]]:34 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,RelBase,RelCont | rel: 1
-// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | c:objc(cs)PermanentEnumerator
+// CHECK: [[@LINE+7]]:12 | class/ObjC | PermanentEnumerator | [[PermanentEnumerator_USR:.*]] | _OBJC_CLASS_$_PermanentEnumerator | Decl | rel: 0
+// CHECK: [[@LINE+6]]:34 | type-alias/C | MyEnumerator | [[MyEnumerator_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
+// CHECK: [[@LINE+4]]:34 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
+// CHECK: [[@LINE+2]]:34 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
@interface PermanentEnumerator : MyEnumerator
@end
+// CHECK: [[@LINE+2]]:48 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:35 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+@interface PermanentEnumerator2 : MyEnumerator<Prot1>
+@end
+
@interface I4
@property id foo;
@end