| //===- LangOptions.h - C Language Family Language Options -------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| /// \file |
| /// Defines the clang::LangOptions interface. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H |
| #define LLVM_CLANG_BASIC_LANGOPTIONS_H |
| |
| #include "clang/Basic/CommentOptions.h" |
| #include "clang/Basic/LLVM.h" |
| #include "clang/Basic/LangStandard.h" |
| #include "clang/Basic/ObjCRuntime.h" |
| #include "clang/Basic/Sanitizers.h" |
| #include "clang/Basic/TargetCXXABI.h" |
| #include "clang/Basic/Visibility.h" |
| #include "llvm/ADT/FloatingPointMode.h" |
| #include "llvm/ADT/StringRef.h" |
| #include "llvm/ADT/Triple.h" |
| #include <string> |
| #include <vector> |
| |
| namespace clang { |
| |
| /// Bitfields of LangOptions, split out from LangOptions in order to ensure that |
| /// this large collection of bitfields is a trivial class type. |
| class LangOptionsBase { |
| friend class CompilerInvocation; |
| |
| public: |
| // Define simple language options (with no accessors). |
| #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; |
| #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) |
| #include "clang/Basic/LangOptions.def" |
| |
| protected: |
| // Define language options of enumeration type. These are private, and will |
| // have accessors (below). |
| #define LANGOPT(Name, Bits, Default, Description) |
| #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ |
| unsigned Name : Bits; |
| #include "clang/Basic/LangOptions.def" |
| }; |
| |
| /// In the Microsoft ABI, this controls the placement of virtual displacement |
| /// members used to implement virtual inheritance. |
| enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable }; |
| |
| /// Keeps track of the various options that can be |
| /// enabled, which controls the dialect of C or C++ that is accepted. |
| class LangOptions : public LangOptionsBase { |
| public: |
| using Visibility = clang::Visibility; |
| using RoundingMode = llvm::RoundingMode; |
| |
| enum GCMode { NonGC, GCOnly, HybridGC }; |
| enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; |
| |
| // Automatic variables live on the stack, and when trivial they're usually |
| // uninitialized because it's undefined behavior to use them without |
| // initializing them. |
| enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern }; |
| |
| enum SignedOverflowBehaviorTy { |
| // Default C standard behavior. |
| SOB_Undefined, |
| |
| // -fwrapv |
| SOB_Defined, |
| |
| // -ftrapv |
| SOB_Trapping |
| }; |
| |
| // FIXME: Unify with TUKind. |
| enum CompilingModuleKind { |
| /// Not compiling a module interface at all. |
| CMK_None, |
| |
| /// Compiling a module from a module map. |
| CMK_ModuleMap, |
| |
| /// Compiling a module from a list of header files. |
| CMK_HeaderModule, |
| |
| /// Compiling a C++ modules TS module interface unit. |
| CMK_ModuleInterface, |
| }; |
| |
| enum PragmaMSPointersToMembersKind { |
| PPTMK_BestCase, |
| PPTMK_FullGeneralitySingleInheritance, |
| PPTMK_FullGeneralityMultipleInheritance, |
| PPTMK_FullGeneralityVirtualInheritance |
| }; |
| |
| using MSVtorDispMode = clang::MSVtorDispMode; |
| |
| enum DefaultCallingConvention { |
| DCC_None, |
| DCC_CDecl, |
| DCC_FastCall, |
| DCC_StdCall, |
| DCC_VectorCall, |
| DCC_RegCall |
| }; |
| |
| enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; |
| |
| // Corresponds to _MSC_VER |
| enum MSVCMajorVersion { |
| MSVC2010 = 1600, |
| MSVC2012 = 1700, |
| MSVC2013 = 1800, |
| MSVC2015 = 1900, |
| MSVC2017 = 1910, |
| MSVC2017_5 = 1912, |
| MSVC2017_7 = 1914, |
| MSVC2019 = 1920, |
| MSVC2019_5 = 1925, |
| MSVC2019_8 = 1928, |
| }; |
| |
| enum SYCLMajorVersion { |
| SYCL_None, |
| SYCL_2017, |
| SYCL_2020, |
| // The "default" SYCL version to be used when none is specified on the |
| // frontend command line. |
| SYCL_Default = SYCL_2020 |
| }; |
| |
| /// Clang versions with different platform ABI conformance. |
| enum class ClangABI { |
| /// Attempt to be ABI-compatible with code generated by Clang 3.8.x |
| /// (SVN r257626). This causes <1 x long long> to be passed in an |
| /// integer register instead of an SSE register on x64_64. |
| Ver3_8, |
| |
| /// Attempt to be ABI-compatible with code generated by Clang 4.0.x |
| /// (SVN r291814). This causes move operations to be ignored when |
| /// determining whether a class type can be passed or returned directly. |
| Ver4, |
| |
| /// Attempt to be ABI-compatible with code generated by Clang 6.0.x |
| /// (SVN r321711). This causes determination of whether a type is |
| /// standard-layout to ignore collisions between empty base classes |
| /// and between base classes and member subobjects, which affects |
| /// whether we reuse base class tail padding in some ABIs. |
| Ver6, |
| |
| /// Attempt to be ABI-compatible with code generated by Clang 7.0.x |
| /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be |
| /// compatible with __alignof (i.e., return the preferred alignment) |
| /// rather than returning the required alignment. |
| Ver7, |
| |
| /// Attempt to be ABI-compatible with code generated by Clang 9.0.x |
| /// (SVN r351319). This causes vectors of __int128 to be passed in memory |
| /// instead of passing in multiple scalar registers on x86_64 on Linux and |
| /// NetBSD. |
| Ver9, |
| |
| /// Attempt to be ABI-compatible with code generated by Clang 11.0.x |
| /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit |
| /// vector member on the stack instead of using registers, to not properly |
| /// mangle substitutions for template names in some cases, and to mangle |
| /// declaration template arguments without a cast to the parameter type |
| /// even when that can lead to mangling collisions. |
| Ver11, |
| |
| /// Attempt to be ABI-compatible with code generated by Clang 12.0.x |
| /// (git 8e464dd76bef). This causes clang to mangle lambdas within |
| /// global-scope inline variables incorrectly. |
| Ver12, |
| |
| /// Attempt to be ABI-compatible with code generated by Clang 13.0.x. |
| /// This causes clang to not pack non-POD members of packed structs. |
| Ver13, |
| |
| /// Conform to the underlying platform's C and C++ ABIs as closely |
| /// as we can. |
| Latest |
| }; |
| |
| enum class CoreFoundationABI { |
| /// No interoperability ABI has been specified |
| Unspecified, |
| /// CoreFoundation does not have any language interoperability |
| Standalone, |
| /// Interoperability with the ObjectiveC runtime |
| ObjectiveC, |
| /// Interoperability with the latest known version of the Swift runtime |
| Swift, |
| /// Interoperability with the Swift 5.0 runtime |
| Swift5_0, |
| /// Interoperability with the Swift 4.2 runtime |
| Swift4_2, |
| /// Interoperability with the Swift 4.1 runtime |
| Swift4_1, |
| }; |
| |
| enum FPModeKind { |
| // Disable the floating point pragma |
| FPM_Off, |
| |
| // Enable the floating point pragma |
| FPM_On, |
| |
| // Aggressively fuse FP ops (E.g. FMA) disregarding pragmas. |
| FPM_Fast, |
| |
| // Aggressively fuse FP ops and honor pragmas. |
| FPM_FastHonorPragmas |
| }; |
| |
| /// Alias for RoundingMode::NearestTiesToEven. |
| static constexpr unsigned FPR_ToNearest = |
| static_cast<unsigned>(llvm::RoundingMode::NearestTiesToEven); |
| |
| /// Possible floating point exception behavior. |
| enum FPExceptionModeKind { |
| /// Assume that floating-point exceptions are masked. |
| FPE_Ignore, |
| /// Transformations do not cause new exceptions but may hide some. |
| FPE_MayTrap, |
| /// Strictly preserve the floating-point exception semantics. |
| FPE_Strict |
| }; |
| |
| /// Possible exception handling behavior. |
| enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm }; |
| |
| enum class LaxVectorConversionKind { |
| /// Permit no implicit vector bitcasts. |
| None, |
| /// Permit vector bitcasts between integer vectors with different numbers |
| /// of elements but the same total bit-width. |
| Integer, |
| /// Permit vector bitcasts between all vectors with the same total |
| /// bit-width. |
| All, |
| }; |
| |
| enum class AltivecSrcCompatKind { |
| // All vector compares produce scalars except vector pixel and vector bool. |
| // The types vector pixel and vector bool return vector results. |
| Mixed, |
| // All vector compares produce vector results as in GCC. |
| GCC, |
| // All vector compares produce scalars as in XL. |
| XL, |
| // Default clang behaviour. |
| Default = Mixed, |
| }; |
| |
| enum class SignReturnAddressScopeKind { |
| /// No signing for any function. |
| None, |
| /// Sign the return address of functions that spill LR. |
| NonLeaf, |
| /// Sign the return address of all functions, |
| All |
| }; |
| |
| enum class SignReturnAddressKeyKind { |
| /// Return address signing uses APIA key. |
| AKey, |
| /// Return address signing uses APIB key. |
| BKey |
| }; |
| |
| enum class ThreadModelKind { |
| /// POSIX Threads. |
| POSIX, |
| /// Single Threaded Environment. |
| Single |
| }; |
| |
| enum class ExtendArgsKind { |
| /// Integer arguments are sign or zero extended to 32/64 bits |
| /// during default argument promotions. |
| ExtendTo32, |
| ExtendTo64 |
| }; |
| |
| public: |
| /// The used language standard. |
| LangStandard::Kind LangStd; |
| |
| /// Set of enabled sanitizers. |
| SanitizerSet Sanitize; |
| /// Is at least one coverage instrumentation type enabled. |
| bool SanitizeCoverage = false; |
| |
| /// Paths to files specifying which objects |
| /// (files, functions, variables) should not be instrumented. |
| std::vector<std::string> NoSanitizeFiles; |
| |
| /// Paths to the XRay "always instrument" files specifying which |
| /// objects (files, functions, variables) should be imbued with the XRay |
| /// "always instrument" attribute. |
| /// WARNING: This is a deprecated field and will go away in the future. |
| std::vector<std::string> XRayAlwaysInstrumentFiles; |
| |
| /// Paths to the XRay "never instrument" files specifying which |
| /// objects (files, functions, variables) should be imbued with the XRay |
| /// "never instrument" attribute. |
| /// WARNING: This is a deprecated field and will go away in the future. |
| std::vector<std::string> XRayNeverInstrumentFiles; |
| |
| /// Paths to the XRay attribute list files, specifying which objects |
| /// (files, functions, variables) should be imbued with the appropriate XRay |
| /// attribute(s). |
| std::vector<std::string> XRayAttrListFiles; |
| |
| /// Paths to special case list files specifying which entities |
| /// (files, functions) should or should not be instrumented. |
| std::vector<std::string> ProfileListFiles; |
| |
| clang::ObjCRuntime ObjCRuntime; |
| |
| CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified; |
| |
| std::string ObjCConstantStringClass; |
| |
| /// The name of the handler function to be called when -ftrapv is |
| /// specified. |
| /// |
| /// If none is specified, abort (GCC-compatible behaviour). |
| std::string OverflowHandler; |
| |
| /// The module currently being compiled as specified by -fmodule-name. |
| std::string ModuleName; |
| |
| /// The name of the current module, of which the main source file |
| /// is a part. If CompilingModule is set, we are compiling the interface |
| /// of this module, otherwise we are compiling an implementation file of |
| /// it. This starts as ModuleName in case -fmodule-name is provided and |
| /// changes during compilation to reflect the current module. |
| std::string CurrentModule; |
| |
| /// The names of any features to enable in module 'requires' decls |
| /// in addition to the hard-coded list in Module.cpp and the target features. |
| /// |
| /// This list is sorted. |
| std::vector<std::string> ModuleFeatures; |
| |
| /// Options for parsing comments. |
| CommentOptions CommentOpts; |
| |
| /// A list of all -fno-builtin-* function names (e.g., memset). |
| std::vector<std::string> NoBuiltinFuncs; |
| |
| /// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE(). |
| std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap; |
| |
| /// Triples of the OpenMP targets that the host code codegen should |
| /// take into account in order to generate accurate offloading descriptors. |
| std::vector<llvm::Triple> OMPTargetTriples; |
| |
| /// Name of the IR file that contains the result of the OpenMP target |
| /// host code generation. |
| std::string OMPHostIRFile; |
| |
| /// The user provided compilation unit ID, if non-empty. This is used to |
| /// externalize static variables which is needed to support accessing static |
| /// device variables in host code for single source offloading languages |
| /// like CUDA/HIP. |
| std::string CUID; |
| |
| /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=. |
| /// This overrides the default ABI used by the target. |
| llvm::Optional<TargetCXXABI::Kind> CXXABI; |
| |
| /// Indicates whether the front-end is explicitly told that the |
| /// input is a header file (i.e. -x c-header). |
| bool IsHeaderFile = false; |
| |
| LangOptions(); |
| |
| // Define accessors/mutators for language options of enumeration type. |
| #define LANGOPT(Name, Bits, Default, Description) |
| #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ |
| Type get##Name() const { return static_cast<Type>(Name); } \ |
| void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } |
| #include "clang/Basic/LangOptions.def" |
| |
| /// Are we compiling a module interface (.cppm or module map)? |
| bool isCompilingModule() const { |
| return getCompilingModule() != CMK_None; |
| } |
| |
| /// Do we need to track the owning module for a local declaration? |
| bool trackLocalOwningModule() const { |
| return isCompilingModule() || ModulesLocalVisibility; |
| } |
| |
| bool isSignedOverflowDefined() const { |
| return getSignedOverflowBehavior() == SOB_Defined; |
| } |
| |
| bool isSubscriptPointerArithmetic() const { |
| return ObjCRuntime.isSubscriptPointerArithmetic() && |
| !ObjCSubscriptingLegacyRuntime; |
| } |
| |
| bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { |
| return MSCompatibilityVersion >= MajorVersion * 100000U; |
| } |
| |
| /// Reset all of the options that are not considered when building a |
| /// module. |
| void resetNonModularOptions(); |
| |
| /// Is this a libc/libm function that is no longer recognized as a |
| /// builtin because a -fno-builtin-* option has been specified? |
| bool isNoBuiltinFunc(StringRef Name) const; |
| |
| /// True if any ObjC types may have non-trivial lifetime qualifiers. |
| bool allowsNonTrivialObjCLifetimeQualifiers() const { |
| return ObjCAutoRefCount || ObjCWeak; |
| } |
| |
| bool assumeFunctionsAreConvergent() const { |
| return ConvergentFunctions; |
| } |
| |
| /// Return the OpenCL C or C++ version as a VersionTuple. |
| VersionTuple getOpenCLVersionTuple() const; |
| |
| /// Return the OpenCL version that kernel language is compatible with |
| unsigned getOpenCLCompatibleVersion() const; |
| |
| /// Return the OpenCL C or C++ for OpenCL language name and version |
| /// as a string. |
| std::string getOpenCLVersionString() const; |
| |
| /// Check if return address signing is enabled. |
| bool hasSignReturnAddress() const { |
| return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; |
| } |
| |
| /// Check if return address signing uses AKey. |
| bool isSignReturnAddressWithAKey() const { |
| return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; |
| } |
| |
| /// Check if leaf functions are also signed. |
| bool isSignReturnAddressScopeAll() const { |
| return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; |
| } |
| |
| bool hasSjLjExceptions() const { |
| return getExceptionHandling() == ExceptionHandlingKind::SjLj; |
| } |
| |
| bool hasSEHExceptions() const { |
| return getExceptionHandling() == ExceptionHandlingKind::WinEH; |
| } |
| |
| bool hasDWARFExceptions() const { |
| return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI; |
| } |
| |
| bool hasWasmExceptions() const { |
| return getExceptionHandling() == ExceptionHandlingKind::Wasm; |
| } |
| |
| bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; } |
| |
| /// Remap path prefix according to -fmacro-prefix-path option. |
| void remapPathPrefix(SmallString<256> &Path) const; |
| }; |
| |
| /// Floating point control options |
| class FPOptionsOverride; |
| class FPOptions { |
| public: |
| // We start by defining the layout. |
| using storage_type = uint16_t; |
| |
| using RoundingMode = llvm::RoundingMode; |
| |
| static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type); |
| |
| // Define a fake option named "First" so that we have a PREVIOUS even for the |
| // real first option. |
| static constexpr storage_type FirstShift = 0, FirstWidth = 0; |
| #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
| static constexpr storage_type NAME##Shift = \ |
| PREVIOUS##Shift + PREVIOUS##Width; \ |
| static constexpr storage_type NAME##Width = WIDTH; \ |
| static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \ |
| << NAME##Shift; |
| #include "clang/Basic/FPOptions.def" |
| |
| static constexpr storage_type TotalWidth = 0 |
| #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH |
| #include "clang/Basic/FPOptions.def" |
| ; |
| static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions"); |
| |
| private: |
| storage_type Value; |
| |
| public: |
| FPOptions() : Value(0) { |
| setFPContractMode(LangOptions::FPM_Off); |
| setRoundingMode(static_cast<RoundingMode>(LangOptions::FPR_ToNearest)); |
| setFPExceptionMode(LangOptions::FPE_Ignore); |
| } |
| explicit FPOptions(const LangOptions &LO) { |
| Value = 0; |
| // The language fp contract option FPM_FastHonorPragmas has the same effect |
| // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in |
| // frontend. |
| auto LangOptContractMode = LO.getDefaultFPContractMode(); |
| if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas) |
| LangOptContractMode = LangOptions::FPM_Fast; |
| setFPContractMode(LangOptContractMode); |
| setRoundingMode(LO.getFPRoundingMode()); |
| setFPExceptionMode(LO.getFPExceptionMode()); |
| setAllowFPReassociate(LO.AllowFPReassoc); |
| setNoHonorNaNs(LO.NoHonorNaNs); |
| setNoHonorInfs(LO.NoHonorInfs); |
| setNoSignedZero(LO.NoSignedZero); |
| setAllowReciprocal(LO.AllowRecip); |
| setAllowApproxFunc(LO.ApproxFunc); |
| if (getFPContractMode() == LangOptions::FPM_On && |
| getRoundingMode() == llvm::RoundingMode::Dynamic && |
| getFPExceptionMode() == LangOptions::FPE_Strict) |
| // If the FP settings are set to the "strict" model, then |
| // FENV access is set to true. (ffp-model=strict) |
| setAllowFEnvAccess(true); |
| else |
| setAllowFEnvAccess(LangOptions::FPM_Off); |
| } |
| |
| bool allowFPContractWithinStatement() const { |
| return getFPContractMode() == LangOptions::FPM_On; |
| } |
| void setAllowFPContractWithinStatement() { |
| setFPContractMode(LangOptions::FPM_On); |
| } |
| |
| bool allowFPContractAcrossStatement() const { |
| return getFPContractMode() == LangOptions::FPM_Fast; |
| } |
| void setAllowFPContractAcrossStatement() { |
| setFPContractMode(LangOptions::FPM_Fast); |
| } |
| |
| bool isFPConstrained() const { |
| return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven || |
| getFPExceptionMode() != LangOptions::FPE_Ignore || |
| getAllowFEnvAccess(); |
| } |
| |
| bool operator==(FPOptions other) const { return Value == other.Value; } |
| |
| /// Return the default value of FPOptions that's used when trailing |
| /// storage isn't required. |
| static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO); |
| |
| storage_type getAsOpaqueInt() const { return Value; } |
| static FPOptions getFromOpaqueInt(storage_type Value) { |
| FPOptions Opts; |
| Opts.Value = Value; |
| return Opts; |
| } |
| |
| // We can define most of the accessors automatically: |
| #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
| TYPE get##NAME() const { \ |
| return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \ |
| } \ |
| void set##NAME(TYPE value) { \ |
| Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ |
| } |
| #include "clang/Basic/FPOptions.def" |
| LLVM_DUMP_METHOD void dump(); |
| }; |
| |
| /// Represents difference between two FPOptions values. |
| /// |
| /// The effect of language constructs changing the set of floating point options |
| /// is usually a change of some FP properties while leaving others intact. This |
| /// class describes such changes by keeping information about what FP options |
| /// are overridden. |
| /// |
| /// The integral set of FP options, described by the class FPOptions, may be |
| /// represented as a default FP option set, defined by language standard and |
| /// command line options, with the overrides introduced by pragmas. |
| /// |
| /// The is implemented as a value of the new FPOptions plus a mask showing which |
| /// fields are actually set in it. |
| class FPOptionsOverride { |
| FPOptions Options = FPOptions::getFromOpaqueInt(0); |
| FPOptions::storage_type OverrideMask = 0; |
| |
| public: |
| using RoundingMode = llvm::RoundingMode; |
| |
| /// The type suitable for storing values of FPOptionsOverride. Must be twice |
| /// as wide as bit size of FPOption. |
| using storage_type = uint32_t; |
| static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type), |
| "Too short type for FPOptionsOverride"); |
| |
| /// Bit mask selecting bits of OverrideMask in serialized representation of |
| /// FPOptionsOverride. |
| static constexpr storage_type OverrideMaskBits = |
| (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1; |
| |
| FPOptionsOverride() {} |
| FPOptionsOverride(const LangOptions &LO) |
| : Options(LO), OverrideMask(OverrideMaskBits) {} |
| FPOptionsOverride(FPOptions FPO) |
| : Options(FPO), OverrideMask(OverrideMaskBits) {} |
| |
| bool requiresTrailingStorage() const { return OverrideMask != 0; } |
| |
| void setAllowFPContractWithinStatement() { |
| setFPContractModeOverride(LangOptions::FPM_On); |
| } |
| |
| void setAllowFPContractAcrossStatement() { |
| setFPContractModeOverride(LangOptions::FPM_Fast); |
| } |
| |
| void setDisallowFPContract() { |
| setFPContractModeOverride(LangOptions::FPM_Off); |
| } |
| |
| void setFPPreciseEnabled(bool Value) { |
| setAllowFPReassociateOverride(!Value); |
| setNoHonorNaNsOverride(!Value); |
| setNoHonorInfsOverride(!Value); |
| setNoSignedZeroOverride(!Value); |
| setAllowReciprocalOverride(!Value); |
| setAllowApproxFuncOverride(!Value); |
| if (Value) |
| /* Precise mode implies fp_contract=on and disables ffast-math */ |
| setAllowFPContractWithinStatement(); |
| else |
| /* Precise mode disabled sets fp_contract=fast and enables ffast-math */ |
| setAllowFPContractAcrossStatement(); |
| } |
| |
| storage_type getAsOpaqueInt() const { |
| return (static_cast<storage_type>(Options.getAsOpaqueInt()) |
| << FPOptions::StorageBitSize) | |
| OverrideMask; |
| } |
| static FPOptionsOverride getFromOpaqueInt(storage_type I) { |
| FPOptionsOverride Opts; |
| Opts.OverrideMask = I & OverrideMaskBits; |
| Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize); |
| return Opts; |
| } |
| |
| FPOptions applyOverrides(FPOptions Base) { |
| FPOptions Result = |
| FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) | |
| (Options.getAsOpaqueInt() & OverrideMask)); |
| return Result; |
| } |
| |
| FPOptions applyOverrides(const LangOptions &LO) { |
| return applyOverrides(FPOptions(LO)); |
| } |
| |
| bool operator==(FPOptionsOverride other) const { |
| return Options == other.Options && OverrideMask == other.OverrideMask; |
| } |
| bool operator!=(FPOptionsOverride other) const { return !(*this == other); } |
| |
| #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
| bool has##NAME##Override() const { \ |
| return OverrideMask & FPOptions::NAME##Mask; \ |
| } \ |
| TYPE get##NAME##Override() const { \ |
| assert(has##NAME##Override()); \ |
| return Options.get##NAME(); \ |
| } \ |
| void clear##NAME##Override() { \ |
| /* Clear the actual value so that we don't have spurious differences when \ |
| * testing equality. */ \ |
| Options.set##NAME(TYPE(0)); \ |
| OverrideMask &= ~FPOptions::NAME##Mask; \ |
| } \ |
| void set##NAME##Override(TYPE value) { \ |
| Options.set##NAME(value); \ |
| OverrideMask |= FPOptions::NAME##Mask; \ |
| } |
| #include "clang/Basic/FPOptions.def" |
| LLVM_DUMP_METHOD void dump(); |
| }; |
| |
| /// Describes the kind of translation unit being processed. |
| enum TranslationUnitKind { |
| /// The translation unit is a complete translation unit. |
| TU_Complete, |
| |
| /// The translation unit is a prefix to a translation unit, and is |
| /// not complete. |
| TU_Prefix, |
| |
| /// The translation unit is a module. |
| TU_Module, |
| |
| /// The translation unit is a is a complete translation unit that we might |
| /// incrementally extend later. |
| TU_Incremental |
| }; |
| |
| } // namespace clang |
| |
| #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H |