diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -434,8 +434,11 @@ 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 fgnuc_version_EQ : Joined<["-"], "fgnuc-version=">, 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, 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, + PosFlag, + NegFlag, BothFlags<[CC1Option]>>; +defm gnu89_inline : BoolFOption<"gnu89-inline", + LangOpts<"GNUInline">, Default, + PosFlag, + NegFlag>, ShouldParseIf; def fgnu_runtime : Flag<["-"], "fgnu-runtime">, 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_dollars_in_identifiers : Flag<["-"], "fno-dollars-in-identifiers">, Group, HelpText<"Disallow '$' in identifiers">, Flags<[CC1Option]>; def fno_eliminate_unused_debug_symbols : Flag<["-"], "fno-eliminate-unused-debug-symbols">, Group; -def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group, Flags<[CC1Option]>; def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group, Flags<[CC1Option]>; def fno_inline : Flag<["-"], "fno-inline">, Group, Flags<[CC1Option]>; def fno_global_isel : Flag<["-"], "fno-global-isel">, Group, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -400,9 +400,11 @@ MERGER(KEYPATH, static_cast(*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 @@ 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(); @@ -1978,7 +1984,6 @@ 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(); @@ -2050,7 +2055,6 @@ // C++ has wchar_t keyword. Opts.WChar = Opts.CPlusPlus; - Opts.GNUKeywords = Opts.GNUMode; Opts.CXXOperatorNames = Opts.CPlusPlus; Opts.AlignedAllocation = Opts.CPlusPlus17; @@ -2248,14 +2252,6 @@ << 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; @@ -2338,14 +2334,6 @@ 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. @@ -2988,7 +2976,7 @@ Res.getCodeGenOpts().Argv0 = Argv0; Res.getCodeGenOpts().CommandLineArgs = CommandLineArgs; - FixupInvocation(Res, Diags, Args); + FixupInvocation(Res, Diags, Args, DashX); return Success; }