summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/CommandLine.cpp
diff options
context:
space:
mode:
authorKadir Cetinkaya <kadircet@google.com>2019-11-29 15:37:14 +0100
committerKadir Cetinkaya <kadircet@google.com>2019-12-04 15:13:12 +0100
commit75656005dbc8866e1888932a68a830b0df403560 (patch)
treee8fab392d5c236a8c49e5ab1b6577d5f187db64f /llvm/lib/Support/CommandLine.cpp
parent45ef055d4ffda4d2b04b62f73e36cc6d5252758b (diff)
downloadbcm5719-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.cpp74
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,
OpenPOWER on IntegriCloud