diff options
author | Daniel Dunbar <daniel@zuster.org> | 2012-03-03 00:36:02 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2012-03-03 00:36:02 +0000 |
commit | 12f28ab8a53d7743081d607617309891fa8156f3 (patch) | |
tree | 1c2b891d7cfc7eccc8180af44e44f144d559d124 | |
parent | 0d95dfcc0e07a81596ab7c3e9e86ab663fd4541c (diff) |
Frontend: Don't automatically create missing directories when using temporary files with createOutputFile()
- 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
-rw-r--r-- | include/clang/Frontend/CompilerInstance.h | 8 | ||||
-rw-r--r-- | lib/Frontend/CompilerInstance.cpp | 26 | ||||
-rw-r--r-- | lib/Frontend/FrontendActions.cpp | 3 |
3 files changed, 28 insertions, 9 deletions
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 1c7b7d54fd..4ee90dfb9c 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -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); diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 2ade1c17e1..a7855112e6 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -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; diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp index 96b0b831ea..a4e168b702 100644 --- a/lib/Frontend/FrontendActions.cpp +++ b/lib/Frontend/FrontendActions.cpp @@ -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; |