Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clang-tools-extra/clangd/tool/ClangdMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,8 +775,8 @@ It should be used via an editor plugin rather than invoked directly. For more in
clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment variable.
)";
llvm::cl::HideUnrelatedOptions(ClangdCategories);
llvm::cl::ParseCommandLineOptions(argc, argv, Overview,
/*Errs=*/nullptr, FlagsEnvVar);
llvm::cl::ParseCommandLineOptions(argc, argv, Overview, /*Errs=*/nullptr,
/*VFS=*/nullptr, FlagsEnvVar);
if (Test) {
if (!Sync.getNumOccurrences())
Sync = true;
Expand Down
12 changes: 7 additions & 5 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,8 @@ getInstrProfOptions(const CodeGenOptions &CodeGenOpts,
return Options;
}

static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) {
static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts,
vfs::FileSystem &VFS) {
SmallVector<const char *, 16> BackendArgs;
BackendArgs.push_back("clang"); // Fake program name.
if (!CodeGenOpts.DebugPass.empty()) {
Expand All @@ -582,8 +583,9 @@ static void setCommandLineOpts(const CodeGenOptions &CodeGenOpts) {
// FIXME: The command line parser below is not thread-safe and shares a global
// state, so this call might crash or overwrite the options of another Clang
// instance in the same process.
llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1,
BackendArgs.data());
llvm::cl::ParseCommandLineOptions(BackendArgs.size() - 1, BackendArgs.data(),
/*Overview=*/"", /*Errs=*/nullptr,
/*VFS=*/&VFS);
}

void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {
Expand Down Expand Up @@ -1260,7 +1262,7 @@ void EmitAssemblyHelper::RunCodegenPipeline(
void EmitAssemblyHelper::emitAssembly(BackendAction Action,
std::unique_ptr<raw_pwrite_stream> OS,
BackendConsumer *BC) {
setCommandLineOpts(CodeGenOpts);
setCommandLineOpts(CodeGenOpts, CI.getVirtualFileSystem());

bool RequiresCodeGen = actionRequiresCodeGen(Action);
CreateTargetMachine(RequiresCodeGen);
Expand Down Expand Up @@ -1295,7 +1297,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
ModuleToDefinedGVSummaries;
CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);

setCommandLineOpts(CGOpts);
setCommandLineOpts(CGOpts, CI.getVirtualFileSystem());

// We can simply import the values mentioned in the combined index, since
// we should only invoke this using the individual indexes written out
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,9 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
for (unsigned i = 0; i != NumArgs; ++i)
Args[i + 1] = Clang->getFrontendOpts().LLVMArgs[i].c_str();
Args[NumArgs + 1] = nullptr;
llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get(), /*Overview=*/"",
/*Errs=*/nullptr,
/*VFS=*/&Clang->getVirtualFileSystem());
}

#if CLANG_ENABLE_STATIC_ANALYZER
Expand Down
5 changes: 4 additions & 1 deletion clang/tools/driver/cc1as_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,8 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
DiagClient->setPrefix("clang -cc1as");
DiagnosticsEngine Diags(DiagnosticIDs::create(), DiagOpts, DiagClient);

auto VFS = vfs::getRealFileSystem();

// Set an error handler, so that any LLVM backend diagnostics go through our
// error handler.
ScopedFatalErrorHandler FatalErrorHandler
Expand Down Expand Up @@ -704,7 +706,8 @@ int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
for (unsigned i = 0; i != NumArgs; ++i)
Args[i + 1] = Asm.LLVMArgs[i].c_str();
Args[NumArgs + 1] = nullptr;
llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get());
llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args.get(), /*Overview=*/"",
/*Errs=*/nullptr, /*VFS=*/VFS.get());
}

// Execute the invocation, unless there were parsing errors.
Expand Down
21 changes: 12 additions & 9 deletions clang/tools/driver/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,17 @@ static void FixupDiagPrefixExeName(TextDiagnosticPrinter *DiagClient,
}

