forked from OSchip/llvm-project
[Support] add vfs support for ExpandResponseFiles
Summary: add vfs support for `ExpandResponseFiles`. Patch By: liu hui(@lh123) Reviewers: kadircet, espindola, alexshap, rupprecht, jhenderson Reviewed By: kadircet Subscribers: mgorny, sammccall, merge_guards_bot, emaste, sbc100, arichardson, hiraditya, aheejin, jakehehrlich, MaskRay, rupprecht, seiya, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D70769
This commit is contained in:
parent
689c114863
commit
3ee277b86b
|
@ -29,6 +29,7 @@
|
||||||
#include "llvm/ADT/iterator_range.h"
|
#include "llvm/ADT/iterator_range.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
|
#include "llvm/Support/VirtualFileSystem.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
@ -1964,10 +1965,13 @@ bool readConfigFile(StringRef CfgFileName, StringSaver &Saver,
|
||||||
/// with nullptrs in the Argv vector.
|
/// with nullptrs in the Argv vector.
|
||||||
/// \param [in] RelativeNames true if names of nested response files must be
|
/// \param [in] RelativeNames true if names of nested response files must be
|
||||||
/// resolved relative to including file.
|
/// resolved relative to including file.
|
||||||
|
/// \param [in] FS File system used for all file access when running the tool.
|
||||||
/// \return true if all @files were expanded successfully or there were none.
|
/// \return true if all @files were expanded successfully or there were none.
|
||||||
bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
|
bool ExpandResponseFiles(
|
||||||
SmallVectorImpl<const char *> &Argv,
|
StringSaver &Saver, TokenizerCallback Tokenizer,
|
||||||
bool MarkEOLs = false, bool RelativeNames = false);
|
SmallVectorImpl<const char *> &Argv, bool MarkEOLs = false,
|
||||||
|
bool RelativeNames = false,
|
||||||
|
llvm::vfs::FileSystem &FS = *llvm::vfs::getRealFileSystem());
|
||||||
|
|
||||||
/// Mark all options not part of this category as cl::ReallyHidden.
|
/// Mark all options not part of this category as cl::ReallyHidden.
|
||||||
///
|
///
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "llvm/Config/config.h"
|
#include "llvm/Config/config.h"
|
||||||
#include "llvm/Support/ConvertUTF.h"
|
#include "llvm/Support/ConvertUTF.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/Error.h"
|
||||||
#include "llvm/Support/ErrorHandling.h"
|
#include "llvm/Support/ErrorHandling.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
#include "llvm/Support/Host.h"
|
#include "llvm/Support/Host.h"
|
||||||
|
@ -37,6 +38,7 @@
|
||||||
#include "llvm/Support/Path.h"
|
#include "llvm/Support/Path.h"
|
||||||
#include "llvm/Support/Process.h"
|
#include "llvm/Support/Process.h"
|
||||||
#include "llvm/Support/StringSaver.h"
|
#include "llvm/Support/StringSaver.h"
|
||||||
|
#include "llvm/Support/VirtualFileSystem.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
@ -1043,14 +1045,18 @@ static bool hasUTF8ByteOrderMark(ArrayRef<char> S) {
|
||||||
return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');
|
return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ExpandResponseFile(StringRef FName, StringSaver &Saver,
|
static llvm::Error ExpandResponseFile(StringRef FName, StringSaver &Saver,
|
||||||
TokenizerCallback Tokenizer,
|
TokenizerCallback Tokenizer,
|
||||||
SmallVectorImpl<const char *> &NewArgv,
|
SmallVectorImpl<const char *> &NewArgv,
|
||||||
bool MarkEOLs, bool RelativeNames) {
|
bool MarkEOLs, bool RelativeNames,
|
||||||
ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =
|
llvm::vfs::FileSystem &FS) {
|
||||||
MemoryBuffer::getFile(FName);
|
llvm::ErrorOr<std::string> CurrDirOrErr = FS.getCurrentWorkingDirectory();
|
||||||
|
if (!CurrDirOrErr)
|
||||||
|
return llvm::errorCodeToError(CurrDirOrErr.getError());
|
||||||
|
llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =
|
||||||
|
FS.getBufferForFile(FName);
|
||||||
if (!MemBufOrErr)
|
if (!MemBufOrErr)
|
||||||
return false;
|
return llvm::errorCodeToError(MemBufOrErr.getError());
|
||||||
MemoryBuffer &MemBuf = *MemBufOrErr.get();
|
MemoryBuffer &MemBuf = *MemBufOrErr.get();
|
||||||
StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize());
|
StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize());
|
||||||
|
|
||||||
|
@ -1059,7 +1065,8 @@ static bool ExpandResponseFile(StringRef FName, StringSaver &Saver,
|
||||||
std::string UTF8Buf;
|
std::string UTF8Buf;
|
||||||
if (hasUTF16ByteOrderMark(BufRef)) {
|
if (hasUTF16ByteOrderMark(BufRef)) {
|
||||||
if (!convertUTF16ToUTF8String(BufRef, UTF8Buf))
|
if (!convertUTF16ToUTF8String(BufRef, UTF8Buf))
|
||||||
return false;
|
return llvm::createStringError(std::errc::illegal_byte_sequence,
|
||||||
|
"Could not convert UTF16 to UTF8");
|
||||||
Str = StringRef(UTF8Buf);
|
Str = StringRef(UTF8Buf);
|
||||||
}
|
}
|
||||||
// If we see UTF-8 BOM sequence at the beginning of a file, we shall remove
|
// If we see UTF-8 BOM sequence at the beginning of a file, we shall remove
|
||||||
|
@ -1084,9 +1091,7 @@ static bool ExpandResponseFile(StringRef FName, StringSaver &Saver,
|
||||||
SmallString<128> ResponseFile;
|
SmallString<128> ResponseFile;
|
||||||
ResponseFile.append(1, '@');
|
ResponseFile.append(1, '@');
|
||||||
if (llvm::sys::path::is_relative(FName)) {
|
if (llvm::sys::path::is_relative(FName)) {
|
||||||
SmallString<128> curr_dir;
|
ResponseFile.append(CurrDirOrErr.get());
|
||||||
llvm::sys::fs::current_path(curr_dir);
|
|
||||||
ResponseFile.append(curr_dir.str());
|
|
||||||
}
|
}
|
||||||
llvm::sys::path::append(
|
llvm::sys::path::append(
|
||||||
ResponseFile, llvm::sys::path::parent_path(FName), FileName);
|
ResponseFile, llvm::sys::path::parent_path(FName), FileName);
|
||||||
|
@ -1095,14 +1100,14 @@ static bool ExpandResponseFile(StringRef FName, StringSaver &Saver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return Error::success();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expand response files on a command line recursively using the given
|
/// Expand response files on a command line recursively using the given
|
||||||
/// StringSaver and tokenization strategy.
|
/// StringSaver and tokenization strategy.
|
||||||
bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
|
bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
|
||||||
SmallVectorImpl<const char *> &Argv,
|
SmallVectorImpl<const char *> &Argv, bool MarkEOLs,
|
||||||
bool MarkEOLs, bool RelativeNames) {
|
bool RelativeNames, llvm::vfs::FileSystem &FS) {
|
||||||
bool AllExpanded = true;
|
bool AllExpanded = true;
|
||||||
struct ResponseFileRecord {
|
struct ResponseFileRecord {
|
||||||
const char *File;
|
const char *File;
|
||||||
|
@ -1139,8 +1144,20 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *FName = Arg + 1;
|
const char *FName = Arg + 1;
|
||||||
auto IsEquivalent = [FName](const ResponseFileRecord &RFile) {
|
auto IsEquivalent = [FName, &FS](const ResponseFileRecord &RFile) {
|
||||||
return sys::fs::equivalent(RFile.File, FName);
|
llvm::ErrorOr<llvm::vfs::Status> LHS = FS.status(FName);
|
||||||
|
if (!LHS) {
|
||||||
|
// TODO: The error should be propagated up the stack.
|
||||||
|
llvm::consumeError(llvm::errorCodeToError(LHS.getError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
llvm::ErrorOr<llvm::vfs::Status> RHS = FS.status(RFile.File);
|
||||||
|
if (!RHS) {
|
||||||
|
// TODO: The error should be propagated up the stack.
|
||||||
|
llvm::consumeError(llvm::errorCodeToError(RHS.getError()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return LHS->equivalent(*RHS);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check for recursive response files.
|
// Check for recursive response files.
|
||||||
|
@ -1155,10 +1172,13 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
|
||||||
// Replace this response file argument with the tokenization of its
|
// Replace this response file argument with the tokenization of its
|
||||||
// contents. Nested response files are expanded in subsequent iterations.
|
// contents. Nested response files are expanded in subsequent iterations.
|
||||||
SmallVector<const char *, 0> ExpandedArgv;
|
SmallVector<const char *, 0> ExpandedArgv;
|
||||||
if (!ExpandResponseFile(FName, Saver, Tokenizer, ExpandedArgv, MarkEOLs,
|
if (llvm::Error Err =
|
||||||
RelativeNames)) {
|
ExpandResponseFile(FName, Saver, Tokenizer, ExpandedArgv, MarkEOLs,
|
||||||
|
RelativeNames, FS)) {
|
||||||
// We couldn't read this file, so we leave it in the argument stream and
|
// We couldn't read this file, so we leave it in the argument stream and
|
||||||
// move on.
|
// move on.
|
||||||
|
// TODO: The error should be propagated up the stack.
|
||||||
|
llvm::consumeError(std::move(Err));
|
||||||
AllExpanded = false;
|
AllExpanded = false;
|
||||||
++I;
|
++I;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1186,9 +1206,14 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
|
||||||
|
|
||||||
bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver,
|
bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver,
|
||||||
SmallVectorImpl<const char *> &Argv) {
|
SmallVectorImpl<const char *> &Argv) {
|
||||||
if (!ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv,
|
if (llvm::Error Err =
|
||||||
/*MarkEOLs*/ false, /*RelativeNames*/ true))
|
ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv,
|
||||||
|
/*MarkEOLs*/ false, /*RelativeNames*/ true,
|
||||||
|
*llvm::vfs::getRealFileSystem())) {
|
||||||
|
// TODO: The error should be propagated up the stack.
|
||||||
|
llvm::consumeError(std::move(Err));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return ExpandResponseFiles(Saver, cl::tokenizeConfigFile, Argv,
|
return ExpandResponseFiles(Saver, cl::tokenizeConfigFile, Argv,
|
||||||
/*MarkEOLs*/ false, /*RelativeNames*/ true);
|
/*MarkEOLs*/ false, /*RelativeNames*/ true);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue