Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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 <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 the __FILE__ macro should use the target's |
||
| 483 | /// platform-specific file separator or whether it should use the build |
||
| 484 | /// 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 | LangOptions(); |
||
| 491 | |||
| 492 | /// Set language defaults for the given input language and |
||
| 493 | /// language standard in the given LangOptions object. |
||
| 494 | /// |
||
| 495 | /// \param Opts - The LangOptions object to set up. |
||
| 496 | /// \param Lang - The input language. |
||
| 497 | /// \param T - The target triple. |
||
| 498 | /// \param Includes - If the language requires extra headers to be implicitly |
||
| 499 | /// included, they will be appended to this list. |
||
| 500 | /// \param LangStd - The input language standard. |
||
| 501 | static void |
||
| 502 | setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T, |
||
| 503 | std::vector<std::string> &Includes, |
||
| 504 | LangStandard::Kind LangStd = LangStandard::lang_unspecified); |
||
| 505 | |||
| 506 | // Define accessors/mutators for language options of enumeration type. |
||
| 507 | #define LANGOPT(Name, Bits, Default, Description) |
||
| 508 | #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \ |
||
| 509 | Type get##Name() const { return static_cast<Type>(Name); } \ |
||
| 510 | void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } |
||
| 511 | #include "clang/Basic/LangOptions.def" |
||
| 512 | |||
| 513 | /// Are we compiling a module? |
||
| 514 | bool isCompilingModule() const { |
||
| 515 | return getCompilingModule() != CMK_None; |
||
| 516 | } |
||
| 517 | |||
| 518 | /// Are we compiling a standard c++ module interface? |
||
| 519 | bool isCompilingModuleInterface() const { |
||
| 520 | return getCompilingModule() == CMK_ModuleInterface; |
||
| 521 | } |
||
| 522 | |||
| 523 | /// Are we compiling a module implementation? |
||
| 524 | bool isCompilingModuleImplementation() const { |
||
| 525 | return !isCompilingModule() && !ModuleName.empty(); |
||
| 526 | } |
||
| 527 | |||
| 528 | /// Do we need to track the owning module for a local declaration? |
||
| 529 | bool trackLocalOwningModule() const { |
||
| 530 | return isCompilingModule() || ModulesLocalVisibility; |
||
| 531 | } |
||
| 532 | |||
| 533 | bool isSignedOverflowDefined() const { |
||
| 534 | return getSignedOverflowBehavior() == SOB_Defined; |
||
| 535 | } |
||
| 536 | |||
| 537 | bool isSubscriptPointerArithmetic() const { |
||
| 538 | return ObjCRuntime.isSubscriptPointerArithmetic() && |
||
| 539 | !ObjCSubscriptingLegacyRuntime; |
||
| 540 | } |
||
| 541 | |||
| 542 | bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const { |
||
| 543 | return MSCompatibilityVersion >= MajorVersion * 100000U; |
||
| 544 | } |
||
| 545 | |||
| 546 | /// Reset all of the options that are not considered when building a |
||
| 547 | /// module. |
||
| 548 | void resetNonModularOptions(); |
||
| 549 | |||
| 550 | /// Is this a libc/libm function that is no longer recognized as a |
||
| 551 | /// builtin because a -fno-builtin-* option has been specified? |
||
| 552 | bool isNoBuiltinFunc(StringRef Name) const; |
||
| 553 | |||
| 554 | /// True if any ObjC types may have non-trivial lifetime qualifiers. |
||
| 555 | bool allowsNonTrivialObjCLifetimeQualifiers() const { |
||
| 556 | return ObjCAutoRefCount || ObjCWeak; |
||
| 557 | } |
||
| 558 | |||
| 559 | bool assumeFunctionsAreConvergent() const { |
||
| 560 | return ConvergentFunctions; |
||
| 561 | } |
||
| 562 | |||
| 563 | /// Return the OpenCL C or C++ version as a VersionTuple. |
||
| 564 | VersionTuple getOpenCLVersionTuple() const; |
||
| 565 | |||
| 566 | /// Return the OpenCL version that kernel language is compatible with |
||
| 567 | unsigned getOpenCLCompatibleVersion() const; |
||
| 568 | |||
| 569 | /// Return the OpenCL C or C++ for OpenCL language name and version |
||
| 570 | /// as a string. |
||
| 571 | std::string getOpenCLVersionString() const; |
||
| 572 | |||
| 573 | /// Returns true if functions without prototypes or functions with an |
||
| 574 | /// identifier list (aka K&R C functions) are not allowed. |
||
| 575 | bool requiresStrictPrototypes() const { |
||
| 576 | return CPlusPlus || C2x || DisableKNRFunctions; |
||
| 577 | } |
||
| 578 | |||
| 579 | /// Returns true if implicit function declarations are allowed in the current |
||
| 580 | /// language mode. |
||
| 581 | bool implicitFunctionsAllowed() const { |
||
| 582 | return !requiresStrictPrototypes() && !OpenCL; |
||
| 583 | } |
||
| 584 | |||
| 585 | /// Returns true if implicit int is part of the language requirements. |
||
| 586 | bool isImplicitIntRequired() const { return !CPlusPlus && !C99; } |
||
| 587 | |||
| 588 | /// Returns true if implicit int is supported at all. |
||
| 589 | bool isImplicitIntAllowed() const { return !CPlusPlus && !C2x; } |
||
| 590 | |||
| 591 | /// Check if return address signing is enabled. |
||
| 592 | bool hasSignReturnAddress() const { |
||
| 593 | return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; |
||
| 594 | } |
||
| 595 | |||
| 596 | /// Check if return address signing uses AKey. |
||
| 597 | bool isSignReturnAddressWithAKey() const { |
||
| 598 | return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; |
||
| 599 | } |
||
| 600 | |||
| 601 | /// Check if leaf functions are also signed. |
||
| 602 | bool isSignReturnAddressScopeAll() const { |
||
| 603 | return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; |
||
| 604 | } |
||
| 605 | |||
| 606 | bool hasSjLjExceptions() const { |
||
| 607 | return getExceptionHandling() == ExceptionHandlingKind::SjLj; |
||
| 608 | } |
||
| 609 | |||
| 610 | bool hasSEHExceptions() const { |
||
| 611 | return getExceptionHandling() == ExceptionHandlingKind::WinEH; |
||
| 612 | } |
||
| 613 | |||
| 614 | bool hasDWARFExceptions() const { |
||
| 615 | return getExceptionHandling() == ExceptionHandlingKind::DwarfCFI; |
||
| 616 | } |
||
| 617 | |||
| 618 | bool hasWasmExceptions() const { |
||
| 619 | return getExceptionHandling() == ExceptionHandlingKind::Wasm; |
||
| 620 | } |
||
| 621 | |||
| 622 | bool isSYCL() const { return SYCLIsDevice || SYCLIsHost; } |
||
| 623 | |||
| 624 | bool hasDefaultVisibilityExportMapping() const { |
||
| 625 | return getDefaultVisibilityExportMapping() != |
||
| 626 | DefaultVisiblityExportMapping::None; |
||
| 627 | } |
||
| 628 | |||
| 629 | bool isExplicitDefaultVisibilityExportMapping() const { |
||
| 630 | return getDefaultVisibilityExportMapping() == |
||
| 631 | DefaultVisiblityExportMapping::Explicit; |
||
| 632 | } |
||
| 633 | |||
| 634 | bool isAllDefaultVisibilityExportMapping() const { |
||
| 635 | return getDefaultVisibilityExportMapping() == |
||
| 636 | DefaultVisiblityExportMapping::All; |
||
| 637 | } |
||
| 638 | |||
| 639 | /// Remap path prefix according to -fmacro-prefix-path option. |
||
| 640 | void remapPathPrefix(SmallVectorImpl<char> &Path) const; |
||
| 641 | |||
| 642 | RoundingMode getDefaultRoundingMode() const { |
||
| 643 | return RoundingMath ? RoundingMode::Dynamic |
||
| 644 | : RoundingMode::NearestTiesToEven; |
||
| 645 | } |
||
| 646 | |||
| 647 | FPExceptionModeKind getDefaultExceptionMode() const { |
||
| 648 | FPExceptionModeKind EM = getFPExceptionMode(); |
||
| 649 | if (EM == FPExceptionModeKind::FPE_Default) |
||
| 650 | return FPExceptionModeKind::FPE_Ignore; |
||
| 651 | return EM; |
||
| 652 | } |
||
| 653 | }; |
||
| 654 | |||
| 655 | /// Floating point control options |
||
| 656 | class FPOptionsOverride; |
||
| 657 | class FPOptions { |
||
| 658 | public: |
||
| 659 | // We start by defining the layout. |
||
| 660 | using storage_type = uint32_t; |
||
| 661 | |||
| 662 | using RoundingMode = llvm::RoundingMode; |
||
| 663 | |||
| 664 | static constexpr unsigned StorageBitSize = 8 * sizeof(storage_type); |
||
| 665 | |||
| 666 | // Define a fake option named "First" so that we have a PREVIOUS even for the |
||
| 667 | // real first option. |
||
| 668 | static constexpr storage_type FirstShift = 0, FirstWidth = 0; |
||
| 669 | #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
||
| 670 | static constexpr storage_type NAME##Shift = \ |
||
| 671 | PREVIOUS##Shift + PREVIOUS##Width; \ |
||
| 672 | static constexpr storage_type NAME##Width = WIDTH; \ |
||
| 673 | static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \ |
||
| 674 | << NAME##Shift; |
||
| 675 | #include "clang/Basic/FPOptions.def" |
||
| 676 | |||
| 677 | static constexpr storage_type TotalWidth = 0 |
||
| 678 | #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) +WIDTH |
||
| 679 | #include "clang/Basic/FPOptions.def" |
||
| 680 | ; |
||
| 681 | static_assert(TotalWidth <= StorageBitSize, "Too short type for FPOptions"); |
||
| 682 | |||
| 683 | private: |
||
| 684 | storage_type Value; |
||
| 685 | |||
| 686 | FPOptionsOverride getChangesSlow(const FPOptions &Base) const; |
||
| 687 | |||
| 688 | public: |
||
| 689 | FPOptions() : Value(0) { |
||
| 690 | setFPContractMode(LangOptions::FPM_Off); |
||
| 691 | setConstRoundingMode(RoundingMode::Dynamic); |
||
| 692 | setSpecifiedExceptionMode(LangOptions::FPE_Default); |
||
| 693 | } |
||
| 694 | explicit FPOptions(const LangOptions &LO) { |
||
| 695 | Value = 0; |
||
| 696 | // The language fp contract option FPM_FastHonorPragmas has the same effect |
||
| 697 | // as FPM_Fast in frontend. For simplicity, use FPM_Fast uniformly in |
||
| 698 | // frontend. |
||
| 699 | auto LangOptContractMode = LO.getDefaultFPContractMode(); |
||
| 700 | if (LangOptContractMode == LangOptions::FPM_FastHonorPragmas) |
||
| 701 | LangOptContractMode = LangOptions::FPM_Fast; |
||
| 702 | setFPContractMode(LangOptContractMode); |
||
| 703 | setRoundingMath(LO.RoundingMath); |
||
| 704 | setConstRoundingMode(LangOptions::RoundingMode::Dynamic); |
||
| 705 | setSpecifiedExceptionMode(LO.getFPExceptionMode()); |
||
| 706 | setAllowFPReassociate(LO.AllowFPReassoc); |
||
| 707 | setNoHonorNaNs(LO.NoHonorNaNs); |
||
| 708 | setNoHonorInfs(LO.NoHonorInfs); |
||
| 709 | setNoSignedZero(LO.NoSignedZero); |
||
| 710 | setAllowReciprocal(LO.AllowRecip); |
||
| 711 | setAllowApproxFunc(LO.ApproxFunc); |
||
| 712 | if (getFPContractMode() == LangOptions::FPM_On && |
||
| 713 | getRoundingMode() == llvm::RoundingMode::Dynamic && |
||
| 714 | getExceptionMode() == LangOptions::FPE_Strict) |
||
| 715 | // If the FP settings are set to the "strict" model, then |
||
| 716 | // FENV access is set to true. (ffp-model=strict) |
||
| 717 | setAllowFEnvAccess(true); |
||
| 718 | else |
||
| 719 | setAllowFEnvAccess(LangOptions::FPM_Off); |
||
| 720 | } |
||
| 721 | |||
| 722 | bool allowFPContractWithinStatement() const { |
||
| 723 | return getFPContractMode() == LangOptions::FPM_On; |
||
| 724 | } |
||
| 725 | void setAllowFPContractWithinStatement() { |
||
| 726 | setFPContractMode(LangOptions::FPM_On); |
||
| 727 | } |
||
| 728 | |||
| 729 | bool allowFPContractAcrossStatement() const { |
||
| 730 | return getFPContractMode() == LangOptions::FPM_Fast; |
||
| 731 | } |
||
| 732 | void setAllowFPContractAcrossStatement() { |
||
| 733 | setFPContractMode(LangOptions::FPM_Fast); |
||
| 734 | } |
||
| 735 | |||
| 736 | bool isFPConstrained() const { |
||
| 737 | return getRoundingMode() != llvm::RoundingMode::NearestTiesToEven || |
||
| 738 | getExceptionMode() != LangOptions::FPE_Ignore || |
||
| 739 | getAllowFEnvAccess(); |
||
| 740 | } |
||
| 741 | |||
| 742 | RoundingMode getRoundingMode() const { |
||
| 743 | RoundingMode RM = getConstRoundingMode(); |
||
| 744 | if (RM == RoundingMode::Dynamic) { |
||
| 745 | // C2x: 7.6.2p3 If the FE_DYNAMIC mode is specified and FENV_ACCESS is |
||
| 746 | // "off", the translator may assume that the default rounding mode is in |
||
| 747 | // effect. |
||
| 748 | if (!getAllowFEnvAccess() && !getRoundingMath()) |
||
| 749 | RM = RoundingMode::NearestTiesToEven; |
||
| 750 | } |
||
| 751 | return RM; |
||
| 752 | } |
||
| 753 | |||
| 754 | LangOptions::FPExceptionModeKind getExceptionMode() const { |
||
| 755 | LangOptions::FPExceptionModeKind EM = getSpecifiedExceptionMode(); |
||
| 756 | if (EM == LangOptions::FPExceptionModeKind::FPE_Default) { |
||
| 757 | if (getAllowFEnvAccess()) |
||
| 758 | return LangOptions::FPExceptionModeKind::FPE_Strict; |
||
| 759 | else |
||
| 760 | return LangOptions::FPExceptionModeKind::FPE_Ignore; |
||
| 761 | } |
||
| 762 | return EM; |
||
| 763 | } |
||
| 764 | |||
| 765 | bool operator==(FPOptions other) const { return Value == other.Value; } |
||
| 766 | |||
| 767 | /// Return the default value of FPOptions that's used when trailing |
||
| 768 | /// storage isn't required. |
||
| 769 | static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO); |
||
| 770 | |||
| 771 | storage_type getAsOpaqueInt() const { return Value; } |
||
| 772 | static FPOptions getFromOpaqueInt(storage_type Value) { |
||
| 773 | FPOptions Opts; |
||
| 774 | Opts.Value = Value; |
||
| 775 | return Opts; |
||
| 776 | } |
||
| 777 | |||
| 778 | /// Return difference with the given option set. |
||
| 779 | FPOptionsOverride getChangesFrom(const FPOptions &Base) const; |
||
| 780 | |||
| 781 | // We can define most of the accessors automatically: |
||
| 782 | #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
||
| 783 | TYPE get##NAME() const { \ |
||
| 784 | return static_cast<TYPE>((Value & NAME##Mask) >> NAME##Shift); \ |
||
| 785 | } \ |
||
| 786 | void set##NAME(TYPE value) { \ |
||
| 787 | Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ |
||
| 788 | } |
||
| 789 | #include "clang/Basic/FPOptions.def" |
||
| 790 | LLVM_DUMP_METHOD void dump(); |
||
| 791 | }; |
||
| 792 | |||
| 793 | /// Represents difference between two FPOptions values. |
||
| 794 | /// |
||
| 795 | /// The effect of language constructs changing the set of floating point options |
||
| 796 | /// is usually a change of some FP properties while leaving others intact. This |
||
| 797 | /// class describes such changes by keeping information about what FP options |
||
| 798 | /// are overridden. |
||
| 799 | /// |
||
| 800 | /// The integral set of FP options, described by the class FPOptions, may be |
||
| 801 | /// represented as a default FP option set, defined by language standard and |
||
| 802 | /// command line options, with the overrides introduced by pragmas. |
||
| 803 | /// |
||
| 804 | /// The is implemented as a value of the new FPOptions plus a mask showing which |
||
| 805 | /// fields are actually set in it. |
||
| 806 | class FPOptionsOverride { |
||
| 807 | FPOptions Options = FPOptions::getFromOpaqueInt(0); |
||
| 808 | FPOptions::storage_type OverrideMask = 0; |
||
| 809 | |||
| 810 | public: |
||
| 811 | using RoundingMode = llvm::RoundingMode; |
||
| 812 | |||
| 813 | /// The type suitable for storing values of FPOptionsOverride. Must be twice |
||
| 814 | /// as wide as bit size of FPOption. |
||
| 815 | using storage_type = uint64_t; |
||
| 816 | static_assert(sizeof(storage_type) >= 2 * sizeof(FPOptions::storage_type), |
||
| 817 | "Too short type for FPOptionsOverride"); |
||
| 818 | |||
| 819 | /// Bit mask selecting bits of OverrideMask in serialized representation of |
||
| 820 | /// FPOptionsOverride. |
||
| 821 | static constexpr storage_type OverrideMaskBits = |
||
| 822 | (static_cast<storage_type>(1) << FPOptions::StorageBitSize) - 1; |
||
| 823 | |||
| 824 | FPOptionsOverride() {} |
||
| 825 | FPOptionsOverride(const LangOptions &LO) |
||
| 826 | : Options(LO), OverrideMask(OverrideMaskBits) {} |
||
| 827 | FPOptionsOverride(FPOptions FPO) |
||
| 828 | : Options(FPO), OverrideMask(OverrideMaskBits) {} |
||
| 829 | FPOptionsOverride(FPOptions FPO, FPOptions::storage_type Mask) |
||
| 830 | : Options(FPO), OverrideMask(Mask) {} |
||
| 831 | |||
| 832 | bool requiresTrailingStorage() const { return OverrideMask != 0; } |
||
| 833 | |||
| 834 | void setAllowFPContractWithinStatement() { |
||
| 835 | setFPContractModeOverride(LangOptions::FPM_On); |
||
| 836 | } |
||
| 837 | |||
| 838 | void setAllowFPContractAcrossStatement() { |
||
| 839 | setFPContractModeOverride(LangOptions::FPM_Fast); |
||
| 840 | } |
||
| 841 | |||
| 842 | void setDisallowFPContract() { |
||
| 843 | setFPContractModeOverride(LangOptions::FPM_Off); |
||
| 844 | } |
||
| 845 | |||
| 846 | void setFPPreciseEnabled(bool Value) { |
||
| 847 | setAllowFPReassociateOverride(!Value); |
||
| 848 | setNoHonorNaNsOverride(!Value); |
||
| 849 | setNoHonorInfsOverride(!Value); |
||
| 850 | setNoSignedZeroOverride(!Value); |
||
| 851 | setAllowReciprocalOverride(!Value); |
||
| 852 | setAllowApproxFuncOverride(!Value); |
||
| 853 | if (Value) |
||
| 854 | /* Precise mode implies fp_contract=on and disables ffast-math */ |
||
| 855 | setAllowFPContractWithinStatement(); |
||
| 856 | else |
||
| 857 | /* Precise mode disabled sets fp_contract=fast and enables ffast-math */ |
||
| 858 | setAllowFPContractAcrossStatement(); |
||
| 859 | } |
||
| 860 | |||
| 861 | storage_type getAsOpaqueInt() const { |
||
| 862 | return (static_cast<storage_type>(Options.getAsOpaqueInt()) |
||
| 863 | << FPOptions::StorageBitSize) | |
||
| 864 | OverrideMask; |
||
| 865 | } |
||
| 866 | static FPOptionsOverride getFromOpaqueInt(storage_type I) { |
||
| 867 | FPOptionsOverride Opts; |
||
| 868 | Opts.OverrideMask = I & OverrideMaskBits; |
||
| 869 | Opts.Options = FPOptions::getFromOpaqueInt(I >> FPOptions::StorageBitSize); |
||
| 870 | return Opts; |
||
| 871 | } |
||
| 872 | |||
| 873 | FPOptions applyOverrides(FPOptions Base) { |
||
| 874 | FPOptions Result = |
||
| 875 | FPOptions::getFromOpaqueInt((Base.getAsOpaqueInt() & ~OverrideMask) | |
||
| 876 | (Options.getAsOpaqueInt() & OverrideMask)); |
||
| 877 | return Result; |
||
| 878 | } |
||
| 879 | |||
| 880 | FPOptions applyOverrides(const LangOptions &LO) { |
||
| 881 | return applyOverrides(FPOptions(LO)); |
||
| 882 | } |
||
| 883 | |||
| 884 | bool operator==(FPOptionsOverride other) const { |
||
| 885 | return Options == other.Options && OverrideMask == other.OverrideMask; |
||
| 886 | } |
||
| 887 | bool operator!=(FPOptionsOverride other) const { return !(*this == other); } |
||
| 888 | |||
| 889 | #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ |
||
| 890 | bool has##NAME##Override() const { \ |
||
| 891 | return OverrideMask & FPOptions::NAME##Mask; \ |
||
| 892 | } \ |
||
| 893 | TYPE get##NAME##Override() const { \ |
||
| 894 | assert(has##NAME##Override()); \ |
||
| 895 | return Options.get##NAME(); \ |
||
| 896 | } \ |
||
| 897 | void clear##NAME##Override() { \ |
||
| 898 | /* Clear the actual value so that we don't have spurious differences when \ |
||
| 899 | * testing equality. */ \ |
||
| 900 | Options.set##NAME(TYPE(0)); \ |
||
| 901 | OverrideMask &= ~FPOptions::NAME##Mask; \ |
||
| 902 | } \ |
||
| 903 | void set##NAME##Override(TYPE value) { \ |
||
| 904 | Options.set##NAME(value); \ |
||
| 905 | OverrideMask |= FPOptions::NAME##Mask; \ |
||
| 906 | } |
||
| 907 | #include "clang/Basic/FPOptions.def" |
||
| 908 | LLVM_DUMP_METHOD void dump(); |
||
| 909 | }; |
||
| 910 | |||
| 911 | inline FPOptionsOverride FPOptions::getChangesFrom(const FPOptions &Base) const { |
||
| 912 | if (Value == Base.Value) |
||
| 913 | return FPOptionsOverride(); |
||
| 914 | return getChangesSlow(Base); |
||
| 915 | } |
||
| 916 | |||
| 917 | /// Describes the kind of translation unit being processed. |
||
| 918 | enum TranslationUnitKind { |
||
| 919 | /// The translation unit is a complete translation unit. |
||
| 920 | TU_Complete, |
||
| 921 | |||
| 922 | /// The translation unit is a prefix to a translation unit, and is |
||
| 923 | /// not complete. |
||
| 924 | TU_Prefix, |
||
| 925 | |||
| 926 | /// The translation unit is a module. |
||
| 927 | TU_Module, |
||
| 928 | |||
| 929 | /// The translation unit is a is a complete translation unit that we might |
||
| 930 | /// incrementally extend later. |
||
| 931 | TU_Incremental |
||
| 932 | }; |
||
| 933 | |||
| 934 | } // namespace clang |
||
| 935 | |||
| 936 | #endif // LLVM_CLANG_BASIC_LANGOPTIONS_H |