[llvm] [Support] Use std::filesystem::remove_all() in remove_directories() (PR #119146)

Dmitry Vasilyev via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 9 04:22:25 PST 2024


https://github.com/slydiman updated https://github.com/llvm/llvm-project/pull/119146

>From 3084c7a0593441530fceb01544425bafa0fca261 Mon Sep 17 00:00:00 2001
From: Dmitry Vasilyev <dvassiliev at accesssoftek.com>
Date: Mon, 9 Dec 2024 00:07:33 +0400
Subject: [PATCH 1/3] [Support] Use std::filesystem::remove_all() in
 remove_directories()

See #118677 for details.
---
 llvm/lib/Support/Path.cpp         |  8 +++++++
 llvm/lib/Support/Unix/Path.inc    | 40 -------------------------------
 llvm/lib/Support/Windows/Path.inc | 26 --------------------
 3 files changed, 8 insertions(+), 66 deletions(-)

diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp
index d7752851971030..4c0804f2dd494d 100644
--- a/llvm/lib/Support/Path.cpp
+++ b/llvm/lib/Support/Path.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
 #include <cctype>
+#include <filesystem>
 
 #if !defined(_MSC_VER) && !defined(__MINGW32__)
 #include <unistd.h>
@@ -1206,6 +1207,13 @@ namespace llvm {
 namespace sys {
 namespace fs {
 
+std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
+  const std::filesystem::path Path(path.str());
+  std::error_code EC;
+  std::filesystem::remove_all(Path, EC);
+  return IgnoreErrors ? std::error_code() : EC;
+}
+
 TempFile::TempFile(StringRef Name, int FD)
     : TmpName(std::string(Name)), FD(FD) {}
 TempFile::TempFile(TempFile &&Other) { *this = std::move(Other); }
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 44097bad7b46ed..b8cc6b8bdb464a 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -1272,46 +1272,6 @@ std::error_code closeFile(file_t &F) {
   return Process::SafelyCloseFileDescriptor(TmpF);
 }
 
-template <typename T>
-static std::error_code remove_directories_impl(const T &Entry,
-                                               bool IgnoreErrors) {
-  std::error_code EC;
-  directory_iterator Begin(Entry, EC, false);
-  directory_iterator End;
-  while (Begin != End) {
-    auto &Item = *Begin;
-    ErrorOr<basic_file_status> st = Item.status();
-    if (st) {
-      if (is_directory(*st)) {
-        EC = remove_directories_impl(Item, IgnoreErrors);
-        if (EC && !IgnoreErrors)
-          return EC;
-      }
-
-      EC = fs::remove(Item.path(), true);
-      if (EC && !IgnoreErrors)
-        return EC;
-    } else if (!IgnoreErrors) {
-      return st.getError();
-    }
-
-    Begin.increment(EC);
-    if (EC && !IgnoreErrors)
-      return EC;
-  }
-  return std::error_code();
-}
-
-std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
-  auto EC = remove_directories_impl(path, IgnoreErrors);
-  if (EC && !IgnoreErrors)
-    return EC;
-  EC = fs::remove(path, true);
-  if (EC && !IgnoreErrors)
-    return EC;
-  return std::error_code();
-}
-
 std::error_code real_path(const Twine &path, SmallVectorImpl<char> &dest,
                           bool expand_tilde) {
   dest.clear();
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index c4bd5e24723517..e70576540edaa1 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -1372,32 +1372,6 @@ std::error_code closeFile(file_t &F) {
   return std::error_code();
 }
 
-std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
-  // Convert to utf-16.
-  SmallVector<wchar_t, 128> Path16;
-  std::error_code EC = widenPath(path, Path16);
-  if (EC && !IgnoreErrors)
-    return EC;
-
-  // SHFileOperation() accepts a list of paths, and so must be double null-
-  // terminated to indicate the end of the list.  The buffer is already null
-  // terminated, but since that null character is not considered part of the
-  // vector's size, pushing another one will just consume that byte.  So we
-  // need to push 2 null terminators.
-  Path16.push_back(0);
-  Path16.push_back(0);
-
-  SHFILEOPSTRUCTW shfos = {};
-  shfos.wFunc = FO_DELETE;
-  shfos.pFrom = Path16.data();
-  shfos.fFlags = FOF_NO_UI;
-
-  int result = ::SHFileOperationW(&shfos);
-  if (result != 0 && !IgnoreErrors)
-    return mapWindowsError(result);
-  return std::error_code();
-}
-
 static void expandTildeExpr(SmallVectorImpl<char> &Path) {
   // Path does not begin with a tilde expression.
   if (Path.empty() || Path[0] != '~')

>From a2cda5e4e815d6aaf13359689d2f8be985e6470e Mon Sep 17 00:00:00 2001
From: Dmitry Vasilyev <dvassiliev at accesssoftek.com>
Date: Mon, 9 Dec 2024 00:52:38 +0400
Subject: [PATCH 2/3] Reverted Unix version due to failed
 FileSystemTest.RealPathNoReadPerm.

---
 llvm/lib/Support/Path.cpp         |  8 -------
 llvm/lib/Support/Unix/Path.inc    | 40 +++++++++++++++++++++++++++++++
 llvm/lib/Support/Windows/Path.inc |  8 +++++++
 3 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Support/Path.cpp b/llvm/lib/Support/Path.cpp
index 4c0804f2dd494d..d7752851971030 100644
--- a/llvm/lib/Support/Path.cpp
+++ b/llvm/lib/Support/Path.cpp
@@ -22,7 +22,6 @@
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
 #include <cctype>
-#include <filesystem>
 
 #if !defined(_MSC_VER) && !defined(__MINGW32__)
 #include <unistd.h>
@@ -1207,13 +1206,6 @@ namespace llvm {
 namespace sys {
 namespace fs {
 
-std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
-  const std::filesystem::path Path(path.str());
-  std::error_code EC;
-  std::filesystem::remove_all(Path, EC);
-  return IgnoreErrors ? std::error_code() : EC;
-}
-
 TempFile::TempFile(StringRef Name, int FD)
     : TmpName(std::string(Name)), FD(FD) {}
 TempFile::TempFile(TempFile &&Other) { *this = std::move(Other); }
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index b8cc6b8bdb464a..44097bad7b46ed 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -1272,6 +1272,46 @@ std::error_code closeFile(file_t &F) {
   return Process::SafelyCloseFileDescriptor(TmpF);
 }
 
+template <typename T>
+static std::error_code remove_directories_impl(const T &Entry,
+                                               bool IgnoreErrors) {
+  std::error_code EC;
+  directory_iterator Begin(Entry, EC, false);
+  directory_iterator End;
+  while (Begin != End) {
+    auto &Item = *Begin;
+    ErrorOr<basic_file_status> st = Item.status();
+    if (st) {
+      if (is_directory(*st)) {
+        EC = remove_directories_impl(Item, IgnoreErrors);
+        if (EC && !IgnoreErrors)
+          return EC;
+      }
+
+      EC = fs::remove(Item.path(), true);
+      if (EC && !IgnoreErrors)
+        return EC;
+    } else if (!IgnoreErrors) {
+      return st.getError();
+    }
+
+    Begin.increment(EC);
+    if (EC && !IgnoreErrors)
+      return EC;
+  }
+  return std::error_code();
+}
+
+std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
+  auto EC = remove_directories_impl(path, IgnoreErrors);
+  if (EC && !IgnoreErrors)
+    return EC;
+  EC = fs::remove(path, true);
+  if (EC && !IgnoreErrors)
+    return EC;
+  return std::error_code();
+}
+
 std::error_code real_path(const Twine &path, SmallVectorImpl<char> &dest,
                           bool expand_tilde) {
   dest.clear();
diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index e70576540edaa1..01d01dacfd80fc 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -19,6 +19,7 @@
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/WindowsError.h"
 #include <fcntl.h>
+#include <filesystem>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -1372,6 +1373,13 @@ std::error_code closeFile(file_t &F) {
   return std::error_code();
 }
 
+std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
+  const std::filesystem::path Path(path.str());
+  std::error_code EC;
+  std::filesystem::remove_all(Path, EC);
+  return IgnoreErrors ? std::error_code() : EC;
+}
+
 static void expandTildeExpr(SmallVectorImpl<char> &Path) {
   // Path does not begin with a tilde expression.
   if (Path.empty() || Path[0] != '~')

>From 0dc400a1d9f67b1fba9e8a43997ed70da6c3eb28 Mon Sep 17 00:00:00 2001
From: Dmitry Vasilyev <dvassiliev at accesssoftek.com>
Date: Mon, 9 Dec 2024 16:22:07 +0400
Subject: [PATCH 3/3] Reverted using widenPath().

---
 llvm/lib/Support/Windows/Path.inc | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc
index 01d01dacfd80fc..f433b1824adb6e 100644
--- a/llvm/lib/Support/Windows/Path.inc
+++ b/llvm/lib/Support/Windows/Path.inc
@@ -1374,8 +1374,13 @@ std::error_code closeFile(file_t &F) {
 }
 
 std::error_code remove_directories(const Twine &path, bool IgnoreErrors) {
-  const std::filesystem::path Path(path.str());
-  std::error_code EC;
+  // Convert to utf-16.
+  SmallVector<wchar_t, 128> Path16;
+  std::error_code EC = widenPath(path, Path16);
+  if (EC && !IgnoreErrors)
+    return EC;
+  Path16.push_back(0);
+  const std::filesystem::path Path(Path16.data());
   std::filesystem::remove_all(Path, EC);
   return IgnoreErrors ? std::error_code() : EC;
 }



More information about the llvm-commits mailing list