Skip to content

Commit 144562e

Browse files
committed
[clangd] Treat preamble patch as main file for include-cleaner analysis
Since we redefine all macros in preamble-patch, and it's parsed after consuming the preamble macros, we can get false missing-include diagnostics while a fresh preamble is being rebuilt. This patch makes sure preamble-patch is treated same as main file for include-cleaner purposes. Differential Revision: https://reviews.llvm.org/D148143
1 parent 9af9245 commit 144562e

File tree

4 files changed

+54
-8
lines changed

4 files changed

+54
-8
lines changed

clang-tools-extra/clangd/IncludeCleaner.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "Diagnostics.h"
1212
#include "Headers.h"
1313
#include "ParsedAST.h"
14+
#include "Preamble.h"
1415
#include "Protocol.h"
1516
#include "SourceCode.h"
1617
#include "URI.h"
@@ -112,12 +113,12 @@ static bool mayConsiderUnused(const Inclusion &Inc, ParsedAST &AST,
112113
return false;
113114
// Check if main file is the public interface for a private header. If so we
114115
// shouldn't diagnose it as unused.
115-
if(auto PHeader = PI->getPublic(*FE); !PHeader.empty()) {
116+
if (auto PHeader = PI->getPublic(*FE); !PHeader.empty()) {
116117
PHeader = PHeader.trim("<>\"");
117118
// Since most private -> public mappings happen in a verbatim way, we
118119
// check textually here. This might go wrong in presence of symlinks or
119120
// header mappings. But that's not different than rest of the places.
120-
if(AST.tuPath().endswith(PHeader))
121+
if (AST.tuPath().endswith(PHeader))
121122
return false;
122123
}
123124
}
@@ -360,6 +361,7 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST &AST) {
360361
include_cleaner::Includes ConvertedIncludes =
361362
convertIncludes(SM, Includes.MainFileIncludes);
362363
const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID());
364+
auto *PreamblePatch = PreamblePatch::getPatchEntry(AST.tuPath(), SM);
363365

364366
std::vector<include_cleaner::SymbolReference> Macros =
365367
collectMacroReferences(AST);
@@ -374,7 +376,7 @@ IncludeCleanerFindings computeIncludeCleanerFindings(ParsedAST &AST) {
374376
bool Satisfied = false;
375377
for (const auto &H : Providers) {
376378
if (H.kind() == include_cleaner::Header::Physical &&
377-
H.physical() == MainFile) {
379+
(H.physical() == MainFile || H.physical() == PreamblePatch)) {
378380
Satisfied = true;
379381
continue;
380382
}

clang-tools-extra/clangd/Preamble.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,14 @@ static std::vector<Diag> patchDiags(llvm::ArrayRef<Diag> BaselineDiags,
738738
return PatchedDiags;
739739
}
740740

741+
static std::string getPatchName(llvm::StringRef FileName) {
742+
// This shouldn't coincide with any real file name.
743+
llvm::SmallString<128> PatchName;
744+
llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName),
745+
PreamblePatch::HeaderName);
746+
return PatchName.str().str();
747+
}
748+
741749
PreamblePatch PreamblePatch::create(llvm::StringRef FileName,
742750
const ParseInputs &Modified,
743751
const PreambleData &Baseline,
@@ -776,11 +784,7 @@ PreamblePatch PreamblePatch::create(llvm::StringRef FileName,
776784

777785
PreamblePatch PP;
778786
PP.Baseline = &Baseline;
779-
// This shouldn't coincide with any real file name.
780-
llvm::SmallString<128> PatchName;
781-
llvm::sys::path::append(PatchName, llvm::sys::path::parent_path(FileName),
782-
PreamblePatch::HeaderName);
783-
PP.PatchFileName = PatchName.str().str();
787+
PP.PatchFileName = getPatchName(FileName);
784788
PP.ModifiedBounds = ModifiedScan->Bounds;
785789

786790
llvm::raw_string_ostream Patch(PP.PatchContents);
@@ -921,5 +925,13 @@ const MainFileMacros &PreamblePatch::mainFileMacros() const {
921925
return Baseline->Macros;
922926
return PatchedMacros;
923927
}
928+
929+
const FileEntry *PreamblePatch::getPatchEntry(llvm::StringRef MainFilePath,
930+
const SourceManager &SM) {
931+
auto PatchFilePath = getPatchName(MainFilePath);
932+
if (auto File = SM.getFileManager().getFile(PatchFilePath))
933+
return *File;
934+
return nullptr;
935+
}
924936
} // namespace clangd
925937
} // namespace clang

