[clang] [clang-tools-extra] [include-cleaner] Pass WorkingDir to suggestPathToFileForDiagnostics (PR #95114)

kadir çetinkaya via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 11 06:51:29 PDT 2024


https://github.com/kadircet created https://github.com/llvm/llvm-project/pull/95114

Addresses https://github.com/llvm/llvm-project/issues/81215.


>From b15c33b685f80dfe7b0f4865a574276bf1c15b40 Mon Sep 17 00:00:00 2001
From: Kadir Cetinkaya <kadircet at google.com>
Date: Tue, 11 Jun 2024 15:36:15 +0200
Subject: [PATCH] [include-cleaner] Pass WorkingDir to
 suggestPathToFileForDiagnostics

---
 .../include-cleaner/lib/IncludeSpeller.cpp     | 11 +++++++++--
 .../unittests/IncludeSpellerTest.cpp           | 18 ++++++++++++++++++
 clang/include/clang/Testing/TestAST.h          |  4 ++++
 clang/lib/Testing/TestAST.cpp                  |  3 +++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp b/clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp
index 2073f0a1d3d87..8332eb685d652 100644
--- a/clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp
+++ b/clang-tools-extra/include-cleaner/lib/IncludeSpeller.cpp
@@ -9,6 +9,7 @@
 #include "clang-include-cleaner/IncludeSpeller.h"
 #include "clang-include-cleaner/Types.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/Registry.h"
 #include <memory>
@@ -30,8 +31,14 @@ class DefaultIncludeSpeller : public IncludeSpeller {
       return Input.H.verbatim().str();
     case Header::Physical:
       bool IsAngled = false;
+      std::string WorkingDir;
+      if (auto WD = Input.HS.getFileMgr()
+                        .getVirtualFileSystem()
+                        .getCurrentWorkingDirectory())
+        WorkingDir = *WD;
       std::string FinalSpelling = Input.HS.suggestPathToFileForDiagnostics(
-          Input.H.physical(), Input.Main->tryGetRealPathName(), &IsAngled);
+          Input.H.resolvedPath(), WorkingDir, Input.Main->tryGetRealPathName(),
+          &IsAngled);
       return IsAngled ? "<" + FinalSpelling + ">" : "\"" + FinalSpelling + "\"";
     }
     llvm_unreachable("Unknown clang::include_cleaner::Header::Kind enum");
@@ -60,4 +67,4 @@ std::string spellHeader(const IncludeSpeller::Input &Input) {
   return Spelling;
 }
 
-} // namespace clang::include_cleaner
\ No newline at end of file
+} // namespace clang::include_cleaner
diff --git a/clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp b/clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp
index a548868071a12..8f6ad09c46cc4 100644
--- a/clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp
+++ b/clang-tools-extra/include-cleaner/unittests/IncludeSpellerTest.cpp
@@ -89,6 +89,24 @@ TEST(IncludeSpeller, CanOverrideSystemHeaders) {
                          HS, MainFile}));
 }
 
+TEST(IncludeSpeller, RelativeIncludeSearchPath) {
+  TestInputs Inputs;
+
+  Inputs.WorkingDir = "/root/inner";
+  Inputs.ExtraArgs.push_back("-I..");
+  Inputs.ExtraFiles["/root/foo.h"] = "";
+  TestAST AST{Inputs};
+
+  auto &FM = AST.fileManager();
+  auto &HS = AST.preprocessor().getHeaderSearchInfo();
+  const auto *MainFile = AST.sourceManager().getFileEntryForID(
+      AST.sourceManager().getMainFileID());
+
+  EXPECT_EQ("\"foo.h\"",
+            spellHeader(
+                {Header{*FM.getOptionalFileRef("/root/foo.h")}, HS, MainFile}));
+}
+
 IncludeSpellingStrategy::Add<DummyIncludeSpeller>
     Speller("dummy", "Dummy Include Speller");
 
diff --git a/clang/include/clang/Testing/TestAST.h b/clang/include/clang/Testing/TestAST.h
index 845e31f65438b..8878bfbe16984 100644
--- a/clang/include/clang/Testing/TestAST.h
+++ b/clang/include/clang/Testing/TestAST.h
@@ -49,6 +49,10 @@ struct TestInputs {
   /// Keys are plain filenames ("foo.h"), values are file content.
   llvm::StringMap<std::string> ExtraFiles = {};
 
+  /// Root of execution, all relative paths in Args/Files are resolved against
+  /// this.
+  std::string WorkingDir;
+
   /// Filename to use for translation unit. A default will be used when empty.
   std::string FileName;
 
diff --git a/clang/lib/Testing/TestAST.cpp b/clang/lib/Testing/TestAST.cpp
index 3a50c2d9b5d05..fe8b93851613d 100644
--- a/clang/lib/Testing/TestAST.cpp
+++ b/clang/lib/Testing/TestAST.cpp
@@ -13,6 +13,7 @@
 #include "clang/Frontend/TextDiagnostic.h"
 #include "clang/Testing/CommandLineArgs.h"
 #include "llvm/ADT/ScopeExit.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/VirtualFileSystem.h"
 
 #include "gtest/gtest.h"
@@ -106,6 +107,8 @@ TestAST::TestAST(const TestInputs &In) {
 
   // Set up a VFS with only the virtual file visible.
   auto VFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
+  if (auto Err = VFS->setCurrentWorkingDirectory(In.WorkingDir))
+    ADD_FAILURE() << "Failed to setWD: " << Err.message();
   VFS->addFile(Filename, /*ModificationTime=*/0,
                llvm::MemoryBuffer::getMemBufferCopy(In.Code, Filename));
   for (const auto &Extra : In.ExtraFiles)



More information about the cfe-commits mailing list