1 //===- LangOptions.h - C Language Family Language Options -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file 10 /// Defines the clang::LangOptions interface. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_BASIC_LANGOPTIONS_H 15 #define LLVM_CLANG_BASIC_LANGOPTIONS_H 16 17 #include "clang/Basic/CommentOptions.h" 18 #include "clang/Basic/LLVM.h" 19 #include "clang/Basic/LangStandard.h" 20 #include "clang/Basic/ObjCRuntime.h" 21 #include "clang/Basic/Sanitizers.h" 22 #include "clang/Basic/TargetCXXABI.h" 23 #include "clang/Basic/Visibility.h" 24 #include "llvm/ADT/FloatingPointMode.h" 25 #include "llvm/ADT/StringRef.h" 26 #include "llvm/ADT/Triple.h" 27 #include <string> 28 #include <vector> 29 30 namespace clang { 31 32 /// Bitfields of LangOptions, split out from LangOptions in order to ensure that 33 /// this large collection of bitfields is a trivial class type. 34 class LangOptionsBase { 35 friend class CompilerInvocation; 36 37 public: 38 // Define simple language options (with no accessors). 39 #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; 40 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) 41 #include "clang/Basic/LangOptions.def" 42 43 protected: 44 // Define language options of enumeration type. These are private, and will 45 // have accessors (below). 46 #define LANGOPT(Name, Bits, Default, Description) 47 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ 48 unsigned Name : Bits; 49 #include "clang/Basic/LangOptions.def" 50 }; 51 52 /// In the Microsoft ABI, this controls the placement of virtual displacement 53 /// members used to implement virtual inheritance. 54 enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable }; 55 56 /// Shader programs run in specific pipeline stages. 57 enum class ShaderStage { 58 Pixel = 0, 59 Vertex, 60 Geometry, 61 Hull, 62 Domain, 63 Compute, 64 Library, 65 RayGeneration, 66 Intersection, 67 AnyHit, 68 ClosestHit, 69 Miss, 70 Callable, 71 Mesh, 72 Amplification, 73 Invalid, 74 }; 75 76 /// Keeps track of the various options that can be 77 /// enabled, which controls the dialect of C or C++ that is accepted. 78 class LangOptions : public LangOptionsBase { 79 public: 80 using Visibility = clang::Visibility; 81 using RoundingMode = llvm::RoundingMode; 82 83 enum GCMode { NonGC, GCOnly, HybridGC }; 84 enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; 85 86 // Automatic variables live on the stack, and when trivial they're usually 87 // uninitialized because it's undefined behavior to use them without 88 // initializing them. 89 enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern }; 90 91 enum SignedOverflowBehaviorTy { 92 // Default C standard behavior. 93 SOB_Undefined, 94 95 // -fwrapv 96 SOB_Defined, 97 98 // -ftrapv 99 SOB_Trapping 100 }; 101 102 // FIXME: Unify with TUKind. 103 enum CompilingModuleKind { 104 /// Not compiling a module interface at all. 105 CMK_None, 106 107 /// Compiling a module from a module map. 108 CMK_ModuleMap, 109 110 /// Compiling a module from a list of header files. 111 CMK_HeaderModule, 112 113 /// Compiling a module header unit. 114 CMK_HeaderUnit, 115 116 /// Compiling a C++ modules TS module interface unit. 117 CMK_ModuleInterface, 118 }; 119 120 enum PragmaMSPointersToMembersKind { 121 PPTMK_BestCase, 122 PPTMK_FullGeneralitySingleInheritance, 123 PPTMK_FullGeneralityMultipleInheritance, 124 PPTMK_FullGeneralityVirtualInheritance 125 }; 126 127 using MSVtorDispMode = clang::MSVtorDispMode; 128 129 enum DefaultCallingConvention { 130 DCC_None, 131 DCC_CDecl, 132 DCC_FastCall, 133 DCC_StdCall, 134 DCC_VectorCall, 135 DCC_RegCall 136 }; 137 138 enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; 139 140 // Corresponds to _MSC_VER 141 enum MSVCMajorVersion { 142 MSVC2010 = 1600, 143 MSVC2012 = 1700, 144 MSVC2013 = 1800, 145 MSVC2015 = 1900, 146 MSVC2017 = 1910, 147 MSVC2017_5 = 1912, 148 MSVC2017_7 = 1914, 149 MSVC2019 = 1920, 150 MSVC2019_5 = 1925, 151 MSVC2019_8 = 1928, 152 }; 153 154 enum SYCLMajorVersion { 155 SYCL_None, 156 SYCL_2017, 157 SYCL_2020, 158 // The "default" SYCL version to be used when none is specified on the 159 // frontend command line. 160 SYCL_Default = SYCL_2020 161 }; 162 163 enum HLSLLangStd { 164 HLSL_Unset = 0, 165 HLSL_2015 = 2015, 166 HLSL_2016 = 2016, 167 HLSL_2017 = 2017, 168 HLSL_2018 = 2018, 169 HLSL_2021 = 2021, 170 HLSL_202x = 2029, 171 }; 172 173 /// Clang versions with different platform ABI conformance. 174 enum class ClangABI { 175 /// Attempt to be ABI-compatible with code generated by Clang 3.8.x 176 /// (SVN r257626). This causes <1 x long long> to be passed in an 177 /// integer register instead of an SSE register on x64_64. 178 Ver3_8, 179 180 /// Attempt to be ABI-compatible with code generated by Clang 4.0.x 181 /// (SVN r291814). This causes move operations to be ignored when 182 /// determining whether a class type can be passed or returned directly. 183 Ver4, 184 185 /// Attempt to be ABI-compatible with code generated by Clang 6.0.x 186 /// (SVN r321711). This causes determination of whether a type is 187 /// standard-layout to ignore collisions between empty base classes 188 /// and between base classes and member subobjects, which affects 189 /// whether we reuse base class tail padding in some ABIs. 190 Ver6, 191 192 /// Attempt to be ABI-compatible with code generated by Clang 7.0.x 193 /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be 194 /// compatible with __alignof (i.e., return the preferred alignment) 195 /// rather than returning the required alignment. 196 Ver7, 197 198 /// Attempt to be ABI-compatible with code generated by Clang 9.0.x 199 /// (SVN r351319). This causes vectors of __int128 to be passed in memory 200 /// instead of passing in multiple scalar registers on x86_64 on Linux and 201 /// NetBSD. 202 Ver9, 203 204 /// Attempt to be ABI-compatible with code generated by Clang 11.0.x 205 /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit 206 /// vector member on the stack instead of using registers, to not properly 207 /// mangle substitutions for template names in some cases, and to mangle 208 /// declaration template arguments without a cast to the parameter type 209 /// even when that can lead to mangling collisions. 210 Ver11, 211 212 /// Attempt to be ABI-compatible with code generated by Clang 12.0.x 213 /// (git 8e464dd76bef). This causes clang to mangle lambdas within 214 /// global-scope inline variables incorrectly. 215 Ver12, 216 217 /// Attempt to be ABI-compatible with code generated by Clang 14.0.x. 218 /// This causes clang to: 219 /// - mangle dependent nested names incorrectly. 220 /// - pack non-POD members of packed structs. 221 /// - make trivial only those defaulted copy constructors with a 222 /// parameter-type-list equivalent to the parameter-type-list of an 223 /// implicit declaration. 224 Ver14, 225 226 /// Conform to the underlying platform's C and C++ ABIs as closely 227 /// as we can. 228 Latest 229 }; 230 231 enum class CoreFoundationABI { 232 /// No interoperability ABI has been specified 233 Unspecified, 234 /// CoreFoundation does not have any language interoperability 235 Standalone, 236 /// Interoperability with the ObjectiveC runtime 237 ObjectiveC, 238 /// Interoperability with the latest known version of the Swift runtime 239 Swift, 240 /// Interoperability with the Swift 5.0 runtime 241 Swift5_0, 242 /// Interoperability with the Swift 4.2 runtime 243 Swift4_2, 244 /// Interoperability with the Swift 4.1 runtime 245 Swift4_1, 246 }; 247 248 enum FPModeKind { 249 // Disable the floating point pragma 250 FPM_Off, 251 252 // Enable the floating point pragma 253 FPM_On, 254 255 // Aggressively fuse FP ops (E.g. FMA) disregarding pragmas. 256 FPM_Fast, 257 258 // Aggressively fuse FP ops and honor pragmas. 259 FPM_FastHonorPragmas 260 }; 261 262 /// Possible floating point exception behavior. 263 enum FPExceptionModeKind { 264 /// Assume that floating-point exceptions are masked. 265 FPE_Ignore, 266 /// Transformations do not cause new exceptions but may hide some. 267 FPE_MayTrap, 268 /// Strictly preserve the floating-point exception semantics. 269 FPE_Strict, 270 /// Used internally to represent initial unspecified value. 271 FPE_Default 272 }; 273 274 /// Possible float expression evaluation method choices. 275 enum FPEvalMethodKind { 276 /// The evaluation method cannot be determined or is inconsistent for this 277 /// target. 278 FEM_Indeterminable = -1, 279 /// Use the declared type for fp arithmetic. 280 FEM_Source = 0, 281 /// Use the type double for fp arithmetic. 282 FEM_Double = 1, 283 /// Use extended type for fp arithmetic. 284 FEM_Extended = 2, 285 /// Used only for FE option processing; this is only used to indicate that 286 /// the user did not specify an explicit evaluation method on the command 287 /// line and so the target should be queried for its default evaluation 288 /// method instead. 289 FEM_UnsetOnCommandLine = 3 290 }; 291 292 /// Possible exception handling behavior. 293 enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm }; 294 295 enum class LaxVectorConversionKind { 296 /// Permit no implicit vector bitcasts. 297 None, 298 /// Permit vector bitcasts between integer vectors with different numbers 299 /// of elements but the same total bit-width. 300 Integer, 301 /// Permit vector bitcasts between all vectors with the same total 302 /// bit-width. 303 All, 304 }; 305 306 enum class AltivecSrcCompatKind { 307 // All vector compares produce scalars except vector pixel and vector bool. 308 // The types vector pixel and vector bool return vector results. 309 Mixed, 310 // All vector compares produce vector results as in GCC. 311 GCC, 312 // All vector compares produce scalars as in XL. 313 XL, 314 // Default clang behaviour. 315 Default = Mixed, 316 }; 317 318 enum class SignReturnAddressScopeKind { 319 /// No signing for any function. 320 None, 321 /// Sign the return address of functions that spill LR. 322 NonLeaf, 323 /// Sign the return address of all functions, 324 All 325 }; 326 327 enum class SignReturnAddressKeyKind { 328 /// Return address signing uses APIA key. 329 AKey, 330 /// Return address signing uses APIB key. 331 BKey 332 }; 333 334 enum class ThreadModelKind { 335 /// POSIX Threads. 336 POSIX, 337 /// Single Threaded Environment. 338 Single 339 }; 340 341 enum class ExtendArgsKind { 342 /// Integer arguments are sign or zero extended to 32/64 bits 343 /// during default argument promotions. 344 ExtendTo32, 345 ExtendTo64 346 }; 347 348 enum class GPUDefaultStreamKind { 349 /// Legacy default stream 350 Legacy, 351 /// Per-thread default stream 352 PerThread, 353 }; 354 355 enum class DefaultVisiblityExportMapping { 356 None, 357 /// map only explicit default visibilities to exported 358 Explicit, 359 /// map all default visibilities to exported 360 All, 361 }; 362 363 public: 364 /// The used language standard. 365 LangStandard::Kind LangStd; 366 367 /// Set of enabled sanitizers. 368 SanitizerSet Sanitize; 369 /// Is at least one coverage instrumentation type enabled. 370 bool SanitizeCoverage = false; 371 372 /// Paths to files specifying which objects 373 /// (files, functions, variables) should not be instrumented. 374 std::vector<std::string> NoSanitizeFiles; 375 376 /// Paths to the XRay "always instrument" files specifying which 377 /// objects (files, functions, variables) should be imbued with the XRay 378 /// "always instrument" attribute. 379 /// WARNING: This is a deprecated field and will go away in the future. 380 std::vector<std::string> XRayAlwaysInstrumentFiles; 381 382 /// Paths to the XRay "never instrument" files specifying which 383 /// objects (files, functions, variables) should be imbued with the XRay 384 /// "never instrument" attribute. 385 /// WARNING: This is a deprecated field and will go away in the future. 386 std::vector<std::string> XRayNeverInstrumentFiles; 387 388 /// Paths to the XRay attribute list files, specifying which objects 389 /// (files, functions, variables) should be imbued with the appropriate XRay 390 /// attribute(s). 391 std::vector<std::string> XRayAttrListFiles; 392 393 /// Paths to special case list files specifying which entities 394 /// (files, functions) should or should not be instrumented. 395 std::vector<std::string> ProfileListFiles; 396 397 clang::ObjCRuntime ObjCRuntime; 398 399 CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified; 400 401 std::string ObjCConstantStringClass; 402 403 /// The name of the handler function to be called when -ftrapv is 404 /// specified. 405 /// 406 /// If none is specified, abort (GCC-compatible behaviour). 407 std::string OverflowHandler; 408 409 /// The module currently being compiled as specified by -fmodule-name. 410 std::string ModuleName; 411 412 /// The name of the current module, of which the main source file 413 /// is a part. If CompilingModule is set, we are compiling the interface 414 /// of this module, otherwise we are compiling an implementation file of 415 /// it. This starts as ModuleName in case -fmodule-name is provided and 416 /// changes during compilation to reflect the current module. 417 std::string CurrentModule; 418 419 /// The names of any features to enable in module 'requires' decls 420 /// in addition to the hard-coded list in Module.cpp and the target features. 421 /// 422 /// This list is sorted. 423 std::vector<std::string> ModuleFeatures; 424 425 /// Options for parsing comments. 426 CommentOptions CommentOpts; 427 428 /// A list of all -fno-builtin-* function names (e.g., memset). 429 std::vector<std::string> NoBuiltinFuncs; 430 431 /// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE(). 432 std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap; 433 434 /// Triples of the OpenMP targets that the host code codegen should 435 /// take into account in order to generate accurate offloading descriptors. 436 std::vector<llvm::Triple> OMPTargetTriples; 437 438 /// Name of the IR file that contains the result of the OpenMP target 439 /// host code generation. 440 std::string OMPHostIRFile; 441 442 /// The user provided compilation unit ID, if non-empty. This is used to 443 /// externalize static variables which is needed to support accessing static 444 /// device variables in host code for single source offloading languages 445 /// like CUDA/HIP. 446 std::string CUID; 447 448 /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=. 449 /// This overrides the default ABI used by the target. 450 llvm::Optional<TargetCXXABI::Kind> CXXABI; 451 452 /// Indicates whether the front-end is explicitly told that the 453 /// input is a header file (i.e. -x c-header). 454 bool IsHeaderFile = false; 455 456 /// The default stream kind used for HIP kernel launching. 457 GPUDefaultStreamKind GPUDefaultStream; 458 459 /// The seed used by the randomize structure layout feature. 460 std::string RandstructSeed; 461 462 /// Indicates whether the __FILE__ macro should use the target's 463 /// platform-specific file separator or whether it should use the build 464 /// environment's platform-specific file separator. 465 /// 466 /// The plaform-specific path separator is the backslash(\) for Windows and 467 /// forward slash (/) elsewhere. 468 bool UseTargetPathSeparator = false; 469 470 LangOptions(); 471 472 /// Set language defaults for the given input language and 473 /// language standard in the given LangOptions object. 474 /// 475 /// \param Opts - The LangOptions object to set up. 476 /// \param Lang - The input language. 477 /// \param T - The target triple. 478 /// \param Includes - If the language requires extra headers to be implicitly 479 /// included, they will be appended to this list. 480 /// \param LangStd - The input language standard. 481 static void 482 setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T, 483 std::vector<std::string> &Includes, 484 LangStandard::Kind LangStd = LangStandard::lang_unspecified); 485 486 // Define accessors/mutators for language options of enumeration type. 487 #define LANGOPT(Name, Bits, Default, Description) 488 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ 489 Type get##Name() const { return static_cast<Type>(Name); } \ 490 void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } 491 #include "clang/Basic/LangOptions.def" 492 493 /// Are we compiling a module interface (.cppm or module map)? 494 bool isCompilingModule() const { 495 return getCompilingModule() != CMK_None; 496 } 497 498 /// Do we need to track the owning module for a local declaration? 499 bool trackLocalOwningModule() const { 500 return isCompilingModule() || ModulesLocalVisibility; 501 } 502 503 bool isSignedOverflowDefined() const { 504 return getSignedOverflowBehavior() == SOB_Defined; 505 } 506 507 bool isSubscriptPointerArithmetic() const { 508 return ObjCRuntime.isSubscriptPointerArithmetic() && 509 !ObjCSubscriptingLegacyRuntime; 510 } 511 512 bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { 513 return MSCompatibilityVersion >= MajorVersion * 100000U; 514 } 515 516 /// Reset all of the options that are not considered when building a 517 /// module. 518 void resetNonModularOptions(); 519 520 /// Is this a libc/libm function that is no longer recognized as a 521 /// builtin because a -fno-builtin-* option has been specified? 522 bool isNoBuiltinFunc(StringRef Name) const; 523 524 /// True if any ObjC types may have non-trivial lifetime qualifiers. 525 bool allowsNonTrivialObjCLifetimeQualifiers() const { 526 return ObjCAutoRefCount || ObjCWeak; 527 } 528 529 bool assumeFunctionsAreConvergent() const { 530 return ConvergentFunctions; 531 } 532 533 /// Return the OpenCL C or C++ version as a VersionTuple. 534 VersionTuple getOpenCLVersionTuple() const; 535 536 /// Return the OpenCL version that kernel language is compatible with 537 unsigned getOpenCLCompatibleVersion() const; 538 539 /// Return the OpenCL C or C++ for OpenCL language name and version 540 /// as a string. 541 std::string getOpenCLVersionString() const; 542 543 /// Returns true if functions without prototypes or functions with an 544 /// identifier list (aka K&R C functions) are not allowed. 545 bool requiresStrictPrototypes() const { 546 return CPlusPlus || C2x || DisableKNRFunctions; 547 } 548 549 /// Returns true if implicit function declarations are allowed in the current 550 /// language mode. 551 bool implicitFunctionsAllowed() const { 552 return !requiresStrictPrototypes() && !OpenCL; 553 } 554 555 /// Returns true if implicit int is part of the language requirements. 556 bool isImplicitIntRequired() const { return !CPlusPlus && !C99; } 557 558 /// Returns true if implicit int is supported at all. 559 bool isImplicitIntAllowed() const { return !CPlusPlus && !C2x; } 560 561 /// Check if return address signing is enabled. 562 bool hasSignReturnAddress() const { 563 return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; 564 } 565 566 /// Check if return address signing uses AKey. 567 bool isSignReturnAddressWithAKey() const { 568 return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; 569 } 570 571 /// Check if leaf functions are also signed. 572 bool isSignReturnAddressScopeAll() const { 573 return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; 574 } 575 576 bool hasSjLjExceptions() const { 577 return getExceptionHandling() == ExceptionHandlingKind::SjLj; 578 } 579 580 bool hasSEHExceptions() const { 581 return getExceptionHandling() == ExceptionHandlingKind::WinEH; 582 } 583 584 bool hasDWARFExceptions() const { 585 return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI; 586 } 587 588 bool hasWasmExceptions() const { 589 return getExceptionHandling() == ExceptionHandlingKind::Wasm; 590 } 591 592 bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; } 593 594 bool hasDefaultVisibilityExportMapping() const { 595 return getDefaultVisibilityExportMapping() != 596 DefaultVisiblityExportMapping::None; 597 } 598 599 bool isExplicitDefaultVisibilityExportMapping() const { 600 return getDefaultVisibilityExportMapping() == 601 DefaultVisiblityExportMapping::Explicit; 602 } 603 604 bool isAllDefaultVisibilityExportMapping() const { 605 return getDefaultVisibilityExportMapping() == 606 DefaultVisiblityExportMapping::All; 607 } 608 609 /// Remap path prefix according to -fmacro-prefix-path option. 610 void remapPathPrefix(SmallVectorImpl<char> &Path) const; 611 612 RoundingMode getDefaultRoundingMode() const { 613 return RoundingMath ? RoundingMode::Dynamic 614 : RoundingMode::NearestTiesToEven; 615 } 616 617 FPExceptionModeKind getDefaultExceptionMode() const { 618 FPExceptionModeKind EM = getFPExceptionMode(); 619 if (EM == FPExceptionModeKind::FPE_Default) 620 return FPExceptionModeKind::FPE_Ignore; 621 return EM; 622 } 623 }; 624 625 /// Floating point control options 626 class FPOptionsOverride; 627 class FPOptions { 628 public: 629 // We start by defining the layout. 630 using storage_type = uint32_t; 631 632 using RoundingMode = llvm::RoundingMode; 633 634 static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type); 635 636 // Define a fake option named "First" so that we have a PREVIOUS even for the 637 // real first option. 638 static constexpr storage_type FirstShift = 0, FirstWidth = 0; 639 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ 640 static constexpr storage_type NAME##Shift = \ 641 PREVIOUS##Shift + PREVIOUS##Width; \ 642 static constexpr storage_type NAME##Width = WIDTH; \ 643 static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \ 644 << NAME##Shift; 645 #include "clang/Basic/FPOptions.def" 646 647 static constexpr storage_type TotalWidth = 0 648 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH 649 #include "clang/Basic/FPOptions.def" 650 ; 651 static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions"); 652 653 private: 654 storage_type Value; 655 656 FPOptionsOverride getChangesSlow(const FPOptions &Base) const; 657 658 public: 659 FPOptions() : Value(0) { 660 setFPContractMode(LangOptions::FPM_Off); 661 setConstRoundingMode(RoundingMode::Dynamic); 662 setSpecifiedExceptionMode(LangOptions::FPE_Default); 663 } 664 explicit FPOptions(const LangOptions &LO) { 665 Value = 0; 666 // The language fp contract option FPM_FastHonorPragmas has the same effect 667 // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in 668 // frontend. 669 auto LangOptContractMode = LO.getDefaultFPContractMode(); 670 if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas) 671 LangOptContractMode = LangOptions::FPM_Fast; 672 setFPContractMode(LangOptContractMode); 673 setRoundingMath(LO.RoundingMath); 674 setConstRoundingMode(LangOptions::RoundingMode::Dynamic); 675 setSpecifiedExceptionMode(LO.getFPExceptionMode()); 676 setAllowFPReassociate(LO.AllowFPReassoc); 677 setNoHonorNaNs(LO.NoHonorNaNs); 678 setNoHonorInfs(LO.NoHonorInfs); 679 setNoSignedZero(LO.NoSignedZero); 680 setAllowReciprocal(LO.AllowRecip); 681 setAllowApproxFunc(LO.ApproxFunc); 682 if (getFPContractMode() == LangOptions::FPM_On && 683 getRoundingMode() == llvm::RoundingMode::Dynamic && 684 getExceptionMode() == LangOptions::FPE_Strict) 685 // If the FP settings are set to the "strict" model, then 686 // FENV access is set to true. (ffp-model=strict) 687 setAllowFEnvAccess(true); 688 else 689 setAllowFEnvAccess(LangOptions::FPM_Off); 690 } 691 692 bool allowFPContractWithinStatement() const { 693 return getFPContractMode() == LangOptions::FPM_On; 694 } 695 void setAllowFPContractWithinStatement() { 696 setFPContractMode(LangOptions::FPM_On); 697 } 698 699 bool allowFPContractAcrossStatement() const { 700 return getFPContractMode() == LangOptions::FPM_Fast; 701 } 702 void setAllowFPContractAcrossStatement() { 703 setFPContractMode(LangOptions::FPM_Fast); 704 } 705 706 bool isFPConstrained() const { 707 return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven || 708 getExceptionMode() != LangOptions::FPE_Ignore || 709 getAllowFEnvAccess(); 710 } 711 712 RoundingMode getRoundingMode() const { 713 RoundingMode RM = getConstRoundingMode(); 714 if (RM == RoundingMode::Dynamic) { 715 // C2x: 7.6.2p3 If the FE_DYNAMIC mode is specified and FENV_ACCESS is 716 // "off", the translator may assume that the default rounding mode is in 717 // effect. 718 if (!getAllowFEnvAccess() && !getRoundingMath()) 719 RM = RoundingMode::NearestTiesToEven; 720 } 721 return RM; 722 } 723 724 LangOptions::FPExceptionModeKind getExceptionMode() const { 725 LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode(); 726 if (EM == LangOptions::FPExceptionModeKind::FPE_Default) { 727 if (getAllowFEnvAccess()) 728 return LangOptions::FPExceptionModeKind::FPE_Strict; 729 else 730 return LangOptions::FPExceptionModeKind::FPE_Ignore; 731 } 732 return EM; 733 } 734 735 bool operator==(FPOptions other) const { return Value == other.Value; } 736 737 /// Return the default value of FPOptions that's used when trailing 738 /// storage isn't required. 739 static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO); 740 741 storage_type getAsOpaqueInt() const { return Value; } 742 static FPOptions getFromOpaqueInt(storage_type Value) { 743 FPOptions Opts; 744 Opts.Value = Value; 745 return Opts; 746 } 747 748 /// Return difference with the given option set. 749 FPOptionsOverride getChangesFrom(const FPOptions &Base) const; 750 751 // We can define most of the accessors automatically: 752 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ 753 TYPE get##NAME() const { \ 754 return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \ 755 } \ 756 void set##NAME(TYPE value) { \ 757 Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ 758 } 759 #include "clang/Basic/FPOptions.def" 760 LLVM_DUMP_METHOD void dump(); 761 }; 762 763 /// Represents difference between two FPOptions values. 764 /// 765 /// The effect of language constructs changing the set of floating point options 766 /// is usually a change of some FP properties while leaving others intact. This 767 /// class describes such changes by keeping information about what FP options 768 /// are overridden. 769 /// 770 /// The integral set of FP options, described by the class FPOptions, may be 771 /// represented as a default FP option set, defined by language standard and 772 /// command line options, with the overrides introduced by pragmas. 773 /// 774 /// The is implemented as a value of the new FPOptions plus a mask showing which 775 /// fields are actually set in it. 776 class FPOptionsOverride { 777 FPOptions Options = FPOptions::getFromOpaqueInt(0); 778 FPOptions::storage_type OverrideMask = 0; 779 780 public: 781 using RoundingMode = llvm::RoundingMode; 782 783 /// The type suitable for storing values of FPOptionsOverride. Must be twice 784 /// as wide as bit size of FPOption. 785 using storage_type = uint64_t; 786 static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type), 787 "Too short type for FPOptionsOverride"); 788 789 /// Bit mask selecting bits of OverrideMask in serialized representation of 790 /// FPOptionsOverride. 791 static constexpr storage_type OverrideMaskBits = 792 (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1; 793 794 FPOptionsOverride() {} 795 FPOptionsOverride(const LangOptions &LO) 796 : Options(LO), OverrideMask(OverrideMaskBits) {} 797 FPOptionsOverride(FPOptions FPO) 798 : Options(FPO), OverrideMask(OverrideMaskBits) {} 799 FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask) 800 : Options(FPO), OverrideMask(Mask) {} 801 802 bool requiresTrailingStorage() const { return OverrideMask != 0; } 803 804 void setAllowFPContractWithinStatement() { 805 setFPContractModeOverride(LangOptions::FPM_On); 806 } 807 808 void setAllowFPContractAcrossStatement() { 809 setFPContractModeOverride(LangOptions::FPM_Fast); 810 } 811 812 void setDisallowFPContract() { 813 setFPContractModeOverride(LangOptions::FPM_Off); 814 } 815 816 void setFPPreciseEnabled(bool Value) { 817 setAllowFPReassociateOverride(!Value); 818 setNoHonorNaNsOverride(!Value); 819 setNoHonorInfsOverride(!Value); 820 setNoSignedZeroOverride(!Value); 821 setAllowReciprocalOverride(!Value); 822 setAllowApproxFuncOverride(!Value); 823 if (Value) 824 /* Precise mode implies fp_contract=on and disables ffast-math */ 825 setAllowFPContractWithinStatement(); 826 else 827 /* Precise mode disabled sets fp_contract=fast and enables ffast-math */ 828 setAllowFPContractAcrossStatement(); 829 } 830 831 storage_type getAsOpaqueInt() const { 832 return (static_cast<storage_type>(Options.getAsOpaqueInt()) 833 << FPOptions::StorageBitSize) | 834 OverrideMask; 835 } 836 static FPOptionsOverride getFromOpaqueInt(storage_type I) { 837 FPOptionsOverride Opts; 838 Opts.OverrideMask = I & OverrideMaskBits; 839 Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize); 840 return Opts; 841 } 842 843 FPOptions applyOverrides(FPOptions Base) { 844 FPOptions Result = 845 FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) | 846 (Options.getAsOpaqueInt() & OverrideMask)); 847 return Result; 848 } 849 850 FPOptions applyOverrides(const LangOptions &LO) { 851 return applyOverrides(FPOptions(LO)); 852 } 853 854 bool operator==(FPOptionsOverride other) const { 855 return Options == other.Options && OverrideMask == other.OverrideMask; 856 } 857 bool operator!=(FPOptionsOverride other) const { return !(*this == other); } 858 859 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ 860 bool has##NAME##Override() const { \ 861 return OverrideMask & FPOptions::NAME##Mask; \ 862 } \ 863 TYPE get##NAME##Override() const { \ 864 assert(has##NAME##Override()); \ 865 return Options.get##NAME(); \ 866 } \ 867 void clear##NAME##Override() { \ 868 /* Clear the actual value so that we don't have spurious differences when \ 869 * testing equality. */ \ 870 Options.set##NAME(TYPE(0)); \ 871 OverrideMask &= ~FPOptions::NAME##Mask; \ 872 } \ 873 void set##NAME##Override(TYPE value) { \ 874 Options.set##NAME(value); \ 875 OverrideMask |= FPOptions::NAME##Mask; \ 876 } 877 #include "clang/Basic/FPOptions.def" 878 LLVM_DUMP_METHOD void dump(); 879 }; 880 881 inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const { 882 if (Value == Base.Value) 883 return FPOptionsOverride(); 884 return getChangesSlow(Base); 885 } 886 887 /// Describes the kind of translation unit being processed. 888 enum TranslationUnitKind { 889 /// The translation unit is a complete translation unit. 890 TU_Complete, 891 892 /// The translation unit is a prefix to a translation unit, and is 893 /// not complete. 894 TU_Prefix, 895 896 /// The translation unit is a module. 897 TU_Module, 898 899 /// The translation unit is a is a complete translation unit that we might 900 /// incrementally extend later. 901 TU_Incremental 902 }; 903 904 } // namespace clang 905 906 #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H 907