File indexing completed on 2026-05-10 08:36:50
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H
0015 #define LLVM_CLANG_BASIC_LANGOPTIONS_H
0016
0017 #include "clang/Basic/CFProtectionOptions.h"
0018 #include "clang/Basic/CommentOptions.h"
0019 #include "clang/Basic/LLVM.h"
0020 #include "clang/Basic/LangStandard.h"
0021 #include "clang/Basic/ObjCRuntime.h"
0022 #include "clang/Basic/Sanitizers.h"
0023 #include "clang/Basic/TargetCXXABI.h"
0024 #include "clang/Basic/Visibility.h"
0025 #include "llvm/ADT/FloatingPointMode.h"
0026 #include "llvm/ADT/StringRef.h"
0027 #include "llvm/TargetParser/Triple.h"
0028 #include <optional>
0029 #include <string>
0030 #include <vector>
0031
0032 namespace clang {
0033
0034
0035
0036 enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
0037
0038
0039
0040
0041
0042 enum class ShaderStage {
0043 Pixel = 0,
0044 Vertex,
0045 Geometry,
0046 Hull,
0047 Domain,
0048 Compute,
0049 Library,
0050 RayGeneration,
0051 Intersection,
0052 AnyHit,
0053 ClosestHit,
0054 Miss,
0055 Callable,
0056 Mesh,
0057 Amplification,
0058 Invalid,
0059 };
0060
0061 enum class PointerAuthenticationMode : unsigned {
0062 None,
0063 Strip,
0064 SignAndStrip,
0065 SignAndAuth
0066 };
0067
0068
0069
0070 class LangOptionsBase {
0071 friend class CompilerInvocation;
0072 friend class CompilerInvocationBase;
0073
0074 public:
0075 using Visibility = clang::Visibility;
0076 using RoundingMode = llvm::RoundingMode;
0077 using CFBranchLabelSchemeKind = clang::CFBranchLabelSchemeKind;
0078
0079 enum GCMode { NonGC, GCOnly, HybridGC };
0080 enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq };
0081
0082
0083
0084
0085 enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern };
0086
0087 enum SignedOverflowBehaviorTy {
0088
0089 SOB_Undefined,
0090
0091
0092 SOB_Defined,
0093
0094
0095 SOB_Trapping
0096 };
0097
0098
0099 enum CompilingModuleKind {
0100
0101 CMK_None,
0102
0103
0104 CMK_ModuleMap,
0105
0106
0107 CMK_HeaderUnit,
0108
0109
0110 CMK_ModuleInterface,
0111 };
0112
0113 enum PragmaMSPointersToMembersKind {
0114 PPTMK_BestCase,
0115 PPTMK_FullGeneralitySingleInheritance,
0116 PPTMK_FullGeneralityMultipleInheritance,
0117 PPTMK_FullGeneralityVirtualInheritance
0118 };
0119
0120 using MSVtorDispMode = clang::MSVtorDispMode;
0121
0122 enum DefaultCallingConvention {
0123 DCC_None,
0124 DCC_CDecl,
0125 DCC_FastCall,
0126 DCC_StdCall,
0127 DCC_VectorCall,
0128 DCC_RegCall,
0129 DCC_RtdCall
0130 };
0131
0132 enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off };
0133
0134
0135 enum MSVCMajorVersion {
0136 MSVC2010 = 1600,
0137 MSVC2012 = 1700,
0138 MSVC2013 = 1800,
0139 MSVC2015 = 1900,
0140 MSVC2017 = 1910,
0141 MSVC2017_5 = 1912,
0142 MSVC2017_7 = 1914,
0143 MSVC2019 = 1920,
0144 MSVC2019_5 = 1925,
0145 MSVC2019_8 = 1928,
0146 MSVC2022_3 = 1933,
0147 MSVC2022_9 = 1939,
0148 };
0149
0150 enum SYCLMajorVersion {
0151 SYCL_None,
0152 SYCL_2017,
0153 SYCL_2020,
0154
0155
0156 SYCL_Default = SYCL_2020
0157 };
0158
0159 enum HLSLLangStd {
0160 HLSL_Unset = 0,
0161 HLSL_2015 = 2015,
0162 HLSL_2016 = 2016,
0163 HLSL_2017 = 2017,
0164 HLSL_2018 = 2018,
0165 HLSL_2021 = 2021,
0166 HLSL_202x = 2028,
0167 HLSL_202y = 2029,
0168 };
0169
0170
0171 enum class ClangABI {
0172
0173
0174
0175 Ver3_8,
0176
0177
0178
0179
0180 Ver4,
0181
0182
0183
0184
0185
0186
0187 Ver6,
0188
0189
0190
0191
0192
0193 Ver7,
0194
0195
0196
0197
0198
0199 Ver9,
0200
0201
0202
0203
0204
0205
0206
0207 Ver11,
0208
0209
0210
0211
0212 Ver12,
0213
0214
0215
0216
0217
0218
0219
0220 Ver14,
0221
0222
0223
0224
0225
0226
0227 Ver15,
0228
0229
0230
0231
0232
0233
0234
0235
0236 Ver17,
0237
0238
0239
0240
0241 Ver18,
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251 Ver19,
0252
0253
0254
0255 Latest
0256 };
0257
0258 enum class CoreFoundationABI {
0259
0260 Unspecified,
0261
0262 Standalone,
0263
0264 ObjectiveC,
0265
0266 Swift,
0267
0268 Swift5_0,
0269
0270 Swift4_2,
0271
0272 Swift4_1,
0273 };
0274
0275 enum FPModeKind {
0276
0277 FPM_Off,
0278
0279
0280 FPM_On,
0281
0282
0283 FPM_Fast,
0284
0285
0286 FPM_FastHonorPragmas
0287 };
0288
0289
0290 enum FPExceptionModeKind {
0291
0292 FPE_Ignore,
0293
0294 FPE_MayTrap,
0295
0296 FPE_Strict,
0297
0298 FPE_Default
0299 };
0300
0301
0302 enum FPEvalMethodKind {
0303
0304
0305 FEM_Indeterminable = -1,
0306
0307 FEM_Source = 0,
0308
0309 FEM_Double = 1,
0310
0311 FEM_Extended = 2,
0312
0313
0314
0315
0316 FEM_UnsetOnCommandLine = 3
0317 };
0318
0319 enum ExcessPrecisionKind { FPP_Standard, FPP_Fast, FPP_None };
0320
0321
0322 enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm };
0323
0324 enum class LaxVectorConversionKind {
0325
0326 None,
0327
0328
0329 Integer,
0330
0331
0332 All,
0333 };
0334
0335 enum class AltivecSrcCompatKind {
0336
0337
0338 Mixed,
0339
0340 GCC,
0341
0342 XL,
0343
0344 Default = Mixed,
0345 };
0346
0347 enum class SignReturnAddressScopeKind {
0348
0349 None,
0350
0351 NonLeaf,
0352
0353 All
0354 };
0355
0356 enum class SignReturnAddressKeyKind {
0357
0358 AKey,
0359
0360 BKey
0361 };
0362
0363 enum class ThreadModelKind {
0364
0365 POSIX,
0366
0367 Single
0368 };
0369
0370 enum class ExtendArgsKind {
0371
0372
0373 ExtendTo32,
0374 ExtendTo64
0375 };
0376
0377 enum class GPUDefaultStreamKind {
0378
0379 Legacy,
0380
0381 PerThread,
0382 };
0383
0384
0385
0386 enum OverflowPatternExclusionKind {
0387
0388 None = 1 << 0,
0389
0390 All = 1 << 1,
0391
0392 AddSignedOverflowTest = 1 << 2,
0393
0394 AddUnsignedOverflowTest = 1 << 3,
0395
0396 NegUnsignedConst = 1 << 4,
0397
0398 PostDecrInWhile = 1 << 5,
0399 };
0400
0401 enum class DefaultVisiblityExportMapping {
0402 None,
0403
0404 Explicit,
0405
0406 All,
0407 };
0408
0409 enum class VisibilityForcedKinds {
0410
0411 ForceHidden,
0412
0413 ForceProtected,
0414
0415 ForceDefault,
0416
0417 Source,
0418 };
0419
0420 enum class VisibilityFromDLLStorageClassKinds {
0421
0422 Keep,
0423
0424 Default,
0425
0426 Hidden,
0427
0428 Protected,
0429 };
0430
0431 enum class StrictFlexArraysLevelKind {
0432
0433 Default = 0,
0434
0435 OneZeroOrIncomplete = 1,
0436
0437 ZeroOrIncomplete = 2,
0438
0439 IncompleteOnly = 3,
0440 };
0441
0442
0443
0444 enum ComplexRangeKind {
0445
0446
0447
0448
0449
0450 CX_Full,
0451
0452
0453
0454
0455 CX_Improved,
0456
0457
0458
0459
0460
0461
0462
0463
0464 CX_Promoted,
0465
0466
0467
0468
0469 CX_Basic,
0470
0471
0472 CX_None
0473 };
0474
0475
0476 enum class RegisterStaticDestructorsKind {
0477
0478 All,
0479
0480 ThreadLocal,
0481
0482 None,
0483 };
0484
0485
0486 #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits;
0487 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description)
0488 #include "clang/Basic/LangOptions.def"
0489
0490 protected:
0491
0492
0493 #define LANGOPT(Name, Bits, Default, Description)
0494 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
0495 LLVM_PREFERRED_TYPE(Type) \
0496 unsigned Name : Bits;
0497 #include "clang/Basic/LangOptions.def"
0498 };
0499
0500
0501
0502 class LangOptions : public LangOptionsBase {
0503 public:
0504
0505 LangStandard::Kind LangStd;
0506
0507
0508 SanitizerSet Sanitize;
0509
0510 bool SanitizeCoverage = false;
0511
0512
0513
0514 std::vector<std::string> NoSanitizeFiles;
0515
0516
0517
0518
0519
0520 std::vector<std::string> XRayAlwaysInstrumentFiles;
0521
0522
0523
0524
0525
0526 std::vector<std::string> XRayNeverInstrumentFiles;
0527
0528
0529
0530
0531 std::vector<std::string> XRayAttrListFiles;
0532
0533
0534
0535 std::vector<std::string> ProfileListFiles;
0536
0537 clang::ObjCRuntime ObjCRuntime;
0538
0539 CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified;
0540
0541 std::string ObjCConstantStringClass;
0542
0543
0544
0545
0546
0547 std::string OverflowHandler;
0548
0549
0550 std::string ModuleName;
0551
0552
0553
0554
0555
0556
0557 std::string CurrentModule;
0558
0559
0560
0561
0562
0563 std::vector<std::string> ModuleFeatures;
0564
0565
0566 CommentOptions CommentOpts;
0567
0568
0569 std::vector<std::string> NoBuiltinFuncs;
0570
0571
0572 std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap;
0573
0574
0575
0576 std::vector<llvm::Triple> OMPTargetTriples;
0577
0578
0579
0580 std::string OMPHostIRFile;
0581
0582
0583
0584
0585
0586 std::string CUID;
0587
0588
0589
0590 std::optional<TargetCXXABI::Kind> CXXABI;
0591
0592
0593
0594 bool IsHeaderFile = false;
0595
0596
0597 GPUDefaultStreamKind GPUDefaultStream;
0598
0599
0600 unsigned OverflowPatternExclusionMask = 0;
0601
0602 std::vector<std::string> OverflowPatternExclusionValues;
0603
0604
0605 std::string RandstructSeed;
0606
0607
0608
0609
0610
0611
0612
0613 bool UseTargetPathSeparator = false;
0614
0615
0616
0617 bool CheckNew = false;
0618
0619
0620
0621
0622 std::string OpenACCMacroOverride;
0623
0624
0625
0626 bool NoWasmOpt = false;
0627
0628 LangOptions();
0629
0630
0631
0632
0633
0634
0635
0636
0637
0638
0639 static void
0640 setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T,
0641 std::vector<std::string> &Includes,
0642 LangStandard::Kind LangStd = LangStandard::lang_unspecified);
0643
0644
0645 #define LANGOPT(Name, Bits, Default, Description)
0646 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
0647 Type get##Name() const { return static_cast<Type>(Name); } \
0648 void set##Name(Type Value) { Name = static_cast<unsigned>(Value); }
0649 #include "clang/Basic/LangOptions.def"
0650
0651
0652 bool isCompilingModule() const {
0653 return getCompilingModule() != CMK_None;
0654 }
0655
0656
0657 bool isCompilingModuleImplementation() const {
0658 return !isCompilingModule() && !ModuleName.empty();
0659 }
0660
0661
0662 bool trackLocalOwningModule() const {
0663 return isCompilingModule() || ModulesLocalVisibility;
0664 }
0665
0666 bool isSignedOverflowDefined() const {
0667 return getSignedOverflowBehavior() == SOB_Defined;
0668 }
0669
0670 bool isSubscriptPointerArithmetic() const {
0671 return ObjCRuntime.isSubscriptPointerArithmetic() &&
0672 !ObjCSubscriptingLegacyRuntime;
0673 }
0674
0675 bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
0676 return MSCompatibilityVersion >= MajorVersion * 100000U;
0677 }
0678
0679 bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const {
0680 if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::None)
0681 return false;
0682 if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::All)
0683 return true;
0684 return OverflowPatternExclusionMask & Kind;
0685 }
0686
0687
0688
0689 void resetNonModularOptions();
0690
0691
0692
0693 bool isNoBuiltinFunc(StringRef Name) const;
0694
0695
0696 bool allowsNonTrivialObjCLifetimeQualifiers() const {
0697 return ObjCAutoRefCount || ObjCWeak;
0698 }
0699
0700 bool assumeFunctionsAreConvergent() const {
0701 return ConvergentFunctions;
0702 }
0703
0704
0705
0706 bool threadPrivateMemoryAtomicsAreUndefined() const {
0707
0708
0709 return OpenCL || CUDA;
0710 }
0711
0712
0713 VersionTuple getOpenCLVersionTuple() const;
0714
0715
0716 unsigned getOpenCLCompatibleVersion() const;
0717
0718
0719
0720 std::string getOpenCLVersionString() const;
0721
0722
0723
0724 bool requiresStrictPrototypes() const {
0725 return CPlusPlus || C23 || DisableKNRFunctions;
0726 }
0727
0728
0729
0730 bool implicitFunctionsAllowed() const {
0731 return !requiresStrictPrototypes() && !OpenCL;
0732 }
0733
0734
0735 bool hasAtExit() const { return !(OpenMP && OpenMPIsTargetDevice); }
0736
0737
0738 bool isImplicitIntRequired() const { return !CPlusPlus && !C99; }
0739
0740
0741 bool isImplicitIntAllowed() const { return !CPlusPlus && !C23; }
0742
0743
0744 bool hasSignReturnAddress() const {
0745 return getSignReturnAddressScope() != SignReturnAddressScopeKind::None;
0746 }
0747
0748
0749 bool isSignReturnAddressWithAKey() const {
0750 return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey;
0751 }
0752
0753
0754 bool isSignReturnAddressScopeAll() const {
0755 return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
0756 }
0757
0758 bool hasSjLjExceptions() const {
0759 return getExceptionHandling() == ExceptionHandlingKind::SjLj;
0760 }
0761
0762 bool hasSEHExceptions() const {
0763 return getExceptionHandling() == ExceptionHandlingKind::WinEH;
0764 }
0765
0766 bool hasDWARFExceptions() const {
0767 return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI;
0768 }
0769
0770 bool hasWasmExceptions() const {
0771 return getExceptionHandling() == ExceptionHandlingKind::Wasm;
0772 }
0773
0774 bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; }
0775
0776 bool hasDefaultVisibilityExportMapping() const {
0777 return getDefaultVisibilityExportMapping() !=
0778 DefaultVisiblityExportMapping::None;
0779 }
0780
0781 bool isExplicitDefaultVisibilityExportMapping() const {
0782 return getDefaultVisibilityExportMapping() ==
0783 DefaultVisiblityExportMapping::Explicit;
0784 }
0785
0786 bool isAllDefaultVisibilityExportMapping() const {
0787 return getDefaultVisibilityExportMapping() ==
0788 DefaultVisiblityExportMapping::All;
0789 }
0790
0791 bool hasGlobalAllocationFunctionVisibility() const {
0792 return getGlobalAllocationFunctionVisibility() !=
0793 VisibilityForcedKinds::Source;
0794 }
0795
0796 bool hasDefaultGlobalAllocationFunctionVisibility() const {
0797 return getGlobalAllocationFunctionVisibility() ==
0798 VisibilityForcedKinds::ForceDefault;
0799 }
0800
0801 bool hasProtectedGlobalAllocationFunctionVisibility() const {
0802 return getGlobalAllocationFunctionVisibility() ==
0803 VisibilityForcedKinds::ForceProtected;
0804 }
0805
0806 bool hasHiddenGlobalAllocationFunctionVisibility() const {
0807 return getGlobalAllocationFunctionVisibility() ==
0808 VisibilityForcedKinds::ForceHidden;
0809 }
0810
0811
0812 void remapPathPrefix(SmallVectorImpl<char> &Path) const;
0813
0814 RoundingMode getDefaultRoundingMode() const {
0815 return RoundingMath ? RoundingMode::Dynamic
0816 : RoundingMode::NearestTiesToEven;
0817 }
0818
0819 FPExceptionModeKind getDefaultExceptionMode() const {
0820 FPExceptionModeKind EM = getFPExceptionMode();
0821 if (EM == FPExceptionModeKind::FPE_Default)
0822 return FPExceptionModeKind::FPE_Ignore;
0823 return EM;
0824 }
0825 };
0826
0827
0828 class FPOptionsOverride;
0829 class FPOptions {
0830 public:
0831
0832 using storage_type = uint32_t;
0833
0834 using RoundingMode = llvm::RoundingMode;
0835
0836 static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type);
0837
0838
0839
0840 static constexpr storage_type FirstShift = 0, FirstWidth = 0;
0841 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
0842 static constexpr storage_type NAME##Shift = \
0843 PREVIOUS##Shift + PREVIOUS##Width; \
0844 static constexpr storage_type NAME##Width = WIDTH; \
0845 static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \
0846 << NAME##Shift;
0847 #include "clang/Basic/FPOptions.def"
0848
0849 static constexpr storage_type TotalWidth = 0
0850 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH
0851 #include "clang/Basic/FPOptions.def"
0852 ;
0853 static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions");
0854
0855 private:
0856 storage_type Value;
0857
0858 FPOptionsOverride getChangesSlow(const FPOptions &Base) const;
0859
0860 public:
0861 FPOptions() : Value(0) {
0862 setFPContractMode(LangOptions::FPM_Off);
0863 setConstRoundingMode(RoundingMode::Dynamic);
0864 setSpecifiedExceptionMode(LangOptions::FPE_Default);
0865 }
0866 explicit FPOptions(const LangOptions &LO) {
0867 Value = 0;
0868
0869
0870
0871 auto LangOptContractMode = LO.getDefaultFPContractMode();
0872 if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas)
0873 LangOptContractMode = LangOptions::FPM_Fast;
0874 setFPContractMode(LangOptContractMode);
0875 setRoundingMath(LO.RoundingMath);
0876 setConstRoundingMode(LangOptions::RoundingMode::Dynamic);
0877 setSpecifiedExceptionMode(LO.getFPExceptionMode());
0878 setAllowFPReassociate(LO.AllowFPReassoc);
0879 setNoHonorNaNs(LO.NoHonorNaNs);
0880 setNoHonorInfs(LO.NoHonorInfs);
0881 setNoSignedZero(LO.NoSignedZero);
0882 setAllowReciprocal(LO.AllowRecip);
0883 setAllowApproxFunc(LO.ApproxFunc);
0884 if (getFPContractMode() == LangOptions::FPM_On &&
0885 getRoundingMode() == llvm::RoundingMode::Dynamic &&
0886 getExceptionMode() == LangOptions::FPE_Strict)
0887
0888
0889 setAllowFEnvAccess(true);
0890 else
0891 setAllowFEnvAccess(LangOptions::FPM_Off);
0892 setComplexRange(LO.getComplexRange());
0893 }
0894
0895 bool allowFPContractWithinStatement() const {
0896 return getFPContractMode() == LangOptions::FPM_On;
0897 }
0898 void setAllowFPContractWithinStatement() {
0899 setFPContractMode(LangOptions::FPM_On);
0900 }
0901
0902 bool allowFPContractAcrossStatement() const {
0903 return getFPContractMode() == LangOptions::FPM_Fast;
0904 }
0905 void setAllowFPContractAcrossStatement() {
0906 setFPContractMode(LangOptions::FPM_Fast);
0907 }
0908
0909 bool isFPConstrained() const {
0910 return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven ||
0911 getExceptionMode() != LangOptions::FPE_Ignore ||
0912 getAllowFEnvAccess();
0913 }
0914
0915 RoundingMode getRoundingMode() const {
0916 RoundingMode RM = getConstRoundingMode();
0917 if (RM == RoundingMode::Dynamic) {
0918
0919
0920
0921 if (!getAllowFEnvAccess() && !getRoundingMath())
0922 RM = RoundingMode::NearestTiesToEven;
0923 }
0924 return RM;
0925 }
0926
0927 LangOptions::FPExceptionModeKind getExceptionMode() const {
0928 LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode();
0929 if (EM == LangOptions::FPExceptionModeKind::FPE_Default) {
0930 if (getAllowFEnvAccess())
0931 return LangOptions::FPExceptionModeKind::FPE_Strict;
0932 else
0933 return LangOptions::FPExceptionModeKind::FPE_Ignore;
0934 }
0935 return EM;
0936 }
0937
0938 bool operator==(FPOptions other) const { return Value == other.Value; }
0939
0940
0941
0942 static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO);
0943
0944 storage_type getAsOpaqueInt() const { return Value; }
0945 static FPOptions getFromOpaqueInt(storage_type Value) {
0946 FPOptions Opts;
0947 Opts.Value = Value;
0948 return Opts;
0949 }
0950
0951
0952 FPOptionsOverride getChangesFrom(const FPOptions &Base) const;
0953
0954 void applyChanges(FPOptionsOverride FPO);
0955
0956
0957 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
0958 TYPE get##NAME() const { \
0959 return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \
0960 } \
0961 void set##NAME(TYPE value) { \
0962 Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \
0963 }
0964 #include "clang/Basic/FPOptions.def"
0965 LLVM_DUMP_METHOD void dump();
0966 };
0967
0968
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978
0979
0980
0981 class FPOptionsOverride {
0982 FPOptions Options = FPOptions::getFromOpaqueInt(0);
0983 FPOptions::storage_type OverrideMask = 0;
0984
0985 public:
0986 using RoundingMode = llvm::RoundingMode;
0987
0988
0989
0990 using storage_type = uint64_t;
0991 static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type),
0992 "Too short type for FPOptionsOverride");
0993
0994
0995
0996 static constexpr storage_type OverrideMaskBits =
0997 (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1;
0998
0999 FPOptionsOverride() {}
1000 FPOptionsOverride(const LangOptions &LO)
1001 : Options(LO), OverrideMask(OverrideMaskBits) {}
1002 FPOptionsOverride(FPOptions FPO)
1003 : Options(FPO), OverrideMask(OverrideMaskBits) {}
1004 FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask)
1005 : Options(FPO), OverrideMask(Mask) {}
1006
1007 bool requiresTrailingStorage() const { return OverrideMask != 0; }
1008
1009 void setAllowFPContractWithinStatement() {
1010 setFPContractModeOverride(LangOptions::FPM_On);
1011 }
1012
1013 void setAllowFPContractAcrossStatement() {
1014 setFPContractModeOverride(LangOptions::FPM_Fast);
1015 }
1016
1017 void setDisallowFPContract() {
1018 setFPContractModeOverride(LangOptions::FPM_Off);
1019 }
1020
1021 void setFPPreciseEnabled(bool Value) {
1022 setAllowFPReassociateOverride(!Value);
1023 setNoHonorNaNsOverride(!Value);
1024 setNoHonorInfsOverride(!Value);
1025 setNoSignedZeroOverride(!Value);
1026 setAllowReciprocalOverride(!Value);
1027 setAllowApproxFuncOverride(!Value);
1028 setMathErrnoOverride(Value);
1029 if (Value)
1030
1031 setAllowFPContractWithinStatement();
1032 else
1033
1034 setAllowFPContractAcrossStatement();
1035 }
1036
1037 void setDisallowOptimizations() { setFPPreciseEnabled(true); }
1038
1039 storage_type getAsOpaqueInt() const {
1040 return (static_cast<storage_type>(Options.getAsOpaqueInt())
1041 << FPOptions::StorageBitSize) |
1042 OverrideMask;
1043 }
1044 static FPOptionsOverride getFromOpaqueInt(storage_type I) {
1045 FPOptionsOverride Opts;
1046 Opts.OverrideMask = I & OverrideMaskBits;
1047 Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize);
1048 return Opts;
1049 }
1050
1051 FPOptions applyOverrides(FPOptions Base) {
1052 FPOptions Result =
1053 FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) |
1054 (Options.getAsOpaqueInt() & OverrideMask));
1055 return Result;
1056 }
1057
1058 FPOptions applyOverrides(const LangOptions &LO) {
1059 return applyOverrides(FPOptions(LO));
1060 }
1061
1062 bool operator==(FPOptionsOverride other) const {
1063 return Options == other.Options && OverrideMask == other.OverrideMask;
1064 }
1065 bool operator!=(FPOptionsOverride other) const { return !(*this == other); }
1066
1067 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \
1068 bool has##NAME##Override() const { \
1069 return OverrideMask & FPOptions::NAME##Mask; \
1070 } \
1071 TYPE get##NAME##Override() const { \
1072 assert(has##NAME##Override()); \
1073 return Options.get##NAME(); \
1074 } \
1075 void clear##NAME##Override() { \
1076
1077 \
1078 Options.set##NAME(TYPE(0)); \
1079 OverrideMask &= ~FPOptions::NAME##Mask; \
1080 } \
1081 void set##NAME##Override(TYPE value) { \
1082 Options.set##NAME(value); \
1083 OverrideMask |= FPOptions::NAME##Mask; \
1084 }
1085 #include "clang/Basic/FPOptions.def"
1086 LLVM_DUMP_METHOD void dump();
1087 };
1088
1089 inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const {
1090 if (Value == Base.Value)
1091 return FPOptionsOverride();
1092 return getChangesSlow(Base);
1093 }
1094
1095 inline void FPOptions::applyChanges(FPOptionsOverride FPO) {
1096 *this = FPO.applyOverrides(*this);
1097 }
1098
1099
1100 enum TranslationUnitKind {
1101
1102 TU_Complete,
1103
1104
1105
1106 TU_Prefix,
1107
1108
1109 TU_ClangModule,
1110
1111
1112
1113 TU_Incremental
1114 };
1115
1116 }
1117
1118 #endif