From: Daniel Dunbar Date: Fri, 4 Dec 2009 21:55:23 +0000 (+0000) Subject: Driver: Switch -ccc-* options to using the standard options functionality. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8477ee93c9d81d1b5fe321706ff95bcd219c744b;p=clang Driver: Switch -ccc-* options to using the standard options functionality. - I still want to get rid of them, but manually handling them isn't adding value. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90602 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index bfe80e6c5e..73dcf2e861 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -61,6 +61,55 @@ def clang_ignored_m_Group : OptionGroup<"">, // = => _EQ // C++ => CXX +// Developer Driver Options + +def ccc_Group : OptionGroup<"">; +def ccc_driver_Group : OptionGroup<"">, + Group, HelpText<"DRIVER OPTIONS">; +def ccc_debug_Group : OptionGroup<"">, + Group, HelpText<"DEBUG/DEVELOPMENT OPTIONS">; + +class CCCDriverOpt : Group, Flags<[DriverOption, HelpHidden]>; +def ccc_cxx : Flag<"-ccc-cxx">, CCCDriverOpt, + HelpText<"Act as a C++ driver">; +def ccc_echo : Flag<"-ccc-echo">, CCCDriverOpt, + HelpText<"Echo commands before running them">; +def ccc_gcc_name : Separate<"-ccc-gcc-name">, CCCDriverOpt, + HelpText<"Name for native GCC compiler">, + MetaVarName<"">; +def ccc_clang_cxx : Flag<"-ccc-clang-cxx">, CCCDriverOpt, + HelpText<"Enable the clang compiler for C++">; +def ccc_no_clang_cxx : Flag<"-ccc-no-clang-cxx">, CCCDriverOpt, + HelpText<"Disable the clang compiler for C++">; +def ccc_no_clang : Flag<"-ccc-no-clang">, CCCDriverOpt, + HelpText<"Disable the clang compiler">; +def ccc_no_clang_cpp : Flag<"-ccc-no-clang-cpp">, CCCDriverOpt, + HelpText<"Disable the clang preprocessor">; +def ccc_clang_archs : Separate<"-ccc-clang-archs">, CCCDriverOpt, + HelpText<"Comma separate list of architectures to use the clang compiler for">, + MetaVarName<"">; +def ccc_pch_is_pch : Flag<"-ccc-pch-is-pch">, CCCDriverOpt, + HelpText<"Use lazy PCH for precompiled headers">; +def ccc_pch_is_pth : Flag<"-ccc-pch-is-pth">, CCCDriverOpt, + HelpText<"Use pretokenized headers for precompiled headers">; + +class CCCDebugOpt : Group, Flags<[DriverOption, HelpHidden]>; +def ccc_host_triple : Separate<"-ccc-host-triple">, CCCDebugOpt, + HelpText<"Simulate running on the given target">; +def ccc_install_dir : Separate<"-ccc-install-dir">, CCCDebugOpt, + HelpText<"Simulate installation in the given directory">; +def ccc_print_options : Flag<"-ccc-print-options">, CCCDebugOpt, + HelpText<"Dump parsed command line arguments">; +def ccc_print_phases : Flag<"-ccc-print-phases">, CCCDebugOpt, + HelpText<"Dump list of actions to perform">; +def ccc_print_bindings : Flag<"-ccc-print-bindings">, CCCDebugOpt, + HelpText<"Show bindings of tools to actions">; + +// Make sure all other -ccc- options are rejected. +def ccc_ : Joined<"-ccc-">, Group, Flags<[Unsupported]>; + +// Standard Options + def _HASH_HASH_HASH : Flag<"-###">, Flags<[DriverOption]>, HelpText<"Print the commands to run for this compilation">; def A : JoinedOrSeparate<"-A">; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 7c21594e6f..672c890549 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -113,81 +113,53 @@ Compilation *Driver::BuildCompilation(int argc, const char **argv) { const char **Start = argv + 1, **End = argv + argc; const char *HostTriple = DefaultHostTriple.c_str(); - // Read -ccc args. + InputArgList *Args = ParseArgStrings(Start, End); + + // Extract -ccc args. // // FIXME: We need to figure out where this behavior should live. Most of it // should be outside in the client; the parts that aren't should have proper // options, either by introducing new ones or by overloading gcc ones like -V // or -b. - for (; Start != End && memcmp(*Start, "-ccc-", 5) == 0; ++Start) { - const char *Opt = *Start + 5; - - if (!strcmp(Opt, "print-options")) { - CCCPrintOptions = true; - } else if (!strcmp(Opt, "print-phases")) { - CCCPrintActions = true; - } else if (!strcmp(Opt, "print-bindings")) { - CCCPrintBindings = true; - } else if (!strcmp(Opt, "cxx")) { - CCCIsCXX = true; - } else if (!strcmp(Opt, "echo")) { - CCCEcho = true; - - } else if (!strcmp(Opt, "gcc-name")) { - assert(Start+1 < End && "FIXME: -ccc- argument handling."); - CCCGenericGCCName = *++Start; - - } else if (!strcmp(Opt, "clang-cxx")) { - CCCUseClangCXX = true; - } else if (!strcmp(Opt, "no-clang-cxx")) { - CCCUseClangCXX = false; - } else if (!strcmp(Opt, "pch-is-pch")) { - CCCUsePCH = true; - } else if (!strcmp(Opt, "pch-is-pth")) { - CCCUsePCH = false; - } else if (!strcmp(Opt, "no-clang")) { - CCCUseClang = false; - } else if (!strcmp(Opt, "no-clang-cpp")) { - CCCUseClangCPP = false; - } else if (!strcmp(Opt, "clang-archs")) { - assert(Start+1 < End && "FIXME: -ccc- argument handling."); - llvm::StringRef Cur = *++Start; - - CCCClangArchs.clear(); - while (!Cur.empty()) { - std::pair Split = Cur.split(','); - - if (!Split.first.empty()) { - llvm::Triple::ArchType Arch = - llvm::Triple(Split.first, "", "").getArch(); - - if (Arch == llvm::Triple::UnknownArch) { - // FIXME: Error handling. - llvm::errs() << "invalid arch name: " << Split.first << "\n"; - exit(1); - } - - CCCClangArchs.insert(Arch); + CCCPrintOptions = Args->hasArg(options::OPT_ccc_print_options); + CCCPrintActions = Args->hasArg(options::OPT_ccc_print_phases); + CCCPrintBindings = Args->hasArg(options::OPT_ccc_print_bindings); + CCCIsCXX = Args->hasArg(options::OPT_ccc_cxx); + CCCEcho = Args->hasArg(options::OPT_ccc_echo); + if (const Arg *A = Args->getLastArg(options::OPT_ccc_gcc_name)) + CCCGenericGCCName = A->getValue(*Args); + CCCUseClangCXX = Args->hasFlag(options::OPT_ccc_clang_cxx, + options::OPT_ccc_no_clang_cxx); + CCCUsePCH = Args->hasFlag(options::OPT_ccc_pch_is_pch, + options::OPT_ccc_pch_is_pth); + CCCUseClang = !Args->hasArg(options::OPT_ccc_no_clang); + CCCUseClangCPP = !Args->hasArg(options::OPT_ccc_no_clang_cpp); + if (const Arg *A = Args->getLastArg(options::OPT_ccc_clang_archs)) { + llvm::StringRef Cur = A->getValue(*Args); + + CCCClangArchs.clear(); + while (!Cur.empty()) { + std::pair Split = Cur.split(','); + + if (!Split.first.empty()) { + llvm::Triple::ArchType Arch = + llvm::Triple(Split.first, "", "").getArch(); + + if (Arch == llvm::Triple::UnknownArch) { + Diag(clang::diag::err_drv_invalid_arch_name) << Arch; + continue; } - Cur = Split.second; + CCCClangArchs.insert(Arch); } - } else if (!strcmp(Opt, "host-triple")) { - assert(Start+1 < End && "FIXME: -ccc- argument handling."); - HostTriple = *++Start; - - } else if (!strcmp(Opt, "install-dir")) { - assert(Start+1 < End && "FIXME: -ccc- argument handling."); - Dir = *++Start; - } else { - // FIXME: Error handling. - llvm::errs() << "invalid option: " << *Start << "\n"; - exit(1); + Cur = Split.second; } } - - InputArgList *Args = ParseArgStrings(Start, End); + if (const Arg *A = Args->getLastArg(options::OPT_ccc_host_triple)) + HostTriple = A->getValue(*Args); + if (const Arg *A = Args->getLastArg(options::OPT_ccc_install_dir)) + Dir = A->getValue(*Args); Host = GetHostInfo(HostTriple); @@ -287,112 +259,11 @@ void Driver::PrintOptions(const ArgList &Args) const { } } -static std::string getOptionHelpName(const OptTable &Opts, options::ID Id) { - std::string Name = Opts.getOptionName(Id); - - // Add metavar, if used. - switch (Opts.getOptionKind(Id)) { - case Option::GroupClass: case Option::InputClass: case Option::UnknownClass: - assert(0 && "Invalid option with help text."); - - case Option::MultiArgClass: case Option::JoinedAndSeparateClass: - assert(0 && "Cannot print metavar for this kind of option."); - - case Option::FlagClass: - break; - - case Option::SeparateClass: case Option::JoinedOrSeparateClass: - Name += ' '; - // FALLTHROUGH - case Option::JoinedClass: case Option::CommaJoinedClass: - Name += Opts.getOptionMetaVar(Id); - break; - } - - return Name; -} - // FIXME: Move -ccc options to real options in the .td file (or eliminate), and // then move to using OptTable::PrintHelp. void Driver::PrintHelp(bool ShowHidden) const { - llvm::raw_ostream &OS = llvm::outs(); - - OS << "OVERVIEW: clang \"gcc-compatible\" driver\n"; - OS << '\n'; - OS << "USAGE: " << Name << " [options] \n"; - OS << '\n'; - OS << "OPTIONS:\n"; - - // Render help text into (option, help) pairs. - std::vector< std::pair > OptionHelp; - - for (unsigned i = 0, e = getOpts().getNumOptions(); i != e; ++i) { - options::ID Id = (options::ID) (i + 1); - if (const char *Text = getOpts().getOptionHelpText(Id)) - OptionHelp.push_back(std::make_pair(getOptionHelpName(getOpts(), Id), - Text)); - } - - if (ShowHidden) { - OptionHelp.push_back(std::make_pair("\nDRIVER OPTIONS:","")); - OptionHelp.push_back(std::make_pair("-ccc-cxx", - "Act as a C++ driver")); - OptionHelp.push_back(std::make_pair("-ccc-gcc-name", - "Name for native GCC compiler")); - OptionHelp.push_back(std::make_pair("-ccc-clang-cxx", - "Enable the clang compiler for C++")); - OptionHelp.push_back(std::make_pair("-ccc-no-clang-cxx", - "Disable the clang compiler for C++")); - OptionHelp.push_back(std::make_pair("-ccc-no-clang", - "Disable the clang compiler")); - OptionHelp.push_back(std::make_pair("-ccc-no-clang-cpp", - "Disable the clang preprocessor")); - OptionHelp.push_back(std::make_pair("-ccc-clang-archs", - "Comma separate list of architectures " - "to use the clang compiler for")); - OptionHelp.push_back(std::make_pair("-ccc-pch-is-pch", - "Use lazy PCH for precompiled headers")); - OptionHelp.push_back(std::make_pair("-ccc-pch-is-pth", - "Use pretokenized headers for precompiled headers")); - - OptionHelp.push_back(std::make_pair("\nDEBUG/DEVELOPMENT OPTIONS:","")); - OptionHelp.push_back(std::make_pair("-ccc-host-triple", - "Simulate running on the given target")); - OptionHelp.push_back(std::make_pair("-ccc-install-dir", - "Simulate installation in the given directory")); - OptionHelp.push_back(std::make_pair("-ccc-print-options", - "Dump parsed command line arguments")); - OptionHelp.push_back(std::make_pair("-ccc-print-phases", - "Dump list of actions to perform")); - OptionHelp.push_back(std::make_pair("-ccc-print-bindings", - "Show bindings of tools to actions")); - OptionHelp.push_back(std::make_pair("CCC_ADD_ARGS", - "(ENVIRONMENT VARIABLE) Comma separated list of " - "arguments to prepend to the command line")); - } - - // Find the maximum option length. - unsigned OptionFieldWidth = 0; - for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) { - // Skip titles. - if (!OptionHelp[i].second) - continue; - - // Limit the amount of padding we are willing to give up for alignment. - unsigned Length = OptionHelp[i].first.size(); - if (Length <= 23) - OptionFieldWidth = std::max(OptionFieldWidth, Length); - } - - for (unsigned i = 0, e = OptionHelp.size(); i != e; ++i) { - const std::string &Option = OptionHelp[i].first; - OS << " " << Option; - for (int j = Option.length(), e = OptionFieldWidth; j < e; ++j) - OS << ' '; - OS << ' ' << OptionHelp[i].second << '\n'; - } - - OS.flush(); + getOpts().PrintHelp(llvm::outs(), Name.c_str(), + "clang \"gcc-compatible\" driver", ShowHidden); } void Driver::PrintVersion(const Compilation &C, llvm::raw_ostream &OS) const { diff --git a/test/Driver/ccc-add-args.c b/test/Driver/ccc-add-args.c index 21e4471c12..afd9bd6f76 100644 --- a/test/Driver/ccc-add-args.c +++ b/test/Driver/ccc-add-args.c @@ -1,3 +1,5 @@ // RUN: env CCC_ADD_ARGS="-ccc-echo,-ccc-print-options,,-v" clang -### 2>&1 | FileCheck %s -// CHECK: Option 0 - Name: "-v", Values: {} -// CHECK: Option 1 - Name: "-###", Values: {} +// CHECK: Option 0 - Name: "-ccc-echo", Values: {} +// CHECK: Option 1 - Name: "-ccc-print-options", Values: {} +// CHECK: Option 2 - Name: "-v", Values: {} +// CHECK: Option 3 - Name: "-###", Values: {} diff --git a/test/Driver/parsing.c b/test/Driver/parsing.c index 8e37128e3e..48b9d6a23f 100644 --- a/test/Driver/parsing.c +++ b/test/Driver/parsing.c @@ -1,14 +1,15 @@ // RUN: clang -ccc-print-options input -Yunknown -m32 -arch ppc -djoined -A separate -Ajoined -Wp,one,two -Xarch_joined AndSeparate -sectalign 1 2 3 2> %t -// RUN: grep 'Option 0 - Name: "", Values: {"input"}' %t -// RUN: grep 'Option 1 - Name: "", Values: {"-Yunknown"}' %t -// RUN: grep 'Option 2 - Name: "-m32", Values: {}' %t -// RUN: grep 'Option 3 - Name: "-arch", Values: {"ppc"}' %t -// RUN: grep 'Option 4 - Name: "-d", Values: {"joined"}' %t -// RUN: grep 'Option 5 - Name: "-A", Values: {"separate"}' %t -// RUN: grep 'Option 6 - Name: "-A", Values: {"joined"}' %t -// RUN: grep 'Option 7 - Name: "-Wp,", Values: {"one", "two"}' %t -// RUN: grep 'Option 8 - Name: "-Xarch_", Values: {"joined", "AndSeparate"}' %t -// RUN: grep 'Option 9 - Name: "-sectalign", Values: {"1", "2", "3"}' %t +// RUN: grep 'Option 0 - Name: "-ccc-print-options", Values: {}' %t +// RUN: grep 'Option 1 - Name: "", Values: {"input"}' %t +// RUN: grep 'Option 2 - Name: "", Values: {"-Yunknown"}' %t +// RUN: grep 'Option 3 - Name: "-m32", Values: {}' %t +// RUN: grep 'Option 4 - Name: "-arch", Values: {"ppc"}' %t +// RUN: grep 'Option 5 - Name: "-d", Values: {"joined"}' %t +// RUN: grep 'Option 6 - Name: "-A", Values: {"separate"}' %t +// RUN: grep 'Option 7 - Name: "-A", Values: {"joined"}' %t +// RUN: grep 'Option 8 - Name: "-Wp,", Values: {"one", "two"}' %t +// RUN: grep 'Option 9 - Name: "-Xarch_", Values: {"joined", "AndSeparate"}' %t +// RUN: grep 'Option 10 - Name: "-sectalign", Values: {"1", "2", "3"}' %t // RUN: not clang -V 2> %t // RUN: grep "error: argument to '-V' is missing (expected 1 value)" %t @@ -17,7 +18,8 @@ // Verify that search continues after find the first option. // RUN: clang -ccc-print-options -Wally 2> %t -// RUN: grep 'Option 0 - Name: "-W", Values: {"ally"}' %t +// RUN: grep 'Option 0 - Name: "-ccc-print-options", Values: {}' %t +// RUN: grep 'Option 1 - Name: "-W", Values: {"ally"}' %t diff --git a/test/Driver/qa_override.c b/test/Driver/qa_override.c index 6f72078f12..822410659e 100644 --- a/test/Driver/qa_override.c +++ b/test/Driver/qa_override.c @@ -1,5 +1,6 @@ // RUN: env QA_OVERRIDE_GCC3_OPTIONS="#+-Os +-Oz +-O +-O3 +-Oignore +a +b +c xb Xa Omagic ^-ccc-print-options " clang x -O2 b -O3 2>&1 | FileCheck %s // CHECK-NOT: ### -// CHECK: Option 0 - Name: "", Values: {"x"} -// CHECK-NEXT: Option 1 - Name: "-O", Values: {"ignore"} -// CHECK-NEXT: Option 2 - Name: "-O", Values: {"magic"} +// CHECK: Option 0 - Name: "-ccc-print-options", Values: {} +// CHECK-NEXT: Option 1 - Name: "", Values: {"x"} +// CHECK-NEXT: Option 2 - Name: "-O", Values: {"ignore"} +// CHECK-NEXT: Option 3 - Name: "-O", Values: {"magic"}