[llvm-branch-commits] [llvm] 083e035 - [clang][cli] Unify boolean marshalling
Jan Svoboda via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Dec 8 04:51:50 PST 2020
Author: Jan Svoboda
Date: 2020-12-08T13:47:30+01:00
New Revision: 083e035c47f6c73084ecf5ab7f41cddca19ce332
URL: https://github.com/llvm/llvm-project/commit/083e035c47f6c73084ecf5ab7f41cddca19ce332
DIFF: https://github.com/llvm/llvm-project/commit/083e035c47f6c73084ecf5ab7f41cddca19ce332.diff
LOG: [clang][cli] Unify boolean marshalling
Use lambdas with captures to replace the redundant infrastructure for marshalling of two boolean flags that control the same keypath.
Reviewed By: dexonsmith
Differential Revision: https://reviews.llvm.org/D92773
Added:
Modified:
clang/include/clang/Driver/Options.td
clang/lib/Frontend/CompilerInvocation.cpp
llvm/include/llvm/Option/OptParser.td
llvm/utils/TableGen/OptParserEmitter.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index c6159f50b781..794aa24f997d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -271,7 +271,7 @@ multiclass OptOutFFlag<string name, string pos_prefix, string neg_prefix,
multiclass BooleanMarshalledFFlag<string name, code keypath, code default_value, string pos_help = "", string neg_help=""> {
def fno_#NAME : Flag<["-"], "fno-"#name>, HelpText<neg_help>;
def f#NAME : Flag<["-"], "f"#name>, HelpText<pos_help>,
- MarshallingInfoBooleanFlag<keypath, default_value, !cast<Option>("fno_"#NAME)>;
+ MarshallingInfoBooleanFlag<keypath, default_value, "fno_"#NAME, "-fno-"#name>;
}
/////////
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index e31f6aa34b36..547dadd37931 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -185,25 +185,21 @@ static FlagToValueNormalizer<T> makeFlagToValueNormalizer(T Value) {
return FlagToValueNormalizer<T>{std::move(Value)};
}
-static Optional<bool> 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<bool> {
+ if (const Arg *A = Args.getLastArg(PosOpt, NegOpt))
+ return A->getOption().matches(PosOpt);
+ return None;
+ };
}
-static void denormalizeBooleanFlag(SmallVectorImpl<const char *> &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<const char *> &Args, const char *PosSpelling,
+ CompilerInvocation::StringAllocator, unsigned, unsigned Value) {
+ Args.push_back(Value ? PosSpelling : NegSpelling);
+ };
}
static Optional<SimpleEnumValue>
@@ -3779,23 +3775,7 @@ bool CompilerInvocation::parseSimpleArgs(const ArgList &Args,
this->KEYPATH, static_cast<decltype(this->KEYPATH)>(*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_cast<decltype(this->KEYPATH)>(*MaybeValue)); \
- }
-
#include "clang/Driver/Options.inc"
-#undef OPTION_WITH_MARSHALLING_BOOLEAN
#undef OPTION_WITH_MARSHALLING
return true;
}
@@ -4060,20 +4040,7 @@ void CompilerInvocation::generateCC1CommandLine(
}(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
index 717b5facf53e..9a935b5d9e6e 100644
--- a/llvm/include/llvm/Option/OptParser.td
+++ b/llvm/include/llvm/Option/OptParser.td
@@ -97,7 +97,6 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
OptionGroup Group = ?;
Option Alias = ?;
list<string> AliasArgs = [];
- string MarshallingInfoKind = ?;
code KeyPath = ?;
code DefaultValue = ?;
code ImpliedValue = ?;
@@ -110,8 +109,6 @@ class Option<list<string> prefixes, string name, OptionKind kind> {
code ValueMerger = "mergeForwardValue";
code ValueExtractor = "extractForwardValue";
list<code> NormalizedValues = ?;
- // Used for BooleanFlagKind
- Option NegOption = ?;
}
// Helpers for defining options.
@@ -154,7 +151,6 @@ class ImpliedByAnyOf<list<Option> options, code value = "true"> {
}
class MarshallingInfo<code keypath, code defaultvalue> {
- string MarshallingInfoKind = "Default";
code KeyPath = keypath;
code DefaultValue = defaultvalue;
}
@@ -175,13 +171,11 @@ class MarshallingInfoBitfieldFlag<code keypath, code value>
code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)";
}
-class MarshallingInfoBooleanFlag<code keypath, code defaultvalue, Option negopt>
+class MarshallingInfoBooleanFlag<code keypath, code defaultvalue, code neg_name, string neg_spelling>
: MarshallingInfoFlag<keypath, defaultvalue> {
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
index edbe66630572..b3fe9d7a91d1 100644
--- a/llvm/utils/TableGen/OptParserEmitter.cpp
+++ b/llvm/utils/TableGen/OptParserEmitter.cpp
@@ -63,9 +63,7 @@ static void emitNameUsingSpelling(raw_ostream &OS, const Record &R) {
class MarshallingInfo {
public:
- using Ptr = std::unique_ptr<MarshallingInfo>;
-
- const char *MacroName;
+ static constexpr const char *MacroName = "OPTION_WITH_MARSHALLING";
const Record &R;
bool ShouldAlwaysEmit;
StringRef KeyPath;
@@ -99,14 +97,9 @@ struct SimpleEnumValueTable {
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 @@ struct SimpleEnumValueTable {
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<UnsetInit>(R.getValueInit("KeyPath")) &&
!isa<UnsetInit>(R.getValueInit("DefaultValue")) &&
!isa<UnsetInit>(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<MarshallingInfo>(R);
- } else if (KindString == "BooleanFlag") {
- Ret = std::make_unique<MarshallingInfoBooleanFlag>(
- 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<UnsetInit>(R.getValueInit("NormalizedValues"))) {
assert(!isa<UnsetInit>(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 @@ static MarshallingInfo::Ptr createMarshallingInfo(const Record &R) {
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 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
array_pod_sort(OptsWithMarshalling.begin(), OptsWithMarshalling.end(),
CmpMarshallingOpts);
- std::vector<MarshallingInfo::Ptr> MarshallingInfos;
+ std::vector<MarshallingInfo> 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 @@ void EmitOptParser(RecordKeeper &Records, raw_ostream &OS) {
OS << MarshallingInfo::ValueTablePreamble;
std::vector<StringRef> 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 << "{";
More information about the llvm-branch-commits
mailing list