<div>This makes the case of removing a file faster, but removing a directory slower, because you’ve essentially got 2 stats for a directory.<br><br><div dir="auto">It may be possible to knock all of this out in one call.</div></div><div dir="auto"><br></div><div dir="auto">Can you try calling CreateFile with</div><div dir="auto"><br></div><div dir="auto">FILE_FLAG_OPEN_REPARSE_POINT // Don’t follow symlinks</div><div dir="auto">| FILE_FLAG_BACKUP_SEMANTICS // Allow opening a directory </div><div dir="auto">| FILE_FLAG_DELETE_ON_CLOSE // Delete it</div><div dir="auto"><br></div><div dir="auto">Not sure if the last two options can be used together, but seems worth a try</div><div><br><div class="gmail_quote"><div>On Mon, Oct 9, 2017 at 9:35 PM Peter Collingbourne via Phabricator <<a href="mailto:reviews@reviews.llvm.org" target="_blank">reviews@reviews.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">pcc created this revision.<br>
Herald added a subscriber: hiraditya.<br>
<br>
This saves a call to stat().<br>
<br>
<br>
<a href="https://reviews.llvm.org/D38715" rel="noreferrer" target="_blank">https://reviews.llvm.org/D38715</a><br>
<br>
Files:<br>
  llvm/lib/Support/Windows/Path.inc<br>
<br>
<br>
Index: llvm/lib/Support/Windows/Path.inc<br>
===================================================================<br>
--- llvm/lib/Support/Windows/Path.inc<br>
+++ llvm/lib/Support/Windows/Path.inc<br>
@@ -259,26 +259,21 @@<br>
 std::error_code remove(const Twine &path, bool IgnoreNonExisting) {<br>
   SmallVector<wchar_t, 128> path_utf16;<br>
<br>
-  file_status ST;<br>
-  if (std::error_code EC = status(path, ST)) {<br>
-    if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)<br>
-      return EC;<br>
-    return std::error_code();<br>
-  }<br>
-<br>
   if (std::error_code ec = widenPath(path, path_utf16))<br>
     return ec;<br>
<br>
-  if (ST.type() == file_type::directory_file) {<br>
-    if (!::RemoveDirectoryW(c_str(path_utf16))) {<br>
-      std::error_code EC = mapWindowsError(::GetLastError());<br>
-      if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)<br>
-        return EC;<br>
-    }<br>
-    return std::error_code();<br>
-  }<br>
+  // Speculate that the path is actually a file in order to save a stat() call.<br>
   if (!::DeleteFileW(c_str(path_utf16))) {<br>
     std::error_code EC = mapWindowsError(::GetLastError());<br>
+    if (EC == errc::permission_denied) {<br>
+      if (!::RemoveDirectoryW(c_str(path_utf16))) {<br>
+        std::error_code EC = mapWindowsError(::GetLastError());<br>
+        if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)<br>
+          return EC;<br>
+      }<br>
+      return std::error_code();<br>
+    }<br>
+<br>
     if (EC != errc::no_such_file_or_directory || !IgnoreNonExisting)<br>
       return EC;<br>
   }<br>
<br>
<br>
</blockquote></div></div>