static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV,
const llvm::ToolContext &ToolContext) {
const llvm::ToolContext &ToolContext,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) {
// If we call the cc1 tool from the clangDriver library (through
// Driver::CC1Main), we need to clean up the options usage count. The options
// are currently global, and they might have been used previously by the
// driver.
llvm::cl::ResetAllOptionOccurrences();

llvm::BumpPtrAllocator A;
llvm::cl::ExpansionContext ECtx(A, llvm::cl::TokenizeGNUCommandLine);
llvm::cl::ExpansionContext ECtx(A, llvm::cl::TokenizeGNUCommandLine,
VFS.get());
if (llvm::Error Err = ECtx.expandResponseFiles(ArgV)) {
llvm::errs() << toString(std::move(Err)) << '\n';
return 1;
Expand Down Expand Up @@ -254,14 +256,16 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
bool ClangCLMode =
IsClangCL(getDriverMode(ProgName, llvm::ArrayRef(Args).slice(1)));

if (llvm::Error Err = expandResponseFiles(Args, ClangCLMode, A)) {
auto VFS = llvm::vfs::getRealFileSystem();

if (llvm::Error Err = expandResponseFiles(Args, ClangCLMode, A, VFS.get())) {
llvm::errs() << toString(std::move(Err)) << '\n';
return 1;
}

// Handle -cc1 integrated tools.
if (Args.size() >= 2 && StringRef(Args[1]).starts_with("-cc1"))
return ExecuteCC1Tool(Args, ToolContext);
return ExecuteCC1Tool(Args, ToolContext, VFS);

// Handle options that need handling before the real command line parsing in
// Driver::BuildCompilation()
Expand Down Expand Up @@ -341,7 +345,6 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
Diags.takeClient(), std::move(SerializedConsumer)));
}

