[clang] 93471e6 - [clang] NFC, move CompilerInvocation::setLangDefaults to LangOptions.h
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 13 00:53:28 PDT 2022
Author: Haojian Wu
Date: 2022-04-13T09:44:39+02:00
New Revision: 93471e65df48372ee59bd0c2f8ba58a254ba1ca5
URL: https://github.com/llvm/llvm-project/commit/93471e65df48372ee59bd0c2f8ba58a254ba1ca5
DIFF: https://github.com/llvm/llvm-project/commit/93471e65df48372ee59bd0c2f8ba58a254ba1ca5.diff
LOG: [clang] NFC, move CompilerInvocation::setLangDefaults to LangOptions.h
The function is moved from clangFrontend to clangBasic, which allows tools
(e.g. clang pseudoparser) which don't depend on clangFrontend to use.
Differential Revision: https://reviews.llvm.org/D121375
Added:
Modified:
clang/include/clang/Basic/LangOptions.h
clang/include/clang/Basic/LangStandard.h
clang/include/clang/Frontend/CompilerInvocation.h
clang/lib/Basic/LangOptions.cpp
clang/lib/Basic/LangStandards.cpp
clang/lib/Frontend/CompilerInvocation.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index f82992877c0b4..b0cc4c98e881e 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -450,6 +450,20 @@ class LangOptions : public LangOptionsBase {
LangOptions();
+ /// Set language defaults for the given input language and
+ /// language standard in the given LangOptions object.
+ ///
+ /// \param Opts - The LangOptions object to set up.
+ /// \param Lang - The input language.
+ /// \param T - The target triple.
+ /// \param Includes - If the language requires extra headers to be implicitly
+ /// included, they will be appended to this list.
+ /// \param LangStd - The input language standard.
+ static void
+ setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T,
+ std::vector<std::string> &Includes,
+ LangStandard::Kind LangStd = LangStandard::lang_unspecified);
+
// Define accessors/mutators for language options of enumeration type.
#define LANGOPT(Name, Bits, Default, Description)
#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h
index fdfd2e7773a87..263985d6b1389 100644
--- a/clang/include/clang/Basic/LangStandard.h
+++ b/clang/include/clang/Basic/LangStandard.h
@@ -12,6 +12,10 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
+namespace llvm {
+class Triple;
+}
+
namespace clang {
/// The language for the input, used to select and validate the language
@@ -138,6 +142,9 @@ struct LangStandard {
static const LangStandard *getLangStandardForName(StringRef Name);
};
+LangStandard::Kind getDefaultLanguageStandard(clang::Language Lang,
+ const llvm::Triple &T);
+
} // end namespace clang
#endif
diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h
index 922c84a3bee2c..0753a6632f81e 100644
--- a/clang/include/clang/Frontend/CompilerInvocation.h
+++ b/clang/include/clang/Frontend/CompilerInvocation.h
@@ -219,19 +219,6 @@ class CompilerInvocation : public CompilerInvocationRefBase,
/// executable), for finding the builtin compiler path.
static std::string GetResourcesPath(const char *Argv0, void *MainAddr);
- /// Set language defaults for the given input language and
- /// language standard in the given LangOptions object.
- ///
- /// \param Opts - The LangOptions object to set up.
- /// \param IK - The input language.
- /// \param T - The target triple.
- /// \param Includes - The affected list of included files.
- /// \param LangStd - The input language standard.
- static void
- setLangDefaults(LangOptions &Opts, InputKind IK, const llvm::Triple &T,
- std::vector<std::string> &Includes,
- LangStandard::Kind LangStd = LangStandard::lang_unspecified);
-
/// Retrieve a module hash string that is suitable for uniquely
/// identifying the conditions under which the module was built.
std::string getModuleHash() const;
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp
index b6dc73d66304d..8c19d7e86795e 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -78,6 +78,126 @@ std::string LangOptions::getOpenCLVersionString() const {
return Result;
}
+void LangOptions::setLangDefaults(LangOptions &Opts, Language Lang,
+ const llvm::Triple &T,
+ std::vector<std::string> &Includes,
+ LangStandard::Kind LangStd) {
+ // Set some properties which depend solely 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.
+ //
+ // FIXME: Perhaps a better model would be for a single source file to have
+ // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std)
+ // simultaneously active?
+ if (Lang == Language::Asm) {
+ Opts.AsmPreprocessor = 1;
+ } else if (Lang == Language::ObjC || Lang == Language::ObjCXX) {
+ Opts.ObjC = 1;
+ }
+
+ if (LangStd == LangStandard::lang_unspecified)
+ LangStd = getDefaultLanguageStandard(Lang, T);
+ const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
+ Opts.LangStd = LangStd;
+ Opts.LineComment = Std.hasLineComments();
+ Opts.C99 = Std.isC99();
+ Opts.C11 = Std.isC11();
+ Opts.C17 = Std.isC17();
+ Opts.C2x = Std.isC2x();
+ Opts.CPlusPlus = Std.isCPlusPlus();
+ Opts.CPlusPlus11 = Std.isCPlusPlus11();
+ Opts.CPlusPlus14 = Std.isCPlusPlus14();
+ Opts.CPlusPlus17 = Std.isCPlusPlus17();
+ Opts.CPlusPlus20 = Std.isCPlusPlus20();
+ Opts.CPlusPlus2b = Std.isCPlusPlus2b();
+ Opts.GNUMode = Std.isGNUMode();
+ Opts.GNUCVersion = 0;
+ Opts.HexFloats = Std.hasHexFloats();
+ Opts.ImplicitInt = Std.hasImplicitInt();
+ Opts.WChar = Std.isCPlusPlus();
+ Opts.Digraphs = Std.hasDigraphs();
+
+ Opts.HLSL = Lang == Language::HLSL;
+
+ // Set OpenCL Version.
+ Opts.OpenCL = Std.isOpenCL();
+ if (LangStd == LangStandard::lang_opencl10)
+ Opts.OpenCLVersion = 100;
+ else if (LangStd == LangStandard::lang_opencl11)
+ Opts.OpenCLVersion = 110;
+ else if (LangStd == LangStandard::lang_opencl12)
+ Opts.OpenCLVersion = 120;
+ else if (LangStd == LangStandard::lang_opencl20)
+ Opts.OpenCLVersion = 200;
+ else if (LangStd == LangStandard::lang_opencl30)
+ Opts.OpenCLVersion = 300;
+ else if (LangStd == LangStandard::lang_openclcpp10)
+ Opts.OpenCLCPlusPlusVersion = 100;
+ else if (LangStd == LangStandard::lang_openclcpp2021)
+ Opts.OpenCLCPlusPlusVersion = 202100;
+ else if (LangStd == LangStandard::lang_hlsl2015)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2015;
+ else if (LangStd == LangStandard::lang_hlsl2016)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2016;
+ else if (LangStd == LangStandard::lang_hlsl2017)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2017;
+ else if (LangStd == LangStandard::lang_hlsl2018)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2018;
+ else if (LangStd == LangStandard::lang_hlsl2021)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2021;
+ else if (LangStd == LangStandard::lang_hlsl202x)
+ Opts.HLSLVersion = (unsigned)LangOptions::HLSL_202x;
+
+ // OpenCL has some additional defaults.
+ if (Opts.OpenCL) {
+ Opts.AltiVec = 0;
+ Opts.ZVector = 0;
+ Opts.setDefaultFPContractMode(LangOptions::FPM_On);
+ Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
+ Opts.OpenCLPipes = Opts.getOpenCLCompatibleVersion() == 200;
+ Opts.OpenCLGenericAddressSpace = Opts.getOpenCLCompatibleVersion() == 200;
+
+ // Include default header file for OpenCL.
+ if (Opts.IncludeDefaultHeader) {
+ if (Opts.DeclareOpenCLBuiltins) {
+ // Only include base header file for builtin types and constants.
+ Includes.push_back("opencl-c-base.h");
+ } else {
+ Includes.push_back("opencl-c.h");
+ }
+ }
+ }
+
+ Opts.HIP = Lang == Language::HIP;
+ Opts.CUDA = Lang == Language::CUDA || Opts.HIP;
+ if (Opts.HIP) {
+ // HIP toolchain does not support 'Fast' FPOpFusion in backends since it
+ // fuses multiplication/addition instructions without contract flag from
+ // device library functions in LLVM bitcode, which causes accuracy loss in
+ // certain math functions, e.g. tan(-1e20) becomes -0.933 instead of 0.8446.
+ // For device library functions in bitcode to work, 'Strict' or 'Standard'
+ // FPOpFusion options in backends is needed. Therefore 'fast-honor-pragmas'
+ // FP contract option is used to allow fuse across statements in frontend
+ // whereas respecting contract flag in backend.
+ Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
+ } else if (Opts.CUDA) {
+ if (T.isSPIRV()) {
+ // Emit OpenCL version metadata in LLVM IR when targeting SPIR-V.
+ Opts.OpenCLVersion = 200;
+ }
+ // Allow fuse across statements disregarding pragmas.
+ Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
+ }
+
+ Opts.RenderScript = Lang == Language::RenderScript;
+
+ // OpenCL, C++ and C2x have bool, true, false keywords.
+ Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x;
+
+ // OpenCL has half keyword
+ Opts.Half = Opts.OpenCL;
+}
+
FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) {
FPOptions result(LO);
return result;
diff --git a/clang/lib/Basic/LangStandards.cpp b/clang/lib/Basic/LangStandards.cpp
index ee27bfd12113c..2671217f3aa8c 100644
--- a/clang/lib/Basic/LangStandards.cpp
+++ b/clang/lib/Basic/LangStandards.cpp
@@ -8,6 +8,7 @@
#include "clang/Basic/LangStandard.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@@ -42,4 +43,47 @@ const LangStandard *LangStandard::getLangStandardForName(StringRef Name) {
return &getLangStandardForKind(K);
}
-
+LangStandard::Kind clang::getDefaultLanguageStandard(clang::Language Lang,
+ const llvm::Triple &T) {
+ switch (Lang) {
+ case Language::Unknown:
+ case Language::LLVM_IR:
+ llvm_unreachable("Invalid input kind!");
+ case Language::OpenCL:
+ return LangStandard::lang_opencl12;
+ case Language::OpenCLCXX:
+ return LangStandard::lang_openclcpp10;
+ case Language::CUDA:
+ return LangStandard::lang_cuda;
+ case Language::Asm:
+ case Language::C:
+#if defined(CLANG_DEFAULT_STD_C)
+ return CLANG_DEFAULT_STD_C;
+#else
+ // The PS4 uses C99 as the default C standard.
+ if (T.isPS4())
+ return LangStandard::lang_gnu99;
+ return LangStandard::lang_gnu17;
+#endif
+ case Language::ObjC:
+#if defined(CLANG_DEFAULT_STD_C)
+ return CLANG_DEFAULT_STD_C;
+#else
+ return LangStandard::lang_gnu11;
+#endif
+ case Language::CXX:
+ case Language::ObjCXX:
+#if defined(CLANG_DEFAULT_STD_CXX)
+ return CLANG_DEFAULT_STD_CXX;
+#else
+ return LangStandard::lang_gnucxx14;
+#endif
+ case Language::RenderScript:
+ return LangStandard::lang_c99;
+ case Language::HIP:
+ return LangStandard::lang_hip;
+ case Language::HLSL:
+ return LangStandard::lang_hlsl2021;
+ }
+ llvm_unreachable("unhandled Language kind!");
+}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 6aa85586df069..87e613a5dce9c 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3173,178 +3173,6 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
return Diags.getNumErrors() == NumErrorsBefore;
}
-void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
- const llvm::Triple &T,
- std::vector<std::string> &Includes,
- LangStandard::Kind LangStd) {
- // Set some properties which depend solely 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.
- //
- // FIXME: Perhaps a better model would be for a single source file to have
- // multiple language standards (C / C++ std, ObjC std, OpenCL std, OpenMP std)
- // simultaneously active?
- if (IK.getLanguage() == Language::Asm) {
- Opts.AsmPreprocessor = 1;
- } else if (IK.isObjectiveC()) {
- Opts.ObjC = 1;
- }
-
- if (LangStd == LangStandard::lang_unspecified) {
- // Based on the base language, pick one.
- switch (IK.getLanguage()) {
- case Language::Unknown:
- case Language::LLVM_IR:
- llvm_unreachable("Invalid input kind!");
- case Language::OpenCL:
- LangStd = LangStandard::lang_opencl12;
- break;
- case Language::OpenCLCXX:
- LangStd = LangStandard::lang_openclcpp10;
- break;
- case Language::CUDA:
- LangStd = LangStandard::lang_cuda;
- break;
- case Language::Asm:
- case Language::C:
-#if defined(CLANG_DEFAULT_STD_C)
- LangStd = CLANG_DEFAULT_STD_C;
-#else
- // The PS4 uses C99 as the default C standard.
- if (T.isPS4())
- LangStd = LangStandard::lang_gnu99;
- else
- LangStd = LangStandard::lang_gnu17;
-#endif
- break;
- case Language::ObjC:
-#if defined(CLANG_DEFAULT_STD_C)
- LangStd = CLANG_DEFAULT_STD_C;
-#else
- LangStd = LangStandard::lang_gnu11;
-#endif
- break;
- case Language::CXX:
- case Language::ObjCXX:
-#if defined(CLANG_DEFAULT_STD_CXX)
- LangStd = CLANG_DEFAULT_STD_CXX;
-#else
- LangStd = LangStandard::lang_gnucxx14;
-#endif
- break;
- case Language::RenderScript:
- LangStd = LangStandard::lang_c99;
- break;
- case Language::HIP:
- LangStd = LangStandard::lang_hip;
- break;
- case Language::HLSL:
- LangStd = LangStandard::lang_hlsl2021;
- break;
- }
- }
-
- const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
- Opts.LangStd = LangStd;
- Opts.LineComment = Std.hasLineComments();
- Opts.C99 = Std.isC99();
- Opts.C11 = Std.isC11();
- Opts.C17 = Std.isC17();
- Opts.C2x = Std.isC2x();
- Opts.CPlusPlus = Std.isCPlusPlus();
- Opts.CPlusPlus11 = Std.isCPlusPlus11();
- Opts.CPlusPlus14 = Std.isCPlusPlus14();
- Opts.CPlusPlus17 = Std.isCPlusPlus17();
- Opts.CPlusPlus20 = Std.isCPlusPlus20();
- Opts.CPlusPlus2b = Std.isCPlusPlus2b();
- Opts.GNUMode = Std.isGNUMode();
- Opts.GNUCVersion = 0;
- Opts.HexFloats = Std.hasHexFloats();
- Opts.ImplicitInt = Std.hasImplicitInt();
- Opts.WChar = Std.isCPlusPlus();
- Opts.Digraphs = Std.hasDigraphs();
-
- Opts.HLSL = IK.getLanguage() == Language::HLSL;
-
- // Set OpenCL Version.
- Opts.OpenCL = Std.isOpenCL();
- if (LangStd == LangStandard::lang_opencl10)
- Opts.OpenCLVersion = 100;
- else if (LangStd == LangStandard::lang_opencl11)
- Opts.OpenCLVersion = 110;
- else if (LangStd == LangStandard::lang_opencl12)
- Opts.OpenCLVersion = 120;
- else if (LangStd == LangStandard::lang_opencl20)
- Opts.OpenCLVersion = 200;
- else if (LangStd == LangStandard::lang_opencl30)
- Opts.OpenCLVersion = 300;
- else if (LangStd == LangStandard::lang_openclcpp10)
- Opts.OpenCLCPlusPlusVersion = 100;
- else if (LangStd == LangStandard::lang_openclcpp2021)
- Opts.OpenCLCPlusPlusVersion = 202100;
- else if (LangStd == LangStandard::lang_hlsl2015)
- Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2015;
- else if (LangStd == LangStandard::lang_hlsl2016)
- Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2016;
- else if (LangStd == LangStandard::lang_hlsl2017)
- Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2017;
- else if (LangStd == LangStandard::lang_hlsl2018)
- Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2018;
- else if (LangStd == LangStandard::lang_hlsl2021)
- Opts.HLSLVersion = (unsigned)LangOptions::HLSL_2021;
- else if (LangStd == LangStandard::lang_hlsl202x)
- Opts.HLSLVersion = (unsigned)LangOptions::HLSL_202x;
-
- // OpenCL has some additional defaults.
- if (Opts.OpenCL) {
- Opts.AltiVec = 0;
- Opts.ZVector = 0;
- Opts.setDefaultFPContractMode(LangOptions::FPM_On);
- Opts.OpenCLCPlusPlus = Opts.CPlusPlus;
- Opts.OpenCLPipes = Opts.getOpenCLCompatibleVersion() == 200;
- Opts.OpenCLGenericAddressSpace = Opts.getOpenCLCompatibleVersion() == 200;
-
- // Include default header file for OpenCL.
- if (Opts.IncludeDefaultHeader) {
- if (Opts.DeclareOpenCLBuiltins) {
- // Only include base header file for builtin types and constants.
- Includes.push_back("opencl-c-base.h");
- } else {
- Includes.push_back("opencl-c.h");
- }
- }
- }
-
- Opts.HIP = IK.getLanguage() == Language::HIP;
- Opts.CUDA = IK.getLanguage() == Language::CUDA || Opts.HIP;
- if (Opts.HIP) {
- // HIP toolchain does not support 'Fast' FPOpFusion in backends since it
- // fuses multiplication/addition instructions without contract flag from
- // device library functions in LLVM bitcode, which causes accuracy loss in
- // certain math functions, e.g. tan(-1e20) becomes -0.933 instead of 0.8446.
- // For device library functions in bitcode to work, 'Strict' or 'Standard'
- // FPOpFusion options in backends is needed. Therefore 'fast-honor-pragmas'
- // FP contract option is used to allow fuse across statements in frontend
- // whereas respecting contract flag in backend.
- Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
- } else if (Opts.CUDA) {
- if (T.isSPIRV()) {
- // Emit OpenCL version metadata in LLVM IR when targeting SPIR-V.
- Opts.OpenCLVersion = 200;
- }
- // Allow fuse across statements disregarding pragmas.
- Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
- }
-
- Opts.RenderScript = IK.getLanguage() == Language::RenderScript;
-
- // OpenCL, C++ and C2x have bool, true, false keywords.
- Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x;
-
- // OpenCL has half keyword
- Opts.Half = Opts.OpenCL;
-}
-
/// Check if input file kind and language standard are compatible.
static bool IsInputCompatibleWithStandard(InputKind IK,
const LangStandard &S) {
@@ -3783,7 +3611,7 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
- CompilerInvocation::setLangDefaults(Opts, IK, T, Includes, LangStd);
+ LangOptions::setLangDefaults(Opts, IK.getLanguage(), T, Includes, LangStd);
// The key paths of codegen options defined in Options.td start with
// "LangOpts->". Let's provide the expected variable name and type.
More information about the cfe-commits
mailing list