llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-tools-extra Author: Jan Svoboda (jansvoboda11) <details> <summary>Changes</summary> This PR passes the VFS down to `llvm::cl` functions so that they don't assume the real file system. --- Full diff: https://github.com/llvm/llvm-project/pull/159174.diff 12 Files Affected: - (modified) clang-tools-extra/clangd/tool/ClangdMain.cpp (+2-2) - (modified) clang/lib/CodeGen/BackendUtil.cpp (+7-5) - (modified) clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp (+3-1) - (modified) clang/tools/driver/cc1as_main.cpp (+4-1) - (modified) clang/tools/driver/driver.cpp (+10-7) - (modified) llvm/include/llvm/Support/CommandLine.h (+3-1) - (modified) llvm/lib/Support/CommandLine.cpp (+11-6) - (modified) llvm/tools/obj2yaml/obj2yaml.cpp (+1-1) - (modified) llvm/tools/yaml2obj/yaml2obj.cpp (+1-1) - (modified) llvm/unittests/Support/CommandLineTest.cpp (+3-3) - (modified) llvm/utils/FileCheck/FileCheck.cpp (+1-1) - (modified) llvm/utils/split-file/split-file.cpp (+1) ``````````diff diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp index f287439f10cab..3be88bd04b6d5 100644 --- a/clang-tools-extra/clangd/tool/ClangdMain.cpp +++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp @@ -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; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 8c99af2bdff83..77bf0c8251fc2 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -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()) { @@ -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) { @@ -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); @@ -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 diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 8b0ab2eb37189..6dcda814b9057 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -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 diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp index 5c30de33c7b46..9c9560f10aebe 100644 --- a/clang/tools/driver/cc1as_main.cpp +++ b/clang/tools/driver/cc1as_main.cpp @@ -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 @@ -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. diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp index e5c3c4ed5f804..87ffaf154c6bc 100644 --- a/clang/tools/driver/driver.cpp +++ b/clang/tools/driver/driver.cpp @@ -204,7 +204,8 @@ 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 @@ -212,7 +213,8 @@ static int ExecuteCC1Tool(SmallVectorImpl<const char *> &ArgV, 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; @@ -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() @@ -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, @@ -362,8 +365,8 @@ int clang_main(int Argc, char **Argv, const llvm::ToolContext &ToolContext) { return 1; auto ExecuteCC1WithContext = - [&ToolContext](SmallVectorImpl<const char *> &ArgV) { - return ExecuteCC1Tool(ArgV, ToolContext); + [&ToolContext, &VFS](SmallVectorImpl<const char *> &ArgV) { + return ExecuteCC1Tool(ArgV, ToolContext, VFS); }; if (!UseNewCC1Process) { TheDriver.CC1Main = ExecuteCC1WithContext; diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h index ca725b8ac8712..b81df756247c9 100644 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -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); @@ -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; diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index be232f5bff587..72b98909abfbd 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -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) { @@ -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) { @@ -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; @@ -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. @@ -1507,6 +1509,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, const char *const *argv, StringRef Overview, raw_ostream *Errs, + vfs::FileSystem *VFS, bool LongOptionsUseDoubleDash) { assert(hasOptions() && "No options specified!"); @@ -1514,6 +1517,8 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, bool IgnoreErrors = Errs; if (!Errs) Errs = &errs(); + if (!VFS) + VFS = vfs::getRealFileSystem().get(); bool ErrorParsing = false; // Expand response files. @@ -1524,7 +1529,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; diff --git a/llvm/tools/obj2yaml/obj2yaml.cpp b/llvm/tools/obj2yaml/obj2yaml.cpp index 63c8cc55ee2d4..94c38d1032c22 100644 --- a/llvm/tools/obj2yaml/obj2yaml.cpp +++ b/llvm/tools/obj2yaml/obj2yaml.cpp @@ -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( diff --git a/llvm/tools/yaml2obj/yaml2obj.cpp b/llvm/tools/yaml2obj/yaml2obj.cpp index dcd6dfcd3de2a..662648b599954 100644 --- a/llvm/tools/yaml2obj/yaml2obj.cpp +++ b/llvm/tools/yaml2obj/yaml2obj.cpp @@ -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) { diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index ad06ca91c226e..10b7d1409c7f4 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -1916,19 +1916,19 @@ 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)); + &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)); + &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)); + &OS, nullptr, nullptr, true)); EXPECT_TRUE(OptA); EXPECT_TRUE(OptBLong); EXPECT_STREQ("val1", OptAB.c_str()); diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp index 9cf3a3164dfec..185b6b30994fc 100644 --- a/llvm/utils/FileCheck/FileCheck.cpp +++ b/llvm/utils/FileCheck/FileCheck.cpp @@ -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. diff --git a/llvm/utils/split-file/split-file.cpp b/llvm/utils/split-file/split-file.cpp index 672877adaba31..c7e9ff4b2b682 100644 --- a/llvm/utils/split-file/split-file.cpp +++ b/llvm/utils/split-file/split-file.cpp @@ -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); `````````` </details> https://github.com/llvm/llvm-project/pull/159174 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits