diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 401 | ||||
-rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 404 |
2 files changed, 404 insertions, 401 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index d2800b52e22..22cc9c25dd0 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1645,206 +1645,207 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true); } - for (const Arg *A : Args.filtered(OPT_idirafter)) - Opts.AddPath(A->getValue(), frontend::After, false, true); - for (const Arg *A : Args.filtered(OPT_iquote)) - Opts.AddPath(A->getValue(), frontend::Quoted, false, true); - for (const Arg *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) - Opts.AddPath(A->getValue(), frontend::System, false, - !A->getOption().matches(OPT_iwithsysroot)); - for (const Arg *A : Args.filtered(OPT_iframework)) - Opts.AddPath(A->getValue(), frontend::System, true, true); - for (const Arg *A : Args.filtered(OPT_iframeworkwithsysroot)) - Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true, - /*IgnoreSysRoot=*/false); - - // Add the paths for the various language specific isystem flags. - for (const Arg *A : Args.filtered(OPT_c_isystem)) - Opts.AddPath(A->getValue(), frontend::CSystem, false, true); - for (const Arg *A : Args.filtered(OPT_cxx_isystem)) - Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true); - for (const Arg *A : Args.filtered(OPT_objc_isystem)) - Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true); - for (const Arg *A : Args.filtered(OPT_objcxx_isystem)) - Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true); - - // Add the internal paths from a driver that detects standard include paths. - for (const Arg *A : - Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) { - frontend::IncludeDirGroup Group = frontend::System; - if (A->getOption().matches(OPT_internal_externc_isystem)) - Group = frontend::ExternCSystem; - Opts.AddPath(A->getValue(), Group, false, true); - } - - // Add the path prefixes which are implicitly treated as being system headers. - for (const Arg *A : - Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix)) - Opts.AddSystemHeaderPrefix( - A->getValue(), A->getOption().matches(OPT_system_header_prefix)); - - for (const Arg *A : Args.filtered(OPT_ivfsoverlay)) - Opts.AddVFSOverlayFile(A->getValue()); -} - -void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK, - const llvm::Triple &T, - PreprocessorOptions &PPOpts, - 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() == InputKind::Asm) { - Opts.AsmPreprocessor = 1; - } else if (IK.isObjectiveC()) { - Opts.ObjC1 = Opts.ObjC2 = 1; - } - - if (LangStd == LangStandard::lang_unspecified) { - // Based on the base language, pick one. - switch (IK.getLanguage()) { - case InputKind::Unknown: - case InputKind::LLVM_IR: - llvm_unreachable("Invalid input kind!"); - case InputKind::OpenCL: - LangStd = LangStandard::lang_opencl10; - break; - case InputKind::CUDA: - LangStd = LangStandard::lang_cuda; - break; - case InputKind::Asm: - case InputKind::C: - // The PS4 uses C99 as the default C standard. - if (T.isPS4()) - LangStd = LangStandard::lang_gnu99; - else - LangStd = LangStandard::lang_gnu11; - break; - case InputKind::ObjC: - LangStd = LangStandard::lang_gnu11; - break; - case InputKind::CXX: - case InputKind::ObjCXX: - // The PS4 uses C++11 as the default C++ standard. - if (T.isPS4()) - LangStd = LangStandard::lang_gnucxx11; - else - LangStd = LangStandard::lang_gnucxx98; - break; - case InputKind::RenderScript: - LangStd = LangStandard::lang_c99; - break; - } - } - - const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd); - Opts.LineComment = Std.hasLineComments(); - Opts.C99 = Std.isC99(); - Opts.C11 = Std.isC11(); - Opts.CPlusPlus = Std.isCPlusPlus(); - Opts.CPlusPlus11 = Std.isCPlusPlus11(); - Opts.CPlusPlus14 = Std.isCPlusPlus14(); - Opts.CPlusPlus17 = Std.isCPlusPlus17(); - Opts.CPlusPlus2a = Std.isCPlusPlus2a(); - Opts.Digraphs = Std.hasDigraphs(); - Opts.GNUMode = Std.isGNUMode(); - Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus; - Opts.HexFloats = Std.hasHexFloats(); - Opts.ImplicitInt = Std.hasImplicitInt(); - - // 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; - - // OpenCL has some additional defaults. - if (Opts.OpenCL) { - Opts.AltiVec = 0; - Opts.ZVector = 0; - Opts.LaxVectorConversions = 0; - Opts.setDefaultFPContractMode(LangOptions::FPC_On); - Opts.NativeHalfType = 1; - Opts.NativeHalfArgsAndReturns = 1; - // Include default header file for OpenCL. - if (Opts.IncludeDefaultHeader) { - PPOpts.Includes.push_back("opencl-c.h"); - } - } - - Opts.CUDA = IK.getLanguage() == InputKind::CUDA; - if (Opts.CUDA) - // Set default FP_CONTRACT to FAST. - Opts.setDefaultFPContractMode(LangOptions::FPC_Fast); - - Opts.RenderScript = IK.getLanguage() == InputKind::RenderScript; - if (Opts.RenderScript) { - Opts.NativeHalfType = 1; - Opts.NativeHalfArgsAndReturns = 1; - } - - // OpenCL and C++ both have bool, true, false keywords. - Opts.Bool = Opts.OpenCL || Opts.CPlusPlus; - - // OpenCL has half keyword - Opts.Half = Opts.OpenCL; - - // C++ has wchar_t keyword. - Opts.WChar = Opts.CPlusPlus; - - Opts.GNUKeywords = Opts.GNUMode; - Opts.CXXOperatorNames = Opts.CPlusPlus; - - Opts.AlignedAllocation = Opts.CPlusPlus17; - - Opts.DollarIdents = !Opts.AsmPreprocessor; -} - -/// Attempt to parse a visibility value out of the given argument. -static Visibility parseVisibility(Arg *arg, ArgList &args, - DiagnosticsEngine &diags) { - StringRef value = arg->getValue(); - if (value == "default") { - return DefaultVisibility; - } else if (value == "hidden" || value == "internal") { - return HiddenVisibility; - } else if (value == "protected") { - // FIXME: diagnose if target does not support protected visibility - return ProtectedVisibility; - } - - diags.Report(diag::err_drv_invalid_value) - << arg->getAsString(args) << value; - return DefaultVisibility; -} - -/// Check if input file kind and language standard are compatible. -static bool IsInputCompatibleWithStandard(InputKind IK, - const LangStandard &S) { - switch (IK.getLanguage()) { - case InputKind::Unknown: - case InputKind::LLVM_IR: - llvm_unreachable("should not parse language flags for this input"); - - case InputKind::C: - case InputKind::ObjC: - case InputKind::RenderScript: - return S.getLanguage() == InputKind::C; - - case InputKind::OpenCL: - return S.getLanguage() == InputKind::OpenCL; - - case InputKind::CXX: - case InputKind::ObjCXX: + for (const Arg *A : Args.filtered(OPT_idirafter))
+ Opts.AddPath(A->getValue(), frontend::After, false, true);
+ for (const Arg *A : Args.filtered(OPT_iquote))
+ Opts.AddPath(A->getValue(), frontend::Quoted, false, true);
+ for (const Arg *A : Args.filtered(OPT_isystem, OPT_iwithsysroot))
+ Opts.AddPath(A->getValue(), frontend::System, false,
+ !A->getOption().matches(OPT_iwithsysroot));
+ for (const Arg *A : Args.filtered(OPT_iframework))
+ Opts.AddPath(A->getValue(), frontend::System, true, true);
+ for (const Arg *A : Args.filtered(OPT_iframeworkwithsysroot))
+ Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
+ /*IgnoreSysRoot=*/false);
+
+ // Add the paths for the various language specific isystem flags.
+ for (const Arg *A : Args.filtered(OPT_c_isystem))
+ Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
+ for (const Arg *A : Args.filtered(OPT_cxx_isystem))
+ Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
+ for (const Arg *A : Args.filtered(OPT_objc_isystem))
+ Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
+ for (const Arg *A : Args.filtered(OPT_objcxx_isystem))
+ Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
+
+ // Add the internal paths from a driver that detects standard include paths.
+ for (const Arg *A :
+ Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
+ frontend::IncludeDirGroup Group = frontend::System;
+ if (A->getOption().matches(OPT_internal_externc_isystem))
+ Group = frontend::ExternCSystem;
+ Opts.AddPath(A->getValue(), Group, false, true);
+ }
+
+ // Add the path prefixes which are implicitly treated as being system headers.
+ for (const Arg *A :
+ Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
+ Opts.AddSystemHeaderPrefix(
+ A->getValue(), A->getOption().matches(OPT_system_header_prefix));
+
+ for (const Arg *A : Args.filtered(OPT_ivfsoverlay))
+ Opts.AddVFSOverlayFile(A->getValue());
+}
+
+void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
+ const llvm::Triple &T,
+ PreprocessorOptions &PPOpts,
+ 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() == InputKind::Asm) {
+ Opts.AsmPreprocessor = 1;
+ } else if (IK.isObjectiveC()) {
+ Opts.ObjC1 = Opts.ObjC2 = 1;
+ }
+
+ if (LangStd == LangStandard::lang_unspecified) {
+ // Based on the base language, pick one.
+ switch (IK.getLanguage()) {
+ case InputKind::Unknown:
+ case InputKind::LLVM_IR:
+ llvm_unreachable("Invalid input kind!");
+ case InputKind::OpenCL:
+ LangStd = LangStandard::lang_opencl10;
+ break;
+ case InputKind::CUDA:
+ LangStd = LangStandard::lang_cuda;
+ break;
+ case InputKind::Asm:
+ case InputKind::C:
+ // The PS4 uses C99 as the default C standard.
+ if (T.isPS4())
+ LangStd = LangStandard::lang_gnu99;
+ else
+ LangStd = LangStandard::lang_gnu11;
+ break;
+ case InputKind::ObjC:
+ LangStd = LangStandard::lang_gnu11;
+ break;
+ case InputKind::CXX:
+ case InputKind::ObjCXX:
+ // The PS4 uses C++11 as the default C++ standard.
+ if (T.isPS4())
+ LangStd = LangStandard::lang_gnucxx11;
+ else
+ LangStd = LangStandard::lang_gnucxx98;
+ break;
+ case InputKind::RenderScript:
+ LangStd = LangStandard::lang_c99;
+ break;
+ }
+ }
+
+ const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
+ Opts.LineComment = Std.hasLineComments();
+ Opts.C99 = Std.isC99();
+ Opts.C11 = Std.isC11();
+ Opts.C17 = Std.isC17();
+ Opts.CPlusPlus = Std.isCPlusPlus();
+ Opts.CPlusPlus11 = Std.isCPlusPlus11();
+ Opts.CPlusPlus14 = Std.isCPlusPlus14();
+ Opts.CPlusPlus17 = Std.isCPlusPlus17();
+ Opts.CPlusPlus2a = Std.isCPlusPlus2a();
+ Opts.Digraphs = Std.hasDigraphs();
+ Opts.GNUMode = Std.isGNUMode();
+ Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus;
+ Opts.HexFloats = Std.hasHexFloats();
+ Opts.ImplicitInt = Std.hasImplicitInt();
+
+ // 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;
+
+ // OpenCL has some additional defaults.
+ if (Opts.OpenCL) {
+ Opts.AltiVec = 0;
+ Opts.ZVector = 0;
+ Opts.LaxVectorConversions = 0;
+ Opts.setDefaultFPContractMode(LangOptions::FPC_On);
+ Opts.NativeHalfType = 1;
+ Opts.NativeHalfArgsAndReturns = 1;
+ // Include default header file for OpenCL.
+ if (Opts.IncludeDefaultHeader) {
+ PPOpts.Includes.push_back("opencl-c.h");
+ }
+ }
+
+ Opts.CUDA = IK.getLanguage() == InputKind::CUDA;
+ if (Opts.CUDA)
+ // Set default FP_CONTRACT to FAST.
+ Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
+
+ Opts.RenderScript = IK.getLanguage() == InputKind::RenderScript;
+ if (Opts.RenderScript) {
+ Opts.NativeHalfType = 1;
+ Opts.NativeHalfArgsAndReturns = 1;
+ }
+
+ // OpenCL and C++ both have bool, true, false keywords.
+ Opts.Bool = Opts.OpenCL || Opts.CPlusPlus;
+
+ // OpenCL has half keyword
+ Opts.Half = Opts.OpenCL;
+
+ // C++ has wchar_t keyword.
+ Opts.WChar = Opts.CPlusPlus;
+
+ Opts.GNUKeywords = Opts.GNUMode;
+ Opts.CXXOperatorNames = Opts.CPlusPlus;
+
+ Opts.AlignedAllocation = Opts.CPlusPlus17;
+
+ Opts.DollarIdents = !Opts.AsmPreprocessor;
+}
+
+/// Attempt to parse a visibility value out of the given argument.
+static Visibility parseVisibility(Arg *arg, ArgList &args,
+ DiagnosticsEngine &diags) {
+ StringRef value = arg->getValue();
+ if (value == "default") {
+ return DefaultVisibility;
+ } else if (value == "hidden" || value == "internal") {
+ return HiddenVisibility;
+ } else if (value == "protected") {
+ // FIXME: diagnose if target does not support protected visibility
+ return ProtectedVisibility;
+ }
+
+ diags.Report(diag::err_drv_invalid_value)
+ << arg->getAsString(args) << value;
+ return DefaultVisibility;
+}
+
+/// Check if input file kind and language standard are compatible.
+static bool IsInputCompatibleWithStandard(InputKind IK,
+ const LangStandard &S) {
+ switch (IK.getLanguage()) {
+ case InputKind::Unknown:
+ case InputKind::LLVM_IR:
+ llvm_unreachable("should not parse language flags for this input");
+
+ case InputKind::C:
+ case InputKind::ObjC:
+ case InputKind::RenderScript:
+ return S.getLanguage() == InputKind::C;
+
+ case InputKind::OpenCL:
+ return S.getLanguage() == InputKind::OpenCL;
+
+ case InputKind::CXX:
+ case InputKind::ObjCXX:
return S.getLanguage() == InputKind::CXX; case InputKind::CUDA: diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index a7ce2868a63..9bdb0d53fb5 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -270,207 +270,209 @@ static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned, DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder); } - -static void DefineFastIntType(unsigned TypeWidth, bool IsSigned, - const TargetInfo &TI, MacroBuilder &Builder) { - // stdint.h currently defines the fast int types as equivalent to the least - // types. - TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned); - if (Ty == TargetInfo::NoInt) - return; - - const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST"; - DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder); - DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder); - - DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder); -} - - -/// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with -/// the specified properties. -static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign, - unsigned InlineWidth) { - // Fully-aligned, power-of-2 sizes no larger than the inline - // width will be inlined as lock-free operations. - if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 && - TypeWidth <= InlineWidth) - return "2"; // "always lock free" - // We cannot be certain what operations the lib calls might be - // able to implement as lock-free on future processors. - return "1"; // "sometimes lock free" -} - -/// \brief Add definitions required for a smooth interaction between -/// Objective-C++ automated reference counting and libstdc++ (4.2). -static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts, - MacroBuilder &Builder) { - Builder.defineMacro("_GLIBCXX_PREDEFINED_OBJC_ARC_IS_SCALAR"); - - std::string Result; - { - // Provide specializations for the __is_scalar type trait so that - // lifetime-qualified objects are not considered "scalar" types, which - // libstdc++ uses as an indicator of the presence of trivial copy, assign, - // default-construct, and destruct semantics (none of which hold for - // lifetime-qualified objects in ARC). - llvm::raw_string_ostream Out(Result); - - Out << "namespace std {\n" - << "\n" - << "struct __true_type;\n" - << "struct __false_type;\n" - << "\n"; - - Out << "template<typename _Tp> struct __is_scalar;\n" - << "\n"; - - if (LangOpts.ObjCAutoRefCount) { - Out << "template<typename _Tp>\n" - << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n" - << " enum { __value = 0 };\n" - << " typedef __false_type __type;\n" - << "};\n" - << "\n"; - } - - if (LangOpts.ObjCWeak) { - Out << "template<typename _Tp>\n" - << "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n" - << " enum { __value = 0 };\n" - << " typedef __false_type __type;\n" - << "};\n" - << "\n"; - } - - if (LangOpts.ObjCAutoRefCount) { - Out << "template<typename _Tp>\n" - << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))" - << " _Tp> {\n" - << " enum { __value = 0 };\n" - << " typedef __false_type __type;\n" - << "};\n" - << "\n"; - } - - Out << "}\n"; - } - Builder.append(Result); -} - -static void InitializeStandardPredefinedMacros(const TargetInfo &TI, - const LangOptions &LangOpts, - const FrontendOptions &FEOpts, - MacroBuilder &Builder) { - if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP) - Builder.defineMacro("__STDC__"); - if (LangOpts.Freestanding) - Builder.defineMacro("__STDC_HOSTED__", "0"); - else - Builder.defineMacro("__STDC_HOSTED__"); - - if (!LangOpts.CPlusPlus) { - if (LangOpts.C11) - Builder.defineMacro("__STDC_VERSION__", "201112L"); - else if (LangOpts.C99) - Builder.defineMacro("__STDC_VERSION__", "199901L"); - else if (!LangOpts.GNUMode && LangOpts.Digraphs) - Builder.defineMacro("__STDC_VERSION__", "199409L"); - } else { - // FIXME: Use correct value for C++20. - if (LangOpts.CPlusPlus2a) - Builder.defineMacro("__cplusplus", "201707L"); - // C++17 [cpp.predefined]p1: - // The name __cplusplus is defined to the value 201703L when compiling a - // C++ translation unit. - else if (LangOpts.CPlusPlus17) - Builder.defineMacro("__cplusplus", "201703L"); - // C++1y [cpp.predefined]p1: - // The name __cplusplus is defined to the value 201402L when compiling a - // C++ translation unit. - else if (LangOpts.CPlusPlus14) - Builder.defineMacro("__cplusplus", "201402L"); - // C++11 [cpp.predefined]p1: - // The name __cplusplus is defined to the value 201103L when compiling a - // C++ translation unit. - else if (LangOpts.CPlusPlus11) - Builder.defineMacro("__cplusplus", "201103L"); - // C++03 [cpp.predefined]p1: - // The name __cplusplus is defined to the value 199711L when compiling a - // C++ translation unit. - else - Builder.defineMacro("__cplusplus", "199711L"); - - // C++1z [cpp.predefined]p1: - // An integer literal of type std::size_t whose value is the alignment - // guaranteed by a call to operator new(std::size_t) - // - // We provide this in all language modes, since it seems generally useful. - Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__", - Twine(TI.getNewAlign() / TI.getCharWidth()) + - TI.getTypeConstantSuffix(TI.getSizeType())); - } - - // In C11 these are environment macros. In C++11 they are only defined - // as part of <cuchar>. To prevent breakage when mixing C and C++ - // code, define these macros unconditionally. We can define them - // unconditionally, as Clang always uses UTF-16 and UTF-32 for 16-bit - // and 32-bit character literals. - Builder.defineMacro("__STDC_UTF_16__", "1"); - Builder.defineMacro("__STDC_UTF_32__", "1"); - - if (LangOpts.ObjC1) - Builder.defineMacro("__OBJC__"); - - // OpenCL v1.0/1.1 s6.9, v1.2/2.0 s6.10: Preprocessor Directives and Macros. - if (LangOpts.OpenCL) { - // OpenCL v1.0 and v1.1 do not have a predefined macro to indicate the - // language standard with which the program is compiled. __OPENCL_VERSION__ - // is for the OpenCL version supported by the OpenCL device, which is not - // necessarily the language standard with which the program is compiled. - // A shared OpenCL header file requires a macro to indicate the language - // standard. As a workaround, __OPENCL_C_VERSION__ is defined for - // OpenCL v1.0 and v1.1. - switch (LangOpts.OpenCLVersion) { - case 100: - Builder.defineMacro("__OPENCL_C_VERSION__", "100"); - break; - case 110: - Builder.defineMacro("__OPENCL_C_VERSION__", "110"); - break; - case 120: - Builder.defineMacro("__OPENCL_C_VERSION__", "120"); - break; - case 200: - Builder.defineMacro("__OPENCL_C_VERSION__", "200"); - break; - default: - llvm_unreachable("Unsupported OpenCL version"); - } - Builder.defineMacro("CL_VERSION_1_0", "100"); - Builder.defineMacro("CL_VERSION_1_1", "110"); - Builder.defineMacro("CL_VERSION_1_2", "120"); - Builder.defineMacro("CL_VERSION_2_0", "200"); - - if (TI.isLittleEndian()) - Builder.defineMacro("__ENDIAN_LITTLE__"); - - if (LangOpts.FastRelaxedMath) - Builder.defineMacro("__FAST_RELAXED_MATH__"); - } - // Not "standard" per se, but available even with the -undef flag. - if (LangOpts.AsmPreprocessor) - Builder.defineMacro("__ASSEMBLER__"); - if (LangOpts.CUDA) - Builder.defineMacro("__CUDA__"); -} - -/// Initialize the predefined C++ language feature test macros defined in -/// ISO/IEC JTC1/SC22/WG21 (C++) SD-6: "SG10 Feature Test Recommendations". -static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, - MacroBuilder &Builder) { - // C++98 features. - if (LangOpts.RTTI) +
+static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
+ const TargetInfo &TI, MacroBuilder &Builder) {
+ // stdint.h currently defines the fast int types as equivalent to the least
+ // types.
+ TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
+ if (Ty == TargetInfo::NoInt)
+ return;
+
+ const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST";
+ DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+ DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+
+ DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
+}
+
+
+/// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with
+/// the specified properties.
+static const char *getLockFreeValue(unsigned TypeWidth, unsigned TypeAlign,
+ unsigned InlineWidth) {
+ // Fully-aligned, power-of-2 sizes no larger than the inline
+ // width will be inlined as lock-free operations.
+ if (TypeWidth == TypeAlign && (TypeWidth & (TypeWidth - 1)) == 0 &&
+ TypeWidth <= InlineWidth)
+ return "2"; // "always lock free"
+ // We cannot be certain what operations the lib calls might be
+ // able to implement as lock-free on future processors.
+ return "1"; // "sometimes lock free"
+}
+
+/// \brief Add definitions required for a smooth interaction between
+/// Objective-C++ automated reference counting and libstdc++ (4.2).
+static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts,
+ MacroBuilder &Builder) {
+ Builder.defineMacro("_GLIBCXX_PREDEFINED_OBJC_ARC_IS_SCALAR");
+
+ std::string Result;
+ {
+ // Provide specializations for the __is_scalar type trait so that
+ // lifetime-qualified objects are not considered "scalar" types, which
+ // libstdc++ uses as an indicator of the presence of trivial copy, assign,
+ // default-construct, and destruct semantics (none of which hold for
+ // lifetime-qualified objects in ARC).
+ llvm::raw_string_ostream Out(Result);
+
+ Out << "namespace std {\n"
+ << "\n"
+ << "struct __true_type;\n"
+ << "struct __false_type;\n"
+ << "\n";
+
+ Out << "template<typename _Tp> struct __is_scalar;\n"
+ << "\n";
+
+ if (LangOpts.ObjCAutoRefCount) {
+ Out << "template<typename _Tp>\n"
+ << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n"
+ << " enum { __value = 0 };\n"
+ << " typedef __false_type __type;\n"
+ << "};\n"
+ << "\n";
+ }
+
+ if (LangOpts.ObjCWeak) {
+ Out << "template<typename _Tp>\n"
+ << "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n"
+ << " enum { __value = 0 };\n"
+ << " typedef __false_type __type;\n"
+ << "};\n"
+ << "\n";
+ }
+
+ if (LangOpts.ObjCAutoRefCount) {
+ Out << "template<typename _Tp>\n"
+ << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))"
+ << " _Tp> {\n"
+ << " enum { __value = 0 };\n"
+ << " typedef __false_type __type;\n"
+ << "};\n"
+ << "\n";
+ }
+
+ Out << "}\n";
+ }
+ Builder.append(Result);
+}
+
+static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
+ const LangOptions &LangOpts,
+ const FrontendOptions &FEOpts,
+ MacroBuilder &Builder) {
+ if (!LangOpts.MSVCCompat && !LangOpts.TraditionalCPP)
+ Builder.defineMacro("__STDC__");
+ if (LangOpts.Freestanding)
+ Builder.defineMacro("__STDC_HOSTED__", "0");
+ else
+ Builder.defineMacro("__STDC_HOSTED__");
+
+ if (!LangOpts.CPlusPlus) {
+ if (LangOpts.C17)
+ Builder.defineMacro("__STDC_VERSION__", "201710L");
+ else if (LangOpts.C11)
+ Builder.defineMacro("__STDC_VERSION__", "201112L");
+ else if (LangOpts.C99)
+ Builder.defineMacro("__STDC_VERSION__", "199901L");
+ else if (!LangOpts.GNUMode && LangOpts.Digraphs)
+ Builder.defineMacro("__STDC_VERSION__", "199409L");
+ } else {
+ // FIXME: Use correct value for C++20.
+ if (LangOpts.CPlusPlus2a)
+ Builder.defineMacro("__cplusplus", "201707L");
+ // C++17 [cpp.predefined]p1:
+ // The name __cplusplus is defined to the value 201703L when compiling a
+ // C++ translation unit.
+ else if (LangOpts.CPlusPlus17)
+ Builder.defineMacro("__cplusplus", "201703L");
+ // C++1y [cpp.predefined]p1:
+ // The name __cplusplus is defined to the value 201402L when compiling a
+ // C++ translation unit.
+ else if (LangOpts.CPlusPlus14)
+ Builder.defineMacro("__cplusplus", "201402L");
+ // C++11 [cpp.predefined]p1:
+ // The name __cplusplus is defined to the value 201103L when compiling a
+ // C++ translation unit.
+ else if (LangOpts.CPlusPlus11)
+ Builder.defineMacro("__cplusplus", "201103L");
+ // C++03 [cpp.predefined]p1:
+ // The name __cplusplus is defined to the value 199711L when compiling a
+ // C++ translation unit.
+ else
+ Builder.defineMacro("__cplusplus", "199711L");
+
+ // C++1z [cpp.predefined]p1:
+ // An integer literal of type std::size_t whose value is the alignment
+ // guaranteed by a call to operator new(std::size_t)
+ //
+ // We provide this in all language modes, since it seems generally useful.
+ Builder.defineMacro("__STDCPP_DEFAULT_NEW_ALIGNMENT__",
+ Twine(TI.getNewAlign() / TI.getCharWidth()) +
+ TI.getTypeConstantSuffix(TI.getSizeType()));
+ }
+
+ // In C11 these are environment macros. In C++11 they are only defined
+ // as part of <cuchar>. To prevent breakage when mixing C and C++
+ // code, define these macros unconditionally. We can define them
+ // unconditionally, as Clang always uses UTF-16 and UTF-32 for 16-bit
+ // and 32-bit character literals.
+ Builder.defineMacro("__STDC_UTF_16__", "1");
+ Builder.defineMacro("__STDC_UTF_32__", "1");
+
+ if (LangOpts.ObjC1)
+ Builder.defineMacro("__OBJC__");
+
+ // OpenCL v1.0/1.1 s6.9, v1.2/2.0 s6.10: Preprocessor Directives and Macros.
+ if (LangOpts.OpenCL) {
+ // OpenCL v1.0 and v1.1 do not have a predefined macro to indicate the
+ // language standard with which the program is compiled. __OPENCL_VERSION__
+ // is for the OpenCL version supported by the OpenCL device, which is not
+ // necessarily the language standard with which the program is compiled.
+ // A shared OpenCL header file requires a macro to indicate the language
+ // standard. As a workaround, __OPENCL_C_VERSION__ is defined for
+ // OpenCL v1.0 and v1.1.
+ switch (LangOpts.OpenCLVersion) {
+ case 100:
+ Builder.defineMacro("__OPENCL_C_VERSION__", "100");
+ break;
+ case 110:
+ Builder.defineMacro("__OPENCL_C_VERSION__", "110");
+ break;
+ case 120:
+ Builder.defineMacro("__OPENCL_C_VERSION__", "120");
+ break;
+ case 200:
+ Builder.defineMacro("__OPENCL_C_VERSION__", "200");
+ break;
+ default:
+ llvm_unreachable("Unsupported OpenCL version");
+ }
+ Builder.defineMacro("CL_VERSION_1_0", "100");
+ Builder.defineMacro("CL_VERSION_1_1", "110");
+ Builder.defineMacro("CL_VERSION_1_2", "120");
+ Builder.defineMacro("CL_VERSION_2_0", "200");
+
+ if (TI.isLittleEndian())
+ Builder.defineMacro("__ENDIAN_LITTLE__");
+
+ if (LangOpts.FastRelaxedMath)
+ Builder.defineMacro("__FAST_RELAXED_MATH__");
+ }
+ // Not "standard" per se, but available even with the -undef flag.
+ if (LangOpts.AsmPreprocessor)
+ Builder.defineMacro("__ASSEMBLER__");
+ if (LangOpts.CUDA)
+ Builder.defineMacro("__CUDA__");
+}
+
+/// Initialize the predefined C++ language feature test macros defined in
+/// ISO/IEC JTC1/SC22/WG21 (C++) SD-6: "SG10 Feature Test Recommendations".
+static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
+ MacroBuilder &Builder) {
+ // C++98 features.
+ if (LangOpts.RTTI)
Builder.defineMacro("__cpp_rtti", "199711"); if (LangOpts.CXXExceptions) Builder.defineMacro("__cpp_exceptions", "199711"); |