diff options
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 404 | ||||
-rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 420 |
2 files changed, 412 insertions, 412 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 22cc9c25dd0..59e5b62c5e8 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1645,207 +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.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:
+ 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: @@ -2165,7 +2165,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, && Opts.OpenCLVersion >= 200); Opts.BlocksRuntimeOptional = Args.hasArg(OPT_fblocks_runtime_optional); Opts.CoroutinesTS = Args.hasArg(OPT_fcoroutines_ts); - + // Enable [[]] attributes in C++11 by default. Opts.DoubleSquareBracketAttributes = Args.hasFlag(OPT_fdouble_square_bracket_attributes, diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 9bdb0d53fb5..d3989049432 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -193,7 +193,7 @@ static void DefineTypeSize(const Twine &MacroName, unsigned TypeWidth, /// the width, suffix, and signedness of the given type static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty, const TargetInfo &TI, MacroBuilder &Builder) { - DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), + DefineTypeSize(MacroName, TI.getTypeWidth(Ty), TI.getTypeConstantSuffix(Ty), TI.isTypeSigned(Ty), Builder); } @@ -270,209 +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.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)
+ +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"); @@ -485,7 +485,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts, Builder.defineMacro("__cpp_user_defined_literals", "200809"); Builder.defineMacro("__cpp_lambdas", "200907"); Builder.defineMacro("__cpp_constexpr", - LangOpts.CPlusPlus17 ? "201603" : + LangOpts.CPlusPlus17 ? "201603" : LangOpts.CPlusPlus14 ? "201304" : "200704"); Builder.defineMacro("__cpp_range_based_for", LangOpts.CPlusPlus17 ? "201603" : "200907"); @@ -561,7 +561,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, Builder.defineMacro("__clang_patchlevel__", TOSTR(CLANG_VERSION_PATCHLEVEL)); #undef TOSTR #undef TOSTR2 - Builder.defineMacro("__clang_version__", + Builder.defineMacro("__clang_version__", "\"" CLANG_VERSION_STRING " " + getClangFullRepositoryVersion() + "\""); if (!LangOpts.MSVCCompat) { @@ -601,7 +601,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, // As sad as it is, enough software depends on the __VERSION__ for version // checks that it is necessary to report 4.2.1 (the base GCC version we claim // compatibility with) first. - Builder.defineMacro("__VERSION__", "\"4.2.1 Compatible " + + Builder.defineMacro("__VERSION__", "\"4.2.1 Compatible " + Twine(getClangFullCPPVersion()) + "\""); // Initialize language-specific preprocessor defines. @@ -616,7 +616,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (LangOpts.ObjC1) { if (LangOpts.ObjCRuntime.isNonFragile()) { Builder.defineMacro("__OBJC2__"); - + if (LangOpts.ObjCExceptions) Builder.defineMacro("OBJC_ZEROCOST_EXCEPTIONS"); } @@ -1108,7 +1108,7 @@ void clang::InitializePreprocessor( } } } - + // Even with predefines off, some macros are still predefined. // These should all be defined in the preprocessor according to the // current language configuration. @@ -1154,7 +1154,7 @@ void clang::InitializePreprocessor( // Instruct the preprocessor to skip the preamble. PP.setSkipMainFilePreamble(InitOpts.PrecompiledPreambleBytes.first, InitOpts.PrecompiledPreambleBytes.second); - + // Copy PredefinedBuffer into the Preprocessor. PP.setPredefines(Predefines.str()); } |