Improvements to unique_file and createUniqueDirectory.

* Don't try to create parent directories in unique_file. It had two problem:
   * It violates the contract that it is atomic. If the directory creation
     success and the file creation fails, we would return an error but the
     file system was modified.
   * When creating a temporary file clang would have to first check if the
     parent directory existed or not to avoid creating one when it was not
     supposed to.

* More efficient implementations of createUniqueDirectory and the unique_file
  that produces only the file name. Now all 3 just call into a static
  function passing what they want (name, file or directory).

Clang also has to be updated, so tests might fail if a bot picks up this commit
and not the corresponding clang one.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185126 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index 1f4f44a..fa03df5 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -153,6 +153,18 @@
   }
 } // end unnamed namespace
 
+enum FSEntity {
+  FS_Dir,
+  FS_File,
+  FS_Name
+};
+
+// Implemented in Unix/Path.inc and Windows/Path.inc.
+static llvm::error_code
+createUniqueEntity(const llvm::Twine &Model, int &ResultFD,
+                   llvm::SmallVectorImpl<char> &ResultPath,
+                   bool MakeAbsolute, unsigned Mode, FSEntity Type);
+
 namespace llvm {
 namespace sys  {
 namespace path {
@@ -625,32 +637,31 @@
 
 namespace fs {
 
-error_code unique_file(const Twine &Model, SmallVectorImpl<char> &ResultPath,
-                       bool MakeAbsolute) {
-  // FIXME: This is really inefficient. unique_path creates a path an tries to
-  // open it. We should factor the code so that we just don't create/open the
-  // file when we don't need it.
-  int FD;
-  error_code Ret = unique_file(Model, FD, ResultPath, MakeAbsolute, all_read);
-  if (Ret)
-    return Ret;
-
-  if (close(FD))
-    return error_code(errno, system_category());
-
-  StringRef P(ResultPath.begin(), ResultPath.size());
-  return fs::remove(P);
+// This is a mkostemps with a different pattern. Unfortunatelly OS X (ond *BSD)
+// don't have it. It might be worth experimenting with mkostemps on systems
+// that have it.
+error_code unique_file(const Twine &Model, int &ResultFD,
+                       SmallVectorImpl<char> &ResultPath, bool MakeAbsolute,
+                       unsigned Mode) {
+  return createUniqueEntity(Model, ResultFD, ResultPath, MakeAbsolute, Mode,
+                            FS_File);
 }
 
+// This is a mktemp with a differet pattern. We use createUniqueEntity mostly
+// for consistency. It might be worth it experimenting with mktemp.
+error_code unique_file(const Twine &Model, SmallVectorImpl<char> &ResultPath,
+                       bool MakeAbsolute) {
+  int Dummy;
+  return createUniqueEntity(Model, Dummy, ResultPath, MakeAbsolute, 0, FS_Name);
+}
+
+// This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
+// for consistency. It might be worth it experimenting with mkdtemp.
 error_code createUniqueDirectory(const Twine &Prefix,
                                  SmallVectorImpl<char> &ResultPath) {
-  // FIXME: This is double inefficient. We compute a unique file name, created
-  // it, delete it and keep only the directory.
-  error_code EC = unique_file(Prefix + "-%%%%%%/dummy", ResultPath);
-  if (EC)
-    return EC;
-  path::remove_filename(ResultPath);
-  return error_code::success();
+  int Dummy;
+  return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
+                            true, 0, FS_Dir);
 }
 
 error_code make_absolute(SmallVectorImpl<char> &path) {