Skip to content

Commit 55a9615

Browse files
committed
[flang][driver] Refactor boolean options
For boolean options, e.g. `-fxor-operator`/`-fno-xor-operator`, we ought to be using TableGen multi-classes. This way, we only have to write one definition to have both forms auto-generated. This patch refactors all of Flang's boolean options to use two new multi-classes: `OptInFC1FFOption` and `OptOutFC1FFOption`. These multi-classes are based on `OptInFFOption`/`OptOutFFOption`, respectively. I've also simplified the processing of the updated options in CompilerInvocation.cpp. With the new approach, "empty" help text (i.e. no `HelpText`) is now replaced with an empty string (i.e. HelpText<"">). When running flang-new --help, that's considered as non-empty help messages, which is then printed (that's controlled by `printHelp` from llvm/lib/Option/OptTable.cpp). This means that with this patch, flang-new --help will start printing e.g. -fno-backslash, even though there is no actual help text to print for this option (apart from the empty string ""). Tests are updated accordingly. Note that with this patch, both `-fxor-operator` and `-fno-xor-operator` (and other boolean options refactored here) remain available in `flang-new` and `flang-new -fc1`. In this respect, nothing changes. In a forthcoming patch, I will refine this so that `flang-new -fc1` only accepts `-ffoo` (`OptInFC1FFOption`) or `-fno-foo` (`OptOutCC1FFOption`). For clarity, `OptInFFOption`/`OptOutFFOption` are renamed as `OptInCC1FFOption`/`OptOutCC1FFOption`, respectively. Otherwise, this is an NFC from Clang's perspective. Differential Revision: https://reviews.llvm.org/D105881
1 parent 92b00ff commit 55a9615

File tree

4 files changed

+81
-60
lines changed

4 files changed

+81
-60
lines changed

clang/include/clang/Driver/Options.td