auto VFS = llvm::vfs::getRealFileSystem();
ProcessWarningOptions(Diags, *DiagOpts, *VFS, /*ReportDiags=*/false);

Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags,
Expand All @@ -361,10 +364,10 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) {
if (!SetBackdoorDriverOutputsFromEnvVars(TheDriver))
return 1;

auto ExecuteCC1WithContext =
[&ToolContext](SmallVectorImpl<const char *> &ArgV) {
return ExecuteCC1Tool(ArgV, ToolContext);
};
auto ExecuteCC1WithContext = [&ToolContext,
&VFS](SmallVectorImpl<const char *> &ArgV) {
return ExecuteCC1Tool(ArgV, ToolContext, VFS);
};
if (!UseNewCC1Process) {
TheDriver.CC1Main = ExecuteCC1WithContext;
// Ensure the CC1Command actually catches cc1 crashes
Expand Down
4 changes: 3 additions & 1 deletion llvm/include/llvm/Support/CommandLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ namespace cl {
LLVM_ABI bool ParseCommandLineOptions(int argc, const char *const *argv,
StringRef Overview = "",
raw_ostream *Errs = nullptr,
vfs::FileSystem *VFS = nullptr,
const char *EnvVar = nullptr,
bool LongOptionsUseDoubleDash = false);

Expand Down Expand Up @@ -2192,7 +2193,8 @@ class ExpansionContext {
SmallVectorImpl<const char *> &NewArgv);

public:
LLVM_ABI ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T);
LLVM_ABI ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T,
vfs::FileSystem *FS = nullptr);

ExpansionContext &setMarkEOLs(bool X) {
MarkEOLs = X;
Expand Down
24 changes: 13 additions & 11 deletions llvm/lib/Support/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class CommandLineParser {

bool ParseCommandLineOptions(int argc, const char *const *argv,
StringRef Overview, raw_ostream *Errs = nullptr,
vfs::FileSystem *VFS = nullptr,
bool LongOptionsUseDoubleDash = false);

void forEachSubCommand(Option &Opt, function_ref<void(SubCommand &)> Action) {
Expand Down Expand Up @@ -1401,8 +1402,9 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
return true;
}

ExpansionContext::ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T)
: Saver(A), Tokenizer(T), FS(vfs::getRealFileSystem().get()) {}
ExpansionContext::ExpansionContext(BumpPtrAllocator &A, TokenizerCallback T,
vfs::FileSystem *FS)
: Saver(A), Tokenizer(T), FS(FS ? FS : vfs::getRealFileSystem().get()) {}

bool ExpansionContext::findConfigFile(StringRef FileName,
SmallVectorImpl<char> &FilePath) {
Expand Down Expand Up @@ -1461,7 +1463,7 @@ Error ExpansionContext::readConfigFile(StringRef CfgFile,
static void initCommonOptions();
bool cl::ParseCommandLineOptions(int argc, const char *const *argv,
StringRef Overview, raw_ostream *Errs,
const char *EnvVar,
vfs::FileSystem *VFS, const char *EnvVar,
bool LongOptionsUseDoubleDash) {
initCommonOptions();
SmallVector<const char *, 20> NewArgv;
Expand All @@ -1482,8 +1484,8 @@ bool cl::ParseCommandLineOptions(int argc, const char *const *argv,
int NewArgc = static_cast<int>(NewArgv.size());

// Parse all options.
return GlobalParser->ParseCommandLineOptions(NewArgc, &NewArgv[0], Overview,
Errs, LongOptionsUseDoubleDash);
return GlobalParser->ParseCommandLineOptions(
NewArgc, &NewArgv[0], Overview, Errs, VFS, LongOptionsUseDoubleDash);
}

/// Reset all options at least once, so that we can parse different options.
Expand All @@ -1503,17 +1505,17 @@ void CommandLineParser::ResetAllOptionOccurrences() {
}
}

bool CommandLineParser::ParseCommandLineOptions(int argc,
const char *const *argv,
StringRef Overview,
raw_ostream *Errs,
bool LongOptionsUseDoubleDash) {
bool CommandLineParser::ParseCommandLineOptions(
int argc, const char *const *argv, StringRef Overview, raw_ostream *Errs,
vfs::FileSystem *VFS, bool LongOptionsUseDoubleDash) {
assert(hasOptions() && "No options specified!");

ProgramOverview = Overview;
bool IgnoreErrors = Errs;
if (!Errs)
Errs = &errs();
if (!VFS)
VFS = vfs::getRealFileSystem().get();
bool ErrorParsing = false;

// Expand response files.
Expand All @@ -1524,7 +1526,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc,
#else
auto Tokenize = cl::TokenizeGNUCommandLine;
#endif
ExpansionContext ECtx(A, Tokenize);
ExpansionContext ECtx(A, Tokenize, VFS);
if (Error Err = ECtx.expandResponseFiles(newArgv)) {
*Errs << toString(std::move(Err)) << '\n';
return false;
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/obj2yaml/obj2yaml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ int main(int argc, char *argv[]) {
cl::HideUnrelatedOptions(Cat);
cl::ParseCommandLineOptions(
argc, argv, "Dump a YAML description from an object file", nullptr,
nullptr, /*LongOptionsUseDoubleDash=*/true);
nullptr, nullptr, /*LongOptionsUseDoubleDash=*/true);

std::error_code EC;
std::unique_ptr<ToolOutputFile> Out(
Expand Down
2 changes: 1 addition & 1 deletion llvm/tools/yaml2obj/yaml2obj.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ int main(int argc, char **argv) {
cl::HideUnrelatedOptions(Cat);
cl::ParseCommandLineOptions(
argc, argv, "Create an object file from a YAML description", nullptr,
nullptr, /*LongOptionsUseDoubleDash=*/true);
nullptr, nullptr, /*LongOptionsUseDoubleDash=*/true);

constexpr StringRef ProgName = "yaml2obj";
auto ErrHandler = [&](const Twine &Msg) {
Expand Down
12 changes: 6 additions & 6 deletions llvm/unittests/Support/CommandLineTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1915,20 +1915,20 @@ TEST(CommandLineTest, LongOptions) {

// Fails because `-ab` is treated as `-a -b`, so `-a` is seen twice, and
// `val1` is unexpected.
EXPECT_FALSE(cl::ParseCommandLineOptions(4, args1, StringRef(),
&OS, nullptr, true));
EXPECT_FALSE(cl::ParseCommandLineOptions(4, args1, StringRef(), &OS, nullptr,
nullptr, true));
EXPECT_FALSE(Errs.empty()); Errs.clear();
cl::ResetAllOptionOccurrences();

// Works because `-a` is treated differently than `--ab`.
EXPECT_TRUE(cl::ParseCommandLineOptions(4, args2, StringRef(),
&OS, nullptr, true));
EXPECT_TRUE(cl::ParseCommandLineOptions(4, args2, StringRef(), &OS, nullptr,
nullptr, true));
EXPECT_TRUE(Errs.empty()); Errs.clear();
cl::ResetAllOptionOccurrences();

// Works because `-ab` is treated as `-a -b`, and `--ab` is a long option.
EXPECT_TRUE(cl::ParseCommandLineOptions(4, args3, StringRef(),
&OS, nullptr, true));
EXPECT_TRUE(cl::ParseCommandLineOptions(4, args3, StringRef(), &OS, nullptr,
nullptr, true));
EXPECT_TRUE(OptA);
EXPECT_TRUE(OptBLong);
EXPECT_STREQ("val1", OptAB.c_str());
Expand Down
2 changes: 1 addition & 1 deletion llvm/utils/FileCheck/FileCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,7 @@ int main(int argc, char **argv) {

InitLLVM X(argc, argv);
cl::ParseCommandLineOptions(argc, argv, /*Overview*/ "", /*Errs*/ nullptr,
"FILECHECK_OPTS");
/*VFS*/ nullptr, "FILECHECK_OPTS");

// Select -dump-input* values. The -help documentation specifies the default
// value and which value to choose if an option is specified multiple times.
Expand Down
1 change: 1 addition & 0 deletions llvm/utils/split-file/split-file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ int main(int argc, const char **argv) {
"Split input into multiple parts separated by regex '^(.|//)--- ' and "
"extract the part specified by '^(.|//)--- <part>'\n",
nullptr,
/*VFS=*/nullptr,
/*EnvVar=*/nullptr,
/*LongOptionsUseDoubleDash=*/true);

Expand Down