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 /// Keeps track of the various options that can be 57 /// enabled, which controls the dialect of C or C++ that is accepted. 58 class LangOptions : public LangOptionsBase { 59 public: 60 using Visibility = clang::Visibility; 61 using RoundingMode = llvm::RoundingMode; 62 63 enum GCMode { NonGC, GCOnly, HybridGC }; 64 enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; 65 66 // Automatic variables live on the stack, and when trivial they're usually 67 // uninitialized because it's undefined behavior to use them without 68 // initializing them. 69 enum class TrivialAutoVarInitKind { Uninitialized, Zero, Pattern }; 70 71 enum SignedOverflowBehaviorTy { 72 // Default C standard behavior. 73 SOB_Undefined, 74 75 // -fwrapv 76 SOB_Defined, 77 78 // -ftrapv 79 SOB_Trapping 80 }; 81 82 // FIXME: Unify with TUKind. 83 enum CompilingModuleKind { 84 /// Not compiling a module interface at all. 85 CMK_None, 86 87 /// Compiling a module from a module map. 88 CMK_ModuleMap, 89 90 /// Compiling a module from a list of header files. 91 CMK_HeaderModule, 92 93 /// Compiling a C++ modules TS module interface unit. 94 CMK_ModuleInterface, 95 }; 96 97 enum PragmaMSPointersToMembersKind { 98 PPTMK_BestCase, 99 PPTMK_FullGeneralitySingleInheritance, 100 PPTMK_FullGeneralityMultipleInheritance, 101 PPTMK_FullGeneralityVirtualInheritance 102 }; 103 104 using MSVtorDispMode = clang::MSVtorDispMode; 105 106 enum DefaultCallingConvention { 107 DCC_None, 108 DCC_CDecl, 109 DCC_FastCall, 110 DCC_StdCall, 111 DCC_VectorCall, 112 DCC_RegCall 113 }; 114 115 enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; 116 117 // Corresponds to _MSC_VER 118 enum MSVCMajorVersion { 119 MSVC2010 = 1600, 120 MSVC2012 = 1700, 121 MSVC2013 = 1800, 122 MSVC2015 = 1900, 123 MSVC2017 = 1910, 124 MSVC2017_5 = 1912, 125 MSVC2017_7 = 1914, 126 MSVC2019 = 1920, 127 MSVC2019_8 = 1928, 128 }; 129 130 enum SYCLMajorVersion { 131 SYCL_None, 132 SYCL_2017, 133 SYCL_2020, 134 // The "default" SYCL version to be used when none is specified on the 135 // frontend command line. 136 SYCL_Default = SYCL_2020 137 }; 138 139 /// Clang versions with different platform ABI conformance. 140 enum class ClangABI { 141 /// Attempt to be ABI-compatible with code generated by Clang 3.8.x 142 /// (SVN r257626). This causes <1 x long long> to be passed in an 143 /// integer register instead of an SSE register on x64_64. 144 Ver3_8, 145 146 /// Attempt to be ABI-compatible with code generated by Clang 4.0.x 147 /// (SVN r291814). This causes move operations to be ignored when 148 /// determining whether a class type can be passed or returned directly. 149 Ver4, 150 151 /// Attempt to be ABI-compatible with code generated by Clang 6.0.x 152 /// (SVN r321711). This causes determination of whether a type is 153 /// standard-layout to ignore collisions between empty base classes 154 /// and between base classes and member subobjects, which affects 155 /// whether we reuse base class tail padding in some ABIs. 156 Ver6, 157 158 /// Attempt to be ABI-compatible with code generated by Clang 7.0.x 159 /// (SVN r338536). This causes alignof (C++) and _Alignof (C11) to be 160 /// compatible with __alignof (i.e., return the preferred alignment) 161 /// rather than returning the required alignment. 162 Ver7, 163 164 /// Attempt to be ABI-compatible with code generated by Clang 9.0.x 165 /// (SVN r351319). This causes vectors of __int128 to be passed in memory 166 /// instead of passing in multiple scalar registers on x86_64 on Linux and 167 /// NetBSD. 168 Ver9, 169 170 /// Attempt to be ABI-compatible with code generated by Clang 11.0.x 171 /// (git 2e10b7a39b93). This causes clang to pass unions with a 256-bit 172 /// vector member on the stack instead of using registers, to not properly 173 /// mangle substitutions for template names in some cases, and to mangle 174 /// declaration template arguments without a cast to the parameter type 175 /// even when that can lead to mangling collisions. 176 Ver11, 177 178 /// Attempt to be ABI-compatible with code generated by Clang 12.0.x 179 /// (git 8e464dd76bef). This causes clang to mangle lambdas within 180 /// global-scope inline variables incorrectly. 181 Ver12, 182 183 /// Conform to the underlying platform's C and C++ ABIs as closely 184 /// as we can. 185 Latest 186 }; 187 188 enum class CoreFoundationABI { 189 /// No interoperability ABI has been specified 190 Unspecified, 191 /// CoreFoundation does not have any language interoperability 192 Standalone, 193 /// Interoperability with the ObjectiveC runtime 194 ObjectiveC, 195 /// Interoperability with the latest known version of the Swift runtime 196 Swift, 197 /// Interoperability with the Swift 5.0 runtime 198 Swift5_0, 199 /// Interoperability with the Swift 4.2 runtime 200 Swift4_2, 201 /// Interoperability with the Swift 4.1 runtime 202 Swift4_1, 203 }; 204 205 enum FPModeKind { 206 // Disable the floating point pragma 207 FPM_Off, 208 209 // Enable the floating point pragma 210 FPM_On, 211 212 // Aggressively fuse FP ops (E.g. FMA) disregarding pragmas. 213 FPM_Fast, 214 215 // Aggressively fuse FP ops and honor pragmas. 216 FPM_FastHonorPragmas 217 }; 218 219 /// Alias for RoundingMode::NearestTiesToEven. 220 static constexpr unsigned FPR_ToNearest = 221 static_cast<unsigned>(llvm::RoundingMode::NearestTiesToEven); 222 223 /// Possible floating point exception behavior. 224 enum FPExceptionModeKind { 225 /// Assume that floating-point exceptions are masked. 226 FPE_Ignore, 227 /// Transformations do not cause new exceptions but may hide some. 228 FPE_MayTrap, 229 /// Strictly preserve the floating-point exception semantics. 230 FPE_Strict 231 }; 232 233 /// Possible exception handling behavior. 234 enum class ExceptionHandlingKind { None, SjLj, WinEH, DwarfCFI, Wasm }; 235 236 enum class LaxVectorConversionKind { 237 /// Permit no implicit vector bitcasts. 238 None, 239 /// Permit vector bitcasts between integer vectors with different numbers 240 /// of elements but the same total bit-width. 241 Integer, 242 /// Permit vector bitcasts between all vectors with the same total 243 /// bit-width. 244 All, 245 }; 246 247 enum class AltivecSrcCompatKind { 248 // All vector compares produce scalars except vector pixel and vector bool. 249 // The types vector pixel and vector bool return vector results. 250 Mixed, 251 // All vector compares produce vector results as in GCC. 252 GCC, 253 // All vector compares produce scalars as in XL. 254 XL, 255 // Default clang behaviour. 256 Default = Mixed, 257 }; 258 259 enum class SignReturnAddressScopeKind { 260 /// No signing for any function. 261 None, 262 /// Sign the return address of functions that spill LR. 263 NonLeaf, 264 /// Sign the return address of all functions, 265 All 266 }; 267 268 enum class SignReturnAddressKeyKind { 269 /// Return address signing uses APIA key. 270 AKey, 271 /// Return address signing uses APIB key. 272 BKey 273 }; 274 275 enum class ThreadModelKind { 276 /// POSIX Threads. 277 POSIX, 278 /// Single Threaded Environment. 279 Single 280 }; 281 282 enum class ExtendArgsKind { 283 /// Integer arguments are sign or zero extended to 32/64 bits 284 /// during default argument promotions. 285 ExtendTo32, 286 ExtendTo64 287 }; 288 289 public: 290 /// The used language standard. 291 LangStandard::Kind LangStd; 292 293 /// Set of enabled sanitizers. 294 SanitizerSet Sanitize; 295 /// Is at least one coverage instrumentation type enabled. 296 bool SanitizeCoverage = false; 297 298 /// Paths to files specifying which objects 299 /// (files, functions, variables) should not be instrumented. 300 std::vector<std::string> NoSanitizeFiles; 301 302 /// Paths to the XRay "always instrument" files specifying which 303 /// objects (files, functions, variables) should be imbued with the XRay 304 /// "always instrument" attribute. 305 /// WARNING: This is a deprecated field and will go away in the future. 306 std::vector<std::string> XRayAlwaysInstrumentFiles; 307 308 /// Paths to the XRay "never instrument" files specifying which 309 /// objects (files, functions, variables) should be imbued with the XRay 310 /// "never instrument" attribute. 311 /// WARNING: This is a deprecated field and will go away in the future. 312 std::vector<std::string> XRayNeverInstrumentFiles; 313 314 /// Paths to the XRay attribute list files, specifying which objects 315 /// (files, functions, variables) should be imbued with the appropriate XRay 316 /// attribute(s). 317 std::vector<std::string> XRayAttrListFiles; 318 319 /// Paths to special case list files specifying which entities 320 /// (files, functions) should or should not be instrumented. 321 std::vector<std::string> ProfileListFiles; 322 323 clang::ObjCRuntime ObjCRuntime; 324 325 CoreFoundationABI CFRuntime = CoreFoundationABI::Unspecified; 326 327 std::string ObjCConstantStringClass; 328 329 /// The name of the handler function to be called when -ftrapv is 330 /// specified. 331 /// 332 /// If none is specified, abort (GCC-compatible behaviour). 333 std::string OverflowHandler; 334 335 /// The module currently being compiled as specified by -fmodule-name. 336 std::string ModuleName; 337 338 /// The name of the current module, of which the main source file 339 /// is a part. If CompilingModule is set, we are compiling the interface 340 /// of this module, otherwise we are compiling an implementation file of 341 /// it. This starts as ModuleName in case -fmodule-name is provided and 342 /// changes during compilation to reflect the current module. 343 std::string CurrentModule; 344 345 /// The names of any features to enable in module 'requires' decls 346 /// in addition to the hard-coded list in Module.cpp and the target features. 347 /// 348 /// This list is sorted. 349 std::vector<std::string> ModuleFeatures; 350 351 /// Options for parsing comments. 352 CommentOptions CommentOpts; 353 354 /// A list of all -fno-builtin-* function names (e.g., memset). 355 std::vector<std::string> NoBuiltinFuncs; 356 357 /// A prefix map for __FILE__, __BASE_FILE__ and __builtin_FILE(). 358 std::map<std::string, std::string, std::greater<std::string>> MacroPrefixMap; 359 360 /// Triples of the OpenMP targets that the host code codegen should 361 /// take into account in order to generate accurate offloading descriptors. 362 std::vector<llvm::Triple> OMPTargetTriples; 363 364 /// Name of the IR file that contains the result of the OpenMP target 365 /// host code generation. 366 std::string OMPHostIRFile; 367 368 /// The user provided compilation unit ID, if non-empty. This is used to 369 /// externalize static variables which is needed to support accessing static 370 /// device variables in host code for single source offloading languages 371 /// like CUDA/HIP. 372 std::string CUID; 373 374 /// C++ ABI to compile with, if specified by the frontend through -fc++-abi=. 375 /// This overrides the default ABI used by the target. 376 llvm::Optional<TargetCXXABI::Kind> CXXABI; 377 378 /// Indicates whether the front-end is explicitly told that the 379 /// input is a header file (i.e. -x c-header). 380 bool IsHeaderFile = false; 381 382 LangOptions(); 383 384 // Define accessors/mutators for language options of enumeration type. 385 #define LANGOPT(Name, Bits, Default, Description) 386 #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ 387 Type get##Name() const { return static_cast<Type>(Name); } \ 388 void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } 389 #include "clang/Basic/LangOptions.def" 390 391 /// Are we compiling a module interface (.cppm or module map)? isCompilingModule()392 bool isCompilingModule() const { 393 return getCompilingModule() != CMK_None; 394 } 395 396 /// Do we need to track the owning module for a local declaration? trackLocalOwningModule()397 bool trackLocalOwningModule() const { 398 return isCompilingModule() || ModulesLocalVisibility; 399 } 400 isSignedOverflowDefined()401 bool isSignedOverflowDefined() const { 402 return getSignedOverflowBehavior() == SOB_Defined; 403 } 404 isSubscriptPointerArithmetic()405 bool isSubscriptPointerArithmetic() const { 406 return ObjCRuntime.isSubscriptPointerArithmetic() && 407 !ObjCSubscriptingLegacyRuntime; 408 } 409 isCompatibleWithMSVC(MSVCMajorVersion MajorVersion)410 bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { 411 return MSCompatibilityVersion >= MajorVersion * 100000U; 412 } 413 414 /// Reset all of the options that are not considered when building a 415 /// module. 416 void resetNonModularOptions(); 417 418 /// Is this a libc/libm function that is no longer recognized as a 419 /// builtin because a -fno-builtin-* option has been specified? 420 bool isNoBuiltinFunc(StringRef Name) const; 421 422 /// True if any ObjC types may have non-trivial lifetime qualifiers. allowsNonTrivialObjCLifetimeQualifiers()423 bool allowsNonTrivialObjCLifetimeQualifiers() const { 424 return ObjCAutoRefCount || ObjCWeak; 425 } 426 assumeFunctionsAreConvergent()427 bool assumeFunctionsAreConvergent() const { 428 return ConvergentFunctions; 429 } 430 431 /// Return the OpenCL C or C++ version as a VersionTuple. 432 VersionTuple getOpenCLVersionTuple() const; 433 434 /// Return the OpenCL version that kernel language is compatible with 435 unsigned getOpenCLCompatibleVersion() const; 436 437 /// Return the OpenCL C or C++ for OpenCL language name and version 438 /// as a string. 439 std::string getOpenCLVersionString() const; 440 441 /// Check if return address signing is enabled. hasSignReturnAddress()442 bool hasSignReturnAddress() const { 443 return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; 444 } 445 446 /// Check if return address signing uses AKey. isSignReturnAddressWithAKey()447 bool isSignReturnAddressWithAKey() const { 448 return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; 449 } 450 451 /// Check if leaf functions are also signed. isSignReturnAddressScopeAll()452 bool isSignReturnAddressScopeAll() const { 453 return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; 454 } 455 hasSjLjExceptions()456 bool hasSjLjExceptions() const { 457 return getExceptionHandling() == ExceptionHandlingKind::SjLj; 458 } 459 hasSEHExceptions()460 bool hasSEHExceptions() const { 461 return getExceptionHandling() == ExceptionHandlingKind::WinEH; 462 } 463 hasDWARFExceptions()464 bool hasDWARFExceptions() const { 465 return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI; 466 } 467 hasWasmExceptions()468 bool hasWasmExceptions() const { 469 return getExceptionHandling() == ExceptionHandlingKind::Wasm; 470 } 471 isSYCL()472 bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; } 473 474 /// Remap path prefix according to -fmacro-prefix-path option. 475 void remapPathPrefix(SmallString<256> &Path) const; 476 }; 477 478 /// Floating point control options 479 class FPOptionsOverride; 480 class FPOptions { 481 public: 482 // We start by defining the layout. 483 using storage_type = uint16_t; 484 485 using RoundingMode = llvm::RoundingMode; 486 487 static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type); 488 489 // Define a fake option named "First" so that we have a PREVIOUS even for the 490 // real first option. 491 static constexpr storage_type FirstShift = 0, FirstWidth = 0; 492 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ 493 static constexpr storage_type NAME##Shift = \ 494 PREVIOUS##Shift + PREVIOUS##Width; \ 495 static constexpr storage_type NAME##Width = WIDTH; \ 496 static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \ 497 << NAME##Shift; 498 #include "clang/Basic/FPOptions.def" 499 500 static constexpr storage_type TotalWidth = 0 501 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH 502 #include "clang/Basic/FPOptions.def" 503 ; 504 static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions"); 505 506 private: 507 storage_type Value; 508 509 public: FPOptions()510 FPOptions() : Value(0) { 511 setFPContractMode(LangOptions::FPM_Off); 512 setRoundingMode(static_cast<RoundingMode>(LangOptions::FPR_ToNearest)); 513 setFPExceptionMode(LangOptions::FPE_Ignore); 514 } FPOptions(const LangOptions & LO)515 explicit FPOptions(const LangOptions &LO) { 516 Value = 0; 517 // The language fp contract option FPM_FastHonorPragmas has the same effect 518 // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in 519 // frontend. 520 auto LangOptContractMode = LO.getDefaultFPContractMode(); 521 if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas) 522 LangOptContractMode = LangOptions::FPM_Fast; 523 setFPContractMode(LangOptContractMode); 524 setRoundingMode(LO.getFPRoundingMode()); 525 setFPExceptionMode(LO.getFPExceptionMode()); 526 setAllowFPReassociate(LO.AllowFPReassoc); 527 setNoHonorNaNs(LO.NoHonorNaNs); 528 setNoHonorInfs(LO.NoHonorInfs); 529 setNoSignedZero(LO.NoSignedZero); 530 setAllowReciprocal(LO.AllowRecip); 531 setAllowApproxFunc(LO.ApproxFunc); 532 if (getFPContractMode() == LangOptions::FPM_On && 533 getRoundingMode() == llvm::RoundingMode::Dynamic && 534 getFPExceptionMode() == LangOptions::FPE_Strict) 535 // If the FP settings are set to the "strict" model, then 536 // FENV access is set to true. (ffp-model=strict) 537 setAllowFEnvAccess(true); 538 else 539 setAllowFEnvAccess(LangOptions::FPM_Off); 540 } 541 allowFPContractWithinStatement()542 bool allowFPContractWithinStatement() const { 543 return getFPContractMode() == LangOptions::FPM_On; 544 } setAllowFPContractWithinStatement()545 void setAllowFPContractWithinStatement() { 546 setFPContractMode(LangOptions::FPM_On); 547 } 548 allowFPContractAcrossStatement()549 bool allowFPContractAcrossStatement() const { 550 return getFPContractMode() == LangOptions::FPM_Fast; 551 } setAllowFPContractAcrossStatement()552 void setAllowFPContractAcrossStatement() { 553 setFPContractMode(LangOptions::FPM_Fast); 554 } 555 isFPConstrained()556 bool isFPConstrained() const { 557 return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven || 558 getFPExceptionMode() != LangOptions::FPE_Ignore || 559 getAllowFEnvAccess(); 560 } 561 562 bool operator==(FPOptions other) const { return Value == other.Value; } 563 564 /// Return the default value of FPOptions that's used when trailing 565 /// storage isn't required. 566 static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO); 567 getAsOpaqueInt()568 storage_type getAsOpaqueInt() const { return Value; } getFromOpaqueInt(storage_type Value)569 static FPOptions getFromOpaqueInt(storage_type Value) { 570 FPOptions Opts; 571 Opts.Value = Value; 572 return Opts; 573 } 574 575 // We can define most of the accessors automatically: 576 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ 577 TYPE get##NAME() const { \ 578 return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \ 579 } \ 580 void set##NAME(TYPE value) { \ 581 Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ 582 } 583 #include "clang/Basic/FPOptions.def" 584 LLVM_DUMP_METHOD void dump(); 585 }; 586 587 /// Represents difference between two FPOptions values. 588 /// 589 /// The effect of language constructs changing the set of floating point options 590 /// is usually a change of some FP properties while leaving others intact. This 591 /// class describes such changes by keeping information about what FP options 592 /// are overridden. 593 /// 594 /// The integral set of FP options, described by the class FPOptions, may be 595 /// represented as a default FP option set, defined by language standard and 596 /// command line options, with the overrides introduced by pragmas. 597 /// 598 /// The is implemented as a value of the new FPOptions plus a mask showing which 599 /// fields are actually set in it. 600 class FPOptionsOverride { 601 FPOptions Options = FPOptions::getFromOpaqueInt(0); 602 FPOptions::storage_type OverrideMask = 0; 603 604 public: 605 using RoundingMode = llvm::RoundingMode; 606 607 /// The type suitable for storing values of FPOptionsOverride. Must be twice 608 /// as wide as bit size of FPOption. 609 using storage_type = uint32_t; 610 static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type), 611 "Too short type for FPOptionsOverride"); 612 613 /// Bit mask selecting bits of OverrideMask in serialized representation of 614 /// FPOptionsOverride. 615 static constexpr storage_type OverrideMaskBits = 616 (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1; 617 FPOptionsOverride()618 FPOptionsOverride() {} FPOptionsOverride(const LangOptions & LO)619 FPOptionsOverride(const LangOptions &LO) 620 : Options(LO), OverrideMask(OverrideMaskBits) {} FPOptionsOverride(FPOptions FPO)621 FPOptionsOverride(FPOptions FPO) 622 : Options(FPO), OverrideMask(OverrideMaskBits) {} 623 requiresTrailingStorage()624 bool requiresTrailingStorage() const { return OverrideMask != 0; } 625 setAllowFPContractWithinStatement()626 void setAllowFPContractWithinStatement() { 627 setFPContractModeOverride(LangOptions::FPM_On); 628 } 629 setAllowFPContractAcrossStatement()630 void setAllowFPContractAcrossStatement() { 631 setFPContractModeOverride(LangOptions::FPM_Fast); 632 } 633 setDisallowFPContract()634 void setDisallowFPContract() { 635 setFPContractModeOverride(LangOptions::FPM_Off); 636 } 637 setFPPreciseEnabled(bool Value)638 void setFPPreciseEnabled(bool Value) { 639 setAllowFPReassociateOverride(!Value); 640 setNoHonorNaNsOverride(!Value); 641 setNoHonorInfsOverride(!Value); 642 setNoSignedZeroOverride(!Value); 643 setAllowReciprocalOverride(!Value); 644 setAllowApproxFuncOverride(!Value); 645 if (Value) 646 /* Precise mode implies fp_contract=on and disables ffast-math */ 647 setAllowFPContractWithinStatement(); 648 else 649 /* Precise mode disabled sets fp_contract=fast and enables ffast-math */ 650 setAllowFPContractAcrossStatement(); 651 } 652 getAsOpaqueInt()653 storage_type getAsOpaqueInt() const { 654 return (static_cast<storage_type>(Options.getAsOpaqueInt()) 655 << FPOptions::StorageBitSize) | 656 OverrideMask; 657 } getFromOpaqueInt(storage_type I)658 static FPOptionsOverride getFromOpaqueInt(storage_type I) { 659 FPOptionsOverride Opts; 660 Opts.OverrideMask = I & OverrideMaskBits; 661 Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize); 662 return Opts; 663 } 664 applyOverrides(FPOptions Base)665 FPOptions applyOverrides(FPOptions Base) { 666 FPOptions Result = 667 FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) | 668 (Options.getAsOpaqueInt() & OverrideMask)); 669 return Result; 670 } 671 applyOverrides(const LangOptions & LO)672 FPOptions applyOverrides(const LangOptions &LO) { 673 return applyOverrides(FPOptions(LO)); 674 } 675 676 bool operator==(FPOptionsOverride other) const { 677 return Options == other.Options && OverrideMask == other.OverrideMask; 678 } 679 bool operator!=(FPOptionsOverride other) const { return !(*this == other); } 680 681 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ 682 bool has##NAME##Override() const { \ 683 return OverrideMask & FPOptions::NAME##Mask; \ 684 } \ 685 TYPE get##NAME##Override() const { \ 686 assert(has##NAME##Override()); \ 687 return Options.get##NAME(); \ 688 } \ 689 void clear##NAME##Override() { \ 690 /* Clear the actual value so that we don't have spurious differences when \ 691 * testing equality. */ \ 692 Options.set##NAME(TYPE(0)); \ 693 OverrideMask &= ~FPOptions::NAME##Mask; \ 694 } \ 695 void set##NAME##Override(TYPE value) { \ 696 Options.set##NAME(value); \ 697 OverrideMask |= FPOptions::NAME##Mask; \ 698 } 699 #include "clang/Basic/FPOptions.def" 700 LLVM_DUMP_METHOD void dump(); 701 }; 702 703 /// Describes the kind of translation unit being processed. 704 enum TranslationUnitKind { 705 /// The translation unit is a complete translation unit. 706 TU_Complete, 707 708 /// The translation unit is a prefix to a translation unit, and is 709 /// not complete. 710 TU_Prefix, 711 712 /// The translation unit is a module. 713 TU_Module, 714 715 /// The translation unit is a is a complete translation unit that we might 716 /// incrementally extend later. 717 TU_Incremental 718 }; 719 720 } // namespace clang 721 722 #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H 723