Skip to content

Commit 4397433

Browse files
committed
[include-cleaner] Unify always_keep with rest of the keep logic
Depends on D156122 Differential Revision: https://reviews.llvm.org/D156123
1 parent 778a5e9 commit 4397433

File tree

7 files changed

+59
-74
lines changed

7 files changed

+59
-74
lines changed

clang-tools-extra/clang-tidy/misc/IncludeCleanerCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ void IncludeCleanerCheck::check(const MatchFinder::MatchResult &Result) {
143143
RecordedPreprocessor.Includes.all()) {
144144
if (Used.contains(&I) || !I.Resolved)
145145
continue;
146-
if (RecordedPI.shouldKeep(I.Line) || RecordedPI.shouldKeep(*I.Resolved))
146+
if (RecordedPI.shouldKeep(*I.Resolved))
147147
continue;
148148
// Check if main file is the public interface for a private header. If so
149149
// we shouldn't diagnose it as unused.

clang-tools-extra/clangd/IncludeCleaner.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ bool mayConsiderUnused(const Inclusion &Inc, ParsedAST &AST,
7575
auto FE = AST.getSourceManager().getFileManager().getFileRef(
7676
AST.getIncludeStructure().getRealPath(HID));
7777
assert(FE);
78-
if (PI && (PI->shouldKeep(Inc.HashLine + 1) || PI->shouldKeep(*FE)))
78+
if (PI && PI->shouldKeep(*FE))
7979
return false;
8080
// FIXME(kirillbobyrev): We currently do not support the umbrella headers.
8181
// System headers are likely to be standard library headers.

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#include "TestTU.h"
1616
#include "clang-include-cleaner/Analysis.h"
1717
#include "clang-include-cleaner/Types.h"
18-
#include "support/Context.h"
1918
#include "clang/AST/DeclBase.h"
2019
#include "clang/Basic/SourceManager.h"
2120
#include "clang/Tooling/Syntax/Tokens.h"
@@ -26,13 +25,11 @@
2625
#include "llvm/Support/Casting.h"
2726
#include "llvm/Support/Error.h"
2827
#include "llvm/Support/ScopedPrinter.h"
29-
#include "llvm/Testing/Support/SupportHelpers.h"
3028
#include "gmock/gmock.h"
3129
#include "gtest/gtest.h"
3230
#include <cstddef>
3331
#include <optional>
3432
#include <string>
35-
#include <utility>
3633
#include <vector>
3734

3835
namespace clang {

clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ class PragmaIncludes {
5959

6060
/// Returns true if the given #include of the main-file should never be
6161
/// removed.
62-
bool shouldKeep(unsigned HashLineNumber) const;
6362
bool shouldKeep(const FileEntry *FE) const;
6463

6564
/// Returns the public mapping include for the given physical header file.
@@ -81,10 +80,6 @@ class PragmaIncludes {
8180

8281
private:
8382
class RecordPragma;
84-
/// 1-based Line numbers for the #include directives of the main file that
85-
/// should always keep (e.g. has the `IWYU pragma: keep` or `IWYU pragma:
86-
/// export` right after).
87-
llvm::DenseSet</*LineNumber*/ unsigned> ShouldKeep;
8883

8984
/// The public header mapping by the IWYU private pragma. For private pragmas
9085
// without public mapping an empty StringRef is stored.
@@ -112,8 +107,10 @@ class PragmaIncludes {
112107

113108
/// Contains all non self-contained files detected during the parsing.
114109
llvm::DenseSet<llvm::sys::fs::UniqueID> NonSelfContainedFiles;
115-
// Files with an always_keep pragma.
116-
llvm::DenseSet<llvm::sys::fs::UniqueID> AlwaysKeep;
110+
// Files whose inclusions shouldn't be dropped. E.g. because they have an
111+
// always_keep pragma or because user marked particular includes with
112+
// keep/export pragmas in the main file.
113+
llvm::DenseSet<llvm::sys::fs::UniqueID> ShouldKeep;
117114

118115
/// Owns the strings.
119116
llvm::BumpPtrAllocator Arena;

clang-tools-extra/include-cleaner/lib/Analysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ analyze(llvm::ArrayRef<Decl *> ASTRoots,
9191
HeaderFilter(I.Resolved->getFileEntry().tryGetRealPathName()))
9292
continue;
9393
if (PI) {
94-
if (PI->shouldKeep(I.Line) || PI->shouldKeep(*I.Resolved))
94+
if (PI->shouldKeep(*I.Resolved))
9595
continue;
9696
// Check if main file is the public interface for a private header. If so
9797
// we shouldn't diagnose it as unused.

clang-tools-extra/include-cleaner/lib/Record.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,13 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
219219
}
220220
if (!IncludedHeader && File)
221221
IncludedHeader = &File->getFileEntry();
222-
checkForExport(HashFID, HashLine, std::move(IncludedHeader));
223-
checkForKeep(HashLine);
222+
checkForExport(HashFID, HashLine, std::move(IncludedHeader), File);
223+
checkForKeep(HashLine, File);
224224
}
225225

226226
void checkForExport(FileID IncludingFile, int HashLine,
227-
std::optional<Header> IncludedHeader) {
227+
std::optional<Header> IncludedHeader,
228+
OptionalFileEntryRef IncludedFile) {
228229
if (ExportStack.empty())
229230
return;
230231
auto &Top = ExportStack.back();
@@ -248,20 +249,22 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
248249
}
249250
}
250251
// main-file #include with export pragma should never be removed.
251-
if (Top.SeenAtFile == SM.getMainFileID())
252-
Out->ShouldKeep.insert(HashLine);
252+
if (Top.SeenAtFile == SM.getMainFileID() && IncludedFile)
253+
Out->ShouldKeep.insert(IncludedFile->getUniqueID());
253254
}
254255
if (!Top.Block) // Pop immediately for single-line export pragma.
255256
ExportStack.pop_back();
256257
}
257258

258-
void checkForKeep(int HashLine) {
259+
void checkForKeep(int HashLine, OptionalFileEntryRef IncludedFile) {
259260
if (!InMainFile || KeepStack.empty())
260261
return;
261262
KeepPragma &Top = KeepStack.back();
262263
// Check if the current include is covered by a keep pragma.
263-
if ((Top.Block && HashLine > Top.SeenAtLine) || Top.SeenAtLine == HashLine)
264-
Out->ShouldKeep.insert(HashLine);
264+
if (IncludedFile && ((Top.Block && HashLine > Top.SeenAtLine) ||
265+
Top.SeenAtLine == HashLine)) {
266+
Out->ShouldKeep.insert(IncludedFile->getUniqueID());
267+
}
265268

266269
if (!Top.Block)
267270
KeepStack.pop_back(); // Pop immediately for single-line keep pragma.
@@ -321,7 +324,7 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
321324
return false;
322325
}
323326
if (Pragma->consume_front("always_keep")) {
324-
Out->AlwaysKeep.insert(CommentUID);
327+
Out->ShouldKeep.insert(CommentUID);
325328
return false;
326329
}
327330
return false;
@@ -418,12 +421,8 @@ bool PragmaIncludes::isPrivate(const FileEntry *FE) const {
418421
return IWYUPublic.contains(FE->getUniqueID());
419422
}
420423

421-
bool PragmaIncludes::shouldKeep(unsigned HashLineNumber) const {
422-
return ShouldKeep.contains(HashLineNumber);
423-
}
424-
425424
bool PragmaIncludes::shouldKeep(const FileEntry *FE) const {
426-
return AlwaysKeep.contains(FE->getUniqueID());
425+
return ShouldKeep.contains(FE->getUniqueID());
427426
}
428427

429428
namespace {

clang-tools-extra/include-cleaner/unittests/RecordTest.cpp

Lines changed: 39 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
#include "clang/Testing/TestAST.h"
1414
#include "clang/Tooling/Inclusions/StandardLibrary.h"
1515
#include "llvm/ADT/ArrayRef.h"
16+
#include "llvm/ADT/StringRef.h"
1617
#include "llvm/Support/raw_ostream.h"
1718
#include "llvm/Testing/Annotations/Annotations.h"
1819
#include "gmock/gmock.h"
1920
#include "gtest/gtest.h"
21+
#include <cassert>
2022

2123
namespace clang::include_cleaner {
2224
namespace {
@@ -309,68 +311,58 @@ class PragmaIncludeTest : public ::testing::Test {
309311
};
310312

311313
TEST_F(PragmaIncludeTest, IWYUKeep) {
312-
llvm::Annotations MainFile(R"cpp(
313-
$keep1^#include "keep1.h" // IWYU pragma: keep
314-
$keep2^#include "keep2.h" /* IWYU pragma: keep */
314+
Inputs.Code = R"cpp(
315+
#include "keep1.h" // IWYU pragma: keep
316+
#include "keep2.h" /* IWYU pragma: keep */
315317
316-
$export1^#include "export1.h" // IWYU pragma: export
317-
$begin_exports^// IWYU pragma: begin_exports
318-
$export2^#include "export2.h"
319-
$export3^#include "export3.h"
320-
$end_exports^// IWYU pragma: end_exports
318+
#include "export1.h" // IWYU pragma: export
319+
// IWYU pragma: begin_exports
320+
#include "export2.h"
321+
#include "export3.h"
322+
// IWYU pragma: end_exports
321323
322-
$normal^#include "normal.h"
324+
#include "normal.h"
323325
324-
$begin_keep^// IWYU pragma: begin_keep
325-
$keep3^#include "keep3.h"
326-
$end_keep^// IWYU pragma: end_keep
326+
// IWYU pragma: begin_keep
327+
#include "keep3.h"
328+
// IWYU pragma: end_keep
327329
328-
// IWYU pragma: begin_keep
329-
$keep4^#include "keep4.h"
330330
// IWYU pragma: begin_keep
331-
$keep5^#include "keep5.h"
331+
#include "keep4.h"
332+
// IWYU pragma: begin_keep
333+
#include "keep5.h"
332334
// IWYU pragma: end_keep
333-
$keep6^#include "keep6.h"
335+
#include "keep6.h"
334336
// IWYU pragma: end_keep
335-
)cpp");
336-
337-
auto OffsetToLineNum = [&MainFile](size_t Offset) {
338-
int Count = MainFile.code().substr(0, Offset).count('\n');
339-
return Count + 1;
340-
};
341-
342-
Inputs.Code = MainFile.code();
337+
#include <vector>
338+
#include <map> // IWYU pragma: keep
339+
#include <set> // IWYU pragma: export
340+
)cpp";
343341
createEmptyFiles({"keep1.h", "keep2.h", "keep3.h", "keep4.h", "keep5.h",
344342
"keep6.h", "export1.h", "export2.h", "export3.h",
345-
"normal.h"});
343+
"normal.h", "std/vector", "std/map", "std/set"});
346344

345+
Inputs.ExtraArgs.push_back("-isystemstd");
347346
TestAST Processed = build();
348-
EXPECT_FALSE(PI.shouldKeep(1));
349-
350-
// Keep
351-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep1"))));
352-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep2"))));
347+
auto &FM = Processed.fileManager();
353348

354-
EXPECT_FALSE(PI.shouldKeep(
355-
OffsetToLineNum(MainFile.point("begin_keep")))); // no # directive
356-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep3"))));
357-
EXPECT_FALSE(PI.shouldKeep(
358-
OffsetToLineNum(MainFile.point("end_keep")))); // no # directive
349+
EXPECT_FALSE(PI.shouldKeep(FM.getFile("normal.h").get()));
350+
EXPECT_FALSE(PI.shouldKeep(FM.getFile("std/vector").get()));
359351

360-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep4"))));
361-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep5"))));
362-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("keep6"))));
352+
// Keep
353+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep1.h").get()));
354+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep2.h").get()));
355+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep3.h").get()));
356+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep4.h").get()));
357+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep5.h").get()));
358+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("keep6.h").get()));
359+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("std/map").get()));
363360

364361
// Exports
365-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export1"))));
366-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export2"))));
367-
EXPECT_TRUE(PI.shouldKeep(OffsetToLineNum(MainFile.point("export3"))));
368-
EXPECT_FALSE(PI.shouldKeep(
369-
OffsetToLineNum(MainFile.point("begin_exports")))); // no # directive
370-
EXPECT_FALSE(PI.shouldKeep(
371-
OffsetToLineNum(MainFile.point("end_exports")))); // no # directive
372-
373-
EXPECT_FALSE(PI.shouldKeep(OffsetToLineNum(MainFile.point("normal"))));
362+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("export1.h").get()));
363+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("export2.h").get()));
364+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("export3.h").get()));
365+
EXPECT_TRUE(PI.shouldKeep(FM.getFile("std/set").get()));
374366
}
375367

376368
TEST_F(PragmaIncludeTest, IWYUPrivate) {

0 commit comments

Comments
 (0)