diff --git a/clang-tools-extra/clangd/Preamble.h b/clang-tools-extra/clangd/Preamble.h --- a/clang-tools-extra/clangd/Preamble.h +++ b/clang-tools-extra/clangd/Preamble.h @@ -182,6 +182,7 @@ std::vector PatchedDiags; PreambleBounds ModifiedBounds = {0, false}; const PreambleData *Baseline = nullptr; + std::vector PatchedMarks; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp --- a/clang-tools-extra/clangd/Preamble.cpp +++ b/clang-tools-extra/clangd/Preamble.cpp @@ -15,7 +15,9 @@ #include "Protocol.h" #include "SourceCode.h" #include "clang-include-cleaner/Record.h" +#include "index/CanonicalIncludes.h" #include "support/Logger.h" +#include "support/Path.h" #include "support/ThreadsafeFS.h" #include "support/Trace.h" #include "clang/AST/DeclTemplate.h" @@ -27,6 +29,7 @@ #include "clang/Basic/TokenKinds.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/PPCallbacks.h" @@ -42,6 +45,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" @@ -50,10 +54,12 @@ #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include +#include #include #include #include #include +#include #include #include @@ -318,6 +324,7 @@ // Literal lines of the preamble contents. std::vector Lines; PreambleBounds Bounds = {0, false}; + std::vector Marks; }; /// Scans the preprocessor directives in the preamble section of the file by @@ -372,6 +379,8 @@ SP.Bounds = Bounds; PP.addPPCallbacks( std::make_unique(PP, SP.TextualDirectives)); + PP.addPPCallbacks( + collectPragmaMarksCallback(PP.getSourceManager(), SP.Marks)); if (llvm::Error Err = Action.Execute()) return std::move(Err); Action.EndSourceFile(); @@ -849,6 +858,7 @@ } PP.PatchedDiags = patchDiags(Baseline.Diags, *BaselineScan, *ModifiedScan); + PP.PatchedMarks = std::move(ModifiedScan->Marks); dlog("Created preamble patch: {0}", Patch.str()); Patch.flush(); return PP; @@ -902,8 +912,7 @@ llvm::ArrayRef PreamblePatch::marks() const { if (PatchContents.empty()) return Baseline->Marks; - // FIXME: Patch pragma marks. - return {}; + return PatchedMarks; } MainFileMacros PreamblePatch::mainFileMacros() const { diff --git a/clang-tools-extra/clangd/unittests/PreambleTests.cpp b/clang-tools-extra/clangd/unittests/PreambleTests.cpp --- a/clang-tools-extra/clangd/unittests/PreambleTests.cpp +++ b/clang-tools-extra/clangd/unittests/PreambleTests.cpp @@ -829,6 +829,10 @@ } } +MATCHER_P2(Mark, Range, Text, "") { + return std::tie(arg.Rng, arg.Trivia) == std::tie(Range, Text); +} + TEST(PreamblePatch, MacroAndMarkHandling) { Config Cfg; Cfg.Diagnostics.AllowStalePreamble = true; @@ -847,13 +851,18 @@ #ifndef FOO #define FOO #define BAR -#pragma mark XX +#pragma $x[[mark XX +]] +#pragma $y[[mark YY +]] #endif)cpp"); auto AST = createPatchedAST(Code.code(), NewCode.code()); // FIXME: Macros and marks have locations that need to be patched. EXPECT_THAT(AST->getMacros().Names, IsEmpty()); - EXPECT_THAT(AST->getMarks(), IsEmpty()); + EXPECT_THAT(AST->getMarks(), + UnorderedElementsAre(Mark(NewCode.range("x"), " XX"), + Mark(NewCode.range("y"), " YY"))); } }