Index: clang/tools/driver/driver.cpp =================================================================== --- clang/tools/driver/driver.cpp +++ clang/tools/driver/driver.cpp @@ -42,6 +42,7 @@ #include "llvm/Support/StringSaver.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/Timer.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -367,7 +368,8 @@ if (MarkEOLs && argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) MarkEOLs = false; - llvm::cl::ExpandResponseFiles(Saver, Tokenizer, argv, MarkEOLs); + llvm::cl::ExpandResponseFiles( + Saver, Tokenizer, *llvm::vfs::getRealFileSystem(), argv, MarkEOLs); // Handle -cc1 integrated tools, even if -cc1 was expanded from a response // file. Index: lld/COFF/DriverUtils.cpp =================================================================== --- lld/COFF/DriverUtils.cpp +++ lld/COFF/DriverUtils.cpp @@ -30,6 +30,7 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Process.h" #include "llvm/Support/Program.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include "llvm/WindowsManifest/WindowsManifestMerger.h" #include @@ -819,7 +820,8 @@ argv.data() + argv.size()); if (!args.hasArg(OPT_lldignoreenv)) addLINK(expandedArgv); - cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv); + cl::ExpandResponseFiles(saver, getQuotingStyle(args), + *llvm::vfs::getRealFileSystem(), expandedArgv); args = table.ParseArgs(makeArrayRef(expandedArgv).drop_front(), missingIndex, missingCount); Index: lld/ELF/DriverUtils.cpp =================================================================== --- lld/ELF/DriverUtils.cpp +++ lld/ELF/DriverUtils.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" +#include "llvm/Support/VirtualFileSystem.h" using namespace llvm; using namespace llvm::sys; @@ -124,7 +125,8 @@ // Expand response files (arguments in the form of @) // and then parse the argument again. - cl::ExpandResponseFiles(saver, getQuotingStyle(args), vec); + cl::ExpandResponseFiles(saver, getQuotingStyle(args), + *llvm::vfs::getRealFileSystem(), vec); concatLTOPluginOptions(vec); args = this->ParseArgs(vec, missingIndex, missingCount); Index: lld/MinGW/Driver.cpp =================================================================== --- lld/MinGW/Driver.cpp +++ lld/MinGW/Driver.cpp @@ -43,6 +43,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" #if !defined(_MSC_VER) && !defined(__MINGW32__) #include @@ -99,7 +100,8 @@ unsigned missingCount; SmallVector vec(argv.data(), argv.data() + argv.size()); - cl::ExpandResponseFiles(saver, getQuotingStyle(), vec); + cl::ExpandResponseFiles(saver, getQuotingStyle(), + *llvm::vfs::getRealFileSystem(), vec); opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount); if (missingCount) Index: lld/tools/lld/lld.cpp =================================================================== --- lld/tools/lld/lld.cpp +++ lld/tools/lld/lld.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/Host.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Path.h" +#include "llvm/Support/VirtualFileSystem.h" #include using namespace lld; @@ -83,7 +84,8 @@ // Expand response files (arguments in the form of @) // to allow detecting the -m argument from arguments in them. SmallVector expandedArgs(v.data(), v.data() + v.size()); - cl::ExpandResponseFiles(saver, getDefaultQuotingStyle(), expandedArgs); + cl::ExpandResponseFiles(saver, getDefaultQuotingStyle(), + *llvm::vfs::getRealFileSystem(), expandedArgs); for (auto it = expandedArgs.begin(); it + 1 != expandedArgs.end(); ++it) { if (StringRef(*it) != "-m") continue; Index: lld/wasm/Driver.cpp =================================================================== --- lld/wasm/Driver.cpp +++ lld/wasm/Driver.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/Process.h" #include "llvm/Support/TarWriter.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/VirtualFileSystem.h" #define DEBUG_TYPE "lld" @@ -165,7 +166,8 @@ unsigned missingCount; // Expand response files (arguments in the form of @) - cl::ExpandResponseFiles(saver, cl::TokenizeGNUCommandLine, vec); + cl::ExpandResponseFiles(saver, cl::TokenizeGNUCommandLine, + *llvm::vfs::getRealFileSystem(), vec); opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount); Index: llvm/include/llvm/Support/CommandLine.h =================================================================== --- llvm/include/llvm/Support/CommandLine.h +++ llvm/include/llvm/Support/CommandLine.h @@ -41,6 +41,10 @@ namespace llvm { +namespace vfs { +class FileSystem; +} // namespace vfs + class StringSaver; class raw_ostream; @@ -1959,6 +1963,7 @@ /// /// \param [in] Saver Delegates back to the caller for saving parsed strings. /// \param [in] Tokenizer Tokenization strategy. Typically Unix or Windows. +/// \param [in] FS VFS used for all file accesses when running the tool. /// \param [in,out] Argv Command line into which to expand response files. /// \param [in] MarkEOLs Mark end of lines and the end of the response file /// with nullptrs in the Argv vector. @@ -1966,6 +1971,7 @@ /// resolved relative to including file. /// \return true if all @files were expanded successfully or there were none. bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, + llvm::vfs::FileSystem &FS, SmallVectorImpl &Argv, bool MarkEOLs = false, bool RelativeNames = false); Index: llvm/lib/Support/CommandLine.cpp =================================================================== --- llvm/lib/Support/CommandLine.cpp +++ llvm/lib/Support/CommandLine.cpp @@ -37,6 +37,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -1045,10 +1046,11 @@ static bool ExpandResponseFile(StringRef FName, StringSaver &Saver, TokenizerCallback Tokenizer, + llvm::vfs::FileSystem &FS, SmallVectorImpl &NewArgv, bool MarkEOLs, bool RelativeNames) { ErrorOr> MemBufOrErr = - MemoryBuffer::getFile(FName); + FS.getBufferForFile(FName); if (!MemBufOrErr) return false; MemoryBuffer &MemBuf = *MemBufOrErr.get(); @@ -1068,6 +1070,9 @@ else if (hasUTF8ByteOrderMark(BufRef)) Str = StringRef(BufRef.data() + 3, BufRef.size() - 3); + llvm::ErrorOr CurrDir = FS.getCurrentWorkingDirectory(); + if (!CurrDir) + return false; // Tokenize the contents into NewArgv. Tokenizer(Str, Saver, NewArgv, MarkEOLs); @@ -1084,9 +1089,7 @@ SmallString<128> ResponseFile; ResponseFile.append(1, '@'); if (llvm::sys::path::is_relative(FName)) { - SmallString<128> curr_dir; - llvm::sys::fs::current_path(curr_dir); - ResponseFile.append(curr_dir.str()); + ResponseFile.append(CurrDir.get()); } llvm::sys::path::append( ResponseFile, llvm::sys::path::parent_path(FName), FileName); @@ -1101,8 +1104,9 @@ /// Expand response files on a command line recursively using the given /// StringSaver and tokenization strategy. bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, - SmallVectorImpl &Argv, - bool MarkEOLs, bool RelativeNames) { + llvm::vfs::FileSystem &FS, + SmallVectorImpl &Argv, bool MarkEOLs, + bool RelativeNames) { bool AllExpanded = true; struct ResponseFileRecord { const char *File; @@ -1139,8 +1143,14 @@ } const char *FName = Arg + 1; - auto IsEquivalent = [FName](const ResponseFileRecord &RFile) { - return sys::fs::equivalent(RFile.File, FName); + auto IsEquivalent = [FName, &FS](const ResponseFileRecord &RFile) { + SmallVector LHSPath; + SmallVector RHSPath; + if (FS.getRealPath(FName, LHSPath) || FS.getRealPath(RFile.File, RHSPath)) { + return false; + } + llvm::sys::fs::equivalent(FName, FName); + return LHSPath == RHSPath; }; // Check for recursive response files. @@ -1155,7 +1165,7 @@ // Replace this response file argument with the tokenization of its // contents. Nested response files are expanded in subsequent iterations. SmallVector ExpandedArgv; - if (!ExpandResponseFile(FName, Saver, Tokenizer, ExpandedArgv, MarkEOLs, + if (!ExpandResponseFile(FName, Saver, Tokenizer, FS, ExpandedArgv, MarkEOLs, RelativeNames)) { // We couldn't read this file, so we leave it in the argument stream and // move on. @@ -1186,10 +1196,12 @@ bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver, SmallVectorImpl &Argv) { - if (!ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv, + if (!ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, + *llvm::vfs::getRealFileSystem(), Argv, /*MarkEOLs*/ false, /*RelativeNames*/ true)) return false; - return ExpandResponseFiles(Saver, cl::tokenizeConfigFile, Argv, + return ExpandResponseFiles(Saver, cl::tokenizeConfigFile, + *llvm::vfs::getRealFileSystem(), Argv, /*MarkEOLs*/ false, /*RelativeNames*/ true); } @@ -1270,9 +1282,10 @@ BumpPtrAllocator A; StringSaver Saver(A); ExpandResponseFiles(Saver, - Triple(sys::getProcessTriple()).isOSWindows() ? - cl::TokenizeWindowsCommandLine : cl::TokenizeGNUCommandLine, - newArgv); + Triple(sys::getProcessTriple()).isOSWindows() + ? cl::TokenizeWindowsCommandLine + : cl::TokenizeGNUCommandLine, + *llvm::vfs::getRealFileSystem(), newArgv); argv = &newArgv[0]; argc = static_cast(newArgv.size()); Index: llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp =================================================================== --- llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp +++ llvm/lib/ToolDrivers/llvm-lib/LibDriver.cpp @@ -27,6 +27,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -267,7 +268,8 @@ // Parse command line arguments. SmallVector NewArgs(ArgsArr.begin(), ArgsArr.end()); - cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine, NewArgs); + cl::ExpandResponseFiles(Saver, cl::TokenizeWindowsCommandLine, + *llvm::vfs::getRealFileSystem(), NewArgs); ArgsArr = NewArgs; LibOptTable Table; Index: llvm/tools/llvm-ar/llvm-ar.cpp =================================================================== --- llvm/tools/llvm-ar/llvm-ar.cpp +++ llvm/tools/llvm-ar/llvm-ar.cpp @@ -32,6 +32,7 @@ #include "llvm/Support/StringSaver.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include "llvm/ToolDrivers/llvm-dlltool/DlltoolDriver.h" @@ -1096,7 +1097,8 @@ static int ar_main(int argc, char **argv) { SmallVector Argv(argv, argv + argc); StringSaver Saver(Alloc); - cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv); + cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, + *llvm::vfs::getRealFileSystem(), Argv); for (size_t i = 1; i < Argv.size(); ++i) { StringRef Arg = Argv[i]; const char *match = nullptr; Index: llvm/tools/llvm-objcopy/llvm-objcopy.cpp =================================================================== --- llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -38,6 +38,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include @@ -338,7 +339,7 @@ Triple(sys::getProcessTriple()).isOSWindows() ? cl::TokenizeWindowsCommandLine : cl::TokenizeGNUCommandLine, - NewArgv); + *llvm::vfs::getRealFileSystem(), NewArgv); auto Args = makeArrayRef(NewArgv).drop_front(); Expected DriverConfig = Index: llvm/unittests/Support/CommandLineTest.cpp =================================================================== --- llvm/unittests/Support/CommandLineTest.cpp +++ llvm/unittests/Support/CommandLineTest.cpp @@ -17,6 +17,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/VirtualFileSystem.h" #include "gtest/gtest.h" #include #include @@ -830,7 +831,8 @@ llvm::BumpPtrAllocator A; llvm::StringSaver Saver(A); bool Res = llvm::cl::ExpandResponseFiles( - Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true); + Saver, llvm::cl::TokenizeGNUCommandLine, *llvm::vfs::getRealFileSystem(), + Argv, false, true); EXPECT_TRUE(Res); EXPECT_EQ(Argv.size(), 13U); EXPECT_STREQ(Argv[0], "test/test"); @@ -905,7 +907,8 @@ #else cl::TokenizerCallback Tokenizer = cl::TokenizeGNUCommandLine; #endif - bool Res = cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false); + bool Res = cl::ExpandResponseFiles( + Saver, Tokenizer, *llvm::vfs::getRealFileSystem(), Argv, false, false); EXPECT_FALSE(Res); EXPECT_EQ(Argv.size(), 9U); @@ -943,7 +946,8 @@ BumpPtrAllocator A; StringSaver Saver(A); - bool Res = cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv, + bool Res = cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, + *llvm::vfs::getRealFileSystem(), Argv, false, false); EXPECT_FALSE(Res);