summaryrefslogtreecommitdiffstats
path: root/clang/lib/Index/IndexDecl.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2017-02-17 04:49:41 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2017-02-17 04:49:41 +0000
commit74790484b53c3824b25eddc005d0caf1310433a6 (patch)
tree27003b4ef3015a7a05893e9760d4daee6e66303b /clang/lib/Index/IndexDecl.cpp
parentca2cfd0bd86890d3dcc989b325d36b72e258a200 (diff)
downloadbcm5719-llvm-74790484b53c3824b25eddc005d0caf1310433a6.tar.gz
bcm5719-llvm-74790484b53c3824b25eddc005d0caf1310433a6.zip
[index] Improvde how we handle synthesized ObjC properties and the associated ivars.
Related synthesized properties with the ivar they use with the 'accessor' relation, and make sure we mark them 'implicit' when appropriate. Patch by Nathan Hawes! https://reviews.llvm.org/D30012 llvm-svn: 295416
Diffstat (limited to 'clang/lib/Index/IndexDecl.cpp')
-rw-r--r--clang/lib/Index/IndexDecl.cpp87
1 files changed, 57 insertions, 30 deletions
diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp
index 3b4f3f81399..6f9d6938632 100644
--- a/clang/lib/Index/IndexDecl.cpp
+++ b/clang/lib/Index/IndexDecl.cpp
@@ -98,7 +98,10 @@ public:
if (MethodLoc.isInvalid())
MethodLoc = D->getLocation();
- if (!IndexCtx.handleDecl(D, MethodLoc, (unsigned)SymbolRole::Dynamic, Relations))
+ SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
+ if (D->isImplicit())
+ Roles |= (SymbolRoleSet)SymbolRole::Implicit;
+ if (!IndexCtx.handleDecl(D, MethodLoc, Roles, Relations))
return false;
IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
@@ -178,14 +181,8 @@ public:
bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
if (D->getSynthesize()) {
- // For synthesized ivars, use the location of the ObjC implementation,
- // not the location of the property.
- // Otherwise the header file containing the @interface will have different
- // indexing contents based on whether the @implementation was present or
- // not in the translation unit.
- return IndexCtx.handleDecl(D,
- cast<Decl>(D->getDeclContext())->getLocation(),
- (unsigned)SymbolRole::Implicit);
+ // handled in VisitObjCPropertyImplDecl
+ return true;
}
if (!IndexCtx.handleDecl(D))
return false;
@@ -281,12 +278,16 @@ public:
if (!IndexCtx.handleDecl(D))
return false;
- // Index the ivars first to make sure the synthesized ivars are indexed
- // before indexing the methods that can reference them.
- for (const auto *IvarI : D->ivars())
- IndexCtx.indexDecl(IvarI);
+ // Visit implicit @synthesize property implementations first as their
+ // location is reported at the name of the @implementation block. This
+ // serves no purpose other than to simplify the FileCheck-based tests.
+ for (const auto *I : D->property_impls()) {
+ if (I->getLocation().isInvalid())
+ IndexCtx.indexDecl(I);
+ }
for (const auto *I : D->decls()) {
- if (!isa<ObjCIvarDecl>(I))
+ if (!isa<ObjCPropertyImplDecl>(I) ||
+ cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
IndexCtx.indexDecl(I);
}
@@ -355,32 +356,58 @@ public:
bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
ObjCPropertyDecl *PD = D->getPropertyDecl();
- if (!IndexCtx.handleReference(PD, D->getLocation(),
- /*Parent=*/cast<NamedDecl>(D->getDeclContext()),
- D->getDeclContext(), SymbolRoleSet(), {},
- /*RefE=*/nullptr, D))
+ auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
+ SourceLocation Loc = D->getLocation();
+ SymbolRoleSet Roles = 0;
+ SmallVector<SymbolRelation, 1> Relations;
+
+ if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
+ Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
+ if (Loc.isInvalid()) {
+ Loc = Container->getLocation();
+ Roles |= (SymbolRoleSet)SymbolRole::Implicit;
+ }
+ if (!IndexCtx.handleDecl(D, Loc, Roles, Relations))
return false;
if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
return true;
- assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
-
- if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
- if (!IvarD->getSynthesize())
- IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
- D->getDeclContext(), SymbolRoleSet());
- }
- auto *ImplD = cast<ObjCImplDecl>(D->getDeclContext());
+ assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
if (MD->isPropertyAccessor() &&
- !hasUserDefined(MD, ImplD))
- IndexCtx.handleDecl(MD, D->getLocation(), SymbolRoleSet(), {}, ImplD);
+ !hasUserDefined(MD, Container))
+ IndexCtx.handleDecl(MD, Loc, SymbolRoleSet(SymbolRole::Implicit), {},
+ Container);
}
if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
if (MD->isPropertyAccessor() &&
- !hasUserDefined(MD, ImplD))
- IndexCtx.handleDecl(MD, D->getLocation(), SymbolRoleSet(), {}, ImplD);
+ !hasUserDefined(MD, Container))
+ IndexCtx.handleDecl(MD, Loc, SymbolRoleSet(SymbolRole::Implicit), {},
+ Container);
+ }
+ if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
+ if (IvarD->getSynthesize()) {
+ // For synthesized ivars, use the location of its name in the
+ // corresponding @synthesize. If there isn't one, use the containing
+ // @implementation's location, rather than the property's location,
+ // otherwise the header file containing the @interface will have different
+ // indexing contents based on whether the @implementation was present or
+ // not in the translation unit.
+ SymbolRoleSet IvarRoles = 0;
+ SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
+ if (D->getLocation().isInvalid()) {
+ IvarLoc = Container->getLocation();
+ IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
+ } else if (D->getLocation() == IvarLoc) {
+ IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
+ }
+ if(!IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles))
+ return false;
+ } else {
+ IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
+ D->getDeclContext(), SymbolRoleSet());
+ }
}
return true;
}
OpenPOWER on IntegriCloud