[clang][cli] Port GNU language options to marshalling system

Port some GNU-related language options to the marshalling system for automatic command line parsing and generation.

Reviewed By: dexonsmith

Differential Revision: https://reviews.llvm.org/D95343
This commit is contained in:
Jan Svoboda 2021-01-26 09:08:08 +01:00
parent 2154cffdc2
commit 956d8e02e8
2 changed files with 25 additions and 25 deletions

View File

@ -434,8 +434,11 @@ class MarshallingInfoVisibility<KeyPathAndMacro kpm, code default>
AutoNormalizeEnum {}
// Key paths that are constant during parsing of options with the same key path prefix.
defvar cplusplus = LangOpts<"CPlusPlus">;
defvar c99 = LangOpts<"C99">;
defvar lang_std = LangOpts<"LangStd">;
defvar open_cl = LangOpts<"OpenCL">;
defvar gnu_mode = LangOpts<"GNUMode">;
defvar std = !strconcat("LangStandard::getLangStandardForKind(", lang_std.KeyPath, ")");
@ -1619,9 +1622,19 @@ def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Opti
def fgnuc_version_EQ : Joined<["-"], "fgnuc-version=">, Group<f_Group>,
HelpText<"Sets various macros to claim compatibility with the given GCC version (default is 4.2.1)">,
Flags<[CC1Option, CoreOption]>;
def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Allow GNU-extension keywords regardless of language standard">;
defm gnu89_inline : OptInFFlag<"gnu89-inline", "Use the gnu89 inline semantics">;
// We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
// keywords. This behavior is provided by GCC's poorly named '-fasm' flag,
// while a subset (the non-C++ GNU keywords) is provided by GCC's
// '-fgnu-keywords'. Clang conflates the two for simplicity under the single
// name, as it doesn't seem a useful distinction.
defm gnu_keywords : BoolFOption<"gnu-keywords",
LangOpts<"GNUKeywords">, Default<gnu_mode.KeyPath>,
PosFlag<SetTrue, [], "Allow GNU-extension keywords regardless of language standard">,
NegFlag<SetFalse>, BothFlags<[CC1Option]>>;
defm gnu89_inline : BoolFOption<"gnu89-inline",
LangOpts<"GNUInline">, Default<!strconcat("!", c99.KeyPath, " && !", cplusplus.KeyPath)>,
PosFlag<SetTrue, [CC1Option], "Use the gnu89 inline semantics">,
NegFlag<SetFalse>>, ShouldParseIf<!strconcat("!", cplusplus.KeyPath)>;
def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>,
HelpText<"Generate output compatible with the standard GNU Objective-C runtime">;
def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>,
@ -1965,7 +1978,6 @@ def fno_declspec : Flag<["-"], "fno-declspec">, Group<f_clang_Group>,
def fno_dollars_in_identifiers : Flag<["-"], "fno-dollars-in-identifiers">, Group<f_Group>,
HelpText<"Disallow '$' in identifiers">, Flags<[CC1Option]>;
def fno_eliminate_unused_debug_symbols : Flag<["-"], "fno-eliminate-unused-debug-symbols">, Group<f_Group>;
def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>;
def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>;
def fno_global_isel : Flag<["-"], "fno-global-isel">, Group<f_clang_Group>,

View File

@ -400,9 +400,11 @@ static T extractMaskValue(T KeyPath) {
MERGER(KEYPATH, static_cast<decltype(KEYPATH)>(*MaybeValue)); \
}
static const StringRef GetInputKindName(InputKind IK);
static void FixupInvocation(CompilerInvocation &Invocation,
DiagnosticsEngine &Diags,
const InputArgList &Args) {
DiagnosticsEngine &Diags, const InputArgList &Args,
InputKind IK) {
LangOptions &LangOpts = *Invocation.getLangOpts();
CodeGenOptions &CodeGenOpts = Invocation.getCodeGenOpts();
TargetOptions &TargetOpts = Invocation.getTargetOpts();
@ -438,6 +440,10 @@ static void FixupInvocation(CompilerInvocation &Invocation,
LangOpts.NewAlignOverride = 0;
}
if (Args.hasArg(OPT_fgnu89_inline) && LangOpts.CPlusPlus)
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< "-fgnu89-inline" << GetInputKindName(IK);
if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
auto DefaultCC = LangOpts.getDefaultCallingConv();
@ -1984,7 +1990,6 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
Opts.CPlusPlus20 = Std.isCPlusPlus20();
Opts.CPlusPlus2b = Std.isCPlusPlus2b();
Opts.GNUMode = Std.isGNUMode();
Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus;
Opts.GNUCVersion = 0;
Opts.HexFloats = Std.hasHexFloats();
Opts.ImplicitInt = Std.hasImplicitInt();
@ -2056,7 +2061,6 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
// C++ has wchar_t keyword.
Opts.WChar = Opts.CPlusPlus;
Opts.GNUKeywords = Opts.GNUMode;
Opts.CXXOperatorNames = Opts.CPlusPlus;
Opts.AlignedAllocation = Opts.CPlusPlus17;
@ -2254,14 +2258,6 @@ void CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
<< Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args);
}
// We abuse '-f[no-]gnu-keywords' to force overriding all GNU-extension
// keywords. This behavior is provided by GCC's poorly named '-fasm' flag,
// while a subset (the non-C++ GNU keywords) is provided by GCC's
// '-fgnu-keywords'. Clang conflates the two for simplicity under the single
// name, as it doesn't seem a useful distinction.
Opts.GNUKeywords = Args.hasFlag(OPT_fgnu_keywords, OPT_fno_gnu_keywords,
Opts.GNUKeywords);
if (Args.hasArg(OPT_fno_operator_names))
Opts.CXXOperatorNames = 0;
@ -2344,14 +2340,6 @@ void CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
}
if (Args.hasArg(OPT_fgnu89_inline)) {
if (Opts.CPlusPlus)
Diags.Report(diag::err_drv_argument_not_allowed_with)
<< "-fgnu89-inline" << GetInputKindName(IK);
else
Opts.GNUInline = 1;
}
if (Args.hasArg(OPT_ftrapv)) {
Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
// Set the handler, if one is specified.
@ -2994,7 +2982,7 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res,
Res.getCodeGenOpts().Argv0 = Argv0;
Res.getCodeGenOpts().CommandLineArgs = CommandLineArgs;
FixupInvocation(Res, Diags, Args);
FixupInvocation(Res, Diags, Args, DashX);
return Success;
}