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 @@ -363,6 +363,16 @@ const std::string &MainFilePath) { const auto &SM = AST.getSourceManager(); + auto Tokens = syntax::spelledTokensTouching(Loc, AST.getTokens()); + if (Tokens.size() != 1) + return {}; + syntax::Token Tok = Tokens[0]; + + // Only consider comment and identifier tokens. + if (!(Tok.kind() == tok::TokenKind::comment || + Tok.kind() == tok::TokenKind::identifier)) + return {}; + // Get the raw word at the specified location. unsigned Pos; FileID File; @@ -374,12 +384,14 @@ unsigned WordOffset = Word.data() - Code.data(); SourceLocation WordStart = SM.getComposedLoc(File, WordOffset); - // Do not consider tokens that survived preprocessing. - // We are erring on the safe side here, as a user may expect to get - // accurate (as opposed to textual-heuristic) results for such tokens. + // If this is an identifier token, do not consider if it it survived + // preprocessing. We are erring on the safe side here, as a user may expect to + // get accurate (as opposed to textual-heuristic) results for such tokens. // FIXME: Relax this for dependent code. - if (tokenSurvivedPreprocessing(WordStart, AST.getTokens())) + if (Tok.kind() == tok::TokenKind::identifier && + tokenSurvivedPreprocessing(WordStart, AST.getTokens())) { return {}; + } // Additionally filter for signals that the word is likely to be an // identifier. This avoids triggering on e.g. random words in a comment. 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 @@ -628,7 +628,8 @@ // Comment mentioning M^yClass )cpp", R"cpp(// String - struct [[MyClass]] {}; + struct MyClass {}; + // Not triggered for string literal tokens. const char* s = "String literal mentioning M^yClass"; )cpp", R"cpp(// Ifdef'ed out code @@ -680,7 +681,7 @@ EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test; } } -} +} // namespace TEST(LocateSymbol, Ambiguous) { auto T = Annotations(R"cpp( diff --git a/clang/lib/Tooling/Syntax/Tokens.cpp b/clang/lib/Tooling/Syntax/Tokens.cpp --- a/clang/lib/Tooling/Syntax/Tokens.cpp +++ b/clang/lib/Tooling/Syntax/Tokens.cpp @@ -340,6 +340,7 @@ // We can't make BufEnd point to FR.endOffset, as Lexer requires a // null terminated buffer. SrcBuffer.data() + SrcBuffer.size()); + L.SetCommentRetentionState(true); clang::Token T; while (!L.LexFromRawLexer(T) && L.getCurrentBufferOffset() < FR.endOffset())