Index: cfe/trunk/include/clang/Driver/Driver.h =================================================================== --- cfe/trunk/include/clang/Driver/Driver.h +++ cfe/trunk/include/clang/Driver/Driver.h @@ -12,6 +12,7 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/LLVM.h" #include "clang/Driver/Action.h" +#include "clang/Driver/Options.h" #include "clang/Driver/Phases.h" #include "clang/Driver/ToolChain.h" #include "clang/Driver/Types.h" @@ -56,8 +57,6 @@ /// Driver - Encapsulate logic for constructing compilation processes /// from a set of gcc-driver-like command line arguments. class Driver { - std::unique_ptr Opts; - DiagnosticsEngine &Diags; IntrusiveRefCntPtr VFS; @@ -301,7 +300,7 @@ const std::string &getConfigFile() const { return ConfigFile; } - const llvm::opt::OptTable &getOpts() const { return *Opts; } + const llvm::opt::OptTable &getOpts() const { return getDriverOptTable(); } const DiagnosticsEngine &getDiags() const { return Diags; } Index: cfe/trunk/include/clang/Driver/Options.h =================================================================== --- cfe/trunk/include/clang/Driver/Options.h +++ cfe/trunk/include/clang/Driver/Options.h @@ -47,7 +47,7 @@ }; } -std::unique_ptr createDriverOptTable(); +const llvm::opt::OptTable &getDriverOptTable(); } } Index: cfe/trunk/lib/Driver/Driver.cpp =================================================================== --- cfe/trunk/lib/Driver/Driver.cpp +++ cfe/trunk/lib/Driver/Driver.cpp @@ -120,16 +120,16 @@ Driver::Driver(StringRef ClangExecutable, StringRef TargetTriple, DiagnosticsEngine &Diags, IntrusiveRefCntPtr VFS) - : Opts(createDriverOptTable()), Diags(Diags), VFS(std::move(VFS)), - Mode(GCCMode), SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), - LTOMode(LTOK_None), ClangExecutable(ClangExecutable), - SysRoot(DEFAULT_SYSROOT), DriverTitle("clang LLVM compiler"), - CCPrintOptionsFilename(nullptr), CCPrintHeadersFilename(nullptr), - CCLogDiagnosticsFilename(nullptr), CCCPrintBindings(false), - CCPrintOptions(false), CCPrintHeaders(false), CCLogDiagnostics(false), - CCGenDiagnostics(false), TargetTriple(TargetTriple), - CCCGenericGCCName(""), Saver(Alloc), CheckInputsExist(true), - GenReproducer(false), SuppressMissingInputWarning(false) { + : Diags(Diags), VFS(std::move(VFS)), Mode(GCCMode), + SaveTemps(SaveTempsNone), BitcodeEmbed(EmbedNone), LTOMode(LTOK_None), + ClangExecutable(ClangExecutable), SysRoot(DEFAULT_SYSROOT), + DriverTitle("clang LLVM compiler"), CCPrintOptionsFilename(nullptr), + CCPrintHeadersFilename(nullptr), CCLogDiagnosticsFilename(nullptr), + CCCPrintBindings(false), CCPrintOptions(false), CCPrintHeaders(false), + CCLogDiagnostics(false), CCGenDiagnostics(false), + TargetTriple(TargetTriple), CCCGenericGCCName(""), Saver(Alloc), + CheckInputsExist(true), GenReproducer(false), + SuppressMissingInputWarning(false) { // Provide a sane fallback if no VFS is specified. if (!this->VFS) @@ -310,7 +310,7 @@ return FinalPhase; } -static Arg *MakeInputArg(DerivedArgList &Args, OptTable &Opts, +static Arg *MakeInputArg(DerivedArgList &Args, const OptTable &Opts, StringRef Value, bool Claim = true) { Arg *A = new Arg(Opts.getOption(options::OPT_INPUT), Value, Args.getBaseArgs().MakeIndex(Value), Value.data()); @@ -321,6 +321,7 @@ } DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const { + const llvm::opt::OptTable &Opts = getOpts(); DerivedArgList *DAL = new DerivedArgList(Args); bool HasNostdlib = Args.hasArg(options::OPT_nostdlib); @@ -337,12 +338,12 @@ A->getOption().matches(options::OPT_Xlinker)) && A->containsValue("--no-demangle")) { // Add the rewritten no-demangle argument. - DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_Xlinker__no_demangle)); + DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_Xlinker__no_demangle)); // Add the remaining values as Xlinker arguments. for (StringRef Val : A->getValues()) if (Val != "--no-demangle") - DAL->AddSeparateArg(A, Opts->getOption(options::OPT_Xlinker), Val); + DAL->AddSeparateArg(A, Opts.getOption(options::OPT_Xlinker), Val); continue; } @@ -355,12 +356,11 @@ A->getValue(0) == StringRef("-MMD"))) { // Rewrite to -MD/-MMD along with -MF. if (A->getValue(0) == StringRef("-MD")) - DAL->AddFlagArg(A, Opts->getOption(options::OPT_MD)); + DAL->AddFlagArg(A, Opts.getOption(options::OPT_MD)); else - DAL->AddFlagArg(A, Opts->getOption(options::OPT_MMD)); + DAL->AddFlagArg(A, Opts.getOption(options::OPT_MMD)); if (A->getNumValues() == 2) - DAL->AddSeparateArg(A, Opts->getOption(options::OPT_MF), - A->getValue(1)); + DAL->AddSeparateArg(A, Opts.getOption(options::OPT_MF), A->getValue(1)); continue; } @@ -371,13 +371,13 @@ // Rewrite unless -nostdlib is present. if (!HasNostdlib && !HasNodefaultlib && !HasNostdlibxx && Value == "stdc++") { - DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_stdcxx)); + DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_stdcxx)); continue; } // Rewrite unconditionally. if (Value == "cc_kext") { - DAL->AddFlagArg(A, Opts->getOption(options::OPT_Z_reserved_lib_cckext)); + DAL->AddFlagArg(A, Opts.getOption(options::OPT_Z_reserved_lib_cckext)); continue; } } @@ -386,7 +386,7 @@ if (A->getOption().matches(options::OPT__DASH_DASH)) { A->claim(); for (StringRef Val : A->getValues()) - DAL->append(MakeInputArg(*DAL, *Opts, Val, false)); + DAL->append(MakeInputArg(*DAL, Opts, Val, false)); continue; } @@ -395,14 +395,14 @@ // Enforce -static if -miamcu is present. if (Args.hasFlag(options::OPT_miamcu, options::OPT_mno_iamcu, false)) - DAL->AddFlagArg(0, Opts->getOption(options::OPT_static)); + DAL->AddFlagArg(0, Opts.getOption(options::OPT_static)); // Add a default value of -mlinker-version=, if one was given and the user // didn't specify one. #if defined(HOST_LINK_VERSION) if (!Args.hasArg(options::OPT_mlinker_version_EQ) && strlen(HOST_LINK_VERSION) > 0) { - DAL->AddJoinedArg(0, Opts->getOption(options::OPT_mlinker_version_EQ), + DAL->AddJoinedArg(0, Opts.getOption(options::OPT_mlinker_version_EQ), HOST_LINK_VERSION); DAL->getLastArg(options::OPT_mlinker_version_EQ)->claim(); } @@ -1592,16 +1592,17 @@ if (llvm::is_contained(Flags, "-Xclang") || llvm::is_contained(Flags, "-cc1")) DisableFlags &= ~options::NoDriverOption; + const llvm::opt::OptTable &Opts = getOpts(); StringRef Cur; Cur = Flags.at(Flags.size() - 1); StringRef Prev; if (Flags.size() >= 2) { Prev = Flags.at(Flags.size() - 2); - SuggestedCompletions = Opts->suggestValueCompletions(Prev, Cur); + SuggestedCompletions = Opts.suggestValueCompletions(Prev, Cur); } if (SuggestedCompletions.empty()) - SuggestedCompletions = Opts->suggestValueCompletions(Cur, ""); + SuggestedCompletions = Opts.suggestValueCompletions(Cur, ""); // If Flags were empty, it means the user typed `clang [tab]` where we should // list all possible flags. If there was no value completion and the user @@ -1619,7 +1620,7 @@ // If the flag is in the form of "--autocomplete=-foo", // we were requested to print out all option names that start with "-foo". // For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only". - SuggestedCompletions = Opts->findByPrefix(Cur, DisableFlags); + SuggestedCompletions = Opts.findByPrefix(Cur, DisableFlags); // We have to query the -W flags manually as they're not in the OptTable. // TODO: Find a good way to add them to OptTable instead and them remove @@ -2037,6 +2038,7 @@ // Construct a the list of inputs and their types. void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args, InputList &Inputs) const { + const llvm::opt::OptTable &Opts = getOpts(); // Track the current user specified (-x) input. We also explicitly track the // argument used to set the type; we only want to claim the type when we // actually use it, so we warn about unused -x arguments. @@ -2160,7 +2162,7 @@ StringRef Value = A->getValue(); if (DiagnoseInputExistence(Args, Value, types::TY_C, /*TypoCorrect=*/false)) { - Arg *InputArg = MakeInputArg(Args, *Opts, A->getValue()); + Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); Inputs.push_back(std::make_pair(types::TY_C, InputArg)); } A->claim(); @@ -2168,7 +2170,7 @@ StringRef Value = A->getValue(); if (DiagnoseInputExistence(Args, Value, types::TY_CXX, /*TypoCorrect=*/false)) { - Arg *InputArg = MakeInputArg(Args, *Opts, A->getValue()); + Arg *InputArg = MakeInputArg(Args, Opts, A->getValue()); Inputs.push_back(std::make_pair(types::TY_CXX, InputArg)); } A->claim(); @@ -2202,7 +2204,7 @@ if (CCCIsCPP() && Inputs.empty()) { // If called as standalone preprocessor, stdin is processed // if no other input is present. - Arg *A = MakeInputArg(Args, *Opts, "-"); + Arg *A = MakeInputArg(Args, Opts, "-"); Inputs.push_back(std::make_pair(types::TY_C, A)); } } Index: cfe/trunk/lib/Driver/DriverOptions.cpp =================================================================== --- cfe/trunk/lib/Driver/DriverOptions.cpp +++ cfe/trunk/lib/Driver/DriverOptions.cpp @@ -39,14 +39,17 @@ } -std::unique_ptr clang::driver::createDriverOptTable() { - auto Result = std::make_unique(); - // Options.inc is included in DriverOptions.cpp, and calls OptTable's - // addValues function. - // Opt is a variable used in the code fragment in Options.inc. - OptTable &Opt = *Result; +const llvm::opt::OptTable &clang::driver::getDriverOptTable() { + static const DriverOptTable *Table = []() { + auto Result = std::make_unique(); + // Options.inc is included in DriverOptions.cpp, and calls OptTable's + // addValues function. + // Opt is a variable used in the code fragment in Options.inc. + OptTable &Opt = *Result; #define OPTTABLE_ARG_INIT #include "clang/Driver/Options.inc" #undef OPTTABLE_ARG_INIT - return std::move(Result); + return Result.release(); + }(); + return *Table; } Index: cfe/trunk/lib/Frontend/CompilerInvocation.cpp =================================================================== --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp @@ -3375,11 +3375,11 @@ bool Success = true; // Parse the arguments. - std::unique_ptr Opts = createDriverOptTable(); + const OptTable &Opts = getDriverOptTable(); const unsigned IncludedFlagsBitmask = options::CC1Option; unsigned MissingArgIndex, MissingArgCount; - InputArgList Args = Opts->ParseArgs(CommandLineArgs, MissingArgIndex, - MissingArgCount, IncludedFlagsBitmask); + InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex, + MissingArgCount, IncludedFlagsBitmask); LangOptions &LangOpts = *Res.getLangOpts(); // Check for missing argument error. @@ -3393,7 +3393,7 @@ for (const auto *A : Args.filtered(OPT_UNKNOWN)) { auto ArgString = A->getAsString(Args); std::string Nearest; - if (Opts->findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1) + if (Opts.findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1) Diags.Report(diag::err_drv_unknown_argument) << ArgString; else Diags.Report(diag::err_drv_unknown_argument_with_suggestion) Index: cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -185,11 +185,11 @@ bool ExecuteCompilerInvocation(CompilerInstance *Clang) { // Honor -help. if (Clang->getFrontendOpts().ShowHelp) { - std::unique_ptr Opts = driver::createDriverOptTable(); - Opts->PrintHelp(llvm::outs(), "clang -cc1 [options] file...", - "LLVM 'Clang' Compiler: http://clang.llvm.org", - /*Include=*/driver::options::CC1Option, - /*Exclude=*/0, /*ShowAllAliases=*/false); + driver::getDriverOptTable().PrintHelp( + llvm::outs(), "clang -cc1 [options] file...", + "LLVM 'Clang' Compiler: http://clang.llvm.org", + /*Include=*/driver::options::CC1Option, + /*Exclude=*/0, /*ShowAllAliases=*/false); return true; } Index: cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp =================================================================== --- cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp +++ cfe/trunk/lib/Tooling/InterpolatingCompilationDatabase.cpp @@ -149,17 +149,17 @@ // We parse each argument individually so that we can retain the exact // spelling of each argument; re-rendering is lossy for aliased flags. // E.g. in CL mode, /W4 maps to -Wall. - auto OptTable = clang::driver::createDriverOptTable(); + auto &OptTable = clang::driver::getDriverOptTable(); if (!OldArgs.empty()) Cmd.CommandLine.emplace_back(OldArgs.front()); for (unsigned Pos = 1; Pos < OldArgs.size();) { using namespace driver::options; const unsigned OldPos = Pos; - std::unique_ptr Arg(OptTable->ParseOneArg( + std::unique_ptr Arg(OptTable.ParseOneArg( ArgList, Pos, - /* Include */ClangCLMode ? CoreOption | CLOption : 0, - /* Exclude */ClangCLMode ? 0 : CLOption)); + /* Include */ ClangCLMode ? CoreOption | CLOption : 0, + /* Exclude */ ClangCLMode ? 0 : CLOption)); if (!Arg) continue; Index: cfe/trunk/lib/Tooling/Tooling.cpp =================================================================== --- cfe/trunk/lib/Tooling/Tooling.cpp +++ cfe/trunk/lib/Tooling/Tooling.cpp @@ -292,8 +292,7 @@ const char *const BinaryName = Argv[0]; IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); unsigned MissingArgIndex, MissingArgCount; - std::unique_ptr Opts = driver::createDriverOptTable(); - llvm::opt::InputArgList ParsedArgs = Opts->ParseArgs( + llvm::opt::InputArgList ParsedArgs = driver::getDriverOptTable().ParseArgs( ArrayRef(Argv).slice(1), MissingArgIndex, MissingArgCount); ParseDiagnosticArgs(*DiagOpts, ParsedArgs); TextDiagnosticPrinter DiagnosticPrinter( Index: cfe/trunk/tools/clang-check/ClangCheck.cpp =================================================================== --- cfe/trunk/tools/clang-check/ClangCheck.cpp +++ cfe/trunk/tools/clang-check/ClangCheck.cpp @@ -52,31 +52,34 @@ ); static cl::OptionCategory ClangCheckCategory("clang-check options"); -static std::unique_ptr Options(createDriverOptTable()); +static const opt::OptTable &Options = getDriverOptTable(); static cl::opt -ASTDump("ast-dump", cl::desc(Options->getOptionHelpText(options::OPT_ast_dump)), - cl::cat(ClangCheckCategory)); + ASTDump("ast-dump", + cl::desc(Options.getOptionHelpText(options::OPT_ast_dump)), + cl::cat(ClangCheckCategory)); static cl::opt -ASTList("ast-list", cl::desc(Options->getOptionHelpText(options::OPT_ast_list)), - cl::cat(ClangCheckCategory)); + ASTList("ast-list", + cl::desc(Options.getOptionHelpText(options::OPT_ast_list)), + cl::cat(ClangCheckCategory)); static cl::opt -ASTPrint("ast-print", - cl::desc(Options->getOptionHelpText(options::OPT_ast_print)), - cl::cat(ClangCheckCategory)); + ASTPrint("ast-print", + cl::desc(Options.getOptionHelpText(options::OPT_ast_print)), + cl::cat(ClangCheckCategory)); static cl::opt ASTDumpFilter( "ast-dump-filter", - cl::desc(Options->getOptionHelpText(options::OPT_ast_dump_filter)), + cl::desc(Options.getOptionHelpText(options::OPT_ast_dump_filter)), cl::cat(ClangCheckCategory)); static cl::opt -Analyze("analyze", cl::desc(Options->getOptionHelpText(options::OPT_analyze)), - cl::cat(ClangCheckCategory)); + Analyze("analyze", + cl::desc(Options.getOptionHelpText(options::OPT_analyze)), + cl::cat(ClangCheckCategory)); static cl::opt -Fixit("fixit", cl::desc(Options->getOptionHelpText(options::OPT_fixit)), - cl::cat(ClangCheckCategory)); + Fixit("fixit", cl::desc(Options.getOptionHelpText(options::OPT_fixit)), + cl::cat(ClangCheckCategory)); static cl::opt FixWhatYouCan( "fix-what-you-can", - cl::desc(Options->getOptionHelpText(options::OPT_fix_what_you_can)), + cl::desc(Options.getOptionHelpText(options::OPT_fix_what_you_can)), cl::cat(ClangCheckCategory)); namespace { Index: cfe/trunk/tools/driver/cc1as_main.cpp =================================================================== --- cfe/trunk/tools/driver/cc1as_main.cpp +++ cfe/trunk/tools/driver/cc1as_main.cpp @@ -176,12 +176,12 @@ bool Success = true; // Parse the arguments. - std::unique_ptr OptTbl(createDriverOptTable()); + const OptTable &OptTbl = getDriverOptTable(); const unsigned IncludedFlagsBitmask = options::CC1AsOption; unsigned MissingArgIndex, MissingArgCount; - InputArgList Args = OptTbl->ParseArgs(Argv, MissingArgIndex, MissingArgCount, - IncludedFlagsBitmask); + InputArgList Args = OptTbl.ParseArgs(Argv, MissingArgIndex, MissingArgCount, + IncludedFlagsBitmask); // Check for missing argument error. if (MissingArgCount) { @@ -194,7 +194,7 @@ for (const Arg *A : Args.filtered(OPT_UNKNOWN)) { auto ArgString = A->getAsString(Args); std::string Nearest; - if (OptTbl->findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1) + if (OptTbl.findNearest(ArgString, Nearest, IncludedFlagsBitmask) > 1) Diags.Report(diag::err_drv_unknown_argument) << ArgString; else Diags.Report(diag::err_drv_unknown_argument_with_suggestion) @@ -574,11 +574,11 @@ return 1; if (Asm.ShowHelp) { - std::unique_ptr Opts(driver::createDriverOptTable()); - Opts->PrintHelp(llvm::outs(), "clang -cc1as [options] file...", - "Clang Integrated Assembler", - /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0, - /*ShowAllAliases=*/false); + getDriverOptTable().PrintHelp( + llvm::outs(), "clang -cc1as [options] file...", + "Clang Integrated Assembler", + /*Include=*/driver::options::CC1AsOption, /*Exclude=*/0, + /*ShowAllAliases=*/false); return 0; } Index: cfe/trunk/tools/driver/driver.cpp =================================================================== --- cfe/trunk/tools/driver/driver.cpp +++ cfe/trunk/tools/driver/driver.cpp @@ -271,10 +271,9 @@ static DiagnosticOptions * CreateAndPopulateDiagOpts(ArrayRef argv) { auto *DiagOpts = new DiagnosticOptions; - std::unique_ptr Opts(createDriverOptTable()); unsigned MissingArgIndex, MissingArgCount; - InputArgList Args = - Opts->ParseArgs(argv.slice(1), MissingArgIndex, MissingArgCount); + InputArgList Args = getDriverOptTable().ParseArgs( + argv.slice(1), MissingArgIndex, MissingArgCount); // We ignore MissingArgCount and the return value of ParseDiagnosticArgs. // Any errors that would be diagnosed here will also be diagnosed later, // when the DiagnosticsEngine actually exists. Index: clang-tools-extra/trunk/modularize/Modularize.cpp =================================================================== --- clang-tools-extra/trunk/modularize/Modularize.cpp +++ clang-tools-extra/trunk/modularize/Modularize.cpp @@ -337,14 +337,13 @@ // Helper function for finding the input file in an arguments list. static std::string findInputFile(const CommandLineArguments &CLArgs) { - std::unique_ptr Opts(createDriverOptTable()); const unsigned IncludedFlagsBitmask = options::CC1Option; unsigned MissingArgIndex, MissingArgCount; SmallVector Argv; for (auto I = CLArgs.begin(), E = CLArgs.end(); I != E; ++I) Argv.push_back(I->c_str()); - InputArgList Args = Opts->ParseArgs(Argv, MissingArgIndex, MissingArgCount, - IncludedFlagsBitmask); + InputArgList Args = getDriverOptTable().ParseArgs( + Argv, MissingArgIndex, MissingArgCount, IncludedFlagsBitmask); std::vector Inputs = Args.getAllArgValues(OPT_INPUT); return ModularizeUtilities::getCanonicalPath(Inputs.back()); }