in glean/lang/clang/ast.cpp [2261:2293]
bool VisitObjCPropertyRefExpr(const clang::ObjCPropertyRefExpr *expr) {
std::vector<XRef> xrefs;
if (expr->isImplicitProperty()) {
// Note things like x.foo += 5 generate xrefs to both getter and setter.
if (expr->isMessagingGetter()) {
if (auto getter = expr->getImplicitPropertyGetter()) {
xrefs.push_back(XRef::toDecl(objcMethodDecls, getter));
}
if (expr->isClassReceiver()) {
xrefTarget(
expr->getReceiverLocation(),
XRef::toDecl(objcContainerDecls, expr->getClassReceiver())
);
}
}
if (expr->isMessagingSetter()) {
if (auto setter = expr->getImplicitPropertySetter()) {
xrefs.push_back(XRef::toDecl(objcMethodDecls, setter));
}
}
} else if (auto prop = expr->getExplicitProperty()) {
xrefs.push_back(XRef::toDecl(objcPropertyDecls, prop));
}
if (!xrefs.empty()) {
const auto start = expr->getLocation();
const auto range = db.rangeOfToken(start);
for (const auto &xref : xrefs) {
xrefTarget(range, xref);
}
}
return true;
}