diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -129,6 +129,23 @@
   return Merged.CanonicalDeclaration;
 }
 
+// Returns true if the given expression is an implicit AST node.
+bool IsImplicitExpr(const Expr *E) {
+  if (!E)
+    return false;
+  // We assume that a constructor expression is implict (was inserted by
+  // clang) if it has an invalid paren/brace location, since such
+  // experssion is impossible to write down.
+  if (const auto *CtorExpr = dyn_cast<CXXConstructExpr>(E))
+    return CtorExpr->getParenOrBraceRange().isInvalid();
+  // Ignore implicit conversion-operator AST node.
+  if (const auto *ME = dyn_cast<MemberExpr>(E)) {
+    if (isa<CXXConversionDecl>(ME->getMemberDecl()))
+      return ME->getMemberLoc().isInvalid();
+  }
+  return isa<ImplicitCastExpr>(E);
+}
+
 /// Finds declarations locations that a given source location refers to.
 class DeclarationAndMacrosFinder : public index::IndexDataConsumer {
   std::vector<DefinedMacro> MacroInfos;
@@ -179,22 +196,6 @@
       return true;
 
     if (Loc == SearchedLocation) {
-      auto IsImplicitExpr = [](const Expr *E) {
-        if (!E)
-          return false;
-        // We assume that a constructor expression is implict (was inserted by
-        // clang) if it has an invalid paren/brace location, since such
-        // experssion is impossible to write down.
-        if (const auto *CtorExpr = dyn_cast<CXXConstructExpr>(E))
-          return CtorExpr->getParenOrBraceRange().isInvalid();
-        // Ignore implicit conversion-operator AST node.
-        if (const auto *ME = dyn_cast<MemberExpr>(E)) {
-          if (isa<CXXConversionDecl>(ME->getMemberDecl()))
-            return ME->getMemberLoc().isInvalid();
-        }
-        return isa<ImplicitCastExpr>(E);
-      };
-
       if (IsImplicitExpr(ASTNode.OrigE))
         return true;
       // Find and add definition declarations (for GoToDefinition).
@@ -408,7 +409,8 @@
     assert(D->isCanonicalDecl() && "expect D to be a canonical declaration");
     const SourceManager &SM = AST.getSourceManager();
     Loc = SM.getFileLoc(Loc);
-    if (isInsideMainFile(Loc, SM) && CanonicalTargets.count(D))
+    if (isInsideMainFile(Loc, SM) && CanonicalTargets.count(D) &&
+        !IsImplicitExpr(ASTNode.OrigE))
       References.push_back({Loc, Roles});
     return true;
   }
diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
--- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -2080,7 +2080,18 @@
         [[a]].operator bool();
         if ([[a^]]) {} // ignore implicit conversion-operator AST node
       }
-    )cpp",
+      )cpp",
+      R"cpp(
+      struct X {
+        [[operator]] bool();
+      };
+
+      int test() {
+        X a;
+        a.[[oper^ator]] bool();
+        if (a) {}
+      }
+      )cpp",
   };
   for (const char *Test : Tests) {
     Annotations T(Test);