diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -271,7 +271,7 @@ multiclass BooleanMarshalledFFlag { def fno_#NAME : Flag<["-"], "fno-"#name>, HelpText; def f#NAME : Flag<["-"], "f"#name>, HelpText, - MarshallingInfoBooleanFlag("fno_"#NAME)>; + MarshallingInfoBooleanFlag; } ///////// diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -185,25 +185,21 @@ return FlagToValueNormalizer{std::move(Value)}; } -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 auto makeBooleanFlagNormalizer(OptSpecifier NegOpt) { + return [NegOpt](OptSpecifier PosOpt, unsigned, const ArgList &Args, + DiagnosticsEngine &) -> Optional { + 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 auto makeBooleanFlagDenormalizer(const char *NegSpelling) { + return [NegSpelling]( + SmallVectorImpl &Args, const char *PosSpelling, + CompilerInvocation::StringAllocator, unsigned, unsigned Value) { + Args.push_back(Value ? PosSpelling : NegSpelling); + }; } static Optional @@ -3779,23 +3775,7 @@ this->KEYPATH, static_castKEYPATH)>(*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, \ - IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \ - TABLE_INDEX, NEG_ID, NEG_SPELLING) \ - { \ - this->KEYPATH = MERGER(this->KEYPATH, DEFAULT_VALUE); \ - if (IMPLIED_CHECK) \ - this->KEYPATH = MERGER(this->KEYPATH, IMPLIED_VALUE); \ - if (auto MaybeValue = \ - NORMALIZER(OPT_##ID, OPT_##NEG_ID, TABLE_INDEX, Args, Diags)) \ - this->KEYPATH = MERGER( \ - this->KEYPATH, static_castKEYPATH)>(*MaybeValue)); \ - } - #include "clang/Driver/Options.inc" -#undef OPTION_WITH_MARSHALLING_BOOLEAN #undef OPTION_WITH_MARSHALLING return true; } @@ -4060,20 +4040,7 @@ }(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, \ - IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \ - TABLE_INDEX, NEG_ID, NEG_SPELLING) \ - if ((FLAGS)&options::CC1Option) { \ - bool Extracted = EXTRACTOR(this->KEYPATH); \ - if (ALWAYS_EMIT || \ - (Extracted != ((IMPLIED_CHECK) ? (IMPLIED_VALUE) : (DEFAULT_VALUE)))) \ - DENORMALIZER(Args, SPELLING, NEG_SPELLING, SA, TABLE_INDEX, Extracted); \ - } - #include "clang/Driver/Options.inc" -#undef OPTION_WITH_MARSHALLING_BOOLEAN #undef OPTION_WITH_MARSHALLING } diff --git a/llvm/include/llvm/Option/OptParser.td b/llvm/include/llvm/Option/OptParser.td --- a/llvm/include/llvm/Option/OptParser.td +++ b/llvm/include/llvm/Option/OptParser.td @@ -97,7 +97,6 @@ OptionGroup Group = ?; Option Alias = ?; list AliasArgs = []; - string MarshallingInfoKind = ?; code KeyPath = ?; code DefaultValue = ?; code ImpliedValue = ?; @@ -110,8 +109,6 @@ code ValueMerger = "mergeForwardValue"; code ValueExtractor = "extractForwardValue"; list NormalizedValues = ?; - // Used for BooleanFlagKind - Option NegOption = ?; } // Helpers for defining options. @@ -154,7 +151,6 @@ } class MarshallingInfo { - string MarshallingInfoKind = "Default"; code KeyPath = keypath; code DefaultValue = defaultvalue; } @@ -175,13 +171,11 @@ code ValueExtractor = "(extractMaskValue)"; } -class MarshallingInfoBooleanFlag +class MarshallingInfoBooleanFlag : MarshallingInfoFlag { bit ShouldAlwaysEmit = 1; - string MarshallingInfoKind = "BooleanFlag"; - code Normalizer = "normalizeBooleanFlag"; - code Denormalizer = "denormalizeBooleanFlag"; - Option NegOption = negopt; + code Normalizer = "makeBooleanFlagNormalizer(OPT_"#neg_name#")"; + code Denormalizer = "makeBooleanFlagDenormalizer(\""#neg_spelling#"\")"; } // Mixins for additional marshalling attributes. diff --git a/llvm/utils/TableGen/OptParserEmitter.cpp b/llvm/utils/TableGen/OptParserEmitter.cpp --- a/llvm/utils/TableGen/OptParserEmitter.cpp +++ b/llvm/utils/TableGen/OptParserEmitter.cpp @@ -63,9 +63,7 @@ class MarshallingInfo { public: - using Ptr = std::unique_ptr; - - const char *MacroName; + static constexpr const char *MacroName = "OPTION_WITH_MARSHALLING"; const Record &R; bool ShouldAlwaysEmit; StringRef KeyPath; @@ -99,14 +97,9 @@ static constexpr const char *ValueTablesDecl = "static const SimpleEnumValueTable SimpleEnumValueTables[] = "; - MarshallingInfo(const Record &R) - : MacroName("OPTION_WITH_MARSHALLING"), R(R) {} - MarshallingInfo(const char *MacroName, const Record &R) - : MacroName(MacroName), R(R){}; - - virtual ~MarshallingInfo() = default; + MarshallingInfo(const Record &R) : R(R) {} - virtual void emit(raw_ostream &OS) const { + void emit(raw_ostream &OS) const { write_cstring(OS, StringRef(getOptionSpelling(R))); OS << ", "; OS << ShouldAlwaysEmit; @@ -157,59 +150,35 @@ size_t MarshallingInfo::NextTableIndex = 0; -class MarshallingInfoBooleanFlag : public MarshallingInfo { -public: - const Record &NegOption; - - MarshallingInfoBooleanFlag(const Record &Option, const Record &NegOption) - : MarshallingInfo("OPTION_WITH_MARSHALLING_BOOLEAN", Option), - NegOption(NegOption) {} - - void emit(raw_ostream &OS) const override { - MarshallingInfo::emit(OS); - OS << ", "; - OS << getOptionName(NegOption); - OS << ", "; - write_cstring(OS, getOptionSpelling(NegOption)); - } -}; - -static MarshallingInfo::Ptr createMarshallingInfo(const Record &R) { +static MarshallingInfo createMarshallingInfo(const Record &R) { assert(!isa(R.getValueInit("KeyPath")) && !isa(R.getValueInit("DefaultValue")) && !isa(R.getValueInit("ValueMerger")) && "MarshallingInfo must have a provide a keypath, default value and a " "value merger"); - MarshallingInfo::Ptr Ret; - StringRef KindString = R.getValueAsString("MarshallingInfoKind"); - if (KindString == "Default") { - Ret = std::make_unique(R); - } else if (KindString == "BooleanFlag") { - Ret = std::make_unique( - R, *R.getValueAsDef("NegOption")); - } + MarshallingInfo Ret(R); - Ret->ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit"); - Ret->KeyPath = R.getValueAsString("KeyPath"); - Ret->DefaultValue = R.getValueAsString("DefaultValue"); - Ret->NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope"); - Ret->ImpliedCheck = R.getValueAsString("ImpliedCheck"); - Ret->ImpliedValue = - R.getValueAsOptionalString("ImpliedValue").getValueOr(Ret->DefaultValue); + Ret.ShouldAlwaysEmit = R.getValueAsBit("ShouldAlwaysEmit"); + Ret.KeyPath = R.getValueAsString("KeyPath"); + Ret.DefaultValue = R.getValueAsString("DefaultValue"); + Ret.NormalizedValuesScope = R.getValueAsString("NormalizedValuesScope"); + Ret.ImpliedCheck = R.getValueAsString("ImpliedCheck"); + Ret.ImpliedValue = + R.getValueAsOptionalString("ImpliedValue").getValueOr(Ret.DefaultValue); - Ret->Normalizer = R.getValueAsString("Normalizer"); - Ret->Denormalizer = R.getValueAsString("Denormalizer"); - Ret->ValueMerger = R.getValueAsString("ValueMerger"); - Ret->ValueExtractor = R.getValueAsString("ValueExtractor"); + Ret.Normalizer = R.getValueAsString("Normalizer"); + Ret.Denormalizer = R.getValueAsString("Denormalizer"); + Ret.ValueMerger = R.getValueAsString("ValueMerger"); + Ret.ValueExtractor = R.getValueAsString("ValueExtractor"); if (!isa(R.getValueInit("NormalizedValues"))) { assert(!isa(R.getValueInit("Values")) && "Cannot provide normalized values for value-less options"); - Ret->TableIndex = MarshallingInfo::NextTableIndex++; - Ret->NormalizedValues = R.getValueAsListOfStrings("NormalizedValues"); - Ret->Values.reserve(Ret->NormalizedValues.size()); - Ret->ValueTableName = getOptionName(R) + "ValueTable"; + Ret.TableIndex = MarshallingInfo::NextTableIndex++; + Ret.NormalizedValues = R.getValueAsListOfStrings("NormalizedValues"); + Ret.Values.reserve(Ret.NormalizedValues.size()); + Ret.ValueTableName = getOptionName(R) + "ValueTable"; StringRef ValuesStr = R.getValueAsString("Values"); for (;;) { @@ -217,22 +186,18 @@ if (Idx == StringRef::npos) break; if (Idx > 0) - Ret->Values.push_back(ValuesStr.slice(0, Idx)); + Ret.Values.push_back(ValuesStr.slice(0, Idx)); ValuesStr = ValuesStr.slice(Idx + 1, StringRef::npos); } if (!ValuesStr.empty()) - Ret->Values.push_back(ValuesStr); + Ret.Values.push_back(ValuesStr); - assert(Ret->Values.size() == Ret->NormalizedValues.size() && + assert(Ret.Values.size() == Ret.NormalizedValues.size() && "The number of normalized values doesn't match the number of " "values"); } - // FIXME: This is a workaround for a bug in older versions of clang (< 3.9) - // The constructor that is supposed to allow for Derived to Base - // conversion does not work. Remove this if we drop support for such - // configurations. - return MarshallingInfo::Ptr(Ret.release()); + return Ret; } /// OptParserEmitter - This tablegen backend takes an input .td file @@ -458,18 +423,18 @@ array_pod_sort(OptsWithMarshalling.begin(), OptsWithMarshalling.end(), CmpMarshallingOpts); - std::vector MarshallingInfos; + std::vector MarshallingInfos; for (const auto *R : OptsWithMarshalling) MarshallingInfos.push_back(createMarshallingInfo(*R)); for (const auto &MI : MarshallingInfos) { - OS << "#ifdef " << MI->MacroName << "\n"; - OS << MI->MacroName << "("; - WriteOptRecordFields(OS, MI->R); + OS << "#ifdef " << MarshallingInfo::MacroName << "\n"; + OS << MarshallingInfo::MacroName << "("; + WriteOptRecordFields(OS, MI.R); OS << ", "; - MI->emit(OS); + MI.emit(OS); OS << ")\n"; - OS << "#endif // " << MI->MacroName << "\n"; + OS << "#endif // " << MarshallingInfo::MacroName << "\n"; } OS << "\n"; @@ -478,7 +443,7 @@ OS << MarshallingInfo::ValueTablePreamble; std::vector ValueTableNames; for (const auto &MI : MarshallingInfos) - if (auto MaybeValueTableName = MI->emitValueTable(OS)) + if (auto MaybeValueTableName = MI.emitValueTable(OS)) ValueTableNames.push_back(*MaybeValueTableName); OS << MarshallingInfo::ValueTablesDecl << "{";