Loading clang/include/clang/Tooling/CompilationDatabase.h +0 −1 Original line number Diff line number Diff line Loading @@ -222,7 +222,6 @@ inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base); /// Returns a wrapped CompilationDatabase that will expand all rsp(response) /// files on commandline returned by underlying database. /// Note: This may change the working directory of FS. std::unique_ptr<CompilationDatabase> expandResponseFiles(std::unique_ptr<CompilationDatabase> Base, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); Loading clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp +3 −7 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" Loading Loading @@ -47,12 +48,6 @@ public: private: std::vector<CompileCommand> expand(std::vector<CompileCommand> Cmds) const { for (auto &Cmd : Cmds) { // FIXME: we should rather propagate the current directory into // ExpandResponseFiles as well in addition to FS. if (std::error_code EC = FS->setCurrentWorkingDirectory(Cmd.Directory)) { llvm::consumeError(llvm::errorCodeToError(EC)); continue; } bool SeenRSPFile = false; llvm::SmallVector<const char *, 20> Argv; Argv.reserve(Cmd.CommandLine.size()); Loading @@ -64,7 +59,8 @@ private: continue; llvm::BumpPtrAllocator Alloc; llvm::StringSaver Saver(Alloc); llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, *FS); llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, *FS, llvm::StringRef(Cmd.Directory)); Cmd.CommandLine.assign(Argv.begin(), Argv.end()); } return Cmds; Loading clang/lib/Tooling/JSONCompilationDatabase.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" #include <cassert> Loading Loading @@ -169,8 +170,7 @@ class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin { JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect); return Base ? inferTargetAndDriverMode( inferMissingCompileCommands(expandResponseFiles( std::move(Base), llvm::vfs::createPhysicalFileSystem().release()))) std::move(Base), llvm::vfs::getRealFileSystem()))) : nullptr; } }; Loading llvm/include/llvm/Support/CommandLine.h +6 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #define LLVM_SUPPORT_COMMANDLINE_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" Loading Loading @@ -1966,12 +1968,15 @@ bool readConfigFile(StringRef CfgFileName, StringSaver &Saver, /// \param [in] RelativeNames true if names of nested response files must be /// resolved relative to including file. /// \param [in] FS File system used for all file access when running the tool. /// \param [in] CurrentDir Path used to resolve relative rsp files. If set to /// None, process' cwd is used instead. /// \return true if all @files were expanded successfully or there were none. bool ExpandResponseFiles( StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &Argv, bool MarkEOLs = false, bool RelativeNames = false, llvm::vfs::FileSystem &FS = *llvm::vfs::getRealFileSystem()); llvm::vfs::FileSystem &FS = *llvm::vfs::getRealFileSystem(), llvm::Optional<llvm::StringRef> CurrentDir = llvm::None); /// Mark all options not part of this category as cl::ReallyHidden. /// Loading llvm/lib/Support/CommandLine.cpp +46 −28 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -42,6 +43,7 @@ #include "llvm/Support/raw_ostream.h" #include <cstdlib> #include <map> #include <string> using namespace llvm; using namespace cl; Loading Loading @@ -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, // 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) { llvm::ErrorOr<std::string> CurrDirOrErr = FS.getCurrentWorkingDirectory(); if (!CurrDirOrErr) return llvm::errorCodeToError(CurrDirOrErr.getError()); assert(sys::path::is_absolute(FName)); llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = FS.getBufferForFile(FName); if (!MemBufOrErr) Loading @@ -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)) { 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.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(); ResponseFile.push_back('@'); ResponseFile.append(BasePath); llvm::sys::path::append(ResponseFile, FileName); Arg = Saver.save(ResponseFile.c_str()).data(); } } } return Error::success(); } Loading @@ -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; }; Loading Loading @@ -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) { Loading Loading @@ -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, Loading Loading
clang/include/clang/Tooling/CompilationDatabase.h +0 −1 Original line number Diff line number Diff line Loading @@ -222,7 +222,6 @@ inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base); /// Returns a wrapped CompilationDatabase that will expand all rsp(response) /// files on commandline returned by underlying database. /// Note: This may change the working directory of FS. std::unique_ptr<CompilationDatabase> expandResponseFiles(std::unique_ptr<CompilationDatabase> Base, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); Loading
clang/lib/Tooling/ExpandResponseFilesCompilationDatabase.cpp +3 −7 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" Loading Loading @@ -47,12 +48,6 @@ public: private: std::vector<CompileCommand> expand(std::vector<CompileCommand> Cmds) const { for (auto &Cmd : Cmds) { // FIXME: we should rather propagate the current directory into // ExpandResponseFiles as well in addition to FS. if (std::error_code EC = FS->setCurrentWorkingDirectory(Cmd.Directory)) { llvm::consumeError(llvm::errorCodeToError(EC)); continue; } bool SeenRSPFile = false; llvm::SmallVector<const char *, 20> Argv; Argv.reserve(Cmd.CommandLine.size()); Loading @@ -64,7 +59,8 @@ private: continue; llvm::BumpPtrAllocator Alloc; llvm::StringSaver Saver(Alloc); llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, *FS); llvm::cl::ExpandResponseFiles(Saver, Tokenizer, Argv, false, false, *FS, llvm::StringRef(Cmd.Directory)); Cmd.CommandLine.assign(Argv.begin(), Argv.end()); } return Cmds; Loading
clang/lib/Tooling/JSONCompilationDatabase.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" #include <cassert> Loading Loading @@ -169,8 +170,7 @@ class JSONCompilationDatabasePlugin : public CompilationDatabasePlugin { JSONDatabasePath, ErrorMessage, JSONCommandLineSyntax::AutoDetect); return Base ? inferTargetAndDriverMode( inferMissingCompileCommands(expandResponseFiles( std::move(Base), llvm::vfs::createPhysicalFileSystem().release()))) std::move(Base), llvm::vfs::getRealFileSystem()))) : nullptr; } }; Loading
llvm/include/llvm/Support/CommandLine.h +6 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ #define LLVM_SUPPORT_COMMANDLINE_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" Loading Loading @@ -1966,12 +1968,15 @@ bool readConfigFile(StringRef CfgFileName, StringSaver &Saver, /// \param [in] RelativeNames true if names of nested response files must be /// resolved relative to including file. /// \param [in] FS File system used for all file access when running the tool. /// \param [in] CurrentDir Path used to resolve relative rsp files. If set to /// None, process' cwd is used instead. /// \return true if all @files were expanded successfully or there were none. bool ExpandResponseFiles( StringSaver &Saver, TokenizerCallback Tokenizer, SmallVectorImpl<const char *> &Argv, bool MarkEOLs = false, bool RelativeNames = false, llvm::vfs::FileSystem &FS = *llvm::vfs::getRealFileSystem()); llvm::vfs::FileSystem &FS = *llvm::vfs::getRealFileSystem(), llvm::Optional<llvm::StringRef> CurrentDir = llvm::None); /// Mark all options not part of this category as cl::ReallyHidden. /// Loading
llvm/lib/Support/CommandLine.cpp +46 −28 Original line number Diff line number Diff line Loading @@ -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" Loading @@ -42,6 +43,7 @@ #include "llvm/Support/raw_ostream.h" #include <cstdlib> #include <map> #include <string> using namespace llvm; using namespace cl; Loading Loading @@ -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, // 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) { llvm::ErrorOr<std::string> CurrDirOrErr = FS.getCurrentWorkingDirectory(); if (!CurrDirOrErr) return llvm::errorCodeToError(CurrDirOrErr.getError()); assert(sys::path::is_absolute(FName)); llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = FS.getBufferForFile(FName); if (!MemBufOrErr) Loading @@ -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)) { 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.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(); ResponseFile.push_back('@'); ResponseFile.append(BasePath); llvm::sys::path::append(ResponseFile, FileName); Arg = Saver.save(ResponseFile.c_str()).data(); } } } return Error::success(); } Loading @@ -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; }; Loading Loading @@ -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) { Loading Loading @@ -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, Loading