Unify Options.td and CC1Options.td, in a first step towards unifying the serialization logic in Frontend and Driver.

Reviewed by Eric, Doug and Chandler, and here: http://llvm.org/reviews/r/7/



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155916 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 6046494..e8345fd 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -13,7 +13,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Driver/Arg.h"
 #include "clang/Driver/ArgList.h"
-#include "clang/Driver/CC1Options.h"
+#include "clang/Driver/Options.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/OptTable.h"
 #include "clang/Driver/Option.h"
@@ -910,7 +910,7 @@
 //===----------------------------------------------------------------------===//
 
 using namespace clang::driver;
-using namespace clang::driver::cc1options;
+using namespace clang::driver::options;
 
 //
 
@@ -919,14 +919,66 @@
   unsigned DefaultOpt = 0;
   if (IK == IK_OpenCL && !Args.hasArg(OPT_cl_opt_disable))
     DefaultOpt = 2;
-  // -Os/-Oz implies -O2
-  return (Args.hasArg(OPT_Os) || Args.hasArg (OPT_Oz)) ? 2 :
-    Args.getLastArgIntValue(OPT_O, DefaultOpt, Diags);
+
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O0))
+      return 0;
+
+    assert (A->getOption().matches(options::OPT_O));
+
+    llvm::StringRef S(A->getValue(Args));
+    if (S == "s" || S == "z" || S.empty())
+      return 2;
+
+    return Args.getLastArgIntValue(OPT_O, DefaultOpt, Diags);
+  }
+
+  return DefaultOpt;
+}
+
+static unsigned getOptimizationLevelSize(ArgList &Args, InputKind IK,
+                                         DiagnosticsEngine &Diags) {
+  if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
+    if (A->getOption().matches(options::OPT_O)) {
+      switch (A->getValue(Args)[0]) {
+      default:
+        return 0;
+      case 's':
+        return 1;
+      case 'z':
+        return 2;
+      }
+    }
+  }
+  return 0;
+}
+
+static void addWarningArgs(ArgList &Args, std::vector<std::string> &Warnings) {
+  for (arg_iterator I = Args.filtered_begin(OPT_W_Group),
+         E = Args.filtered_end(); I != E; ++I) {
+    Arg *A = *I;
+    // If the argument is a pure flag, add its name (minus the "-W" at the beginning)
+    // to the warning list. Else, add its value (for the OPT_W case).
+    if (A->getOption().getKind() == Option::FlagClass) {
+      Warnings.push_back(A->getOption().getName().substr(2));
+    } else {
+      for (unsigned Idx = 0, End = A->getNumValues();
+           Idx < End; ++Idx) {
+        StringRef V = A->getValue(Args, Idx);
+        // "-Wl," and such are not warning options.
+        // FIXME: Should be handled by putting these in separate flags.
+        if (V.startswith("l,") || V.startswith("a,") || V.startswith("p,"))
+          continue;
+
+        Warnings.push_back(V);
+      }
+    }
+  }
 }
 
 static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
                               DiagnosticsEngine &Diags) {
-  using namespace cc1options;
+  using namespace options;
   bool Success = true;
   if (Arg *A = Args.getLastArg(OPT_analyzer_store)) {
     StringRef Name = A->getValue(Args);
@@ -1076,7 +1128,7 @@
 
 static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
                              DiagnosticsEngine &Diags) {
-  using namespace cc1options;
+  using namespace options;
   bool Success = true;
 
   unsigned OptLevel = getOptimizationLevel(Args, IK, Diags);
@@ -1096,7 +1148,7 @@
   Opts.Inlining = Args.hasArg(OPT_fno_inline_functions) ?
     CodeGenOptions::OnlyAlwaysInlining : Opts.Inlining;
 
-  if (Args.hasArg(OPT_g)) {
+  if (Args.hasArg(OPT_g_Flag)) {
     if (Args.hasFlag(OPT_flimit_debug_info, OPT_fno_limit_debug_info, true))
       Opts.DebugInfo = CodeGenOptions::LimitedDebugInfo;
     else
@@ -1113,8 +1165,7 @@
   Opts.MergeAllConstants = !Args.hasArg(OPT_fno_merge_all_constants);
   Opts.NoCommon = Args.hasArg(OPT_fno_common);
   Opts.NoImplicitFloat = Args.hasArg(OPT_no_implicit_float);
-  Opts.OptimizeSize = Args.hasArg(OPT_Os);
-  Opts.OptimizeSize = Args.hasArg(OPT_Oz) ? 2 : Opts.OptimizeSize;
+  Opts.OptimizeSize = getOptimizationLevelSize(Args, IK, Diags);
   Opts.SimplifyLibCalls = !(Args.hasArg(OPT_fno_builtin) ||
                             Args.hasArg(OPT_ffreestanding));
   Opts.UnrollLoops = Args.hasArg(OPT_funroll_loops) ||
@@ -1199,7 +1250,7 @@
 
 static void ParseDependencyOutputArgs(DependencyOutputOptions &Opts,
                                       ArgList &Args) {
-  using namespace cc1options;
+  using namespace options;
   Opts.OutputFile = Args.getLastArgValue(OPT_dependency_file);
   Opts.Targets = Args.getAllArgValues(OPT_MT);
   Opts.IncludeSystemHeaders = Args.hasArg(OPT_sys_header_deps);
@@ -1212,7 +1263,7 @@
 
 bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
                                 DiagnosticsEngine *Diags) {
-  using namespace cc1options;
+  using namespace options;
   bool Success = true;
 
   Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file);
@@ -1309,16 +1360,7 @@
   }
   Opts.MessageLength = Args.getLastArgIntValue(OPT_fmessage_length, 0, Diags);
   Opts.DumpBuildInformation = Args.getLastArgValue(OPT_dump_build_information);
-
-  for (arg_iterator it = Args.filtered_begin(OPT_W),
-         ie = Args.filtered_end(); it != ie; ++it) {
-    StringRef V = (*it)->getValue(Args);
-    // "-Wl," and such are not warnings options.
-    if (V.startswith("l,") || V.startswith("a,") || V.startswith("p,"))
-      continue;
-
-    Opts.Warnings.push_back(V);
-  }
+  addWarningArgs(Args, Opts.Warnings);
 
   return Success;
 }
@@ -1329,7 +1371,7 @@
 
 static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
                                    DiagnosticsEngine &Diags) {
-  using namespace cc1options;
+  using namespace options;
   Opts.ProgramAction = frontend::ParseSyntaxOnly;
   if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
     switch (A->getOption().getID()) {
@@ -1549,7 +1591,7 @@
 }
 
 static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
-  using namespace cc1options;
+  using namespace options;
   Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/");
   Opts.Verbose = Args.hasArg(OPT_v);
   Opts.UseBuiltinIncludes = !Args.hasArg(OPT_nobuiltininc);
@@ -1895,7 +1937,7 @@
   Opts.ConstexprCallDepth = Args.getLastArgIntValue(OPT_fconstexpr_depth, 512,
                                                     Diags);
   Opts.DelayedTemplateParsing = Args.hasArg(OPT_fdelayed_template_parsing);
-  Opts.NumLargeByValueCopy = Args.getLastArgIntValue(OPT_Wlarge_by_value_copy,
+  Opts.NumLargeByValueCopy = Args.getLastArgIntValue(OPT_Wlarge_by_value_copy_EQ,
                                                     0, Diags);
   Opts.MSBitfields = Args.hasArg(OPT_mms_bitfields);
   Opts.NeXTRuntime = !Args.hasArg(OPT_fgnu_runtime);
@@ -1908,7 +1950,7 @@
     Args.hasArg(OPT_fobjc_default_synthesize_properties);
   Opts.CatchUndefined = Args.hasArg(OPT_fcatch_undefined_behavior);
   Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
-  Opts.PackStruct = Args.getLastArgIntValue(OPT_fpack_struct, 0, Diags);
+  Opts.PackStruct = Args.getLastArgIntValue(OPT_fpack_struct_EQ, 0, Diags);
   Opts.PICLevel = Args.getLastArgIntValue(OPT_pic_level, 0, Diags);
   Opts.PIELevel = Args.getLastArgIntValue(OPT_pie_level, 0, Diags);
   Opts.Static = Args.hasArg(OPT_static_define);
@@ -1940,7 +1982,7 @@
   // FIXME: Eliminate this dependency.
   unsigned Opt = getOptimizationLevel(Args, IK, Diags);
   Opts.Optimize = Opt != 0;
-  Opts.OptimizeSize = Args.hasArg(OPT_Os) || Args.hasArg(OPT_Oz);
+  Opts.OptimizeSize = getOptimizationLevelSize(Args, IK, Diags);
 
   // This is the __NO_INLINE__ define, which just depends on things like the
   // optimization level and -fno-inline, not actually whether the backend has
@@ -1964,7 +2006,7 @@
 static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
                                   FileManager &FileMgr,
                                   DiagnosticsEngine &Diags) {
-  using namespace cc1options;
+  using namespace options;
   Opts.ImplicitPCHInclude = Args.getLastArgValue(OPT_include_pch);
   Opts.ImplicitPTHInclude = Args.getLastArgValue(OPT_include_pth);
   if (const Arg *A = Args.getLastArg(OPT_token_cache))
@@ -2066,7 +2108,7 @@
 
 static void ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts,
                                         ArgList &Args) {
-  using namespace cc1options;
+  using namespace options;
   Opts.ShowCPP = !Args.hasArg(OPT_dM);
   Opts.ShowComments = Args.hasArg(OPT_C);
   Opts.ShowLineMarkers = !Args.hasArg(OPT_P);
@@ -2075,7 +2117,7 @@
 }
 
 static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
-  using namespace cc1options;
+  using namespace options;
   Opts.ABI = Args.getLastArgValue(OPT_target_abi);
   Opts.CXXABI = Args.getLastArgValue(OPT_cxx_abi);
   Opts.CPU = Args.getLastArgValue(OPT_target_cpu);
@@ -2097,7 +2139,7 @@
   bool Success = true;
 
   // Parse the arguments.
-  OwningPtr<OptTable> Opts(createCC1OptTable());
+  OwningPtr<OptTable> Opts(createDriverOptTable());
   unsigned MissingArgIndex, MissingArgCount;
   OwningPtr<InputArgList> Args(
     Opts->ParseArgs(ArgBegin, ArgEnd,MissingArgIndex, MissingArgCount));
@@ -2116,6 +2158,15 @@
     Success = false;
   }
 
+  // Issue errors on arguments that are not valid for CC1.
+  for (ArgList::iterator I = Args->begin(), E = Args->end();
+       I != E; ++I) {
+    if (!(*I)->getOption().isCC1Option()) {
+      Diags.Report(diag::err_drv_unknown_argument) << (*I)->getAsString(*Args);
+      Success = false;
+    }
+  }
+
   Success = ParseAnalyzerArgs(Res.getAnalyzerOpts(), *Args, Diags) && Success;
   Success = ParseMigratorArgs(Res.getMigratorOpts(), *Args) && Success;
   ParseDependencyOutputArgs(Res.getDependencyOutputOpts(), *Args);