[clang-tools-extra] ab4e461 - [include-cleaner] allow spelling strategies to customize verbatim/system headers
Sam McCall via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 21 17:41:04 PDT 2023
Author: Sam McCall
Date: 2023-07-22T02:36:29+02:00
New Revision: ab4e461353bb16e538aca260121533fec7e0678c
URL: https://github.com/llvm/llvm-project/commit/ab4e461353bb16e538aca260121533fec7e0678c
DIFF: https://github.com/llvm/llvm-project/commit/ab4e461353bb16e538aca260121533fec7e0678c.diff
LOG: [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
Added:
Modified:
clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp
clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp b/clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp
index e29a8104c0ae85..8e6143820a2b73 100644
--- a/clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp
+++ b/clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp
@@ -23,44 +23,40 @@ namespace {
class DefaultIncludeSpeller : public IncludeSpeller {
public:
std::string operator()(const Input &Input) const override {
- bool IsSystem = false;
- std::string FinalSpelling = Input.HS.suggestPathToFileForDiagnostics(
- Input.H.physical(), Input.Main->tryGetRealPathName(), &IsSystem);
- return IsSystem ? "<" + FinalSpelling + ">" : "\"" + FinalSpelling + "\"";
+ switch (Input.H.kind()) {
+ case Header::Standard:
+ return Input.H.standard().name().str();
+ case Header::Verbatim:
+ return Input.H.verbatim().str();
+ case Header::Physical:
+ bool IsSystem = false;
+ std::string FinalSpelling = Input.HS.suggestPathToFileForDiagnostics(
+ Input.H.physical(), Input.Main->tryGetRealPathName(), &IsSystem);
+ return IsSystem ? "<" + FinalSpelling + ">" : "\"" + FinalSpelling + "\"";
+ }
}
};
-std::string spellPhysicalHeader(const IncludeSpeller::Input &Input) {
- static auto Spellers = [] {
- llvm::SmallVector<std::unique_ptr<include_cleaner::IncludeSpeller>> Result;
+} // namespace
+
+std::string spellHeader(const IncludeSpeller::Input &Input) {
+ static auto *Spellers = [] {
+ auto *Result =
+ new llvm::SmallVector<std::unique_ptr<include_cleaner::IncludeSpeller>>;
for (const auto &Strategy :
include_cleaner::IncludeSpellingStrategy::entries())
- Result.push_back(Strategy.instantiate());
- Result.push_back(std::make_unique<DefaultIncludeSpeller>());
+ Result->push_back(Strategy.instantiate());
+ Result->push_back(std::make_unique<DefaultIncludeSpeller>());
return Result;
}();
std::string Spelling;
- for (const auto &Speller : Spellers) {
+ for (const auto &Speller : *Spellers) {
Spelling = (*Speller)(Input);
if (!Spelling.empty())
break;
}
return Spelling;
}
-} // namespace
-std::string spellHeader(const IncludeSpeller::Input &Input) {
- const Header &H = Input.H;
- switch (H.kind()) {
- case Header::Standard:
- return H.standard().name().str();
- case Header::Verbatim:
- return H.verbatim().str();
- case Header::Physical:
- // Spelling physical headers allows for various plug-in strategies.
- return spellPhysicalHeader(Input);
- }
- llvm_unreachable("Unknown Header kind");
-}
} // namespace clang::include_cleaner
\ No newline at end of file
diff --git a/clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp b/clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp
index 1dd4d28ed81be7..361320a2f48f38 100644
--- a/clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp
@@ -11,6 +11,7 @@
#include "clang-include-cleaner/Types.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Testing/TestAST.h"
+#include "clang/Tooling/Inclusions/StandardLibrary.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Path.h"
@@ -42,6 +43,10 @@ std::string testPath(llvm::StringRef File) {
class DummyIncludeSpeller : public IncludeSpeller {
public:
std::string operator()(const IncludeSpeller::Input &Input) const override {
+ if (Input.H.kind() == Header::Standard)
+ return "<bits/stdc++.h>";
+ if (Input.H.kind() != Header::Physical)
+ return "";
llvm::StringRef AbsolutePath = Input.H.physical()->tryGetRealPathName();
std::string RootWithSeparator{testRoot()};
RootWithSeparator += llvm::sys::path::get_separator();
@@ -71,6 +76,16 @@ TEST(IncludeSpeller, IsRelativeToTestRoot) {
spellHeader({Header{*FM.getFile("dir/header.h")}, HS, MainFile}));
}
+TEST(IncludeSpeller, CanOverrideSystemHeaders) {
+ TestAST AST("");
+ auto &HS = AST.preprocessor().getHeaderSearchInfo();
+ const auto *MainFile = AST.sourceManager().getFileEntryForID(
+ AST.sourceManager().getMainFileID());
+ EXPECT_EQ("<bits/stdc++.h>",
+ spellHeader({Header{*tooling::stdlib::Header::named("<vector>")},
+ HS, MainFile}));
+}
+
IncludeSpellingStrategy::Add<DummyIncludeSpeller>
Speller("dummy", "Dummy Include Speller");
More information about the cfe-commits
mailing list