Add clang -cc1 parsing of CodeGenOptions.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89464 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Driver/CC1Options.cpp b/lib/Driver/CC1Options.cpp
index c9bb5d0..7655770 100644
--- a/lib/Driver/CC1Options.cpp
+++ b/lib/Driver/CC1Options.cpp
@@ -55,6 +55,21 @@
   return Default;
 }
 
+static int getLastArgIntValue(ArgList &Args, cc1options::ID ID,
+                              int Default = 0) {
+  Arg *A = Args.getLastArg(ID);
+  if (!A)
+    return Default;
+
+  int Res = Default;
+  // FIXME: What to do about argument parsing errors?
+  if (llvm::StringRef(A->getValue(Args)).getAsInteger(10, Res))
+    llvm::errs() << "error: invalid integral argument in '"
+                 << A->getAsString(Args) << "'\n";
+
+  return Res;
+}
+
 static std::vector<std::string>
 getAllArgValues(ArgList &Args, cc1options::ID ID) {
   llvm::SmallVector<const char *, 16> Values;
@@ -62,6 +77,50 @@
   return std::vector<std::string>(Values.begin(), Values.end());
 }
 
+//
+
+static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args) {
+  // -Os implies -O2
+  if (Args.hasArg(cc1options::OPT_Os))
+    Opts.OptimizationLevel = 2;
+  else
+    Opts.OptimizationLevel = getLastArgIntValue(Args, cc1options::OPT_O);
+
+  // FIXME: What to do about argument parsing errors?
+  if (Opts.OptimizationLevel > 3) {
+    llvm::errs() << "error: invalid optimization level '"
+                 << Opts.OptimizationLevel << "' (out of range)\n";
+    Opts.OptimizationLevel = 3;
+  }
+
+  // We must always run at least the always inlining pass.
+  Opts.Inlining = (Opts.OptimizationLevel > 1) ? CodeGenOptions::NormalInlining
+    : CodeGenOptions::OnlyAlwaysInlining;
+
+  Opts.DebugInfo = Args.hasArg(cc1options::OPT_g);
+  Opts.DisableLLVMOpts = Args.hasArg(cc1options::OPT_disable_llvm_optzns);
+  Opts.DisableRedZone = Args.hasArg(cc1options::OPT_disable_red_zone);
+  Opts.MergeAllConstants = !Args.hasArg(cc1options::OPT_fno_merge_all_constants);
+  Opts.NoCommon = Args.hasArg(cc1options::OPT_fno_common);
+  Opts.NoImplicitFloat = Args.hasArg(cc1options::OPT_no_implicit_float);
+  Opts.OptimizeSize = Args.hasArg(cc1options::OPT_Os);
+  Opts.SimplifyLibCalls = 1;
+  Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize);
+
+  // FIXME: Implement!
+  // FIXME: Eliminate this dependency?
+//   if (Lang.NoBuiltin)
+//     Opts.SimplifyLibCalls = 0;
+//   if (Lang.CPlusPlus)
+//     Opts.NoCommon = 1;
+//   Opts.TimePasses = TimePasses;
+
+  // FIXME: Put elsewhere?
+#ifdef NDEBUG
+  Opts.VerifyModule = 0;
+#endif
+}
+
 static void ParseTargetArgs(TargetOptions &Opts, ArgList &Args) {
   Opts.ABI = getLastArgValue(Args, cc1options::OPT_target_abi);
   Opts.CPU = getLastArgValue(Args, cc1options::OPT_mcpu);
@@ -73,6 +132,8 @@
     Opts.Triple = llvm::sys::getHostTriple();
 }
 
+//
+
 void CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
                            const llvm::SmallVectorImpl<llvm::StringRef> &Args) {
   // This is gratuitous, but until we switch the driver to using StringRe we
@@ -98,5 +159,6 @@
                  << " value )\n";
   }
 
+  ParseCodeGenArgs(Res.getCodeGenOpts(), *InputArgs);
   ParseTargetArgs(Res.getTargetOpts(), *InputArgs);
 }
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 89fd70a..eecd976 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -102,7 +102,8 @@
     Res.push_back("-disable-red-zone");
   if (!Opts.MergeAllConstants)
     Res.push_back("-fno-merge-all-constants");
-  // NoCommon is only derived.
+  if (Opts.NoCommon)
+    Res.push_back("-fno-common");
   if (Opts.NoImplicitFloat)
     Res.push_back("-no-implicit-float");
   if (Opts.OptimizeSize) {