diff --git a/clang-tools-extra/clangd/ParsedAST.cpp b/clang-tools-extra/clangd/ParsedAST.cpp --- a/clang-tools-extra/clangd/ParsedAST.cpp +++ b/clang-tools-extra/clangd/ParsedAST.cpp @@ -605,16 +605,15 @@ // Copy over the macros in the preamble region of the main file, and combine // with non-preamble macros below. MainFileMacros Macros; - if (Preamble) - Macros = Preamble->Macros; + std::vector Marks; + if (Preamble) { + Macros = Patch->mainFileMacros(); + Marks = Patch->marks(); + } Clang->getPreprocessor().addPPCallbacks( std::make_unique(Clang->getSourceManager(), Macros)); - std::vector Marks; - // FIXME: We need to patch the marks for stale preambles. - if (Preamble) - Marks = Preamble->Marks; Clang->getPreprocessor().addPPCallbacks( collectPragmaMarksCallback(Clang->getSourceManager(), Marks)); 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 @@ -163,6 +163,9 @@ static constexpr llvm::StringLiteral HeaderName = "__preamble_patch__.h"; + llvm::ArrayRef marks() const; + MainFileMacros mainFileMacros() const; + private: static PreamblePatch create(llvm::StringRef FileName, const ParseInputs &Modified, @@ -178,6 +181,7 @@ // Diags that were attached to a line preserved in Modified contents. std::vector PatchedDiags; PreambleBounds ModifiedBounds = {0, false}; + const PreambleData *Baseline = nullptr; }; } // 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 @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "Preamble.h" +#include "CollectMacros.h" #include "Compiler.h" #include "Config.h" #include "Diagnostics.h" @@ -765,6 +766,7 @@ return PreamblePatch::unmodified(Baseline); PreamblePatch PP; + PP.Baseline = &Baseline; // This shouldn't coincide with any real file name. llvm::SmallString<128> PatchName; llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName), @@ -886,6 +888,7 @@ PreamblePatch PreamblePatch::unmodified(const PreambleData &Preamble) { PreamblePatch PP; + PP.Baseline = &Preamble; PP.PreambleIncludes = Preamble.Includes.MainFileIncludes; PP.ModifiedBounds = Preamble.Preamble.getBounds(); PP.PatchedDiags = Preamble.Diags; @@ -896,5 +899,18 @@ return PatchContents.empty() || Config::current().Diagnostics.AllowStalePreamble; } +llvm::ArrayRef PreamblePatch::marks() const { + if (PatchContents.empty()) + return Baseline->Marks; + // FIXME: Patch pragma marks. + return {}; +} + +MainFileMacros PreamblePatch::mainFileMacros() const { + if (PatchContents.empty()) + return Baseline->Macros; + // FIXME: Patch main file macros. + return MainFileMacros(); +} } // namespace clangd } // namespace clang 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 @@ -19,6 +19,7 @@ #include "TestFS.h" #include "TestTU.h" #include "XRefs.h" +#include "support/Context.h" #include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" #include "clang/Frontend/FrontendActions.h" @@ -36,6 +37,7 @@ #include #include #include +#include #include using testing::AllOf; @@ -826,6 +828,35 @@ EXPECT_THAT(*AST->getDiagnostics(), IsEmpty()); } } + +TEST(PreamblePatch, MacroAndMarkHandling) { + Config Cfg; + Cfg.Diagnostics.AllowStalePreamble = true; + WithContextValue WithCfg(Config::Key, std::move(Cfg)); + + { + Annotations Code(R"cpp( +#ifndef FOO +#define FOO +// Some comments +#pragma mark XX +#define BAR + +#endif)cpp"); + Annotations NewCode(R"cpp( +#ifndef FOO +#define FOO +#define BAR +#pragma mark XX + +#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()); + } +} + } // namespace } // namespace clangd } // namespace clang