From: Peter Collingbourne Date: Sat, 4 Dec 2010 01:50:27 +0000 (+0000) Subject: Introduce CompilerInvocation::setLangDefaults function X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=53c92be3b233cede6114702a5f86f146f55d6c6e;p=clang Introduce CompilerInvocation::setLangDefaults function This patch refactors the CompilerInvocation code to introduce a CompilerInvocation::setLangDefaults function, which can set up a LangOptions with the defaults for a given language and language standard. This function is useful for non-command line based Clang clients which need to set up a CompilerInvocation manually for a specific language. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@120874 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h index 641c5f6650..e0329dbc96 100644 --- a/include/clang/Frontend/CompilerInvocation.h +++ b/include/clang/Frontend/CompilerInvocation.h @@ -19,6 +19,7 @@ #include "clang/Frontend/DiagnosticOptions.h" #include "clang/Frontend/FrontendOptions.h" #include "clang/Frontend/HeaderSearchOptions.h" +#include "clang/Frontend/LangStandard.h" #include "clang/Frontend/PreprocessorOptions.h" #include "clang/Frontend/PreprocessorOutputOptions.h" #include "llvm/ADT/StringRef.h" @@ -106,6 +107,25 @@ public: /// passing to CreateFromArgs. void toArgs(std::vector &Res); + /// setLangDefaults - Set language defaults for the given input language and + /// language standard in this CompilerInvocation. + /// + /// \param IK - The input language. + /// \param LangStd - The input language standard. + void setLangDefaults(InputKind IK, + LangStandard::Kind LangStd = LangStandard::lang_unspecified) { + setLangDefaults(LangOpts, IK, LangStd); + } + + /// setLangDefaults - Set language defaults for the given input language and + /// language standard in the given LangOptions object. + /// + /// \param LangOpts - The LangOptions object to set up. + /// \param IK - The input language. + /// \param LangStd - The input language standard. + static void setLangDefaults(LangOptions &Opts, InputKind IK, + LangStandard::Kind LangStd = LangStandard::lang_unspecified); + /// @} /// @name Option Subgroups /// @{ diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index fcefad7b3e..d1d1a381b0 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1218,10 +1218,8 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { // FIXME: Need options for the various environment variables! } -static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, - Diagnostic &Diags) { - // FIXME: Cleanup per-file based stuff. - +void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, + LangStandard::Kind LangStd) { // Set some properties which depend soley on the input kind; it would be nice // to move these to the language standard, and have the driver resolve the // input kind + language standard. @@ -1234,18 +1232,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ObjC1 = Opts.ObjC2 = 1; } - LangStandard::Kind LangStd = LangStandard::lang_unspecified; - if (const Arg *A = Args.getLastArg(OPT_std_EQ)) { - LangStd = llvm::StringSwitch(A->getValue(Args)) -#define LANGSTANDARD(id, name, desc, features) \ - .Case(name, LangStandard::lang_##id) -#include "clang/Frontend/LangStandards.def" - .Default(LangStandard::lang_unspecified); - if (LangStd == LangStandard::lang_unspecified) - Diags.Report(diag::err_drv_invalid_value) - << A->getAsString(Args) << A->getValue(Args); - } - if (LangStd == LangStandard::lang_unspecified) { // Based on the base language, pick one. switch (IK) { @@ -1300,16 +1286,43 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // OpenCL and C++ both have bool, true, false keywords. Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; + Opts.GNUKeywords = Opts.GNUMode; + Opts.CXXOperatorNames = Opts.CPlusPlus; + + // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs + // is specified, or -std is set to a conforming mode. + Opts.Trigraphs = !Opts.GNUMode; + + Opts.DollarIdents = !Opts.AsmPreprocessor; +} + +static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, + Diagnostic &Diags) { + // FIXME: Cleanup per-file based stuff. + LangStandard::Kind LangStd = LangStandard::lang_unspecified; + if (const Arg *A = Args.getLastArg(OPT_std_EQ)) { + LangStd = llvm::StringSwitch(A->getValue(Args)) +#define LANGSTANDARD(id, name, desc, features) \ + .Case(name, LangStandard::lang_##id) +#include "clang/Frontend/LangStandards.def" + .Default(LangStandard::lang_unspecified); + if (LangStd == LangStandard::lang_unspecified) + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(Args); + } + + CompilerInvocation::setLangDefaults(Opts, IK, LangStd); + // 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.GNUMode); + Opts.GNUKeywords); - if (Opts.CPlusPlus) - Opts.CXXOperatorNames = !Args.hasArg(OPT_fno_operator_names); + if (Args.hasArg(OPT_fno_operator_names)) + Opts.CXXOperatorNames = 0; if (Args.hasArg(OPT_fobjc_gc_only)) Opts.setGCMode(LangOptions::GCOnly); @@ -1350,15 +1363,12 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, else if (Args.hasArg(OPT_fwrapv)) Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined); - // Mimicing gcc's behavior, trigraphs are only enabled if -trigraphs - // is specified, or -std is set to a conforming mode. - Opts.Trigraphs = !Opts.GNUMode; if (Args.hasArg(OPT_trigraphs)) Opts.Trigraphs = 1; Opts.DollarIdents = Args.hasFlag(OPT_fdollars_in_identifiers, OPT_fno_dollars_in_identifiers, - !Opts.AsmPreprocessor); + Opts.DollarIdents); Opts.PascalStrings = Args.hasArg(OPT_fpascal_strings); Opts.Microsoft = Args.hasArg(OPT_fms_extensions); Opts.MSCVersion = Args.getLastArgIntValue(OPT_fmsc_version, 0, Diags);