Skip to content

Commit ab4e461

Browse files
committed
[include-cleaner] allow spelling strategies to customize verbatim/system headers
Our use case is wanting to apply a spelling strategy to rewrite the spellings written in IWYU pragma private directives. Differential Revision: https://reviews.llvm.org/D155671
1 parent f09f0a6 commit ab4e461

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

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

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,44 +23,40 @@ namespace {
2323
class DefaultIncludeSpeller : public IncludeSpeller {
2424
public:
2525
std::string operator()(const Input &Input) const override {
26-
bool IsSystem = false;
27-
std::string FinalSpelling = Input.HS.suggestPathToFileForDiagnostics(
28-
Input.H.physical(), Input.Main->tryGetRealPathName(), &IsSystem);
29-
return IsSystem ? "<" + FinalSpelling + ">" : "\"" + FinalSpelling + "\"";
26+
switch (Input.H.kind()) {
27+
case Header::Standard:
28+
return Input.H.standard().name().str();
29+
case Header::Verbatim:
30+
return Input.H.verbatim().str();
31+
case Header::Physical:
32+
bool IsSystem = false;
33+
std::string FinalSpelling = Input.HS.suggestPathToFileForDiagnostics(
34+
Input.H.physical(), Input.Main->tryGetRealPathName(), &IsSystem);
35+
return IsSystem ? "<" + FinalSpelling + ">" : "\"" + FinalSpelling + "\"";
36+
}
3037
}
3138
};
3239

33-
std::string spellPhysicalHeader(const IncludeSpeller::Input &Input) {
34-
static auto Spellers = [] {
35-
llvm::SmallVector<std::unique_ptr<include_cleaner::IncludeSpeller>> Result;
40+
} // namespace
41+
42+
std::string spellHeader(const IncludeSpeller::Input &Input) {
43+
static auto *Spellers = [] {
44+
auto *Result =
45+
new llvm::SmallVector<std::unique_ptr<include_cleaner::IncludeSpeller>>;
3646
for (const auto &Strategy :
3747
include_cleaner::IncludeSpellingStrategy::entries())
38-
Result.push_back(Strategy.instantiate());
39-
Result.push_back(std::make_unique<DefaultIncludeSpeller>());
48+
Result->push_back(Strategy.instantiate());
49+
Result->push_back(std::make_unique<DefaultIncludeSpeller>());
4050
return Result;
4151
}();
4252

4353
std::string Spelling;
44-
for (const auto &Speller : Spellers) {
54+
for (const auto &Speller : *Spellers) {
4555
Spelling = (*Speller)(Input);
4656
if (!Spelling.empty())
4757
break;
4858
}
4959
return Spelling;
5060
}
51-
} // namespace
5261

53-
std::string spellHeader(const IncludeSpeller::Input &Input) {
54-
const Header &H = Input.H;
55-
switch (H.kind()) {
56-
case Header::Standard:
57-
return H.standard().name().str();
58-
case Header::Verbatim:
59-
return H.verbatim().str();
60-
case Header::Physical:
61-
// Spelling physical headers allows for various plug-in strategies.
62-
return spellPhysicalHeader(Input);
63-
}
64-
llvm_unreachable("Unknown Header kind");
65-
}
6662
} // namespace clang::include_cleaner

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "clang-include-cleaner/Types.h"
1212
#include "clang/Lex/Preprocessor.h"
1313
#include "clang/Testing/TestAST.h"
14+
#include "clang/Tooling/Inclusions/StandardLibrary.h"
1415
#include "llvm/ADT/SmallString.h"
1516
#include "llvm/ADT/StringRef.h"
1617
#include "llvm/Support/Path.h"
@@ -42,6 +43,10 @@ std::string testPath(llvm::StringRef File) {
4243
class DummyIncludeSpeller : public IncludeSpeller {
4344
public:
4445
std::string operator()(const IncludeSpeller::Input &Input) const override {
46+
if (Input.H.kind() == Header::Standard)
47+
return "<bits/stdc++.h>";
48+
if (Input.H.kind() != Header::Physical)
49+
return "";
4550
llvm::StringRef AbsolutePath = Input.H.physical()->tryGetRealPathName();
4651
std::string RootWithSeparator{testRoot()};
4752
RootWithSeparator += llvm::sys::path::get_separator();
@@ -71,6 +76,16 @@ TEST(IncludeSpeller, IsRelativeToTestRoot) {
7176
spellHeader({Header{*FM.getFile("dir/header.h")}, HS, MainFile}));
7277
}
7378

79+
TEST(IncludeSpeller, CanOverrideSystemHeaders) {
80+
TestAST AST("");
81+
auto &HS = AST.preprocessor().getHeaderSearchInfo();
82+
const auto *MainFile = AST.sourceManager().getFileEntryForID(
83+
AST.sourceManager().getMainFileID());
84+
EXPECT_EQ("<bits/stdc++.h>",
85+
spellHeader({Header{*tooling::stdlib::Header::named("<vector>")},
86+
HS, MainFile}));
87+
}
88+
7489
IncludeSpellingStrategy::Add<DummyIncludeSpeller>
7590
Speller("dummy", "Dummy Include Speller");
7691

0 commit comments

Comments
 (0)