+37-27
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ class MigratorOpts<string base>
272272
// Args.hasArg(OPT_ffoo) can be used to check that the flag is enabled.
273273
// This is useful if the option is usually disabled.
274274
// Use this only when the option cannot be declared via BoolFOption.
275-
multiclass OptInFFlag<string name, string pos_prefix, string neg_prefix="",
275+
multiclass OptInCC1FFlag<string name, string pos_prefix, string neg_prefix="",
276276
string help="", list<OptionFlag> flags=[]> {
277277
def f#NAME : Flag<["-"], "f"#name>, Flags<[CC1Option] # flags>,
278278
Group<f_Group>, HelpText<pos_prefix # help>;
@@ -283,14 +283,35 @@ multiclass OptInFFlag<string name, string pos_prefix, string neg_prefix="",
283283
// A boolean option which is opt-out in CC1. The negative option exists in CC1 and
284284
// Args.hasArg(OPT_fno_foo) can be used to check that the flag is disabled.
285285
// Use this only when the option cannot be declared via BoolFOption.
286-
multiclass OptOutFFlag<string name, string pos_prefix, string neg_prefix,
286+
multiclass OptOutCC1FFlag<string name, string pos_prefix, string neg_prefix,
287287
string help="", list<OptionFlag> flags=[]> {
288288
def f#NAME : Flag<["-"], "f"#name>, Flags<flags>,
289289
Group<f_Group>, HelpText<pos_prefix # help>;
290290
def fno_#NAME : Flag<["-"], "fno-"#name>, Flags<[CC1Option] # flags>,
291291
Group<f_Group>, HelpText<neg_prefix # help>;
292292
}
293293

294+
// A boolean option which is opt-in in FC1. The positive option exists in FC1 and
295+
// Args.hasArg(OPT_ffoo) can be used to check that the flag is enabled.
296+
// This is useful if the option is usually disabled.
297+
multiclass OptInFC1FFlag<string name, string pos_prefix, string neg_prefix="",
298+
string help="", list<OptionFlag> flags=[]> {
299+
def f#NAME : Flag<["-"], "f"#name>, Flags<[FC1Option] # flags>,
300+
Group<f_Group>, HelpText<pos_prefix # help>;
301+
def fno_#NAME : Flag<["-"], "fno-"#name>, Flags<flags>,
302+
Group<f_Group>, HelpText<neg_prefix # help>;
303+
}
304+
305+
// A boolean option which is opt-out in FC1. The negative option exists in FC1 and
306+
// Args.hasArg(OPT_fno_foo) can be used to check that the flag is disabled.
307+
multiclass OptOutFC1FFlag<string name, string pos_prefix, string neg_prefix,
308+
string help="", list<OptionFlag> flags=[]> {
309+
def f#NAME : Flag<["-"], "f"#name>, Flags<flags>,
310+
Group<f_Group>, HelpText<pos_prefix # help>;
311+
def fno_#NAME : Flag<["-"], "fno-"#name>, Flags<[FC1Option] # flags>,
312+
Group<f_Group>, HelpText<neg_prefix # help>;
313+
}
314+
294315
// Creates a positive and negative flags where both of them are prefixed with
295316
// "m", have help text specified for positive and negative option, and a Group
296317
// optionally specified by the opt_group argument, otherwise Group<m_Group>.
@@ -1257,7 +1278,7 @@ defm addrsig : BoolFOption<"addrsig",
12571278
CodeGenOpts<"Addrsig">, DefaultFalse,
12581279
PosFlag<SetTrue, [CC1Option], "Emit">, NegFlag<SetFalse, [], "Don't emit">,
12591280
BothFlags<[CoreOption], " an address-significance table">>;
1260-
defm blocks : OptInFFlag<"blocks", "Enable the 'blocks' language feature", "", "", [CoreOption]>;
1281+
defm blocks : OptInCC1FFlag<"blocks", "Enable the 'blocks' language feature", "", "", [CoreOption]>;
12611282
def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
12621283
defm borland_extensions : BoolFOption<"borland-extensions",
12631284
LangOpts<"Borland">, DefaultFalse,
@@ -1273,7 +1294,7 @@ def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Gr
12731294
Flags<[CC1Option]>, MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
12741295
HelpText<"Attempt to match the ABI of Clang <version>">;
12751296
def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
1276-
defm color_diagnostics : OptInFFlag<"color-diagnostics", "Enable", "Disable", " colors in diagnostics",
1297+
defm color_diagnostics : OptInCC1FFlag<"color-diagnostics", "Enable", "Disable", " colors in diagnostics",
12771298
[CoreOption, FlangOption]>;
12781299
def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>,
12791300
Flags<[CoreOption, NoXarchOption]>;
@@ -1394,7 +1415,7 @@ def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>,
13941415
HelpText<"Do not elide types when printing diagnostics">,
13951416
MarshallingInfoNegativeFlag<DiagnosticOpts<"ElideType">>;
13961417
def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>;
1397-
defm eliminate_unused_debug_types : OptOutFFlag<"eliminate-unused-debug-types",
1418+
defm eliminate_unused_debug_types : OptOutCC1FFlag<"eliminate-unused-debug-types",
13981419
"Do not emit ", "Emit ", " debug info for defined but unused types">;
13991420
def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>,
14001421
HelpText<"Emit all declarations, even if unused">,
@@ -1499,7 +1520,7 @@ defm cxx_static_destructors : BoolFOption<"c++-static-destructors",
14991520
def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>,
15001521
Flags<[CC1Option]>, MarshallingInfoString<CodeGenOpts<"SymbolPartition">>;
15011522

1502-
defm memory_profile : OptInFFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">;
1523+
defm memory_profile : OptInCC1FFlag<"memory-profile", "Enable", "Disable", " heap memory profiling">;
15031524
def fmemory_profile_EQ : Joined<["-"], "fmemory-profile=">,
15041525
Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<directory>">,
15051526
HelpText<"Enable heap memory profiling and dump results into <directory>">;
@@ -2143,9 +2164,9 @@ defm pch_instantiate_templates : BoolFOption<"pch-instantiate-templates",
21432164
LangOpts<"PCHInstantiateTemplates">, DefaultFalse,
21442165
PosFlag<SetTrue, [], "Instantiate templates already while building a PCH">,
21452166
NegFlag<SetFalse>, BothFlags<[CC1Option, CoreOption]>>;
2146-
defm pch_codegen: OptInFFlag<"pch-codegen", "Generate ", "Do not generate ",
2167+
defm pch_codegen: OptInCC1FFlag<"pch-codegen", "Generate ", "Do not generate ",
21472168
"code for uses of this PCH that assumes an explicit object file will be built for the PCH">;
2148-
defm pch_debuginfo: OptInFFlag<"pch-debuginfo", "Generate ", "Do not generate ",
2169+
defm pch_debuginfo: OptInCC1FFlag<"pch-debuginfo", "Generate ", "Do not generate ",
21492170
"debug info for types in an object file built from this PCH and do not generate them elsewhere">;
21502171

21512172
def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group>,
@@ -4509,26 +4530,18 @@ def fdefault_real_8 : Flag<["-"],"fdefault-real-8">, Group<f_Group>,
45094530
HelpText<"Set the default real kind to an 8 byte wide type">;
45104531
def flarge_sizes : Flag<["-"],"flarge-sizes">, Group<f_Group>,
45114532
HelpText<"Use INTEGER(KIND=8) for the result type in size-related intrinsics">;
4512-
def fbackslash : Flag<["-"], "fbackslash">, Group<f_Group>,
4513-
HelpText<"Specify that backslash in string introduces an escape character">,
4514-
DocBrief<[{Change the interpretation of backslashes in string literals from
4515-
a single backslash character to "C-style" escape characters.}]>;
4516-
def fno_backslash : Flag<["-"], "fno-backslash">, Group<f_Group>;
4517-
def fxor_operator : Flag<["-"], "fxor-operator">, Group<f_Group>,
4518-
HelpText<"Enable .XOR. as a synonym of .NEQV.">;
4519-
def fno_xor_operator : Flag<["-"], "fno-xor-operator">, Group<f_Group>;
4520-
def flogical_abbreviations : Flag<["-"], "flogical-abbreviations">, Group<f_Group>,
4521-
HelpText<"Enable logical abbreviations">;
4522-
def fno_logical_abbreviations : Flag<["-"], "fno-logical-abbreviations">, Group<f_Group>;
4523-
def fimplicit_none : Flag<["-"], "fimplicit-none">, Group<f_Group>,
4524-
HelpText<"No implicit typing allowed unless overridden by IMPLICIT statements">;
4525-
def fno_implicit_none : Flag<["-"], "fno-implicit-none">, Group<f_Group>;
4533+
45264534
def falternative_parameter_statement : Flag<["-"], "falternative-parameter-statement">, Group<f_Group>,
45274535
HelpText<"Enable the old style PARAMETER statement">;
45284536
def fintrinsic_modules_path : Separate<["-"], "fintrinsic-modules-path">, Group<f_Group>, MetaVarName<"<dir>">,
45294537
HelpText<"Specify where to find the compiled intrinsic modules">,
45304538
DocBrief<[{This option specifies the location of pre-compiled intrinsic modules,
45314539
if they are not in the default location expected by the compiler.}]>;
4540+
4541+
defm backslash : OptInFC1FFlag<"backslash", "Specify that backslash in string introduces an escape character">;
4542+
defm xor_operator : OptInFC1FFlag<"xor-operator", "Enable .XOR. as a synonym of .NEQV.">;
4543+
defm logical_abbreviations : OptInFC1FFlag<"logical-abbreviations", "Enable logical abbreviations">;
4544+
defm implicit_none : OptInFC1FFlag<"implicit-none", "No implicit typing allowed unless overridden by IMPLICIT statements">;
45324545
}
45334546

