diff options
author | Kadir Cetinkaya <kadircet@google.com> | 2019-11-29 15:37:14 +0100 |
---|---|---|
committer | Kadir Cetinkaya <kadircet@google.com> | 2019-12-04 15:13:12 +0100 |
commit | 75656005dbc8866e1888932a68a830b0df403560 (patch) | |
tree | e8fab392d5c236a8c49e5ab1b6577d5f187db64f /llvm/lib/Support/CommandLine.cpp | |
parent | 45ef055d4ffda4d2b04b62f73e36cc6d5252758b (diff) | |
download | bcm5719-llvm-75656005dbc8866e1888932a68a830b0df403560.tar.gz bcm5719-llvm-75656005dbc8866e1888932a68a830b0df403560.zip |
[llvm][Support] Take in CurrentDirectory as a parameter in ExpandResponseFiles
Summary:
This is a follow-up to D70769 and D70222, which allows propagation of
current directory down to ExpandResponseFiles for handling of relative paths.
Previously clients had to mutate FS to achieve that, which is not thread-safe
and can even be thread-hostile in the case of real file system.
Reviewers: sammccall
Subscribers: hiraditya, cfe-commits, llvm-commits
Tags: #clang, #llvm
Differential Revision: https://reviews.llvm.org/D70857
Diffstat (limited to 'llvm/lib/Support/CommandLine.cpp')
-rw-r--r-- | llvm/lib/Support/CommandLine.cpp | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index daeab6fade5..1f424075d47 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" @@ -42,6 +43,7 @@ #include "llvm/Support/raw_ostream.h" #include <cstdlib> #include <map> +#include <string> using namespace llvm; using namespace cl; @@ -1045,14 +1047,12 @@ static bool hasUTF8ByteOrderMark(ArrayRef<char> S) { return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf'); } -static llvm::Error ExpandResponseFile(StringRef FName, StringSaver &Saver, - TokenizerCallback Tokenizer, - SmallVectorImpl<const char *> &NewArgv, - bool MarkEOLs, bool RelativeNames, - llvm::vfs::FileSystem &FS) { - llvm::ErrorOr<std::string> CurrDirOrErr = FS.getCurrentWorkingDirectory(); - if (!CurrDirOrErr) - return llvm::errorCodeToError(CurrDirOrErr.getError()); +// FName must be an absolute path. +static llvm::Error ExpandResponseFile( + StringRef FName, StringSaver &Saver, TokenizerCallback Tokenizer, + SmallVectorImpl<const char *> &NewArgv, bool MarkEOLs, bool RelativeNames, + llvm::vfs::FileSystem &FS) { + assert(sys::path::is_absolute(FName)); llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = FS.getBufferForFile(FName); if (!MemBufOrErr) @@ -1078,28 +1078,28 @@ static llvm::Error ExpandResponseFile(StringRef FName, StringSaver &Saver, // Tokenize the contents into NewArgv. Tokenizer(Str, Saver, NewArgv, MarkEOLs); + if (!RelativeNames) + return Error::success(); + llvm::StringRef BasePath = llvm::sys::path::parent_path(FName); // If names of nested response files should be resolved relative to including // file, replace the included response file names with their full paths // obtained by required resolution. - if (RelativeNames) - for (unsigned I = 0; I < NewArgv.size(); ++I) - if (NewArgv[I]) { - StringRef Arg = NewArgv[I]; - if (Arg.front() == '@') { - StringRef FileName = Arg.drop_front(); - if (llvm::sys::path::is_relative(FileName)) { - SmallString<128> ResponseFile; - ResponseFile.append(1, '@'); - if (llvm::sys::path::is_relative(FName)) { - ResponseFile.append(CurrDirOrErr.get()); - } - llvm::sys::path::append( - ResponseFile, llvm::sys::path::parent_path(FName), FileName); - NewArgv[I] = Saver.save(ResponseFile.c_str()).data(); - } - } - } + for (auto &Arg : NewArgv) { + // Skip non-rsp file arguments. + if (!Arg || Arg[0] != '@') + continue; + + StringRef FileName(Arg + 1); + // Skip if non-relative. + if (!llvm::sys::path::is_relative(FileName)) + continue; + SmallString<128> ResponseFile; + ResponseFile.push_back('@'); + ResponseFile.append(BasePath); + llvm::sys::path::append(ResponseFile, FileName); + Arg = Saver.save(ResponseFile.c_str()).data(); + } return Error::success(); } @@ -1107,10 +1107,11 @@ static llvm::Error ExpandResponseFile(StringRef FName, StringSaver &Saver, /// StringSaver and tokenization strategy. bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &Argv, bool MarkEOLs, - bool RelativeNames, llvm::vfs::FileSystem &FS) { + bool RelativeNames, llvm::vfs::FileSystem &FS, + llvm::Optional<llvm::StringRef> CurrentDir) { bool AllExpanded = true; struct ResponseFileRecord { - const char *File; + std::string File; size_t End; }; @@ -1144,6 +1145,17 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, } const char *FName = Arg + 1; + // Note that CurrentDir is only used for top-level rsp files, the rest will + // always have an absolute path deduced from the containing file. + SmallString<128> CurrDir; + if (llvm::sys::path::is_relative(FName)) { + if (!CurrentDir) + llvm::sys::fs::current_path(CurrDir); + else + CurrDir = *CurrentDir; + llvm::sys::path::append(CurrDir, FName); + FName = CurrDir.c_str(); + } auto IsEquivalent = [FName, &FS](const ResponseFileRecord &RFile) { llvm::ErrorOr<llvm::vfs::Status> LHS = FS.status(FName); if (!LHS) { @@ -1206,6 +1218,12 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver, SmallVectorImpl<const char *> &Argv) { + SmallString<128> AbsPath; + if (sys::path::is_relative(CfgFile)) { + llvm::sys::fs::current_path(AbsPath); + llvm::sys::path::append(AbsPath, CfgFile); + CfgFile = AbsPath.str(); + } if (llvm::Error Err = ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv, /*MarkEOLs*/ false, /*RelativeNames*/ true, |