diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-07-13 19:25:38 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-07-13 19:25:38 +0000 |
commit | 8746d127c04f5bbaf6c6e88cef8606ca5a6a54e9 (patch) | |
tree | 84c9d77f8c764f04bcef0b1da4eedfa233d67a46 /lib/Index/IndexBody.cpp | |
parent | cf1b401909b5e54edfd80656b1a18eaa31f9f6f1 (diff) |
Notes
Diffstat (limited to 'lib/Index/IndexBody.cpp')
-rw-r--r-- | lib/Index/IndexBody.cpp | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp index d3632b8b9b15f..6bbd38102509f 100644 --- a/lib/Index/IndexBody.cpp +++ b/lib/Index/IndexBody.cpp @@ -230,7 +230,31 @@ public: SmallVector<SymbolRelation, 2> Relations; addCallRole(Roles, Relations); Stmt *Containing = getParentStmt(); - if (E->isImplicit() || (Containing && isa<PseudoObjectExpr>(Containing))) + + auto IsImplicitProperty = [](const PseudoObjectExpr *POE) -> bool { + const auto *E = POE->getSyntacticForm(); + if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) + E = BinOp->getLHS(); + const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E); + if (!PRE) + return false; + if (PRE->isExplicitProperty()) + return false; + if (const ObjCMethodDecl *Getter = PRE->getImplicitPropertyGetter()) { + // Class properties that are explicitly defined using @property + // declarations are represented implicitly as there is no ivar for + // class properties. + if (Getter->isClassMethod() && + Getter->getCanonicalDecl()->findPropertyDecl()) + return false; + } + return true; + }; + bool IsPropCall = Containing && isa<PseudoObjectExpr>(Containing); + // Implicit property message sends are not 'implicit'. + if ((E->isImplicit() || IsPropCall) && + !(IsPropCall && + IsImplicitProperty(cast<PseudoObjectExpr>(Containing)))) Roles |= (unsigned)SymbolRole::Implicit; if (isDynamic(E)) { |