| 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/CFProtectionOptions.h" |
| 18 | #include "clang/Basic/CommentOptions.h" |
| 19 | #include "clang/Basic/LLVM.h" |
| 20 | #include "clang/Basic/LangStandard.h" |
| 21 | #include "clang/Basic/ObjCRuntime.h" |
| 22 | #include "clang/Basic/Sanitizers.h" |
| 23 | #include "clang/Basic/TargetCXXABI.h" |
| 24 | #include "clang/Basic/Visibility.h" |
| 25 | #include "llvm/ADT/FloatingPointMode.h" |
| 26 | #include "llvm/ADT/StringRef.h" |
| 27 | #include "llvm/BinaryFormat/DXContainer.h" |
| 28 | #include "llvm/TargetParser/Triple.h" |
| 29 | #include <optional> |
| 30 | #include <string> |
| 31 | #include <vector> |
| 32 | |
| 33 | namespace clang { |
| 34 | |
| 35 | /// In the Microsoft ABI, this controls the placement of virtual displacement |
| 36 | /// members used to implement virtual inheritance. |
| 37 | enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable }; |
| 38 | |
| 39 | /// Shader programs run in specific pipeline stages. |
| 40 | /// The order of these values matters, and must be kept in sync with the |
| 41 | /// Triple Environment enum in llvm::Triple. The ordering is enforced in |
| 42 | /// static_asserts in Triple.cpp and in clang/Basic/HLSLRuntime.h. |
| 43 | enum class ShaderStage { |
| 44 | Pixel = 0, |
| 45 | Vertex, |
| 46 | Geometry, |
| 47 | Hull, |
| 48 | Domain, |
| 49 | Compute, |
| 50 | Library, |
| 51 | RayGeneration, |
| 52 | Intersection, |
| 53 | AnyHit, |
| 54 | ClosestHit, |
| 55 | Miss, |
| 56 | Callable, |
| 57 | Mesh, |
| 58 | Amplification, |
| 59 | Invalid, |
| 60 | }; |
| 61 | |
| 62 | enum class PointerAuthenticationMode : unsigned { |
| 63 | None, |
| 64 | Strip, |
| 65 | SignAndStrip, |
| 66 | SignAndAuth |
| 67 | }; |
| 68 | |
| 69 | /// Bitfields of LangOptions, split out from LangOptions in order to ensure that |
| 70 | /// this large collection of bitfields is a trivial class type. |
| 71 | class LangOptionsBase { |
| 72 | friend class CompilerInvocation; |
| 73 | friend class CompilerInvocationBase; |
| 74 | |
| 75 | public: |
| 76 | using Visibility = clang::Visibility; |
| 77 | using RoundingMode = llvm::RoundingMode; |
| 78 | using CFBranchLabelSchemeKind = clang::CFBranchLabelSchemeKind; |
| 79 | |
| 80 | enum GCMode { NonGC, GCOnly, HybridGC }; |
| 81 | enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; |
| 82 | |
| 83 | // Automatic variables live on the stack, and when trivial they're usually |
| 84 | // uninitialized because it's undefined behavior to use them without |
| 85 | // initializing them. |
| 86 | enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern }; |
| 87 | |
| 88 | enum SignedOverflowBehaviorTy { |
| 89 | // Default C standard behavior. |
| 90 | SOB_Undefined, |
| 91 | |
| 92 | // -fwrapv |
| 93 | SOB_Defined, |
| 94 | |
| 95 | // -ftrapv |
| 96 | SOB_Trapping |
| 97 | }; |
| 98 | |
| 99 | // FIXME: Unify with TUKind. |
| 100 | enum CompilingModuleKind { |
| 101 | /// Not compiling a module interface at all. |
| 102 | CMK_None, |
| 103 | |
| 104 | /// Compiling a module from a module map. |
| 105 | CMK_ModuleMap, |
| 106 | |
| 107 | /// Compiling a module header unit. |
| 108 | , |
| 109 | |
| 110 | /// Compiling a C++ modules interface unit. |
| 111 | CMK_ModuleInterface, |
| 112 | }; |
| 113 | |
| 114 | enum PragmaMSPointersToMembersKind { |
| 115 | PPTMK_BestCase, |
| 116 | PPTMK_FullGeneralitySingleInheritance, |
| 117 | PPTMK_FullGeneralityMultipleInheritance, |
| 118 | PPTMK_FullGeneralityVirtualInheritance |
| 119 | }; |
| 120 | |
| 121 | using MSVtorDispMode = clang::MSVtorDispMode; |
| 122 | |
| 123 | enum DefaultCallingConvention { |
| 124 | DCC_None, |
| 125 | DCC_CDecl, |
| 126 | DCC_FastCall, |
| 127 | DCC_StdCall, |
| 128 | DCC_VectorCall, |
| 129 | DCC_RegCall, |
| 130 | DCC_RtdCall |
| 131 | }; |
| 132 | |
| 133 | enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; |
| 134 | |
| 135 | // Corresponds to _MSC_VER |
| 136 | enum MSVCMajorVersion { |
| 137 | MSVC2010 = 1600, |
| 138 | MSVC2012 = 1700, |
| 139 | MSVC2013 = 1800, |
| 140 | MSVC2015 = 1900, |
| 141 | MSVC2017 = 1910, |
| 142 | MSVC2017_5 = 1912, |
| 143 | MSVC2017_7 = 1914, |
| 144 | MSVC2019 = 1920, |
| 145 | MSVC2019_5 = 1925, |
| 146 | MSVC2019_8 = 1928, |
| 147 | MSVC2022_3 = 1933, |
| 148 | MSVC2022_9 = 1939, |
| 149 | }; |
| 150 | |
| 151 | enum SYCLMajorVersion { |
| 152 | SYCL_None, |
| 153 | SYCL_2017, |
| 154 | SYCL_2020, |
| 155 | // The "default" SYCL version to be used when none is specified on the |
| 156 | // frontend command line. |
| 157 | SYCL_Default = SYCL_2020 |
| 158 | }; |
| 159 | |
| 160 | enum HLSLLangStd { |
| 161 | HLSL_Unset = 0, |
| 162 | HLSL_2015 = 2015, |
| 163 | HLSL_2016 = 2016, |
| 164 | HLSL_2017 = 2017, |
| 165 | HLSL_2018 = 2018, |
| 166 | HLSL_2021 = 2021, |
| 167 | HLSL_202x = 2028, |
| 168 | HLSL_202y = 2029, |
| 169 | }; |
| 170 | |
| 171 | /// Clang versions with different platform ABI conformance. |
| 172 | enum class ClangABI { |
| 173 | /// Attempt to be ABI-compatible with code generated by Clang 3.8.x |
| 174 | /// (SVN r257626). This causes <1 x long long> to be passed in an |
| 175 | /// integer register instead of an SSE register on x64_64. |
| 176 | Ver3_8, |
| 177 | |
| 178 | /// Attempt to be ABI-compatible with code generated by Clang 4.0.x |
| 179 | /// (SVN r291814). This causes move operations to be ignored when |
| 180 | /// determining whether a class type can be passed or returned directly. |
| 181 | Ver4, |
| 182 | |
| 183 | /// Attempt to be ABI-compatible with code generated by Clang 6.0.x |
| 184 | /// (SVN r321711). This causes determination of whether a type is |
| 185 | /// standard-layout to ignore collisions between empty base classes |
| 186 | /// and between base classes and member subobjects, which affects |
| 187 | /// whether we reuse base class tail padding in some ABIs. |
| 188 | Ver6, |
| 189 | |
| 190 | /// Attempt to be ABI-compatible with code generated by Clang 7.0.x |
| 191 | /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be |
| 192 | /// compatible with __alignof (i.e., return the preferred alignment) |
| 193 | /// rather than returning the required alignment. |
| 194 | Ver7, |
| 195 | |
| 196 | /// Attempt to be ABI-compatible with code generated by Clang 9.0.x |
| 197 | /// (SVN r351319). This causes vectors of __int128 to be passed in memory |
| 198 | /// instead of passing in multiple scalar registers on x86_64 on Linux and |
| 199 | /// NetBSD. |
| 200 | Ver9, |
| 201 | |
| 202 | /// Attempt to be ABI-compatible with code generated by Clang 11.0.x |
| 203 | /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit |
| 204 | /// vector member on the stack instead of using registers, to not properly |
| 205 | /// mangle substitutions for template names in some cases, and to mangle |
| 206 | /// declaration template arguments without a cast to the parameter type |
| 207 | /// even when that can lead to mangling collisions. |
| 208 | Ver11, |
| 209 | |
| 210 | /// Attempt to be ABI-compatible with code generated by Clang 12.0.x |
| 211 | /// (git 8e464dd76bef). This causes clang to mangle lambdas within |
| 212 | /// global-scope inline variables incorrectly. |
| 213 | Ver12, |
| 214 | |
| 215 | /// Attempt to be ABI-compatible with code generated by Clang 14.0.x. |
| 216 | /// This causes clang to: |
| 217 | /// - mangle dependent nested names incorrectly. |
| 218 | /// - make trivial only those defaulted copy constructors with a |
| 219 | /// parameter-type-list equivalent to the parameter-type-list of an |
| 220 | /// implicit declaration. |
| 221 | Ver14, |
| 222 | |
| 223 | /// Attempt to be ABI-compatible with code generated by Clang 15.0.x. |
| 224 | /// This causes clang to: |
| 225 | /// - Reverse the implementation for DR692, DR1395 and DR1432. |
| 226 | /// - pack non-POD members of packed structs. |
| 227 | /// - consider classes with defaulted special member functions non-pod. |
| 228 | Ver15, |
| 229 | |
| 230 | /// Attempt to be ABI-compatible with code generated by Clang 17.0.x. |
| 231 | /// This causes clang to revert some fixes to its implementation of the |
| 232 | /// Itanium name mangling scheme, with the consequence that overloaded |
| 233 | /// function templates are mangled the same if they differ only by: |
| 234 | /// - constraints |
| 235 | /// - whether a non-type template parameter has a deduced type |
| 236 | /// - the parameter list of a template template parameter |
| 237 | Ver17, |
| 238 | |
| 239 | /// Attempt to be ABI-compatible with code generated by Clang 18.0.x. |
| 240 | /// This causes clang to revert some fixes to the mangling of lambdas |
| 241 | /// in the initializers of members of local classes. |
| 242 | Ver18, |
| 243 | |
| 244 | /// Attempt to be ABI-compatible with code generated by Clang 19.0.x. |
| 245 | /// This causes clang to: |
| 246 | /// - Incorrectly mangle the 'base type' substitutions of the CXX |
| 247 | /// construction vtable because it hasn't added 'type' as a substitution. |
| 248 | /// - Skip mangling enclosing class templates of member-like friend |
| 249 | /// function templates. |
| 250 | /// - Ignore empty struct arguments in C++ mode for ARM, instead of |
| 251 | /// passing them as if they had a size of 1 byte. |
| 252 | Ver19, |
| 253 | |
| 254 | /// Attempt to be ABI-compatible with code generated by Clang 20.0.x. |
| 255 | /// This causes clang to: |
| 256 | /// - Incorrectly return C++ records in AVX registers on x86_64. |
| 257 | Ver20, |
| 258 | |
| 259 | /// Conform to the underlying platform's C and C++ ABIs as closely |
| 260 | /// as we can. |
| 261 | Latest |
| 262 | }; |
| 263 | |
| 264 | enum class CoreFoundationABI { |
| 265 | /// No interoperability ABI has been specified |
| 266 | Unspecified, |
| 267 | /// CoreFoundation does not have any language interoperability |
| 268 | Standalone, |
| 269 | /// Interoperability with the ObjectiveC runtime |
| 270 | ObjectiveC, |
| 271 | /// Interoperability with the latest known version of the Swift runtime |
| 272 | Swift, |
| 273 | /// Interoperability with the Swift 5.0 runtime |
| 274 | Swift5_0, |
| 275 | /// Interoperability with the Swift 4.2 runtime |
| 276 | Swift4_2, |
| 277 | /// Interoperability with the Swift 4.1 runtime |
| 278 | Swift4_1, |
| 279 | }; |
| 280 | |
| 281 | enum FPModeKind { |
| 282 | // Disable the floating point pragma |
| 283 | FPM_Off, |
| 284 | |
| 285 | // Enable the floating point pragma |
| 286 | FPM_On, |
| 287 | |
| 288 | // Aggressively fuse FP ops (E.g. FMA) disregarding pragmas. |
| 289 | FPM_Fast, |
| 290 | |
| 291 | // Aggressively fuse FP ops and honor pragmas. |
| 292 | FPM_FastHonorPragmas |
| 293 | }; |
| 294 | |
| 295 | /// Possible floating point exception behavior. |
| 296 | enum FPExceptionModeKind { |
| 297 | /// Assume that floating-point exceptions are masked. |
| 298 | FPE_Ignore, |
| 299 | /// Transformations do not cause new exceptions but may hide some. |
| 300 | FPE_MayTrap, |
| 301 | /// Strictly preserve the floating-point exception semantics. |
| 302 | FPE_Strict, |
| 303 | /// Used internally to represent initial unspecified value. |
| 304 | FPE_Default |
| 305 | }; |
| 306 | |
| 307 | /// Possible float expression evaluation method choices. |
| 308 | enum FPEvalMethodKind : unsigned { |
| 309 | /// Use the declared type for fp arithmetic. |
| 310 | FEM_Source = 0, |
| 311 | /// Use the type double for fp arithmetic. |
| 312 | FEM_Double = 1, |
| 313 | /// Use extended type for fp arithmetic. |
| 314 | FEM_Extended = 2, |
| 315 | /// Used only for FE option processing; this is only used to indicate that |
| 316 | /// the user did not specify an explicit evaluation method on the command |
| 317 | /// line and so the target should be queried for its default evaluation |
| 318 | /// method instead. |
| 319 | FEM_UnsetOnCommandLine = 3 |
| 320 | }; |
| 321 | |
| 322 | enum ExcessPrecisionKind { FPP_Standard, FPP_Fast, FPP_None }; |
| 323 | |
| 324 | /// Possible exception handling behavior. |
| 325 | enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm }; |
| 326 | |
| 327 | enum class LaxVectorConversionKind { |
| 328 | /// Permit no implicit vector bitcasts. |
| 329 | None, |
| 330 | /// Permit vector bitcasts between integer vectors with different numbers |
| 331 | /// of elements but the same total bit-width. |
| 332 | Integer, |
| 333 | /// Permit vector bitcasts between all vectors with the same total |
| 334 | /// bit-width. |
| 335 | All, |
| 336 | }; |
| 337 | |
| 338 | enum class AltivecSrcCompatKind { |
| 339 | // All vector compares produce scalars except vector pixel and vector bool. |
| 340 | // The types vector pixel and vector bool return vector results. |
| 341 | Mixed, |
| 342 | // All vector compares produce vector results as in GCC. |
| 343 | GCC, |
| 344 | // All vector compares produce scalars as in XL. |
| 345 | XL, |
| 346 | // Default clang behaviour. |
| 347 | Default = Mixed, |
| 348 | }; |
| 349 | |
| 350 | enum class SignReturnAddressScopeKind { |
| 351 | /// No signing for any function. |
| 352 | None, |
| 353 | /// Sign the return address of functions that spill LR. |
| 354 | NonLeaf, |
| 355 | /// Sign the return address of all functions, |
| 356 | All |
| 357 | }; |
| 358 | |
| 359 | enum class SignReturnAddressKeyKind { |
| 360 | /// Return address signing uses APIA key. |
| 361 | AKey, |
| 362 | /// Return address signing uses APIB key. |
| 363 | BKey |
| 364 | }; |
| 365 | |
| 366 | enum class ThreadModelKind { |
| 367 | /// POSIX Threads. |
| 368 | POSIX, |
| 369 | /// Single Threaded Environment. |
| 370 | Single |
| 371 | }; |
| 372 | |
| 373 | enum class ExtendArgsKind { |
| 374 | /// Integer arguments are sign or zero extended to 32/64 bits |
| 375 | /// during default argument promotions. |
| 376 | ExtendTo32, |
| 377 | ExtendTo64 |
| 378 | }; |
| 379 | |
| 380 | enum class GPUDefaultStreamKind { |
| 381 | /// Legacy default stream |
| 382 | Legacy, |
| 383 | /// Per-thread default stream |
| 384 | PerThread, |
| 385 | }; |
| 386 | |
| 387 | /// Exclude certain code patterns from being instrumented by arithmetic |
| 388 | /// overflow sanitizers |
| 389 | enum OverflowPatternExclusionKind { |
| 390 | /// Don't exclude any overflow patterns from sanitizers |
| 391 | None = 1 << 0, |
| 392 | /// Exclude all overflow patterns (below) |
| 393 | All = 1 << 1, |
| 394 | /// if (a + b < a) |
| 395 | AddSignedOverflowTest = 1 << 2, |
| 396 | /// if (a + b < a) |
| 397 | AddUnsignedOverflowTest = 1 << 3, |
| 398 | /// -1UL |
| 399 | NegUnsignedConst = 1 << 4, |
| 400 | /// while (count--) |
| 401 | PostDecrInWhile = 1 << 5, |
| 402 | }; |
| 403 | |
| 404 | enum class DefaultVisiblityExportMapping { |
| 405 | None, |
| 406 | /// map only explicit default visibilities to exported |
| 407 | Explicit, |
| 408 | /// map all default visibilities to exported |
| 409 | All, |
| 410 | }; |
| 411 | |
| 412 | enum class VisibilityForcedKinds { |
| 413 | /// Force hidden visibility |
| 414 | ForceHidden, |
| 415 | /// Force protected visibility |
| 416 | ForceProtected, |
| 417 | /// Force default visibility |
| 418 | ForceDefault, |
| 419 | /// Don't alter the visibility |
| 420 | Source, |
| 421 | }; |
| 422 | |
| 423 | enum class VisibilityFromDLLStorageClassKinds { |
| 424 | /// Keep the IR-gen assigned visibility. |
| 425 | Keep, |
| 426 | /// Override the IR-gen assigned visibility with default visibility. |
| 427 | Default, |
| 428 | /// Override the IR-gen assigned visibility with hidden visibility. |
| 429 | Hidden, |
| 430 | /// Override the IR-gen assigned visibility with protected visibility. |
| 431 | Protected, |
| 432 | }; |
| 433 | |
| 434 | enum class StrictFlexArraysLevelKind { |
| 435 | /// Any trailing array member is a FAM. |
| 436 | Default = 0, |
| 437 | /// Any trailing array member of undefined, 0, or 1 size is a FAM. |
| 438 | OneZeroOrIncomplete = 1, |
| 439 | /// Any trailing array member of undefined or 0 size is a FAM. |
| 440 | ZeroOrIncomplete = 2, |
| 441 | /// Any trailing array member of undefined size is a FAM. |
| 442 | IncompleteOnly = 3, |
| 443 | }; |
| 444 | |
| 445 | /// Controls the various implementations for complex multiplication and |
| 446 | // division. |
| 447 | enum ComplexRangeKind { |
| 448 | /// Implementation of complex division and multiplication using a call to |
| 449 | /// runtime library functions(generally the case, but the BE might |
| 450 | /// sometimes replace the library call if it knows enough about the |
| 451 | /// potential range of the inputs). Overflow and non-finite values are |
| 452 | /// handled by the library implementation. This is the default value. |
| 453 | CX_Full, |
| 454 | |
| 455 | /// Implementation of complex division offering an improved handling |
| 456 | /// for overflow in intermediate calculations with no special handling for |
| 457 | /// NaN and infinite values. |
| 458 | CX_Improved, |
| 459 | |
| 460 | /// Implementation of complex division using algebraic formulas at |
| 461 | /// higher precision. Overflow is handled. Non-finite values are handled in |
| 462 | /// some cases. If the target hardware does not have native support for a |
| 463 | /// higher precision data type, an implementation for the complex operation |
| 464 | /// will be used to provide improved guards against intermediate overflow, |
| 465 | /// but overflow and underflow may still occur in some cases. NaN and |
| 466 | /// infinite values are not handled. |
| 467 | CX_Promoted, |
| 468 | |
| 469 | /// Implementation of complex division and multiplication using |
| 470 | /// algebraic formulas at source precision. No special handling to avoid |
| 471 | /// overflow. NaN and infinite values are not handled. |
| 472 | CX_Basic, |
| 473 | |
| 474 | /// No range rule is enabled. |
| 475 | CX_None |
| 476 | }; |
| 477 | |
| 478 | /// Controls which variables have static destructors registered. |
| 479 | enum class RegisterStaticDestructorsKind { |
| 480 | /// Register static destructors for all variables. |
| 481 | All, |
| 482 | /// Register static destructors only for thread-local variables. |
| 483 | ThreadLocal, |
| 484 | /// Don't register static destructors for any variables. |
| 485 | None, |
| 486 | }; |
| 487 | |
| 488 | // Define simple language options (with no accessors). |
| 489 | #define LANGOPT(Name, Bits, Default, Description) unsigned Name : Bits; |
| 490 | #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) |
| 491 | #include "clang/Basic/LangOptions.def" |
| 492 | |
| 493 | protected: |
| 494 | // Define language options of enumeration type. These are private, and will |
| 495 | // have accessors (below). |
| 496 | #define LANGOPT(Name, Bits, Default, Description) |
| 497 | #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ |
| 498 | LLVM_PREFERRED_TYPE(Type) \ |
| 499 | unsigned Name : Bits; |
| 500 | #include "clang/Basic/LangOptions.def" |
| 501 | }; |
| 502 | |
| 503 | /// Keeps track of the various options that can be |
| 504 | /// enabled, which controls the dialect of C or C++ that is accepted. |
| 505 | class LangOptions : public LangOptionsBase { |
| 506 | public: |
| 507 | /// The used language standard. |
| 508 | LangStandard::Kind LangStd; |
| 509 | |
| 510 | /// Set of enabled sanitizers. |
| 511 | SanitizerSet Sanitize; |
| 512 | /// Is at least one coverage instrumentation type enabled. |
| 513 | bool SanitizeCoverage = false; |
| 514 | |
| 515 | /// Paths to files specifying which objects |
| 516 | /// (files, functions, variables) should not be instrumented. |
| 517 | std::vector<std::string> NoSanitizeFiles; |
| 518 | |
| 519 | /// Paths to the XRay "always instrument" files specifying which |
| 520 | /// objects (files, functions, variables) should be imbued with the XRay |
| 521 | /// "always instrument" attribute. |
| 522 | /// WARNING: This is a deprecated field and will go away in the future. |
| 523 | std::vector<std::string> XRayAlwaysInstrumentFiles; |
| 524 | |
| 525 | /// Paths to the XRay "never instrument" files specifying which |
| 526 | /// objects (files, functions, variables) should be imbued with the XRay |
| 527 | /// "never instrument" attribute. |
| 528 | /// WARNING: This is a deprecated field and will go away in the future. |
| 529 | std::vector<std::string> XRayNeverInstrumentFiles; |
| 530 | |
| 531 | /// Paths to the XRay attribute list files, specifying which objects |
| 532 | /// (files, functions, variables) should be imbued with the appropriate XRay |
| 533 | /// attribute(s). |
| 534 | std::vector<std::string> XRayAttrListFiles; |
| 535 | |
| 536 | /// Paths to special case list files specifying which entities |
| 537 | /// (files, functions) should or should not be instrumented. |
| 538 | std::vector<std::string> ProfileListFiles; |
| 539 | |
| 540 | clang::ObjCRuntime ObjCRuntime; |
| 541 | |
| 542 | CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified; |
| 543 | |
| 544 | std::string ObjCConstantStringClass; |
| 545 | |
| 546 | /// The name of the handler function to be called when -ftrapv is |
| 547 | /// specified. |
| 548 | /// |
| 549 | /// If none is specified, abort (GCC-compatible behaviour). |
| 550 | std::string OverflowHandler; |
| 551 | |
| 552 | /// The module currently being compiled as specified by -fmodule-name. |
| 553 | std::string ModuleName; |
| 554 | |
| 555 | /// The name of the current module, of which the main source file |
| 556 | /// is a part. If CompilingModule is set, we are compiling the interface |
| 557 | /// of this module, otherwise we are compiling an implementation file of |
| 558 | /// it. This starts as ModuleName in case -fmodule-name is provided and |
| 559 | /// changes during compilation to reflect the current module. |
| 560 | std::string CurrentModule; |
| 561 | |
| 562 | /// The names of any features to enable in module 'requires' decls |
| 563 | /// in addition to the hard-coded list in Module.cpp and the target features. |
| 564 | /// |
| 565 | /// This list is sorted. |
| 566 | std::vector<std::string> ModuleFeatures; |
| 567 | |
| 568 | /// Options for parsing comments. |
| 569 | CommentOptions ; |
| 570 | |
| 571 | /// A list of all -fno-builtin-* function names (e.g., memset). |
| 572 | std::vector<std::string> NoBuiltinFuncs; |
| 573 | |
| 574 | /// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE(). |
| 575 | std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap; |
| 576 | |
| 577 | /// Triples of the OpenMP targets that the host code codegen should |
| 578 | /// take into account in order to generate accurate offloading descriptors. |
| 579 | std::vector<llvm::Triple> OMPTargetTriples; |
| 580 | |
| 581 | /// Name of the IR file that contains the result of the OpenMP target |
| 582 | /// host code generation. |
| 583 | std::string OMPHostIRFile; |
| 584 | |
| 585 | /// The user provided compilation unit ID, if non-empty. This is used to |
| 586 | /// externalize static variables which is needed to support accessing static |
| 587 | /// device variables in host code for single source offloading languages |
| 588 | /// like CUDA/HIP. |
| 589 | std::string CUID; |
| 590 | |
| 591 | /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=. |
| 592 | /// This overrides the default ABI used by the target. |
| 593 | std::optional<TargetCXXABI::Kind> CXXABI; |
| 594 | |
| 595 | /// Indicates whether the front-end is explicitly told that the |
| 596 | /// input is a header file (i.e. -x c-header). |
| 597 | bool = false; |
| 598 | |
| 599 | /// The default stream kind used for HIP kernel launching. |
| 600 | GPUDefaultStreamKind GPUDefaultStream; |
| 601 | |
| 602 | /// Which overflow patterns should be excluded from sanitizer instrumentation |
| 603 | unsigned OverflowPatternExclusionMask = 0; |
| 604 | |
| 605 | std::vector<std::string> OverflowPatternExclusionValues; |
| 606 | |
| 607 | /// The seed used by the randomize structure layout feature. |
| 608 | std::string RandstructSeed; |
| 609 | |
| 610 | /// Indicates whether to use target's platform-specific file separator when |
| 611 | /// __FILE__ macro is used and when concatenating filename with directory or |
| 612 | /// to use build environment environment's platform-specific file separator. |
| 613 | /// |
| 614 | /// The plaform-specific path separator is the backslash(\) for Windows and |
| 615 | /// forward slash (/) elsewhere. |
| 616 | bool UseTargetPathSeparator = false; |
| 617 | |
| 618 | // Indicates whether we should keep all nullptr checks for pointers |
| 619 | // received as a result of a standard operator new (-fcheck-new) |
| 620 | bool CheckNew = false; |
| 621 | |
| 622 | // In OpenACC mode, contains a user provided override for the _OPENACC macro. |
| 623 | // This exists so that we can override the macro value and test our incomplete |
| 624 | // implementation on real-world examples. |
| 625 | std::string OpenACCMacroOverride; |
| 626 | |
| 627 | /// The HLSL root signature version for dxil. |
| 628 | llvm::dxbc::RootSignatureVersion HLSLRootSigVer = |
| 629 | llvm::dxbc::RootSignatureVersion::V1_1; |
| 630 | |
| 631 | // Indicates if the wasm-opt binary must be ignored in the case of a |
| 632 | // WebAssembly target. |
| 633 | bool NoWasmOpt = false; |
| 634 | |
| 635 | /// Atomic code-generation options. |
| 636 | /// These flags are set directly from the command-line options. |
| 637 | bool AtomicRemoteMemory = false; |
| 638 | bool AtomicFineGrainedMemory = false; |
| 639 | bool AtomicIgnoreDenormalMode = false; |
| 640 | |
| 641 | LangOptions(); |
| 642 | |
| 643 | /// Set language defaults for the given input language and |
| 644 | /// language standard in the given LangOptions object. |
| 645 | /// |
| 646 | /// \param Opts - The LangOptions object to set up. |
| 647 | /// \param Lang - The input language. |
| 648 | /// \param T - The target triple. |
| 649 | /// \param Includes - If the language requires extra headers to be implicitly |
| 650 | /// included, they will be appended to this list. |
| 651 | /// \param LangStd - The input language standard. |
| 652 | static void |
| 653 | setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T, |
| 654 | std::vector<std::string> &Includes, |
| 655 | LangStandard::Kind LangStd = LangStandard::lang_unspecified); |
| 656 | |
| 657 | // Define accessors/mutators for language options of enumeration type. |
| 658 | #define LANGOPT(Name, Bits, Default, Description) |
| 659 | #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ |
| 660 | Type get##Name() const { return static_cast<Type>(Name); } \ |
| 661 | void set##Name(Type Value) { \ |
| 662 | assert(static_cast<unsigned>(Value) < (1u << Bits)); \ |
| 663 | Name = static_cast<unsigned>(Value); \ |
| 664 | } |
| 665 | #include "clang/Basic/LangOptions.def" |
| 666 | |
| 667 | /// Are we compiling a module? |
| 668 | bool isCompilingModule() const { |
| 669 | return getCompilingModule() != CMK_None; |
| 670 | } |
| 671 | |
| 672 | /// Are we compiling a module implementation? |
| 673 | bool isCompilingModuleImplementation() const { |
| 674 | return !isCompilingModule() && !ModuleName.empty(); |
| 675 | } |
| 676 | |
| 677 | /// Do we need to track the owning module for a local declaration? |
| 678 | bool trackLocalOwningModule() const { |
| 679 | return isCompilingModule() || ModulesLocalVisibility; |
| 680 | } |
| 681 | |
| 682 | bool isSignedOverflowDefined() const { |
| 683 | return getSignedOverflowBehavior() == SOB_Defined; |
| 684 | } |
| 685 | |
| 686 | bool isSubscriptPointerArithmetic() const { |
| 687 | return ObjCRuntime.isSubscriptPointerArithmetic() && |
| 688 | !ObjCSubscriptingLegacyRuntime; |
| 689 | } |
| 690 | |
| 691 | bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { |
| 692 | return MSCompatibilityVersion >= MajorVersion * 100000U; |
| 693 | } |
| 694 | |
| 695 | bool isOverflowPatternExcluded(OverflowPatternExclusionKind Kind) const { |
| 696 | if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::None) |
| 697 | return false; |
| 698 | if (OverflowPatternExclusionMask & OverflowPatternExclusionKind::All) |
| 699 | return true; |
| 700 | return OverflowPatternExclusionMask & Kind; |
| 701 | } |
| 702 | |
| 703 | /// Reset all of the options that are not considered when building a |
| 704 | /// module. |
| 705 | void resetNonModularOptions(); |
| 706 | |
| 707 | /// Is this a libc/libm function that is no longer recognized as a |
| 708 | /// builtin because a -fno-builtin-* option has been specified? |
| 709 | bool isNoBuiltinFunc(StringRef Name) const; |
| 710 | |
| 711 | /// True if any ObjC types may have non-trivial lifetime qualifiers. |
| 712 | bool allowsNonTrivialObjCLifetimeQualifiers() const { |
| 713 | return ObjCAutoRefCount || ObjCWeak; |
| 714 | } |
| 715 | |
| 716 | bool assumeFunctionsAreConvergent() const { |
| 717 | return ConvergentFunctions; |
| 718 | } |
| 719 | |
| 720 | /// Return true if atomicrmw operations targeting allocations in private |
| 721 | /// memory are undefined. |
| 722 | bool threadPrivateMemoryAtomicsAreUndefined() const { |
| 723 | // Should be false for OpenMP. |
| 724 | // TODO: Should this be true for SYCL? |
| 725 | return OpenCL || CUDA; |
| 726 | } |
| 727 | |
| 728 | /// Return the OpenCL C or C++ version as a VersionTuple. |
| 729 | VersionTuple getOpenCLVersionTuple() const; |
| 730 | |
| 731 | /// Return the OpenCL version that kernel language is compatible with |
| 732 | unsigned getOpenCLCompatibleVersion() const; |
| 733 | |
| 734 | /// Return the OpenCL C or C++ for OpenCL language name and version |
| 735 | /// as a string. |
| 736 | std::string getOpenCLVersionString() const; |
| 737 | |
| 738 | /// Returns true if functions without prototypes or functions with an |
| 739 | /// identifier list (aka K&R C functions) are not allowed. |
| 740 | bool requiresStrictPrototypes() const { |
| 741 | return CPlusPlus || C23 || DisableKNRFunctions; |
| 742 | } |
| 743 | |
| 744 | /// Returns true if implicit function declarations are allowed in the current |
| 745 | /// language mode. |
| 746 | bool implicitFunctionsAllowed() const { |
| 747 | return !requiresStrictPrototypes() && !OpenCL; |
| 748 | } |
| 749 | |
| 750 | /// Returns true if the language supports calling the 'atexit' function. |
| 751 | bool hasAtExit() const { return !(OpenMP && OpenMPIsTargetDevice); } |
| 752 | |
| 753 | /// Returns true if implicit int is part of the language requirements. |
| 754 | bool isImplicitIntRequired() const { return !CPlusPlus && !C99; } |
| 755 | |
| 756 | /// Returns true if implicit int is supported at all. |
| 757 | bool isImplicitIntAllowed() const { return !CPlusPlus && !C23; } |
| 758 | |
| 759 | /// Check if return address signing is enabled. |
| 760 | bool hasSignReturnAddress() const { |
| 761 | return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; |
| 762 | } |
| 763 | |
| 764 | /// Check if return address signing uses AKey. |
| 765 | bool isSignReturnAddressWithAKey() const { |
| 766 | return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; |
| 767 | } |
| 768 | |
| 769 | /// Check if leaf functions are also signed. |
| 770 | bool isSignReturnAddressScopeAll() const { |
| 771 | return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; |
| 772 | } |
| 773 | |
| 774 | bool hasSjLjExceptions() const { |
| 775 | return getExceptionHandling() == ExceptionHandlingKind::SjLj; |
| 776 | } |
| 777 | |
| 778 | bool hasSEHExceptions() const { |
| 779 | return getExceptionHandling() == ExceptionHandlingKind::WinEH; |
| 780 | } |
| 781 | |
| 782 | bool hasDWARFExceptions() const { |
| 783 | return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI; |
| 784 | } |
| 785 | |
| 786 | bool hasWasmExceptions() const { |
| 787 | return getExceptionHandling() == ExceptionHandlingKind::Wasm; |
| 788 | } |
| 789 | |
| 790 | bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; } |
| 791 | |
| 792 | bool hasDefaultVisibilityExportMapping() const { |
| 793 | return getDefaultVisibilityExportMapping() != |
| 794 | DefaultVisiblityExportMapping::None; |
| 795 | } |
| 796 | |
| 797 | bool isExplicitDefaultVisibilityExportMapping() const { |
| 798 | return getDefaultVisibilityExportMapping() == |
| 799 | DefaultVisiblityExportMapping::Explicit; |
| 800 | } |
| 801 | |
| 802 | bool isAllDefaultVisibilityExportMapping() const { |
| 803 | return getDefaultVisibilityExportMapping() == |
| 804 | DefaultVisiblityExportMapping::All; |
| 805 | } |
| 806 | |
| 807 | bool hasGlobalAllocationFunctionVisibility() const { |
| 808 | return getGlobalAllocationFunctionVisibility() != |
| 809 | VisibilityForcedKinds::Source; |
| 810 | } |
| 811 | |
| 812 | bool hasDefaultGlobalAllocationFunctionVisibility() const { |
| 813 | return getGlobalAllocationFunctionVisibility() == |
| 814 | VisibilityForcedKinds::ForceDefault; |
| 815 | } |
| 816 | |
| 817 | bool hasProtectedGlobalAllocationFunctionVisibility() const { |
| 818 | return getGlobalAllocationFunctionVisibility() == |
| 819 | VisibilityForcedKinds::ForceProtected; |
| 820 | } |
| 821 | |
| 822 | bool hasHiddenGlobalAllocationFunctionVisibility() const { |
| 823 | return getGlobalAllocationFunctionVisibility() == |
| 824 | VisibilityForcedKinds::ForceHidden; |
| 825 | } |
| 826 | |
| 827 | bool allowArrayReturnTypes() const { return HLSL; } |
| 828 | |
| 829 | /// Remap path prefix according to -fmacro-prefix-path option. |
| 830 | void remapPathPrefix(SmallVectorImpl<char> &Path) const; |
| 831 | |
| 832 | RoundingMode getDefaultRoundingMode() const { |
| 833 | return RoundingMath ? RoundingMode::Dynamic |
| 834 | : RoundingMode::NearestTiesToEven; |
| 835 | } |
| 836 | |
| 837 | FPExceptionModeKind getDefaultExceptionMode() const { |
| 838 | FPExceptionModeKind EM = getFPExceptionMode(); |
| 839 | if (EM == FPExceptionModeKind::FPE_Default) |
| 840 | return FPExceptionModeKind::FPE_Ignore; |
| 841 | return EM; |
| 842 | } |
| 843 | |
| 844 | /// True when compiling for an offloading target device. |
| 845 | bool isTargetDevice() const { |
| 846 | return OpenMPIsTargetDevice || CUDAIsDevice || SYCLIsDevice; |
| 847 | } |
| 848 | }; |
| 849 | |
| 850 | /// Floating point control options |
| 851 | class FPOptionsOverride; |
| 852 | class FPOptions { |
| 853 | public: |
| 854 | // We start by defining the layout. |
| 855 | using storage_type = uint32_t; |
| 856 | |
| 857 | using RoundingMode = llvm::RoundingMode; |
| 858 | |
| 859 | static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type); |
| 860 | |
| 861 | // Define a fake option named "First" so that we have a PREVIOUS even for the |
| 862 | // real first option. |
| 863 | static constexpr storage_type FirstShift = 0, FirstWidth = 0; |
| 864 | #define FP_OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
| 865 | static constexpr storage_type NAME##Shift = \ |
| 866 | PREVIOUS##Shift + PREVIOUS##Width; \ |
| 867 | static constexpr storage_type NAME##Width = WIDTH; \ |
| 868 | static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \ |
| 869 | << NAME##Shift; |
| 870 | #include "clang/Basic/FPOptions.def" |
| 871 | |
| 872 | static constexpr storage_type TotalWidth = 0 |
| 873 | #define FP_OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH |
| 874 | #include "clang/Basic/FPOptions.def" |
| 875 | ; |
| 876 | static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions" ); |
| 877 | |
| 878 | private: |
| 879 | storage_type Value; |
| 880 | |
| 881 | FPOptionsOverride getChangesSlow(const FPOptions &Base) const; |
| 882 | |
| 883 | public: |
| 884 | FPOptions() : Value(0) { |
| 885 | setFPContractMode(LangOptions::FPM_Off); |
| 886 | setConstRoundingMode(RoundingMode::Dynamic); |
| 887 | setSpecifiedExceptionMode(LangOptions::FPE_Default); |
| 888 | } |
| 889 | explicit FPOptions(const LangOptions &LO) { |
| 890 | Value = 0; |
| 891 | // The language fp contract option FPM_FastHonorPragmas has the same effect |
| 892 | // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in |
| 893 | // frontend. |
| 894 | auto LangOptContractMode = LO.getDefaultFPContractMode(); |
| 895 | if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas) |
| 896 | LangOptContractMode = LangOptions::FPM_Fast; |
| 897 | setFPContractMode(LangOptContractMode); |
| 898 | setRoundingMath(LO.RoundingMath); |
| 899 | setConstRoundingMode(LangOptions::RoundingMode::Dynamic); |
| 900 | setSpecifiedExceptionMode(LO.getFPExceptionMode()); |
| 901 | setAllowFPReassociate(LO.AllowFPReassoc); |
| 902 | setNoHonorNaNs(LO.NoHonorNaNs); |
| 903 | setNoHonorInfs(LO.NoHonorInfs); |
| 904 | setNoSignedZero(LO.NoSignedZero); |
| 905 | setAllowReciprocal(LO.AllowRecip); |
| 906 | setAllowApproxFunc(LO.ApproxFunc); |
| 907 | if (getFPContractMode() == LangOptions::FPM_On && |
| 908 | getRoundingMode() == llvm::RoundingMode::Dynamic && |
| 909 | getExceptionMode() == LangOptions::FPE_Strict) |
| 910 | // If the FP settings are set to the "strict" model, then |
| 911 | // FENV access is set to true. (ffp-model=strict) |
| 912 | setAllowFEnvAccess(true); |
| 913 | else |
| 914 | setAllowFEnvAccess(LangOptions::FPM_Off); |
| 915 | setComplexRange(LO.getComplexRange()); |
| 916 | } |
| 917 | |
| 918 | bool allowFPContractWithinStatement() const { |
| 919 | return getFPContractMode() == LangOptions::FPM_On; |
| 920 | } |
| 921 | void setAllowFPContractWithinStatement() { |
| 922 | setFPContractMode(LangOptions::FPM_On); |
| 923 | } |
| 924 | |
| 925 | bool allowFPContractAcrossStatement() const { |
| 926 | return getFPContractMode() == LangOptions::FPM_Fast; |
| 927 | } |
| 928 | void setAllowFPContractAcrossStatement() { |
| 929 | setFPContractMode(LangOptions::FPM_Fast); |
| 930 | } |
| 931 | |
| 932 | bool isFPConstrained() const { |
| 933 | return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven || |
| 934 | getExceptionMode() != LangOptions::FPE_Ignore || |
| 935 | getAllowFEnvAccess(); |
| 936 | } |
| 937 | |
| 938 | RoundingMode getRoundingMode() const { |
| 939 | RoundingMode RM = getConstRoundingMode(); |
| 940 | if (RM == RoundingMode::Dynamic) { |
| 941 | // C23: 7.6.2p3 If the FE_DYNAMIC mode is specified and FENV_ACCESS is |
| 942 | // "off", the translator may assume that the default rounding mode is in |
| 943 | // effect. |
| 944 | if (!getAllowFEnvAccess() && !getRoundingMath()) |
| 945 | RM = RoundingMode::NearestTiesToEven; |
| 946 | } |
| 947 | return RM; |
| 948 | } |
| 949 | |
| 950 | LangOptions::FPExceptionModeKind getExceptionMode() const { |
| 951 | LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode(); |
| 952 | if (EM == LangOptions::FPExceptionModeKind::FPE_Default) { |
| 953 | if (getAllowFEnvAccess()) |
| 954 | return LangOptions::FPExceptionModeKind::FPE_Strict; |
| 955 | else |
| 956 | return LangOptions::FPExceptionModeKind::FPE_Ignore; |
| 957 | } |
| 958 | return EM; |
| 959 | } |
| 960 | |
| 961 | bool operator==(FPOptions other) const { return Value == other.Value; } |
| 962 | |
| 963 | /// Return the default value of FPOptions that's used when trailing |
| 964 | /// storage isn't required. |
| 965 | static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO); |
| 966 | |
| 967 | storage_type getAsOpaqueInt() const { return Value; } |
| 968 | static FPOptions getFromOpaqueInt(storage_type Value) { |
| 969 | FPOptions Opts; |
| 970 | Opts.Value = Value; |
| 971 | return Opts; |
| 972 | } |
| 973 | |
| 974 | /// Return difference with the given option set. |
| 975 | FPOptionsOverride getChangesFrom(const FPOptions &Base) const; |
| 976 | |
| 977 | void applyChanges(FPOptionsOverride FPO); |
| 978 | |
| 979 | // We can define most of the accessors automatically: |
| 980 | // TODO: consider enforcing the assertion that value fits within bits |
| 981 | // statically. |
| 982 | #define FP_OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
| 983 | TYPE get##NAME() const { \ |
| 984 | return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \ |
| 985 | } \ |
| 986 | void set##NAME(TYPE value) { \ |
| 987 | assert(storage_type(value) < (1u << WIDTH)); \ |
| 988 | Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ |
| 989 | } |
| 990 | #include "clang/Basic/FPOptions.def" |
| 991 | LLVM_DUMP_METHOD void dump(); |
| 992 | }; |
| 993 | |
| 994 | /// Represents difference between two FPOptions values. |
| 995 | /// |
| 996 | /// The effect of language constructs changing the set of floating point options |
| 997 | /// is usually a change of some FP properties while leaving others intact. This |
| 998 | /// class describes such changes by keeping information about what FP options |
| 999 | /// are overridden. |
| 1000 | /// |
| 1001 | /// The integral set of FP options, described by the class FPOptions, may be |
| 1002 | /// represented as a default FP option set, defined by language standard and |
| 1003 | /// command line options, with the overrides introduced by pragmas. |
| 1004 | /// |
| 1005 | /// The is implemented as a value of the new FPOptions plus a mask showing which |
| 1006 | /// fields are actually set in it. |
| 1007 | class FPOptionsOverride { |
| 1008 | FPOptions Options = FPOptions::getFromOpaqueInt(Value: 0); |
| 1009 | FPOptions::storage_type OverrideMask = 0; |
| 1010 | |
| 1011 | public: |
| 1012 | using RoundingMode = llvm::RoundingMode; |
| 1013 | |
| 1014 | /// The type suitable for storing values of FPOptionsOverride. Must be twice |
| 1015 | /// as wide as bit size of FPOption. |
| 1016 | using storage_type = uint64_t; |
| 1017 | static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type), |
| 1018 | "Too short type for FPOptionsOverride" ); |
| 1019 | |
| 1020 | /// Bit mask selecting bits of OverrideMask in serialized representation of |
| 1021 | /// FPOptionsOverride. |
| 1022 | static constexpr storage_type OverrideMaskBits = |
| 1023 | (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1; |
| 1024 | |
| 1025 | FPOptionsOverride() {} |
| 1026 | FPOptionsOverride(const LangOptions &LO) |
| 1027 | : Options(LO), OverrideMask(OverrideMaskBits) {} |
| 1028 | FPOptionsOverride(FPOptions FPO) |
| 1029 | : Options(FPO), OverrideMask(OverrideMaskBits) {} |
| 1030 | FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask) |
| 1031 | : Options(FPO), OverrideMask(Mask) {} |
| 1032 | |
| 1033 | bool requiresTrailingStorage() const { return OverrideMask != 0; } |
| 1034 | |
| 1035 | void setAllowFPContractWithinStatement() { |
| 1036 | setFPContractModeOverride(LangOptions::FPM_On); |
| 1037 | } |
| 1038 | |
| 1039 | void setAllowFPContractAcrossStatement() { |
| 1040 | setFPContractModeOverride(LangOptions::FPM_Fast); |
| 1041 | } |
| 1042 | |
| 1043 | void setDisallowFPContract() { |
| 1044 | setFPContractModeOverride(LangOptions::FPM_Off); |
| 1045 | } |
| 1046 | |
| 1047 | void setFPPreciseEnabled(bool Value) { |
| 1048 | setAllowFPReassociateOverride(!Value); |
| 1049 | setNoHonorNaNsOverride(!Value); |
| 1050 | setNoHonorInfsOverride(!Value); |
| 1051 | setNoSignedZeroOverride(!Value); |
| 1052 | setAllowReciprocalOverride(!Value); |
| 1053 | setAllowApproxFuncOverride(!Value); |
| 1054 | setMathErrnoOverride(Value); |
| 1055 | if (Value) |
| 1056 | /* Precise mode implies fp_contract=on and disables ffast-math */ |
| 1057 | setAllowFPContractWithinStatement(); |
| 1058 | else |
| 1059 | /* Precise mode disabled sets fp_contract=fast and enables ffast-math */ |
| 1060 | setAllowFPContractAcrossStatement(); |
| 1061 | } |
| 1062 | |
| 1063 | void setDisallowOptimizations() { setFPPreciseEnabled(true); } |
| 1064 | |
| 1065 | storage_type getAsOpaqueInt() const { |
| 1066 | return (static_cast<storage_type>(Options.getAsOpaqueInt()) |
| 1067 | << FPOptions::StorageBitSize) | |
| 1068 | OverrideMask; |
| 1069 | } |
| 1070 | static FPOptionsOverride getFromOpaqueInt(storage_type I) { |
| 1071 | FPOptionsOverride Opts; |
| 1072 | Opts.OverrideMask = I & OverrideMaskBits; |
| 1073 | Opts.Options = FPOptions::getFromOpaqueInt(Value: I >> FPOptions::StorageBitSize); |
| 1074 | return Opts; |
| 1075 | } |
| 1076 | |
| 1077 | FPOptions applyOverrides(FPOptions Base) { |
| 1078 | FPOptions Result = |
| 1079 | FPOptions::getFromOpaqueInt(Value: (Base.getAsOpaqueInt() & ~OverrideMask) | |
| 1080 | (Options.getAsOpaqueInt() & OverrideMask)); |
| 1081 | return Result; |
| 1082 | } |
| 1083 | |
| 1084 | FPOptions applyOverrides(const LangOptions &LO) { |
| 1085 | return applyOverrides(Base: FPOptions(LO)); |
| 1086 | } |
| 1087 | |
| 1088 | bool operator==(FPOptionsOverride other) const { |
| 1089 | return Options == other.Options && OverrideMask == other.OverrideMask; |
| 1090 | } |
| 1091 | bool operator!=(FPOptionsOverride other) const { return !(*this == other); } |
| 1092 | |
| 1093 | #define FP_OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
| 1094 | bool has##NAME##Override() const { \ |
| 1095 | return OverrideMask & FPOptions::NAME##Mask; \ |
| 1096 | } \ |
| 1097 | TYPE get##NAME##Override() const { \ |
| 1098 | assert(has##NAME##Override()); \ |
| 1099 | return Options.get##NAME(); \ |
| 1100 | } \ |
| 1101 | void clear##NAME##Override() { \ |
| 1102 | /* Clear the actual value so that we don't have spurious differences when \ |
| 1103 | * testing equality. */ \ |
| 1104 | Options.set##NAME(TYPE(0)); \ |
| 1105 | OverrideMask &= ~FPOptions::NAME##Mask; \ |
| 1106 | } \ |
| 1107 | void set##NAME##Override(TYPE value) { \ |
| 1108 | Options.set##NAME(value); \ |
| 1109 | OverrideMask |= FPOptions::NAME##Mask; \ |
| 1110 | } |
| 1111 | #include "clang/Basic/FPOptions.def" |
| 1112 | LLVM_DUMP_METHOD void dump(); |
| 1113 | }; |
| 1114 | |
| 1115 | inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const { |
| 1116 | if (Value == Base.Value) |
| 1117 | return FPOptionsOverride(); |
| 1118 | return getChangesSlow(Base); |
| 1119 | } |
| 1120 | |
| 1121 | inline void FPOptions::applyChanges(FPOptionsOverride FPO) { |
| 1122 | *this = FPO.applyOverrides(Base: *this); |
| 1123 | } |
| 1124 | |
| 1125 | // The three atomic code-generation options. |
| 1126 | // The canonical (positive) names are: |
| 1127 | // "remote_memory", "fine_grained_memory", and "ignore_denormal_mode". |
| 1128 | // In attribute or command-line parsing, a token prefixed with "no_" inverts its |
| 1129 | // value. |
| 1130 | enum class AtomicOptionKind { |
| 1131 | RemoteMemory, // enable remote memory. |
| 1132 | FineGrainedMemory, // enable fine-grained memory. |
| 1133 | IgnoreDenormalMode, // ignore floating-point denormals. |
| 1134 | LANGOPT_ATOMIC_OPTION_LAST = IgnoreDenormalMode, |
| 1135 | }; |
| 1136 | |
| 1137 | struct AtomicOptions { |
| 1138 | // Bitfields for each option. |
| 1139 | unsigned remote_memory : 1; |
| 1140 | unsigned fine_grained_memory : 1; |
| 1141 | unsigned ignore_denormal_mode : 1; |
| 1142 | |
| 1143 | AtomicOptions() |
| 1144 | : remote_memory(0), fine_grained_memory(0), ignore_denormal_mode(0) {} |
| 1145 | |
| 1146 | AtomicOptions(const LangOptions &LO) |
| 1147 | : remote_memory(LO.AtomicRemoteMemory), |
| 1148 | fine_grained_memory(LO.AtomicFineGrainedMemory), |
| 1149 | ignore_denormal_mode(LO.AtomicIgnoreDenormalMode) {} |
| 1150 | |
| 1151 | bool getOption(AtomicOptionKind Kind) const { |
| 1152 | switch (Kind) { |
| 1153 | case AtomicOptionKind::RemoteMemory: |
| 1154 | return remote_memory; |
| 1155 | case AtomicOptionKind::FineGrainedMemory: |
| 1156 | return fine_grained_memory; |
| 1157 | case AtomicOptionKind::IgnoreDenormalMode: |
| 1158 | return ignore_denormal_mode; |
| 1159 | } |
| 1160 | llvm_unreachable("Invalid AtomicOptionKind" ); |
| 1161 | } |
| 1162 | |
| 1163 | void setOption(AtomicOptionKind Kind, bool Value) { |
| 1164 | switch (Kind) { |
| 1165 | case AtomicOptionKind::RemoteMemory: |
| 1166 | remote_memory = Value; |
| 1167 | return; |
| 1168 | case AtomicOptionKind::FineGrainedMemory: |
| 1169 | fine_grained_memory = Value; |
| 1170 | return; |
| 1171 | case AtomicOptionKind::IgnoreDenormalMode: |
| 1172 | ignore_denormal_mode = Value; |
| 1173 | return; |
| 1174 | } |
| 1175 | llvm_unreachable("Invalid AtomicOptionKind" ); |
| 1176 | } |
| 1177 | |
| 1178 | LLVM_DUMP_METHOD void dump() const { |
| 1179 | llvm::errs() << "\n remote_memory: " << remote_memory |
| 1180 | << "\n fine_grained_memory: " << fine_grained_memory |
| 1181 | << "\n ignore_denormal_mode: " << ignore_denormal_mode << "\n" ; |
| 1182 | } |
| 1183 | }; |
| 1184 | |
| 1185 | /// Describes the kind of translation unit being processed. |
| 1186 | enum TranslationUnitKind { |
| 1187 | /// The translation unit is a complete translation unit. |
| 1188 | TU_Complete, |
| 1189 | |
| 1190 | /// The translation unit is a prefix to a translation unit, and is |
| 1191 | /// not complete. |
| 1192 | TU_Prefix, |
| 1193 | |
| 1194 | /// The translation unit is a clang module. |
| 1195 | TU_ClangModule, |
| 1196 | |
| 1197 | /// The translation unit is a is a complete translation unit that we might |
| 1198 | /// incrementally extend later. |
| 1199 | TU_Incremental |
| 1200 | }; |
| 1201 | |
| 1202 | } // namespace clang |
| 1203 | |
| 1204 | #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H |
| 1205 | |