45344547
def J : JoinedOrSeparate<["-"], "J">,
@@ -4583,13 +4596,10 @@ def fget_symbols_sources : Flag<["-"], "fget-symbols-sources">, Group<Action_Gro
45834596

45844597
def module_suffix : Separate<["-"], "module-suffix">, Group<f_Group>, MetaVarName<"<suffix>">,
45854598
HelpText<"Use <suffix> as the suffix for module files (the default value is `.mod`)">;
4586-
def fanalyzed_objects_for_unparse : Flag<["-"],
4587-
"fanalyzed-objects-for-unparse">, Group<f_Group>;
4588-
def fno_analyzed_objects_for_unparse : Flag<["-"],
4589-
"fno-analyzed-objects-for-unparse">, Group<f_Group>,
4590-
HelpText<"Do not use the analyzed objects when unparsing">;
45914599
def fno_reformat : Flag<["-"], "fno-reformat">, Group<Preprocessor_Group>,
45924600
HelpText<"Dump the cooked character stream in -E mode">;
4601+
defm analyzed_objects_for_unparse : OptOutFC1FFlag<"analyzed-objects-for-unparse", "", "Do not use the analyzed objects when unparsing">;
4602+
45934603
}
45944604

45954605
//===----------------------------------------------------------------------===//

