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);