diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -1860,6 +1860,7 @@ TEST(CompletionTest, CompletionTokenRange) { MockFSProvider FS; MockCompilationDatabase CDB; + FS.Files["foo/abc/foo.h"] = ""; ClangdServer Server(CDB, FS, ClangdServer::optsForTest()); constexpr const char *TestCodes[] = { @@ -1882,7 +1883,14 @@ Auxilary x; x.[[]]^; } - )cpp"}; + )cpp", + R"cpp( + #include "foo/[[a^/]]foo.h" + )cpp", + R"cpp( + #include "foo/abc/[[fo^o.h"]] + )cpp", + }; for (const auto &Text : TestCodes) { Annotations TestCode(Text); auto Results = completions(Server, TestCode.code(), TestCode.point()); diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -29,6 +29,7 @@ #include "clang/Basic/TokenKinds.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/StringRef.h" @@ -2092,7 +2093,8 @@ bool IsAngled) { // Completion only applies to the filename, after the last slash. StringRef PartialPath(PathStart, CompletionPoint - PathStart); - auto Slash = PartialPath.find_last_of(LangOpts.MSVCCompat ? "/\\" : "/"); + llvm::StringRef SlashChars = LangOpts.MSVCCompat ? "/\\" : "/"; + auto Slash = PartialPath.find_last_of(SlashChars); StringRef Dir = (Slash == StringRef::npos) ? "" : PartialPath.take_front(Slash); const char *StartOfFilename = @@ -2100,7 +2102,8 @@ // Code completion filter range is the filename only, up to completion point. PP->setCodeCompletionIdentifierInfo(&PP->getIdentifierTable().get( StringRef(StartOfFilename, CompletionPoint - StartOfFilename))); - // We should replace the characters up to the closing quote, if any. + // We should replace the characters up to the closing quote or closest slash, + // if any. while (CompletionPoint < BufferEnd) { char Next = *(CompletionPoint + 1); if (Next == 0 || Next == '\r' || Next == '\n') @@ -2108,7 +2111,10 @@ ++CompletionPoint; if (Next == (IsAngled ? '>' : '"')) break; + if (llvm::is_contained(SlashChars, Next)) + break; } + PP->setCodeCompletionTokenRange( FileLoc.getLocWithOffset(StartOfFilename - BufferStart), FileLoc.getLocWithOffset(CompletionPoint - BufferStart));