string Spelling
= prefix#!cond(flag.Polarity.Value : "", true : "no-")#spelling;
- // Does the flag have CC1Option?
- bit IsCC1 = !not(!empty(!filter(opt_flag, flag.OptionFlags,
- !eq(opt_flag, CC1Option))));
-
// Can the flag be implied by another flag?
bit CanBeImplied = !not(!empty(flag.ImpliedBy));
code ValueAsCode = !cond(flag.Value : "true", true: "false");
}
-// Creates simple flag record.
-class BoolOptionFlag<FlagDefExpanded flag, code keypath, Default default>
- : Flag<["-"], flag.Spelling>, Flags<flag.OptionFlags>, HelpText<flag.Help> {}
-
-// Creates marshalled flag record.
-class CC1BoolOptionFlag<FlagDefExpanded flag, FlagDefExpanded other,
- code keypath, Default default>
+// Creates record with a marshalled flag.
+class BoolOptionFlag<FlagDefExpanded flag, FlagDefExpanded other,
+ FlagDefExpanded implied, code keypath, Default default>
: Flag<["-"], flag.Spelling>, Flags<flag.OptionFlags>, HelpText<flag.Help>,
MarshallingInfoBooleanFlag<keypath, default.Value, flag.ValueAsCode,
flag.RecordName, other.ValueAsCode,
other.RecordName, other.Spelling>,
- ImpliedByAnyOf<flag.ImpliedBy, flag.ValueAsCode> {}
+ ImpliedByAnyOf<implied.ImpliedBy, implied.ValueAsCode> {}
// Generates TableGen records for two command line flags that control the same
// keypath via the marshalling infrastructure.
// TODO: Assert that the flags have different value.
// TODO: Assert that only one of the flags can be implied.
- if flag1.IsCC1 then {
- def flag1.RecordName : CC1BoolOptionFlag<flag1, flag2, keypath, default>;
- } else {
- def flag1.RecordName : BoolOptionFlag<flag1, keypath, default>;
- }
-
- if flag2.IsCC1 then {
- def flag2.RecordName : CC1BoolOptionFlag<flag2, flag1, keypath, default>;
- } else {
- def flag2.RecordName : BoolOptionFlag<flag2, keypath, default>;
- }
+ defvar implied = !cond(flag1.CanBeImplied: flag1, true: flag2);
+
+ def flag1.RecordName : BoolOptionFlag<flag1, flag2, implied, keypath, default>;
+ def flag2.RecordName : BoolOptionFlag<flag2, flag1, implied, keypath, default>;
}
//===----------------------------------------------------------------------===//
def flto_unit: Flag<["-"], "flto-unit">,
HelpText<"Emit IR to support LTO unit features (CFI, whole program vtable opt)">;
def fno_lto_unit: Flag<["-"], "fno-lto-unit">;
-def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">,
- HelpText<"Prints debug information for the new pass manager">;
-def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">,
- HelpText<"Disables debug printing for the new pass manager">;
+defm debug_pass_manager : BoolOption<"debug-pass-manager",
+ "CodeGenOpts.DebugPassManager", DefaultsToFalse,
+ ChangedBy<PosFlag, [], "Prints debug information for the new pass manager">,
+ ResetBy<NegFlag, [], "Disables debug printing for the new pass manager">,
+ BothFlags<[]>, "f">;
def fexperimental_debug_variable_locations : Flag<["-"],
"fexperimental-debug-variable-locations">,
HelpText<"Use experimental new value-tracking variable locations">;
}
}
- Opts.DebugPassManager =
- Args.hasFlag(OPT_fdebug_pass_manager, OPT_fno_debug_pass_manager,
- /* Default */ false);
-
if (Arg *A = Args.getLastArg(OPT_fveclib)) {
StringRef Name = A->getValue();
if (Name == "Accelerate")
HELPTEXT, METAVAR, VALUES, SPELLING, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \
TABLE_INDEX) \
- { \
+ if ((FLAGS)&options::CC1Option) { \
this->KEYPATH = MERGER(this->KEYPATH, DEFAULT_VALUE); \
if (IMPLIED_CHECK) \
this->KEYPATH = MERGER(this->KEYPATH, IMPLIED_VALUE); \
ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq(PassManagerChangedByFlag))));
}
+// Boolean option that gets the CC1Option flag from a let statement (which
+// is applied **after** the record is defined):
+//
+// let Flags = [CC1Option] in {
+// defm option : BoolOption<...>;
+// }
+
+TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentNone) {
+ const char *Args[] = {""};
+
+ CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
+
+ ASSERT_FALSE(Diags->hasErrorOccurred());
+ ASSERT_FALSE(Invocation.getCodeGenOpts().DebugPassManager);
+
+ Invocation.generateCC1CommandLine(GeneratedArgs, *this);
+
+ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdebug-pass-manager"))));
+ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager"))));
+}
+
+TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentPos) {
+ const char *Args[] = {"-fdebug-pass-manager"};
+
+ CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
+
+ ASSERT_FALSE(Diags->hasErrorOccurred());
+ ASSERT_TRUE(Invocation.getCodeGenOpts().DebugPassManager);
+
+ Invocation.generateCC1CommandLine(GeneratedArgs, *this);
+
+ ASSERT_THAT(GeneratedArgs, Contains(StrEq("-fdebug-pass-manager")));
+ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager"))));
+}
+
+TEST_F(CommandLineTest, BoolOptionCC1ViaLetPresentNeg) {
+ const char *Args[] = {"-fno-debug-pass-manager"};
+
+ CompilerInvocation::CreateFromArgs(Invocation, Args, *Diags);
+
+ ASSERT_FALSE(Diags->hasErrorOccurred());
+ ASSERT_FALSE(Invocation.getCodeGenOpts().DebugPassManager);
+
+ Invocation.generateCC1CommandLine(GeneratedArgs, *this);
+
+ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fno-debug-pass-manager"))));
+ ASSERT_THAT(GeneratedArgs, Not(Contains(StrEq("-fdebug-pass-manager"))));
+}
+
TEST_F(CommandLineTest, CanGenerateCC1CommandLineFlag) {
const char *Args[] = {"-fmodules-strict-context-hash"};