mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[clang][cli] Specify KeyPath prefixes via TableGen classes
It turns out we need to handle `LangOptions` separately from the rest of the options. `LangOptions` used to be conditionally parsed only when `!(DashX.getFormat() == InputKind::Precompiled || DashX.getLanguage() == Language::LLVM_IR)` and we need to restore this order (for more info, see D94682). We could do this similarly to how `DiagnosticOptions` are handled: via a counterpart to the `IsDiag` mix-in (e.g. `IsLang`). These mix-ins would prefix the option key path with the appropriate `CompilerInvocation::XxxOpts` member. However, this solution would be problematic, as we'd now have two kinds of options (`Lang` and `Diag`) with seemingly incomplete key paths in the same file. To understand what `CompilerInvocation` member an option affects, one would need to read the whole option definition and notice the `IsDiag` or `IsLang` class. Instead, this patch introduces more robust way to handle different kinds of options separately: via the `KeyPathAndMacroPrefix` class. We have one specialization of that class per `CompilerInvocation` member (e.g. `LangOpts`, `DiagnosticOpts`, etc.). Now, instead of specifying a key path with `"LangOpts->UndefPrefixes"`, we use `LangOpts<"UndefPrefixes">`. This keeps the readability intact (you don't have to look for the `IsLang` mix-in, the key path is complete on its own) and allows us to specify a custom macro prefix within `LangOpts`. Reviewed By: Bigcheese Differential Revision: https://reviews.llvm.org/D94676
This commit is contained in:
parent
39185b091b
commit
4f287c334a
@ -146,58 +146,67 @@ class ValuesCode<code valuecode> { code ValuesCode = valuecode; }
|
||||
|
||||
// Helpers for defining marshalling information.
|
||||
|
||||
class KeyPathAndMacro<string key_path_prefix, string key_path_base,
|
||||
string macro_prefix = ""> {
|
||||
code KeyPath = !strconcat(key_path_prefix, key_path_base);
|
||||
code MacroPrefix = macro_prefix;
|
||||
}
|
||||
|
||||
def EmptyKPM : KeyPathAndMacro<"", "">;
|
||||
|
||||
class ImpliedByAnyOf<list<Option> options, code value = "true"> {
|
||||
code ImpliedCheck = !foldl("false", options, accumulator, option,
|
||||
!strconcat(accumulator, " || ", option.KeyPath));
|
||||
code ImpliedValue = value;
|
||||
}
|
||||
|
||||
class MarshallingInfo<code keypath, code defaultvalue> {
|
||||
code KeyPath = keypath;
|
||||
class MarshallingInfo<KeyPathAndMacro kpm, code defaultvalue> {
|
||||
code KeyPath = kpm.KeyPath;
|
||||
code MacroPrefix = kpm.MacroPrefix;
|
||||
code DefaultValue = defaultvalue;
|
||||
}
|
||||
|
||||
class MarshallingInfoString<code keypath, code defaultvalue="std::string()">
|
||||
: MarshallingInfo<keypath, defaultvalue> {
|
||||
class MarshallingInfoString<KeyPathAndMacro kpm, code defaultvalue="std::string()">
|
||||
: MarshallingInfo<kpm, defaultvalue> {
|
||||
code Normalizer = "normalizeString";
|
||||
code Denormalizer = "denormalizeString";
|
||||
}
|
||||
|
||||
class MarshallingInfoStringInt<code keypath, code defaultvalue="0", code type="unsigned">
|
||||
: MarshallingInfo<keypath, defaultvalue> {
|
||||
class MarshallingInfoStringInt<KeyPathAndMacro kpm, code defaultvalue="0", code type="unsigned">
|
||||
: MarshallingInfo<kpm, defaultvalue> {
|
||||
code Normalizer = "normalizeStringIntegral<"#type#">";
|
||||
code Denormalizer = "denormalizeString";
|
||||
}
|
||||
|
||||
class MarshallingInfoStringVector<code keypath>
|
||||
: MarshallingInfo<keypath, "std::vector<std::string>({})"> {
|
||||
class MarshallingInfoStringVector<KeyPathAndMacro kpm>
|
||||
: MarshallingInfo<kpm, "std::vector<std::string>({})"> {
|
||||
code Normalizer = "normalizeStringVector";
|
||||
code Denormalizer = "denormalizeStringVector";
|
||||
}
|
||||
|
||||
class MarshallingInfoFlag<code keypath, code defaultvalue = "false">
|
||||
: MarshallingInfo<keypath, defaultvalue> {
|
||||
class MarshallingInfoFlag<KeyPathAndMacro kpm, code defaultvalue = "false">
|
||||
: MarshallingInfo<kpm, defaultvalue> {
|
||||
code Normalizer = "normalizeSimpleFlag";
|
||||
code Denormalizer = "denormalizeSimpleFlag";
|
||||
}
|
||||
|
||||
class MarshallingInfoNegativeFlag<code keypath, code defaultvalue = "true">
|
||||
: MarshallingInfo<keypath, defaultvalue> {
|
||||
class MarshallingInfoNegativeFlag<KeyPathAndMacro kpm, code defaultvalue = "true">
|
||||
: MarshallingInfo<kpm, defaultvalue> {
|
||||
code Normalizer = "normalizeSimpleNegativeFlag";
|
||||
code Denormalizer = "denormalizeSimpleFlag";
|
||||
}
|
||||
|
||||
class MarshallingInfoBitfieldFlag<code keypath, code value>
|
||||
: MarshallingInfoFlag<keypath, "0u"> {
|
||||
class MarshallingInfoBitfieldFlag<KeyPathAndMacro kpm, code value>
|
||||
: MarshallingInfoFlag<kpm, "0u"> {
|
||||
code Normalizer = "makeFlagToValueNormalizer("#value#")";
|
||||
code ValueMerger = "mergeMaskValue";
|
||||
code ValueExtractor = "(extractMaskValue<unsigned, decltype("#value#"), "#value#">)";
|
||||
}
|
||||
|
||||
// Marshalling info for booleans. Applied to the flag setting keypath to false.
|
||||
class MarshallingInfoBooleanFlag<code keypath, code defaultvalue, code value, code name,
|
||||
class MarshallingInfoBooleanFlag<KeyPathAndMacro kpm, code defaultvalue, code value, code name,
|
||||
code other_value, code other_name>
|
||||
: MarshallingInfoFlag<keypath, defaultvalue> {
|
||||
: MarshallingInfoFlag<kpm, defaultvalue> {
|
||||
code Normalizer = "makeBooleanOptionNormalizer("#value#", "#other_value#", OPT_"#other_name#")";
|
||||
code Denormalizer = "makeBooleanOptionDenormalizer("#value#")";
|
||||
}
|
||||
|
@ -34,22 +34,22 @@ TEST(OptionMarshalling, EmittedOrderSameAsDefinitionOrder) {
|
||||
}
|
||||
|
||||
TEST(OptionMarshalling, EmittedSpecifiedKeyPath) {
|
||||
ASSERT_STREQ(MarshallingTable[0].KeyPath, "MarshalledFlagD");
|
||||
ASSERT_STREQ(MarshallingTable[1].KeyPath, "MarshalledFlagC");
|
||||
ASSERT_STREQ(MarshallingTable[2].KeyPath, "MarshalledFlagB");
|
||||
ASSERT_STREQ(MarshallingTable[3].KeyPath, "MarshalledFlagA");
|
||||
ASSERT_STREQ(MarshallingTable[0].KeyPath, "X->MarshalledFlagD");
|
||||
ASSERT_STREQ(MarshallingTable[1].KeyPath, "X->MarshalledFlagC");
|
||||
ASSERT_STREQ(MarshallingTable[2].KeyPath, "X->MarshalledFlagB");
|
||||
ASSERT_STREQ(MarshallingTable[3].KeyPath, "X->MarshalledFlagA");
|
||||
}
|
||||
|
||||
TEST(OptionMarshalling, ImpliedCheckContainsDisjunctionOfKeypaths) {
|
||||
ASSERT_STREQ(MarshallingTable[0].ImpliedCheck, "false");
|
||||
|
||||
ASSERT_STREQ(MarshallingTable[1].ImpliedCheck, "false || MarshalledFlagD");
|
||||
ASSERT_STREQ(MarshallingTable[1].ImpliedCheck, "false || X->MarshalledFlagD");
|
||||
ASSERT_STREQ(MarshallingTable[1].ImpliedValue, "true");
|
||||
|
||||
ASSERT_STREQ(MarshallingTable[2].ImpliedCheck, "false || MarshalledFlagD");
|
||||
ASSERT_STREQ(MarshallingTable[2].ImpliedCheck, "false || X->MarshalledFlagD");
|
||||
ASSERT_STREQ(MarshallingTable[2].ImpliedValue, "true");
|
||||
|
||||
ASSERT_STREQ(MarshallingTable[3].ImpliedCheck,
|
||||
"false || MarshalledFlagC || MarshalledFlagB");
|
||||
"false || X->MarshalledFlagC || X->MarshalledFlagB");
|
||||
ASSERT_STREQ(MarshallingTable[3].ImpliedValue, "true");
|
||||
}
|
||||
|
@ -45,14 +45,16 @@ def Blurmpq_eq : Flag<["--"], "blurmp=">;
|
||||
|
||||
def DashDash : Option<["--"], "", KIND_REMAINING_ARGS>;
|
||||
|
||||
class XOpts<string base> : KeyPathAndMacro<"X->", base> {}
|
||||
|
||||
def marshalled_flag_d : Flag<["-"], "marshalled-flag-d">,
|
||||
MarshallingInfoFlag<"MarshalledFlagD">;
|
||||
MarshallingInfoFlag<XOpts<"MarshalledFlagD">>;
|
||||
def marshalled_flag_c : Flag<["-"], "marshalled-flag-c">,
|
||||
MarshallingInfoFlag<"MarshalledFlagC">,
|
||||
MarshallingInfoFlag<XOpts<"MarshalledFlagC">>,
|
||||
ImpliedByAnyOf<[marshalled_flag_d], "true">;
|
||||
def marshalled_flag_b : Flag<["-"], "marshalled-flag-b">,
|
||||
MarshallingInfoFlag<"MarshalledFlagB">,
|
||||
MarshallingInfoFlag<XOpts<"MarshalledFlagB">>,
|
||||
ImpliedByAnyOf<[marshalled_flag_d], "true">;
|
||||
def marshalled_flag_a : Flag<["-"], "marshalled-flag-a">,
|
||||
MarshallingInfoFlag<"MarshalledFlagA">,
|
||||
MarshallingInfoFlag<XOpts<"MarshalledFlagA">>,
|
||||
ImpliedByAnyOf<[marshalled_flag_c, marshalled_flag_b]>;
|
||||
|
Loading…
Reference in New Issue
Block a user