flang/lib/Frontend/CompilerInvocation.cpp

+25-31
Original file line numberDiff line numberDiff line change
@@ -277,32 +277,27 @@ static bool ParseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
277277
}
278278
}
279279

280-
if (const llvm::opt::Arg *arg =
281-
args.getLastArg(clang::driver::options::OPT_fimplicit_none,
282-
clang::driver::options::OPT_fno_implicit_none)) {
283-
opts.features.Enable(
284-
Fortran::common::LanguageFeature::ImplicitNoneTypeAlways,
285-
arg->getOption().matches(clang::driver::options::OPT_fimplicit_none));
286-
}
287-
if (const llvm::opt::Arg *arg =
288-
args.getLastArg(clang::driver::options::OPT_fbackslash,
289-
clang::driver::options::OPT_fno_backslash)) {
290-
opts.features.Enable(Fortran::common::LanguageFeature::BackslashEscapes,
291-
arg->getOption().matches(clang::driver::options::OPT_fbackslash));
292-
}
293-
if (const llvm::opt::Arg *arg =
294-
args.getLastArg(clang::driver::options::OPT_flogical_abbreviations,
295-
clang::driver::options::OPT_fno_logical_abbreviations)) {
296-
opts.features.Enable(Fortran::common::LanguageFeature::LogicalAbbreviations,
297-
arg->getOption().matches(
298-
clang::driver::options::OPT_flogical_abbreviations));
299-
}
300-
if (const llvm::opt::Arg *arg =
301-
args.getLastArg(clang::driver::options::OPT_fxor_operator,
302-
clang::driver::options::OPT_fno_xor_operator)) {
303-
opts.features.Enable(Fortran::common::LanguageFeature::XOROperator,
304-
arg->getOption().matches(clang::driver::options::OPT_fxor_operator));
305-
}
280+
// -f{no-}implicit-none
281+
opts.features.Enable(
282+
Fortran::common::LanguageFeature::ImplicitNoneTypeAlways,
283+
args.hasFlag(clang::driver::options::OPT_fimplicit_none,
284+
clang::driver::options::OPT_fno_implicit_none, false));
285+
286+
// -f{no-}backslash
287+
opts.features.Enable(Fortran::common::LanguageFeature::BackslashEscapes,
288+
args.hasFlag(clang::driver::options::OPT_fbackslash,
289+
clang::driver::options::OPT_fno_backslash, false));
290+
291+
// -f{no-}logical-abbreviations
292+
opts.features.Enable(Fortran::common::LanguageFeature::LogicalAbbreviations,
293+
args.hasFlag(clang::driver::options::OPT_flogical_abbreviations,
294+
clang::driver::options::OPT_fno_logical_abbreviations, false));
295+
296+
// -f{no-}xor-operator
297+
opts.features.Enable(Fortran::common::LanguageFeature::XOROperator,
298+
args.hasFlag(clang::driver::options::OPT_fxor_operator,
299+
clang::driver::options::OPT_fno_xor_operator, false));
300+
306301
if (args.hasArg(
307302
clang::driver::options::OPT_falternative_parameter_statement)) {
308303
opts.features.Enable(Fortran::common::LanguageFeature::OldStyleParameter);
@@ -406,11 +401,10 @@ static bool parseSemaArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
406401
res.SetModuleFileSuffix(moduleSuffix->getValue());
407402
}
408403

