From a9876cafe2363800bc928cfe3541c158a98f7074 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Thu, 23 Mar 2017 16:34:47 +0000 Subject: [PATCH] [index] When indexing system headers make sure to report important reference relations Even if we exclude plain reference occurrences, we should include relation-based references, like the 'base' one. rdar://31010737 llvm-svn: 298622 --- clang/include/clang/Index/IndexSymbol.h | 2 ++ clang/lib/Index/IndexSymbol.cpp | 17 ++++++++-- clang/lib/Index/IndexingContext.cpp | 45 +++++++++++++++++++++++++- clang/test/Index/Core/Inputs/sys/system-head.h | 36 +++++++++++++++++++++ clang/test/Index/Core/index-system.mm | 3 ++ 5 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 clang/test/Index/Core/Inputs/sys/system-head.h create mode 100644 clang/test/Index/Core/index-system.mm diff --git a/clang/include/clang/Index/IndexSymbol.h b/clang/include/clang/Index/IndexSymbol.h index eb718d7..217d6b1 100644 --- a/clang/include/clang/Index/IndexSymbol.h +++ b/clang/include/clang/Index/IndexSymbol.h @@ -132,6 +132,8 @@ bool isFunctionLocalSymbol(const Decl *D); void applyForEachSymbolRole(SymbolRoleSet Roles, llvm::function_ref Fn); +bool applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles, + llvm::function_ref Fn); void printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS); /// \returns true if no name was printed, false otherwise. diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp index 785125c..fe3c178 100644 --- a/clang/lib/Index/IndexSymbol.cpp +++ b/clang/lib/Index/IndexSymbol.cpp @@ -321,11 +321,12 @@ SymbolInfo index::getSymbolInfo(const Decl *D) { return Info; } -void index::applyForEachSymbolRole(SymbolRoleSet Roles, - llvm::function_ref Fn) { +bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles, + llvm::function_ref Fn) { #define APPLY_FOR_ROLE(Role) \ if (Roles & (unsigned)SymbolRole::Role) \ - Fn(SymbolRole::Role) + if (!Fn(SymbolRole::Role)) \ + return false; APPLY_FOR_ROLE(Declaration); APPLY_FOR_ROLE(Definition); @@ -347,6 +348,16 @@ void index::applyForEachSymbolRole(SymbolRoleSet Roles, APPLY_FOR_ROLE(RelationIBTypeOf); #undef APPLY_FOR_ROLE + + return true; +} + +void index::applyForEachSymbolRole(SymbolRoleSet Roles, + llvm::function_ref Fn) { + applyForEachSymbolRoleInterruptible(Roles, [&](SymbolRole r) -> bool { + Fn(r); + return true; + }); } void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) { diff --git a/clang/lib/Index/IndexingContext.cpp b/clang/lib/Index/IndexingContext.cpp index 9a4028f..c5ccf45 100644 --- a/clang/lib/Index/IndexingContext.cpp +++ b/clang/lib/Index/IndexingContext.cpp @@ -204,6 +204,49 @@ static const Decl *getCanonicalDecl(const Decl *D) { return D; } +static bool shouldReportOccurrenceForSystemDeclOnlyMode( + bool IsRef, SymbolRoleSet Roles, ArrayRef Relations) { + if (!IsRef) + return true; + + auto acceptForRelation = [](SymbolRoleSet roles) -> bool { + bool accept = false; + applyForEachSymbolRoleInterruptible(roles, [&accept](SymbolRole r) -> bool { + switch (r) { + case SymbolRole::RelationChildOf: + case SymbolRole::RelationBaseOf: + case SymbolRole::RelationOverrideOf: + case SymbolRole::RelationExtendedBy: + case SymbolRole::RelationAccessorOf: + case SymbolRole::RelationIBTypeOf: + accept = true; + return false; + case SymbolRole::Declaration: + case SymbolRole::Definition: + case SymbolRole::Reference: + case SymbolRole::Read: + case SymbolRole::Write: + case SymbolRole::Call: + case SymbolRole::Dynamic: + case SymbolRole::AddressOf: + case SymbolRole::Implicit: + case SymbolRole::RelationReceivedBy: + case SymbolRole::RelationCalledBy: + case SymbolRole::RelationContainedBy: + return true; + } + }); + return accept; + }; + + for (auto &Rel : Relations) { + if (acceptForRelation(Rel.Roles)) + return true; + } + + return false; +} + bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc, bool IsRef, const Decl *Parent, SymbolRoleSet Roles, @@ -239,7 +282,7 @@ bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc, case IndexingOptions::SystemSymbolFilterKind::None: return true; case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly: - if (IsRef) + if (!shouldReportOccurrenceForSystemDeclOnlyMode(IsRef, Roles, Relations)) return true; break; case IndexingOptions::SystemSymbolFilterKind::All: diff --git a/clang/test/Index/Core/Inputs/sys/system-head.h b/clang/test/Index/Core/Inputs/sys/system-head.h new file mode 100644 index 0000000..df0e39e --- /dev/null +++ b/clang/test/Index/Core/Inputs/sys/system-head.h @@ -0,0 +1,36 @@ +// CHECK: [[@LINE+1]]:12 | class/ObjC | Base | [[Base_USR:.*]] | {{.*}} | Decl | rel: 0 +@interface Base +@end + +// CHECK: [[@LINE+1]]:11 | protocol/ObjC | Prot1 | [[Prot1_USR:.*]] | {{.*}} | Decl | rel: 0 +@protocol Prot1 +@end + +// CHECK: [[@LINE+3]]:11 | protocol/ObjC | Prot2 | [[Prot2_USR:.*]] | {{.*}} | Decl | rel: 0 +// CHECK: [[@LINE+2]]:17 | protocol/ObjC | Prot1 | [[Prot1_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1 +// CHECK-NEXT: RelBase,RelCont | Prot2 | [[Prot2_USR]] +@protocol Prot2 +@end + +// CHECK: [[@LINE+7]]:12 | class/ObjC | Sub | [[Sub_USR:.*]] | {{.*}} | Decl | rel: 0 +// CHECK: [[@LINE+6]]:18 | class/ObjC | Base | [[Base_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1 +// CHECK-NEXT: RelBase,RelCont | Sub | [[Sub_USR]] +// CHECK: [[@LINE+4]]:23 | protocol/ObjC | Prot2 | [[Prot2_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1 +// CHECK-NEXT: RelBase,RelCont | Sub | [[Sub_USR]] +// CHECK: [[@LINE+2]]:30 | protocol/ObjC | Prot1 | [[Prot1_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1 +// CHECK-NEXT: RelBase,RelCont | Sub | [[Sub_USR]] +@interface Sub : Base +// CHECK-NOT: [[@LINE+1]]:3 | class/ObjC | Sub | +-(Sub*)getit; +@end + +// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] | {{.*}} | Def | rel: 0 +class Cls {}; + +// CHECK: [[@LINE+3]]:7 | class/C++ | SubCls1 | [[SubCls1_USR:.*]] | {{.*}} | Def | rel: 0 +// CHECK: [[@LINE+2]]:24 | class/C++ | Cls | [[Cls_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1 +// CHECK-NEXT: RelBase,RelCont | SubCls1 | [[SubCls1_USR]] +class SubCls1 : public Cls { + // CHECK-NOT: [[@LINE+1]]:3 | class/C++ | SubCls1 | + SubCls1 *f; +}; diff --git a/clang/test/Index/Core/index-system.mm b/clang/test/Index/Core/index-system.mm new file mode 100644 index 0000000..2ad31fa --- /dev/null +++ b/clang/test/Index/Core/index-system.mm @@ -0,0 +1,3 @@ +// RUN: c-index-test core -print-source-symbols -- %s -isystem %S/Inputs/sys | FileCheck %S/Inputs/sys/system-head.h + +#include "system-head.h" -- 2.7.4