clang-tools-extra/clangd/Preamble.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,19 @@
3030
#include "clang-include-cleaner/Record.h"
3131
#include "index/CanonicalIncludes.h"
3232
#include "support/Path.h"
33+
#include "clang/Basic/SourceManager.h"
3334
#include "clang/Frontend/CompilerInvocation.h"
3435
#include "clang/Frontend/PrecompiledPreamble.h"
3536
#include "clang/Lex/Lexer.h"
3637
#include "clang/Tooling/CompilationDatabase.h"
3738
#include "llvm/ADT/ArrayRef.h"
3839
#include "llvm/ADT/StringRef.h"
3940

41+
#include <cstddef>
42+
#include <functional>
4043
#include <memory>
4144
#include <string>
45+
#include <utility>
4246
#include <vector>
4347

4448
namespace clang {
@@ -135,6 +139,10 @@ class PreamblePatch {
135139
static PreamblePatch createMacroPatch(llvm::StringRef FileName,
136140
const ParseInputs &Modified,
137141
const PreambleData &Baseline);
142+
/// Returns the FileEntry for the preamble patch of MainFilePath in SM, if
143+
/// any.
144+
static const FileEntry *getPatchEntry(llvm::StringRef MainFilePath,
145+
const SourceManager &SM);
138146

139147
/// Adjusts CI (which compiles the modified inputs) to be used with the
140148
/// baseline preamble. This is done by inserting an artifical include to the

clang-tools-extra/clangd/unittests/PreambleTests.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,7 @@ TEST(PreamblePatch, DiagnosticsToPreamble) {
666666
Config Cfg;
667667
Cfg.Diagnostics.AllowStalePreamble = true;
668668
Cfg.Diagnostics.UnusedIncludes = Config::IncludesPolicy::Strict;
669+
Cfg.Diagnostics.MissingIncludes = Config::IncludesPolicy::Strict;
669670
WithContextValue WithCfg(Config::Key, std::move(Cfg));
670671

671672
llvm::StringMap<std::string> AdditionalFiles;
@@ -699,6 +700,8 @@ TEST(PreamblePatch, DiagnosticsToPreamble) {
699700
{
700701
Annotations Code("#define [[FOO]] 1\n");
701702
// Check ranges for notes.
703+
// This also makes sure we don't generate missing-include diagnostics
704+
// because macros are redefined in preamble-patch.
702705
Annotations NewCode(R"(#define BARXYZ 1
703706
#define $foo1[[FOO]] 1
704707
void foo();
@@ -866,6 +869,27 @@ TEST(PreamblePatch, MacroAndMarkHandling) {
866869
}
867870
}
868871

872+
TEST(PreamblePatch, PatchFileEntry) {
873+
Annotations Code(R"cpp(#define FOO)cpp");
874+
Annotations NewCode(R"cpp(
875+
#define BAR
876+
#define FOO)cpp");
877+
{
878+
auto AST = createPatchedAST(Code.code(), Code.code());
879+
EXPECT_EQ(
880+
PreamblePatch::getPatchEntry(AST->tuPath(), AST->getSourceManager()),
881+
nullptr);
882+
}
883+
{
884+
auto AST = createPatchedAST(Code.code(), NewCode.code());
885+
auto *FE =
886+
PreamblePatch::getPatchEntry(AST->tuPath(), AST->getSourceManager());
887+
ASSERT_NE(FE, nullptr);
888+
EXPECT_THAT(FE->getName().str(),
889+
testing::EndsWith(PreamblePatch::HeaderName.str()));
890+
}
891+
}
892+
869893
} // namespace
870894
} // namespace clangd
871895
} // namespace clang

0 commit comments

Comments
 (0)