409-
// -fno-analyzed-objects-for-unparse
410-
if (args.hasArg(
411-
clang::driver::options::OPT_fno_analyzed_objects_for_unparse)) {
412-
res.SetUseAnalyzedObjectsForUnparse(false);
413-
}
404+
// -f{no-}analyzed-objects-for-unparse
405+
res.SetUseAnalyzedObjectsForUnparse(
406+
args.hasFlag(clang::driver::options::OPT_fanalyzed_objects_for_unparse,
407+
clang::driver::options::OPT_fno_analyzed_objects_for_unparse, true));
414408

415409
return diags.getNumErrors() == numErrorsBefore;
416410
}

flang/test/Driver/driver-help-hidden.f90

+6-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@
4040
! CHECK-NEXT: Specify where to find the compiled intrinsic modules
4141
! CHECK-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics
4242
! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations
43-
! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics
43+
! CHECK-NEXT: -fno-backslash
44+
! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics
45+
! CHECK-NEXT: -fno-implicit-none
46+
! CHECK-NEXT: -fno-logical-abbreviations
47+
! CHECK-NEXT: {{[[:space:]]$}}
48+
! CHECK-NEXT: -fno-xor-operator
4449
! CHECK-NEXT: -fopenacc Enable OpenACC
4550
! CHECK-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code.
4651
! CHECK-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV.

flang/test/Driver/driver-help.f90

+13-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@
4040
! HELP-NEXT: Specify where to find the compiled intrinsic modules
4141
! HELP-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics
4242
! HELP-NEXT: -flogical-abbreviations Enable logical abbreviations
43-
! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics
43+
! HELP-NEXT: -fno-backslash
44+
! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics
45+
! HELP-NEXT: -fno-implicit-none
46+
! HELP-NEXT: -fno-logical-abbreviations
47+
! HELP-NEXT: {{[[:space:]]$}}
48+
! HELP-NEXT: -fno-xor-operator
4449
! HELP-NEXT: -fopenacc Enable OpenACC
4550
! HELP-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code.
4651
! HELP-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV.
@@ -69,6 +74,8 @@
6974
! HELP-FC1-NEXT: -E Only run the preprocessor
7075
! HELP-FC1-NEXT: -falternative-parameter-statement
7176
! HELP-FC1-NEXT: Enable the old style PARAMETER statement
77+
! HELP-FC1-NEXT: -fanalyzed-objects-for-unparse
78+
! HELP-FC1-NEXT: {{[[:space:]]$}}
7279
! HELP-FC1-NEXT: -fbackslash Specify that backslash in string introduces an escape character
7380
! HELP-FC1-NEXT: -fdebug-dump-all Dump symbols and the parse tree after the semantic checks
7481
! HELP-FC1-NEXT: -fdebug-dump-parse-tree-no-sema
@@ -104,7 +111,12 @@
104111
! HELP-FC1-NEXT: -flogical-abbreviations Enable logical abbreviations
105112
! HELP-FC1-NEXT: -fno-analyzed-objects-for-unparse
106113
! HELP-FC1-NEXT: Do not use the analyzed objects when unparsing
114+
! HELP-FC1-NEXT: -fno-backslash
115+
! HELP-FC1-NEXT: -fno-implicit-none
116+
! HELP-FC1-NEXT: -fno-logical-abbreviations
117+
! HELP-FC1-NEXT: {{[[:space:]]$}}
107118
! HELP-FC1-NEXT: -fno-reformat Dump the cooked character stream in -E mode
119+
! HELP-FC1-NEXT: -fno-xor-operator
108120
! HELP-FC1-NEXT: -fopenacc Enable OpenACC
109121
! HELP-FC1-NEXT: -fopenmp Parse OpenMP pragmas and generate parallel code.
110122
! HELP-FC1-NEXT: -fxor-operator Enable .XOR. as a synonym of .NEQV.

0 commit comments

Comments
 (0)