diff options
| -rw-r--r-- | clang/lib/Index/IndexDecl.cpp | 35 | ||||
| -rw-r--r-- | clang/test/Index/Core/index-source.m | 19 | 
2 files changed, 40 insertions, 14 deletions
diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp index 6f9d6938632..4c5a87b29b2 100644 --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -225,14 +225,17 @@ public:    }    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; @@ -241,12 +244,26 @@ public:    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, @@ -258,7 +275,8 @@ public:    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, @@ -306,7 +324,8 @@ public:      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;    } diff --git a/clang/test/Index/Core/index-source.m b/clang/test/Index/Core/index-source.m index 794d72ca324..e54198ab861 100644 --- a/clang/test/Index/Core/index-source.m +++ b/clang/test/Index/Core/index-source.m @@ -202,20 +202,27 @@ extern int setjmp(jmp_buf);  @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  | 

