GraphWriter: Provide an API for writing a graph into a specified file
authorGeorge Karpenkov <ekarpenkov@apple.com>
Fri, 28 Sep 2018 18:49:01 +0000 (18:49 +0000)
committerGeorge Karpenkov <ekarpenkov@apple.com>
Fri, 28 Sep 2018 18:49:01 +0000 (18:49 +0000)
Always generating a temporary file is not always suitable, especially for tests

Differential Revision: https://reviews.llvm.org/D52636

llvm-svn: 343351

llvm/include/llvm/Support/GraphWriter.h

index c9a9f40..02d98be 100644 (file)
@@ -27,6 +27,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/DOTGraphTraits.h"
+#include "llvm/Support/FileSystem.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cstddef>
@@ -320,14 +321,32 @@ raw_ostream &WriteGraph(raw_ostream &O, const GraphType &G,
 
 std::string createGraphFilename(const Twine &Name, int &FD);
 
+/// Writes graph into a provided {@code Filename}.
+/// If {@code Filename} is empty, generates a random one.
+/// \return The resulting filename, or an empty string if writing
+/// failed.
 template <typename GraphType>
 std::string WriteGraph(const GraphType &G, const Twine &Name,
-                       bool ShortNames = false, const Twine &Title = "") {
+                       bool ShortNames = false,
+                       const Twine &Title = "",
+                       std::string Filename = "") {
   int FD;
   // Windows can't always handle long paths, so limit the length of the name.
   std::string N = Name.str();
   N = N.substr(0, std::min<std::size_t>(N.size(), 140));
-  std::string Filename = createGraphFilename(N, FD);
+  if (Filename.empty()) {
+    Filename = createGraphFilename(N, FD);
+  } else {
+    std::error_code EC = sys::fs::openFileForWrite(Filename, FD);
+
+    // Writing over an existing file is not considered an error.
+    if (EC == std::errc::file_exists) {
+      errs() << "file exists, overwriting" << "\n";
+    } else if (EC) {
+      errs() << "error writing into file" << "\n";
+      return "";
+    }
+  }
   raw_fd_ostream O(FD, /*shouldClose=*/ true);
 
   if (FD == -1) {