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