From 2f3055c543f8f5e8cd975350fae5f4b0ac4871c3 Mon Sep 17 00:00:00 2001 From: Jan Svoboda Date: Fri, 13 Nov 2020 14:17:54 +0100 Subject: [clang][cli] Add support for options with two flags for controlling the same field. This enables automatically parsing and generating CC1 arguments for options where two flags control the same field, e.g. -fexperimental-new-pass-manager and -fno-experimental new pass manager. Reviewed By: Bigcheese, dexonsmith Original patch by Daniel Grumberg. Differential Revision: https://reviews.llvm.org/D83071 --- clang/lib/Frontend/CompilerInvocation.cpp | 70 ++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 11 deletions(-) (limited to 'clang/lib/Frontend/CompilerInvocation.cpp') diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2e20ece..c4133ec 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -134,6 +134,13 @@ static llvm::Optional normalizeSimpleFlag(OptSpecifier Opt, return None; } +void denormalizeSimpleFlag(SmallVectorImpl &Args, + const char *Spelling, + CompilerInvocation::StringAllocator SA, + unsigned TableIndex, unsigned Value) { + Args.push_back(Spelling); +} + template static llvm::Optional normalizeFlagToValue(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, @@ -143,6 +150,27 @@ normalizeFlagToValue(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, return None; } +static Optional normalizeBooleanFlag(OptSpecifier PosOpt, + OptSpecifier NegOpt, + unsigned TableIndex, + const ArgList &Args, + DiagnosticsEngine &Diags) { + if (const Arg *A = Args.getLastArg(PosOpt, NegOpt)) + return A->getOption().matches(PosOpt); + return None; +} + +static void denormalizeBooleanFlag(SmallVectorImpl &Args, + const char *Spelling, + const char *NegSpelling, + CompilerInvocation::StringAllocator SA, + unsigned TableIndex, unsigned Value) { + if (Value) + Args.push_back(Spelling); + else + Args.push_back(NegSpelling); +} + static llvm::Optional normalizeSimpleEnum(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, @@ -165,12 +193,14 @@ static llvm::Optional normalizeSimpleEnum(OptSpecifier Opt, } static void denormalizeSimpleEnum(SmallVectorImpl &Args, + const char *Spelling, CompilerInvocation::StringAllocator SA, unsigned TableIndex, unsigned Value) { assert(TableIndex < SimpleEnumValueTablesSize); const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; for (int I = 0, E = Table.Size; I != E; ++I) { if (Value == Table.Table[I].Value) { + Args.push_back(Spelling); Args.push_back(Table.Table[I].Name); return; } @@ -181,8 +211,10 @@ static void denormalizeSimpleEnum(SmallVectorImpl &Args, } static void denormalizeString(SmallVectorImpl &Args, + const char *Spelling, CompilerInvocation::StringAllocator SA, unsigned TableIndex, const std::string &Value) { + Args.push_back(Spelling); Args.push_back(SA(Value)); } @@ -777,10 +809,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } } - Opts.ExperimentalNewPassManager = Args.hasFlag( - OPT_fexperimental_new_pass_manager, OPT_fno_experimental_new_pass_manager, - /* Default */ ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER); - Opts.DebugPassManager = Args.hasFlag(OPT_fdebug_pass_manager, OPT_fno_debug_pass_manager, /* Default */ false); @@ -3741,7 +3769,21 @@ bool CompilerInvocation::parseSimpleArgs(const ArgList &Args, this->KEYPATH = MERGER(this->KEYPATH, static_cast(*MaybeValue)); \ } +#define OPTION_WITH_MARSHALLING_BOOLEAN( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX, NEG_ID, \ + NEG_SPELLING) \ + { \ + if (auto MaybeValue = \ + NORMALIZER(OPT_##ID, OPT_##NEG_ID, TABLE_INDEX, Args, Diags)) \ + this->KEYPATH = MERGER(this->KEYPATH, static_cast(*MaybeValue)); \ + else \ + this->KEYPATH = MERGER(this->KEYPATH, DEFAULT_VALUE); \ + } + #include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_BOOLEAN #undef OPTION_WITH_MARSHALLING return true; } @@ -4000,16 +4042,22 @@ void CompilerInvocation::generateCC1CommandLine( TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ if (((FLAGS) & options::CC1Option) && \ (ALWAYS_EMIT || EXTRACTOR(this->KEYPATH) != (DEFAULT_VALUE))) { \ - if (Option::KIND##Class == Option::FlagClass) { \ - Args.push_back(SPELLING); \ - } \ - if (Option::KIND##Class == Option::SeparateClass) { \ - Args.push_back(SPELLING); \ - DENORMALIZER(Args, SA, TABLE_INDEX, EXTRACTOR(this->KEYPATH)); \ - } \ + DENORMALIZER(Args, SPELLING, SA, TABLE_INDEX, EXTRACTOR(this->KEYPATH)); \ + } + +#define OPTION_WITH_MARSHALLING_BOOLEAN( \ + PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \ + HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + TYPE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX, NEG_ID, \ + NEG_SPELLING) \ + if (((FLAGS)&options::CC1Option) && \ + (ALWAYS_EMIT || EXTRACTOR(this->KEYPATH) != DEFAULT_VALUE)) { \ + DENORMALIZER(Args, SPELLING, NEG_SPELLING, SA, TABLE_INDEX, \ + EXTRACTOR(this->KEYPATH)); \ } #include "clang/Driver/Options.inc" +#undef OPTION_WITH_MARSHALLING_BOOLEAN #undef OPTION_WITH_MARSHALLING } -- cgit v1.1