]> granicus.if.org Git - clang/commitdiff
Frontend: Don't automatically create missing directories when using temporary files...
authorDaniel Dunbar <daniel@zuster.org>
Sat, 3 Mar 2012 00:36:02 +0000 (00:36 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sat, 3 Mar 2012 00:36:02 +0000 (00:36 +0000)
 - This would otherwise happen as a side effect of llvm::sys::fs::unique_file creating parent directories.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151960 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/CompilerInstance.h
lib/Frontend/CompilerInstance.cpp
lib/Frontend/FrontendActions.cpp

index 1c7b7d54fda01c5376a98c825f062f8c71fec99a..4ee90dfb9cd21994f91018d4d653dd57ed89a733 100644 (file)
@@ -586,7 +586,8 @@ public:
                    bool Binary = true, bool RemoveFileOnSignal = true,
                    StringRef BaseInput = "",
                    StringRef Extension = "",
-                   bool UseTemporary = false);
+                   bool UseTemporary = false,
+                   bool CreateMissingDirectories = false);
 
   /// Create a new output file, optionally deriving the output path name.
   ///
@@ -606,7 +607,9 @@ public:
   /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for
   /// multithreaded use, as the underlying signal mechanism is not reentrant
   /// \param UseTemporary - Create a new temporary file that must be renamed to
-  ///         OutputPath in the end
+  /// OutputPath in the end.
+  /// \param CreateMissingDirectories - When \arg UseTemporary is true, create
+  /// missing directories in the output path.
   /// \param ResultPathName [out] - If given, the result path name will be
   /// stored here on success.
   /// \param TempPathName [out] - If given, the temporary file path name
@@ -617,6 +620,7 @@ public:
                    StringRef BaseInput = "",
                    StringRef Extension = "",
                    bool UseTemporary = false,
+                   bool CreateMissingDirectories = false,
                    std::string *ResultPathName = 0,
                    std::string *TempPathName = 0);
 
index 2ade1c17e13b6c7e32f80d803ae12f61763afe0e..a7855112e65de880908b802ac4085a646d3b7c27 100644 (file)
@@ -478,12 +478,14 @@ CompilerInstance::createOutputFile(StringRef OutputPath,
                                    bool Binary, bool RemoveFileOnSignal,
                                    StringRef InFile,
                                    StringRef Extension,
-                                   bool UseTemporary) {
+                                   bool UseTemporary,
+                                   bool CreateMissingDirectories) {
   std::string Error, OutputPathName, TempPathName;
   llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary,
                                               RemoveFileOnSignal,
                                               InFile, Extension,
                                               UseTemporary,
+                                              CreateMissingDirectories,
                                               &OutputPathName,
                                               &TempPathName);
   if (!OS) {
@@ -508,8 +510,12 @@ CompilerInstance::createOutputFile(StringRef OutputPath,
                                    StringRef InFile,
                                    StringRef Extension,
                                    bool UseTemporary,
+                                   bool CreateMissingDirectories,
                                    std::string *ResultPathName,
                                    std::string *TempPathName) {
+  assert((!CreateMissingDirectories || UseTemporary) &&
+         "CreateMissingDirectories is only allowed when using temporary files");
+
   std::string OutFile, TempFile;
   if (!OutputPath.empty()) {
     OutFile = OutputPath;
@@ -528,12 +534,20 @@ CompilerInstance::createOutputFile(StringRef OutputPath,
   std::string OSFile;
 
   if (UseTemporary && OutFile != "-") {
-    llvm::sys::Path OutPath(OutFile);
-    // Only create the temporary if we can actually write to OutPath, otherwise
-    // we want to fail early.
+    // Only create the temporary if the parent directory exists (or create
+    // missing directories is true) and we can actually write to OutPath,
+    // otherwise we want to fail early.
+    SmallString<256> AbsPath(OutputPath);
+    llvm::sys::fs::make_absolute(AbsPath);
+    llvm::sys::Path OutPath(AbsPath);
+    bool ParentExists = false;
+    if (llvm::sys::fs::exists(llvm::sys::path::parent_path(AbsPath.str()),
+                              ParentExists))
+      ParentExists = false;
     bool Exists;
-    if ((llvm::sys::fs::exists(OutPath.str(), Exists) || !Exists) ||
-        (OutPath.isRegularFile() && OutPath.canWrite())) {
+    if ((CreateMissingDirectories || ParentExists) &&
+        ((llvm::sys::fs::exists(AbsPath.str(), Exists) || !Exists) ||
+         (OutPath.isRegularFile() && OutPath.canWrite()))) {
       // Create a temporary file.
       SmallString<128> TempPath;
       TempPath = OutFile;
index 96b0b831ea5c03b43aef2607d0d45e4eb93ed85c..a4e168b702b6ad129abcb7363d38e92313260313 100644 (file)
@@ -340,7 +340,8 @@ bool GenerateModuleAction::ComputeASTConsumerArguments(CompilerInstance &CI,
   // We use a temporary to avoid race conditions.
   OS = CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
                            /*RemoveFileOnSignal=*/false, InFile,
-                           /*Extension=*/"", /*useTemporary=*/true);
+                           /*Extension=*/"", /*useTemporary=*/true,
+                           /*CreateMissingDirectories=*/true);
   if (!OS)
     return true;