1
0
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:
Jan Svoboda 2021-01-13 12:50:19 +01:00
parent 39185b091b
commit 4f287c334a
3 changed files with 38 additions and 27 deletions

View File

@ -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#")";
}

View File

@ -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");
}

View File

@ -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]>;