diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2017-12-07 21:46:26 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2017-12-07 21:46:26 +0000 |
commit | 5b6c0f75e01571851b767dc63a3229c962f464f1 (patch) | |
tree | a8586f01569b3a15185424e3f737ebac11e1dc33 /clang/lib/Frontend | |
parent | 48f5f4d895ecada915677f528d493814a76e890d (diff) | |
download | bcm5719-llvm-5b6c0f75e01571851b767dc63a3229c962f464f1.tar.gz bcm5719-llvm-5b6c0f75e01571851b767dc63a3229c962f464f1.zip |
Add new language mode flags for C17.
This adds -std=c17, -std=gnu17, and -std=iso9899:2017 as language mode flags for C17 and updates the value of __STDC_VERSION__ to the value based on the C17 FDIS. Given that this ballot cannot succeed until 2018, it is expected that we (and GCC) will add c18 flags as aliases once the ballot passes.
llvm-svn: 320089
Diffstat (limited to 'clang/lib/Frontend')
-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"); |