diff options
author | Haojian Wu <hokein.wu@gmail.com> | 2022-04-08 13:23:12 +0200 |
---|---|---|
committer | Haojian Wu <hokein.wu@gmail.com> | 2022-04-13 09:44:39 +0200 |
commit | 93471e65df48372ee59bd0c2f8ba58a254ba1ca5 (patch) | |
tree | b28af6cd0fc50a6f183964ab9201d28cbafd6852 /clang/lib/Basic | |
parent | 63f2d1f4d4b8ee284b4ab977242e322a9458a168 (diff) | |
download | llvm-93471e65df48372ee59bd0c2f8ba58a254ba1ca5.zip llvm-93471e65df48372ee59bd0c2f8ba58a254ba1ca5.tar.gz llvm-93471e65df48372ee59bd0c2f8ba58a254ba1ca5.tar.bz2 |
[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
Diffstat (limited to 'clang/lib/Basic')
-rw-r--r-- | clang/lib/Basic/LangOptions.cpp | 120 | ||||
-rw-r--r-- | clang/lib/Basic/LangStandards.cpp | 46 |
2 files changed, 165 insertions, 1 deletions
diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp index b6dc73d..8c19d7e 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 ee27bfd..2671217 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!"); +} |