[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