Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:51

0001 //===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Defines the clang::TargetInfo interface.
0011 ///
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_BASIC_TARGETINFO_H
0015 #define LLVM_CLANG_BASIC_TARGETINFO_H
0016 
0017 #include "clang/Basic/AddressSpaces.h"
0018 #include "clang/Basic/BitmaskEnum.h"
0019 #include "clang/Basic/CFProtectionOptions.h"
0020 #include "clang/Basic/CodeGenOptions.h"
0021 #include "clang/Basic/LLVM.h"
0022 #include "clang/Basic/LangOptions.h"
0023 #include "clang/Basic/Specifiers.h"
0024 #include "clang/Basic/TargetCXXABI.h"
0025 #include "clang/Basic/TargetOptions.h"
0026 #include "llvm/ADT/APFloat.h"
0027 #include "llvm/ADT/APInt.h"
0028 #include "llvm/ADT/APSInt.h"
0029 #include "llvm/ADT/ArrayRef.h"
0030 #include "llvm/ADT/IntrusiveRefCntPtr.h"
0031 #include "llvm/ADT/SmallSet.h"
0032 #include "llvm/ADT/StringMap.h"
0033 #include "llvm/ADT/StringRef.h"
0034 #include "llvm/ADT/StringSet.h"
0035 #include "llvm/Frontend/OpenMP/OMPGridValues.h"
0036 #include "llvm/IR/DerivedTypes.h"
0037 #include "llvm/Support/DataTypes.h"
0038 #include "llvm/Support/Error.h"
0039 #include "llvm/Support/VersionTuple.h"
0040 #include "llvm/TargetParser/Triple.h"
0041 #include <cassert>
0042 #include <optional>
0043 #include <string>
0044 #include <utility>
0045 #include <vector>
0046 
0047 namespace llvm {
0048 struct fltSemantics;
0049 }
0050 
0051 namespace clang {
0052 class DiagnosticsEngine;
0053 class LangOptions;
0054 class CodeGenOptions;
0055 class MacroBuilder;
0056 
0057 /// Contains information gathered from parsing the contents of TargetAttr.
0058 struct ParsedTargetAttr {
0059   std::vector<std::string> Features;
0060   StringRef CPU;
0061   StringRef Tune;
0062   StringRef BranchProtection;
0063   StringRef Duplicate;
0064   bool operator ==(const ParsedTargetAttr &Other) const {
0065     return Duplicate == Other.Duplicate && CPU == Other.CPU &&
0066            Tune == Other.Tune && BranchProtection == Other.BranchProtection &&
0067            Features == Other.Features;
0068   }
0069 };
0070 
0071 namespace Builtin { struct Info; }
0072 
0073 enum class FloatModeKind {
0074   NoFloat = 0,
0075   Half = 1 << 0,
0076   Float = 1 << 1,
0077   Double = 1 << 2,
0078   LongDouble = 1 << 3,
0079   Float128 = 1 << 4,
0080   Ibm128 = 1 << 5,
0081   LLVM_MARK_AS_BITMASK_ENUM(Ibm128)
0082 };
0083 
0084 /// Fields controlling how types are laid out in memory; these may need to
0085 /// be copied for targets like AMDGPU that base their ABIs on an auxiliary
0086 /// CPU target.
0087 struct TransferrableTargetInfo {
0088   unsigned char PointerWidth, PointerAlign;
0089   unsigned char BoolWidth, BoolAlign;
0090   unsigned char ShortWidth, ShortAlign;
0091   unsigned char IntWidth, IntAlign;
0092   unsigned char HalfWidth, HalfAlign;
0093   unsigned char BFloat16Width, BFloat16Align;
0094   unsigned char FloatWidth, FloatAlign;
0095   unsigned char DoubleWidth, DoubleAlign;
0096   unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align, Ibm128Align;
0097   unsigned char LargeArrayMinWidth, LargeArrayAlign;
0098   unsigned char LongWidth, LongAlign;
0099   unsigned char LongLongWidth, LongLongAlign;
0100   unsigned char Int128Align;
0101 
0102   // This is an optional parameter for targets that
0103   // don't use 'LongLongAlign' for '_BitInt' max alignment
0104   std::optional<unsigned> BitIntMaxAlign;
0105 
0106   // Fixed point bit widths
0107   unsigned char ShortAccumWidth, ShortAccumAlign;
0108   unsigned char AccumWidth, AccumAlign;
0109   unsigned char LongAccumWidth, LongAccumAlign;
0110   unsigned char ShortFractWidth, ShortFractAlign;
0111   unsigned char FractWidth, FractAlign;
0112   unsigned char LongFractWidth, LongFractAlign;
0113 
0114   // If true, unsigned fixed point types have the same number of fractional bits
0115   // as their signed counterparts, forcing the unsigned types to have one extra
0116   // bit of padding. Otherwise, unsigned fixed point types have
0117   // one more fractional bit than its corresponding signed type. This is false
0118   // by default.
0119   bool PaddingOnUnsignedFixedPoint;
0120 
0121   // Fixed point integral and fractional bit sizes
0122   // Saturated types share the same integral/fractional bits as their
0123   // corresponding unsaturated types.
0124   // For simplicity, the fractional bits in a _Fract type will be one less the
0125   // width of that _Fract type. This leaves all signed _Fract types having no
0126   // padding and unsigned _Fract types will only have 1 bit of padding after the
0127   // sign if PaddingOnUnsignedFixedPoint is set.
0128   unsigned char ShortAccumScale;
0129   unsigned char AccumScale;
0130   unsigned char LongAccumScale;
0131 
0132   unsigned char DefaultAlignForAttributeAligned;
0133   unsigned char MinGlobalAlign;
0134 
0135   unsigned short SuitableAlign;
0136   unsigned short NewAlign;
0137   unsigned MaxVectorAlign;
0138   unsigned MaxTLSAlign;
0139 
0140   const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat,
0141       *DoubleFormat, *LongDoubleFormat, *Float128Format, *Ibm128Format;
0142 
0143   ///===---- Target Data Type Query Methods -------------------------------===//
0144   enum IntType {
0145     NoInt = 0,
0146     SignedChar,
0147     UnsignedChar,
0148     SignedShort,
0149     UnsignedShort,
0150     SignedInt,
0151     UnsignedInt,
0152     SignedLong,
0153     UnsignedLong,
0154     SignedLongLong,
0155     UnsignedLongLong
0156   };
0157 
0158 protected:
0159   IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType, WIntType,
0160       Char16Type, Char32Type, Int64Type, Int16Type, SigAtomicType,
0161       ProcessIDType;
0162 
0163   /// Whether Objective-C's built-in boolean type should be signed char.
0164   ///
0165   /// Otherwise, when this flag is not set, the normal built-in boolean type is
0166   /// used.
0167   LLVM_PREFERRED_TYPE(bool)
0168   unsigned UseSignedCharForObjCBool : 1;
0169 
0170   /// Control whether the alignment of bit-field types is respected when laying
0171   /// out structures. If true, then the alignment of the bit-field type will be
0172   /// used to (a) impact the alignment of the containing structure, and (b)
0173   /// ensure that the individual bit-field will not straddle an alignment
0174   /// boundary.
0175   LLVM_PREFERRED_TYPE(bool)
0176   unsigned UseBitFieldTypeAlignment : 1;
0177 
0178   /// Whether zero length bitfields (e.g., int : 0;) force alignment of
0179   /// the next bitfield.
0180   ///
0181   /// If the alignment of the zero length bitfield is greater than the member
0182   /// that follows it, `bar', `bar' will be aligned as the type of the
0183   /// zero-length bitfield.
0184   LLVM_PREFERRED_TYPE(bool)
0185   unsigned UseZeroLengthBitfieldAlignment : 1;
0186 
0187   /// Whether zero length bitfield alignment is respected if they are the
0188   /// leading members.
0189   LLVM_PREFERRED_TYPE(bool)
0190   unsigned UseLeadingZeroLengthBitfield : 1;
0191 
0192   ///  Whether explicit bit field alignment attributes are honored.
0193   LLVM_PREFERRED_TYPE(bool)
0194   unsigned UseExplicitBitFieldAlignment : 1;
0195 
0196   /// If non-zero, specifies a fixed alignment value for bitfields that follow
0197   /// zero length bitfield, regardless of the zero length bitfield type.
0198   unsigned ZeroLengthBitfieldBoundary;
0199 
0200   /// If non-zero, specifies a maximum alignment to truncate alignment
0201   /// specified in the aligned attribute of a static variable to this value.
0202   unsigned MaxAlignedAttribute;
0203 };
0204 
0205 /// OpenCL type kinds.
0206 enum OpenCLTypeKind : uint8_t {
0207   OCLTK_Default,
0208   OCLTK_ClkEvent,
0209   OCLTK_Event,
0210   OCLTK_Image,
0211   OCLTK_Pipe,
0212   OCLTK_Queue,
0213   OCLTK_ReserveID,
0214   OCLTK_Sampler,
0215 };
0216 
0217 /// Exposes information about the current target.
0218 ///
0219 class TargetInfo : public TransferrableTargetInfo,
0220                    public RefCountedBase<TargetInfo> {
0221   std::shared_ptr<TargetOptions> TargetOpts;
0222   llvm::Triple Triple;
0223 protected:
0224   // Target values set by the ctor of the actual target implementation.  Default
0225   // values are specified by the TargetInfo constructor.
0226   bool BigEndian;
0227   bool TLSSupported;
0228   bool VLASupported;
0229   bool NoAsmVariants;  // True if {|} are normal characters.
0230   bool HasLegalHalfType; // True if the backend supports operations on the half
0231                          // LLVM IR type.
0232   bool HalfArgsAndReturns;
0233   bool HasFloat128;
0234   bool HasFloat16;
0235   bool HasBFloat16;
0236   bool HasFullBFloat16; // True if the backend supports native bfloat16
0237                         // arithmetic. Used to determine excess precision
0238                         // support in the frontend.
0239   bool HasIbm128;
0240   bool HasLongDouble;
0241   bool HasFPReturn;
0242   bool HasStrictFP;
0243 
0244   unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
0245   std::string DataLayoutString;
0246   const char *UserLabelPrefix;
0247   const char *MCountName;
0248   unsigned char RegParmMax, SSERegParmMax;
0249   TargetCXXABI TheCXXABI;
0250   const LangASMap *AddrSpaceMap;
0251 
0252   mutable StringRef PlatformName;
0253   mutable VersionTuple PlatformMinVersion;
0254 
0255   LLVM_PREFERRED_TYPE(bool)
0256   unsigned HasAlignMac68kSupport : 1;
0257   LLVM_PREFERRED_TYPE(FloatModeKind)
0258   unsigned RealTypeUsesObjCFPRetMask : llvm::BitWidth<FloatModeKind>;
0259   LLVM_PREFERRED_TYPE(bool)
0260   unsigned ComplexLongDoubleUsesFP2Ret : 1;
0261 
0262   LLVM_PREFERRED_TYPE(bool)
0263   unsigned HasBuiltinMSVaList : 1;
0264 
0265   LLVM_PREFERRED_TYPE(bool)
0266   unsigned HasAArch64SVETypes : 1;
0267 
0268   LLVM_PREFERRED_TYPE(bool)
0269   unsigned HasRISCVVTypes : 1;
0270 
0271   LLVM_PREFERRED_TYPE(bool)
0272   unsigned AllowAMDGPUUnsafeFPAtomics : 1;
0273 
0274   LLVM_PREFERRED_TYPE(bool)
0275   unsigned HasUnalignedAccess : 1;
0276 
0277   unsigned ARMCDECoprocMask : 8;
0278 
0279   unsigned MaxOpenCLWorkGroupSize;
0280 
0281   std::optional<unsigned> MaxBitIntWidth;
0282 
0283   std::optional<llvm::Triple> DarwinTargetVariantTriple;
0284 
0285   // TargetInfo Constructor.  Default initializes all fields.
0286   TargetInfo(const llvm::Triple &T);
0287 
0288   // UserLabelPrefix must match DL's getGlobalPrefix() when interpreted
0289   // as a DataLayout object.
0290   void resetDataLayout(StringRef DL, const char *UserLabelPrefix = "");
0291 
0292   // Target features that are read-only and should not be disabled/enabled
0293   // by command line options. Such features are for emitting predefined
0294   // macros or checking availability of builtin functions and can be omitted
0295   // in function attributes in IR.
0296   llvm::StringSet<> ReadOnlyFeatures;
0297 
0298 public:
0299   /// Construct a target for the given options.
0300   ///
0301   /// \param Opts - The options to use to initialize the target. The target may
0302   /// modify the options to canonicalize the target feature information to match
0303   /// what the backend expects.
0304   static TargetInfo *
0305   CreateTargetInfo(DiagnosticsEngine &Diags,
0306                    const std::shared_ptr<TargetOptions> &Opts);
0307 
0308   virtual ~TargetInfo();
0309 
0310   /// Retrieve the target options.
0311   TargetOptions &getTargetOpts() const {
0312     assert(TargetOpts && "Missing target options");
0313     return *TargetOpts;
0314   }
0315 
0316   /// The different kinds of __builtin_va_list types defined by
0317   /// the target implementation.
0318   enum BuiltinVaListKind {
0319     /// typedef char* __builtin_va_list;
0320     CharPtrBuiltinVaList = 0,
0321 
0322     /// typedef void* __builtin_va_list;
0323     VoidPtrBuiltinVaList,
0324 
0325     /// __builtin_va_list as defined by the AArch64 ABI
0326     /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
0327     AArch64ABIBuiltinVaList,
0328 
0329     /// __builtin_va_list as defined by the PNaCl ABI:
0330     /// http://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Machine-Types
0331     PNaClABIBuiltinVaList,
0332 
0333     /// __builtin_va_list as defined by the Power ABI:
0334     /// https://www.power.org
0335     ///        /resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf
0336     PowerABIBuiltinVaList,
0337 
0338     /// __builtin_va_list as defined by the x86-64 ABI:
0339     /// http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf
0340     X86_64ABIBuiltinVaList,
0341 
0342     /// __builtin_va_list as defined by ARM AAPCS ABI
0343     /// http://infocenter.arm.com
0344     //        /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
0345     AAPCSABIBuiltinVaList,
0346 
0347     // typedef struct __va_list_tag
0348     //   {
0349     //     long __gpr;
0350     //     long __fpr;
0351     //     void *__overflow_arg_area;
0352     //     void *__reg_save_area;
0353     //   } va_list[1];
0354     SystemZBuiltinVaList,
0355 
0356     // typedef struct __va_list_tag {
0357     //    void *__current_saved_reg_area_pointer;
0358     //    void *__saved_reg_area_end_pointer;
0359     //    void *__overflow_area_pointer;
0360     //} va_list;
0361     HexagonBuiltinVaList,
0362 
0363     // typedef struct __va_list_tag {
0364     //    int* __va_stk;
0365     //    int* __va_reg;
0366     //    int __va_ndx;
0367     //} va_list;
0368     XtensaABIBuiltinVaList
0369   };
0370 
0371 protected:
0372   /// Specify if mangling based on address space map should be used or
0373   /// not for language specific address spaces
0374   bool UseAddrSpaceMapMangling;
0375 
0376 public:
0377   IntType getSizeType() const { return SizeType; }
0378   IntType getSignedSizeType() const {
0379     switch (SizeType) {
0380     case UnsignedShort:
0381       return SignedShort;
0382     case UnsignedInt:
0383       return SignedInt;
0384     case UnsignedLong:
0385       return SignedLong;
0386     case UnsignedLongLong:
0387       return SignedLongLong;
0388     default:
0389       llvm_unreachable("Invalid SizeType");
0390     }
0391   }
0392   IntType getIntMaxType() const { return IntMaxType; }
0393   IntType getUIntMaxType() const {
0394     return getCorrespondingUnsignedType(IntMaxType);
0395   }
0396   IntType getPtrDiffType(LangAS AddrSpace) const {
0397     return AddrSpace == LangAS::Default ? PtrDiffType
0398                                         : getPtrDiffTypeV(AddrSpace);
0399   }
0400   IntType getUnsignedPtrDiffType(LangAS AddrSpace) const {
0401     return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
0402   }
0403   IntType getIntPtrType() const { return IntPtrType; }
0404   IntType getUIntPtrType() const {
0405     return getCorrespondingUnsignedType(IntPtrType);
0406   }
0407   IntType getWCharType() const { return WCharType; }
0408   IntType getWIntType() const { return WIntType; }
0409   IntType getChar16Type() const { return Char16Type; }
0410   IntType getChar32Type() const { return Char32Type; }
0411   IntType getInt64Type() const { return Int64Type; }
0412   IntType getUInt64Type() const {
0413     return getCorrespondingUnsignedType(Int64Type);
0414   }
0415   IntType getInt16Type() const { return Int16Type; }
0416   IntType getUInt16Type() const {
0417     return getCorrespondingUnsignedType(Int16Type);
0418   }
0419   IntType getSigAtomicType() const { return SigAtomicType; }
0420   IntType getProcessIDType() const { return ProcessIDType; }
0421 
0422   static IntType getCorrespondingUnsignedType(IntType T) {
0423     switch (T) {
0424     case SignedChar:
0425       return UnsignedChar;
0426     case SignedShort:
0427       return UnsignedShort;
0428     case SignedInt:
0429       return UnsignedInt;
0430     case SignedLong:
0431       return UnsignedLong;
0432     case SignedLongLong:
0433       return UnsignedLongLong;
0434     default:
0435       llvm_unreachable("Unexpected signed integer type");
0436     }
0437   }
0438 
0439   /// In the event this target uses the same number of fractional bits for its
0440   /// unsigned types as it does with its signed counterparts, there will be
0441   /// exactly one bit of padding.
0442   /// Return true if unsigned fixed point types have padding for this target.
0443   bool doUnsignedFixedPointTypesHavePadding() const {
0444     return PaddingOnUnsignedFixedPoint;
0445   }
0446 
0447   /// Return the width (in bits) of the specified integer type enum.
0448   ///
0449   /// For example, SignedInt -> getIntWidth().
0450   unsigned getTypeWidth(IntType T) const;
0451 
0452   /// Return integer type with specified width.
0453   virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
0454 
0455   /// Return the smallest integer type with at least the specified width.
0456   virtual IntType getLeastIntTypeByWidth(unsigned BitWidth,
0457                                          bool IsSigned) const;
0458 
0459   /// Return floating point type with specified width. On PPC, there are
0460   /// three possible types for 128-bit floating point: "PPC double-double",
0461   /// IEEE 754R quad precision, and "long double" (which under the covers
0462   /// is represented as one of those two). At this time, there is no support
0463   /// for an explicit "PPC double-double" type (i.e. __ibm128) so we only
0464   /// need to differentiate between "long double" and IEEE quad precision.
0465   FloatModeKind getRealTypeByWidth(unsigned BitWidth,
0466                                    FloatModeKind ExplicitType) const;
0467 
0468   /// Return the alignment (in bits) of the specified integer type enum.
0469   ///
0470   /// For example, SignedInt -> getIntAlign().
0471   unsigned getTypeAlign(IntType T) const;
0472 
0473   /// Returns true if the type is signed; false otherwise.
0474   static bool isTypeSigned(IntType T);
0475 
0476   /// Return the width of pointers on this target, for the
0477   /// specified address space.
0478   uint64_t getPointerWidth(LangAS AddrSpace) const {
0479     return AddrSpace == LangAS::Default ? PointerWidth
0480                                         : getPointerWidthV(AddrSpace);
0481   }
0482   uint64_t getPointerAlign(LangAS AddrSpace) const {
0483     return AddrSpace == LangAS::Default ? PointerAlign
0484                                         : getPointerAlignV(AddrSpace);
0485   }
0486 
0487   /// Return the maximum width of pointers on this target.
0488   virtual uint64_t getMaxPointerWidth() const {
0489     return PointerWidth;
0490   }
0491 
0492   /// Get integer value for null pointer.
0493   /// \param AddrSpace address space of pointee in source language.
0494   virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; }
0495 
0496   /// Returns true if an address space can be safely converted to another.
0497   /// \param A address space of target in source language.
0498   /// \param B address space of source in source language.
0499   virtual bool isAddressSpaceSupersetOf(LangAS A, LangAS B) const {
0500     return A == B;
0501   }
0502 
0503   /// Return the size of '_Bool' and C++ 'bool' for this target, in bits.
0504   unsigned getBoolWidth() const { return BoolWidth; }
0505 
0506   /// Return the alignment of '_Bool' and C++ 'bool' for this target.
0507   unsigned getBoolAlign() const { return BoolAlign; }
0508 
0509   unsigned getCharWidth() const { return 8; } // FIXME
0510   unsigned getCharAlign() const { return 8; } // FIXME
0511 
0512   /// getShortWidth/Align - Return the size of 'signed short' and
0513   /// 'unsigned short' for this target, in bits.
0514   unsigned getShortWidth() const { return ShortWidth; }
0515   unsigned getShortAlign() const { return ShortAlign; }
0516 
0517   /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
0518   /// this target, in bits.
0519   unsigned getIntWidth() const { return IntWidth; }
0520   unsigned getIntAlign() const { return IntAlign; }
0521 
0522   /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
0523   /// for this target, in bits.
0524   unsigned getLongWidth() const { return LongWidth; }
0525   unsigned getLongAlign() const { return LongAlign; }
0526 
0527   /// getLongLongWidth/Align - Return the size of 'signed long long' and
0528   /// 'unsigned long long' for this target, in bits.
0529   unsigned getLongLongWidth() const { return LongLongWidth; }
0530   unsigned getLongLongAlign() const { return LongLongAlign; }
0531 
0532   /// getInt128Align() - Returns the alignment of Int128.
0533   unsigned getInt128Align() const { return Int128Align; }
0534 
0535   /// getBitIntMaxAlign() - Returns the maximum possible alignment of
0536   /// '_BitInt' and 'unsigned _BitInt'.
0537   unsigned getBitIntMaxAlign() const {
0538     return BitIntMaxAlign.value_or(LongLongAlign);
0539   }
0540 
0541   /// getBitIntAlign/Width - Return aligned size of '_BitInt' and
0542   /// 'unsigned _BitInt' for this target, in bits.
0543   unsigned getBitIntWidth(unsigned NumBits) const {
0544     return llvm::alignTo(NumBits, getBitIntAlign(NumBits));
0545   }
0546   unsigned getBitIntAlign(unsigned NumBits) const {
0547     return std::clamp<unsigned>(llvm::PowerOf2Ceil(NumBits), getCharWidth(),
0548                                 getBitIntMaxAlign());
0549   }
0550 
0551   /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
0552   /// 'unsigned short _Accum' for this target, in bits.
0553   unsigned getShortAccumWidth() const { return ShortAccumWidth; }
0554   unsigned getShortAccumAlign() const { return ShortAccumAlign; }
0555 
0556   /// getAccumWidth/Align - Return the size of 'signed _Accum' and
0557   /// 'unsigned _Accum' for this target, in bits.
0558   unsigned getAccumWidth() const { return AccumWidth; }
0559   unsigned getAccumAlign() const { return AccumAlign; }
0560 
0561   /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and
0562   /// 'unsigned long _Accum' for this target, in bits.
0563   unsigned getLongAccumWidth() const { return LongAccumWidth; }
0564   unsigned getLongAccumAlign() const { return LongAccumAlign; }
0565 
0566   /// getShortFractWidth/Align - Return the size of 'signed short _Fract' and
0567   /// 'unsigned short _Fract' for this target, in bits.
0568   unsigned getShortFractWidth() const { return ShortFractWidth; }
0569   unsigned getShortFractAlign() const { return ShortFractAlign; }
0570 
0571   /// getFractWidth/Align - Return the size of 'signed _Fract' and
0572   /// 'unsigned _Fract' for this target, in bits.
0573   unsigned getFractWidth() const { return FractWidth; }
0574   unsigned getFractAlign() const { return FractAlign; }
0575 
0576   /// getLongFractWidth/Align - Return the size of 'signed long _Fract' and
0577   /// 'unsigned long _Fract' for this target, in bits.
0578   unsigned getLongFractWidth() const { return LongFractWidth; }
0579   unsigned getLongFractAlign() const { return LongFractAlign; }
0580 
0581   /// getShortAccumScale/IBits - Return the number of fractional/integral bits
0582   /// in a 'signed short _Accum' type.
0583   unsigned getShortAccumScale() const { return ShortAccumScale; }
0584   unsigned getShortAccumIBits() const {
0585     return ShortAccumWidth - ShortAccumScale - 1;
0586   }
0587 
0588   /// getAccumScale/IBits - Return the number of fractional/integral bits
0589   /// in a 'signed _Accum' type.
0590   unsigned getAccumScale() const { return AccumScale; }
0591   unsigned getAccumIBits() const { return AccumWidth - AccumScale - 1; }
0592 
0593   /// getLongAccumScale/IBits - Return the number of fractional/integral bits
0594   /// in a 'signed long _Accum' type.
0595   unsigned getLongAccumScale() const { return LongAccumScale; }
0596   unsigned getLongAccumIBits() const {
0597     return LongAccumWidth - LongAccumScale - 1;
0598   }
0599 
0600   /// getUnsignedShortAccumScale/IBits - Return the number of
0601   /// fractional/integral bits in a 'unsigned short _Accum' type.
0602   unsigned getUnsignedShortAccumScale() const {
0603     return PaddingOnUnsignedFixedPoint ? ShortAccumScale : ShortAccumScale + 1;
0604   }
0605   unsigned getUnsignedShortAccumIBits() const {
0606     return PaddingOnUnsignedFixedPoint
0607                ? getShortAccumIBits()
0608                : ShortAccumWidth - getUnsignedShortAccumScale();
0609   }
0610 
0611   /// getUnsignedAccumScale/IBits - Return the number of fractional/integral
0612   /// bits in a 'unsigned _Accum' type.
0613   unsigned getUnsignedAccumScale() const {
0614     return PaddingOnUnsignedFixedPoint ? AccumScale : AccumScale + 1;
0615   }
0616   unsigned getUnsignedAccumIBits() const {
0617     return PaddingOnUnsignedFixedPoint ? getAccumIBits()
0618                                        : AccumWidth - getUnsignedAccumScale();
0619   }
0620 
0621   /// getUnsignedLongAccumScale/IBits - Return the number of fractional/integral
0622   /// bits in a 'unsigned long _Accum' type.
0623   unsigned getUnsignedLongAccumScale() const {
0624     return PaddingOnUnsignedFixedPoint ? LongAccumScale : LongAccumScale + 1;
0625   }
0626   unsigned getUnsignedLongAccumIBits() const {
0627     return PaddingOnUnsignedFixedPoint
0628                ? getLongAccumIBits()
0629                : LongAccumWidth - getUnsignedLongAccumScale();
0630   }
0631 
0632   /// getShortFractScale - Return the number of fractional bits
0633   /// in a 'signed short _Fract' type.
0634   unsigned getShortFractScale() const { return ShortFractWidth - 1; }
0635 
0636   /// getFractScale - Return the number of fractional bits
0637   /// in a 'signed _Fract' type.
0638   unsigned getFractScale() const { return FractWidth - 1; }
0639 
0640   /// getLongFractScale - Return the number of fractional bits
0641   /// in a 'signed long _Fract' type.
0642   unsigned getLongFractScale() const { return LongFractWidth - 1; }
0643 
0644   /// getUnsignedShortFractScale - Return the number of fractional bits
0645   /// in a 'unsigned short _Fract' type.
0646   unsigned getUnsignedShortFractScale() const {
0647     return PaddingOnUnsignedFixedPoint ? getShortFractScale()
0648                                        : getShortFractScale() + 1;
0649   }
0650 
0651   /// getUnsignedFractScale - Return the number of fractional bits
0652   /// in a 'unsigned _Fract' type.
0653   unsigned getUnsignedFractScale() const {
0654     return PaddingOnUnsignedFixedPoint ? getFractScale() : getFractScale() + 1;
0655   }
0656 
0657   /// getUnsignedLongFractScale - Return the number of fractional bits
0658   /// in a 'unsigned long _Fract' type.
0659   unsigned getUnsignedLongFractScale() const {
0660     return PaddingOnUnsignedFixedPoint ? getLongFractScale()
0661                                        : getLongFractScale() + 1;
0662   }
0663 
0664   /// Determine whether the __int128 type is supported on this target.
0665   virtual bool hasInt128Type() const {
0666     return (getPointerWidth(LangAS::Default) >= 64) ||
0667            getTargetOpts().ForceEnableInt128;
0668   } // FIXME
0669 
0670   /// Determine whether the _BitInt type is supported on this target. This
0671   /// limitation is put into place for ABI reasons.
0672   /// FIXME: _BitInt is a required type in C23, so there's not much utility in
0673   /// asking whether the target supported it or not; I think this should be
0674   /// removed once backends have been alerted to the type and have had the
0675   /// chance to do implementation work if needed.
0676   virtual bool hasBitIntType() const {
0677     return false;
0678   }
0679 
0680   // Different targets may support a different maximum width for the _BitInt
0681   // type, depending on what operations are supported.
0682   virtual size_t getMaxBitIntWidth() const {
0683     // Consider -fexperimental-max-bitint-width= first.
0684     if (MaxBitIntWidth)
0685       return std::min<size_t>(*MaxBitIntWidth, llvm::IntegerType::MAX_INT_BITS);
0686 
0687     // FIXME: this value should be llvm::IntegerType::MAX_INT_BITS, which is
0688     // maximum bit width that LLVM claims its IR can support. However, most
0689     // backends currently have a bug where they only support float to int
0690     // conversion (and vice versa) on types that are <= 128 bits and crash
0691     // otherwise. We're setting the max supported value to 128 to be
0692     // conservative.
0693     return 128;
0694   }
0695 
0696   /// Determine whether _Float16 is supported on this target.
0697   virtual bool hasLegalHalfType() const { return HasLegalHalfType; }
0698 
0699   /// Whether half args and returns are supported.
0700   virtual bool allowHalfArgsAndReturns() const { return HalfArgsAndReturns; }
0701 
0702   /// Determine whether the __float128 type is supported on this target.
0703   virtual bool hasFloat128Type() const { return HasFloat128; }
0704 
0705   /// Determine whether the _Float16 type is supported on this target.
0706   virtual bool hasFloat16Type() const { return HasFloat16; }
0707 
0708   /// Determine whether the _BFloat16 type is supported on this target.
0709   virtual bool hasBFloat16Type() const {
0710     return HasBFloat16 || HasFullBFloat16;
0711   }
0712 
0713   /// Determine whether the BFloat type is fully supported on this target, i.e
0714   /// arithemtic operations.
0715   virtual bool hasFullBFloat16Type() const { return HasFullBFloat16; }
0716 
0717   /// Determine whether the __ibm128 type is supported on this target.
0718   virtual bool hasIbm128Type() const { return HasIbm128; }
0719 
0720   /// Determine whether the long double type is supported on this target.
0721   virtual bool hasLongDoubleType() const { return HasLongDouble; }
0722 
0723   /// Determine whether return of a floating point value is supported
0724   /// on this target.
0725   virtual bool hasFPReturn() const { return HasFPReturn; }
0726 
0727   /// Determine whether constrained floating point is supported on this target.
0728   virtual bool hasStrictFP() const { return HasStrictFP; }
0729 
0730   /// Return the alignment that is the largest alignment ever used for any
0731   /// scalar/SIMD data type on the target machine you are compiling for
0732   /// (including types with an extended alignment requirement).
0733   unsigned getSuitableAlign() const { return SuitableAlign; }
0734 
0735   /// Return the default alignment for __attribute__((aligned)) on
0736   /// this target, to be used if no alignment value is specified.
0737   unsigned getDefaultAlignForAttributeAligned() const {
0738     return DefaultAlignForAttributeAligned;
0739   }
0740 
0741   /// getMinGlobalAlign - Return the minimum alignment of a global variable,
0742   /// unless its alignment is explicitly reduced via attributes. If \param
0743   /// HasNonWeakDef is true, this concerns a VarDecl which has a definition
0744   /// in current translation unit and that is not weak.
0745   virtual unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const {
0746     return MinGlobalAlign;
0747   }
0748 
0749   /// Return the largest alignment for which a suitably-sized allocation with
0750   /// '::operator new(size_t)' is guaranteed to produce a correctly-aligned
0751   /// pointer.
0752   unsigned getNewAlign() const {
0753     return NewAlign ? NewAlign : std::max(LongDoubleAlign, LongLongAlign);
0754   }
0755 
0756   /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
0757   /// bits.
0758   unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
0759   unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
0760 
0761   /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
0762   /// bits.
0763   unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
0764   unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
0765 
0766   /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
0767   /// bits.
0768   unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
0769   unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
0770 
0771   /// getHalfWidth/Align/Format - Return the size/align/format of 'half'.
0772   unsigned getHalfWidth() const { return HalfWidth; }
0773   unsigned getHalfAlign() const { return HalfAlign; }
0774   const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; }
0775 
0776   /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
0777   unsigned getFloatWidth() const { return FloatWidth; }
0778   unsigned getFloatAlign() const { return FloatAlign; }
0779   const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
0780 
0781   /// getBFloat16Width/Align/Format - Return the size/align/format of '__bf16'.
0782   unsigned getBFloat16Width() const { return BFloat16Width; }
0783   unsigned getBFloat16Align() const { return BFloat16Align; }
0784   const llvm::fltSemantics &getBFloat16Format() const { return *BFloat16Format; }
0785 
0786   /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
0787   unsigned getDoubleWidth() const { return DoubleWidth; }
0788   unsigned getDoubleAlign() const { return DoubleAlign; }
0789   const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
0790 
0791   /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
0792   /// double'.
0793   unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
0794   unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
0795   const llvm::fltSemantics &getLongDoubleFormat() const {
0796     return *LongDoubleFormat;
0797   }
0798 
0799   /// getFloat128Width/Align/Format - Return the size/align/format of
0800   /// '__float128'.
0801   unsigned getFloat128Width() const { return 128; }
0802   unsigned getFloat128Align() const { return Float128Align; }
0803   const llvm::fltSemantics &getFloat128Format() const {
0804     return *Float128Format;
0805   }
0806 
0807   /// getIbm128Width/Align/Format - Return the size/align/format of
0808   /// '__ibm128'.
0809   unsigned getIbm128Width() const { return 128; }
0810   unsigned getIbm128Align() const { return Ibm128Align; }
0811   const llvm::fltSemantics &getIbm128Format() const { return *Ibm128Format; }
0812 
0813   /// Return the mangled code of long double.
0814   virtual const char *getLongDoubleMangling() const { return "e"; }
0815 
0816   /// Return the mangled code of __float128.
0817   virtual const char *getFloat128Mangling() const { return "g"; }
0818 
0819   /// Return the mangled code of __ibm128.
0820   virtual const char *getIbm128Mangling() const {
0821     llvm_unreachable("ibm128 not implemented on this target");
0822   }
0823 
0824   /// Return the mangled code of bfloat.
0825   virtual const char *getBFloat16Mangling() const { return "DF16b"; }
0826 
0827   /// Return the value for the C99 FLT_EVAL_METHOD macro.
0828   virtual LangOptions::FPEvalMethodKind getFPEvalMethod() const {
0829     return LangOptions::FPEvalMethodKind::FEM_Source;
0830   }
0831 
0832   virtual bool supportSourceEvalMethod() const { return true; }
0833 
0834   // getLargeArrayMinWidth/Align - Return the minimum array size that is
0835   // 'large' and its alignment.
0836   unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
0837   unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
0838 
0839   /// Return the maximum width lock-free atomic operation which will
0840   /// ever be supported for the given target
0841   unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; }
0842   /// Return the maximum width lock-free atomic operation which can be
0843   /// inlined given the supported features of the given target.
0844   unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
0845   /// Set the maximum inline or promote width lock-free atomic operation
0846   /// for the given target.
0847   virtual void setMaxAtomicWidth() {}
0848   /// Returns true if the given target supports lock-free atomic
0849   /// operations at the specified width and alignment.
0850   virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits,
0851                                 uint64_t AlignmentInBits) const {
0852     return AtomicSizeInBits <= AlignmentInBits &&
0853            AtomicSizeInBits <= getMaxAtomicInlineWidth() &&
0854            (AtomicSizeInBits <= getCharWidth() ||
0855             llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth()));
0856   }
0857 
0858   /// Return the maximum vector alignment supported for the given target.
0859   unsigned getMaxVectorAlign() const { return MaxVectorAlign; }
0860 
0861   unsigned getMaxOpenCLWorkGroupSize() const { return MaxOpenCLWorkGroupSize; }
0862 
0863   /// Return the alignment (in bits) of the thrown exception object. This is
0864   /// only meaningful for targets that allocate C++ exceptions in a system
0865   /// runtime, such as those using the Itanium C++ ABI.
0866   virtual unsigned getExnObjectAlignment() const {
0867     // Itanium says that an _Unwind_Exception has to be "double-word"
0868     // aligned (and thus the end of it is also so-aligned), meaning 16
0869     // bytes.  Of course, that was written for the actual Itanium,
0870     // which is a 64-bit platform.  Classically, the ABI doesn't really
0871     // specify the alignment on other platforms, but in practice
0872     // libUnwind declares the struct with __attribute__((aligned)), so
0873     // we assume that alignment here.  (It's generally 16 bytes, but
0874     // some targets overwrite it.)
0875     return getDefaultAlignForAttributeAligned();
0876   }
0877 
0878   /// Return the size of intmax_t and uintmax_t for this target, in bits.
0879   unsigned getIntMaxTWidth() const {
0880     return getTypeWidth(IntMaxType);
0881   }
0882 
0883   // Return the size of unwind_word for this target.
0884   virtual unsigned getUnwindWordWidth() const {
0885     return getPointerWidth(LangAS::Default);
0886   }
0887 
0888   /// Return the "preferred" register width on this target.
0889   virtual unsigned getRegisterWidth() const {
0890     // Currently we assume the register width on the target matches the pointer
0891     // width, we can introduce a new variable for this if/when some target wants
0892     // it.
0893     return PointerWidth;
0894   }
0895 
0896   /// Return true iff unaligned accesses are a single instruction (rather than
0897   /// a synthesized sequence).
0898   bool hasUnalignedAccess() const { return HasUnalignedAccess; }
0899 
0900   /// Return true iff unaligned accesses are cheap. This affects placement and
0901   /// size of bitfield loads/stores. (Not the ABI-mandated placement of
0902   /// the bitfields themselves.)
0903   bool hasCheapUnalignedBitFieldAccess() const {
0904     // Simply forward to the unaligned access getter.
0905     return hasUnalignedAccess();
0906   }
0907 
0908   /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro,
0909   /// which is the prefix given to user symbols by default.
0910   ///
0911   /// On most platforms this is "", but it is "_" on some.
0912   const char *getUserLabelPrefix() const { return UserLabelPrefix; }
0913 
0914   /// Returns the name of the mcount instrumentation function.
0915   const char *getMCountName() const {
0916     return MCountName;
0917   }
0918 
0919   /// Check if the Objective-C built-in boolean type should be signed
0920   /// char.
0921   ///
0922   /// Otherwise, if this returns false, the normal built-in boolean type
0923   /// should also be used for Objective-C.
0924   bool useSignedCharForObjCBool() const {
0925     return UseSignedCharForObjCBool;
0926   }
0927   void noSignedCharForObjCBool() {
0928     UseSignedCharForObjCBool = false;
0929   }
0930 
0931   /// Check whether the alignment of bit-field types is respected
0932   /// when laying out structures.
0933   bool useBitFieldTypeAlignment() const {
0934     return UseBitFieldTypeAlignment;
0935   }
0936 
0937   /// Check whether zero length bitfields should force alignment of
0938   /// the next member.
0939   bool useZeroLengthBitfieldAlignment() const {
0940     return UseZeroLengthBitfieldAlignment;
0941   }
0942 
0943   /// Check whether zero length bitfield alignment is respected if they are
0944   /// leading members.
0945   bool useLeadingZeroLengthBitfield() const {
0946     return UseLeadingZeroLengthBitfield;
0947   }
0948 
0949   /// Get the fixed alignment value in bits for a member that follows
0950   /// a zero length bitfield.
0951   unsigned getZeroLengthBitfieldBoundary() const {
0952     return ZeroLengthBitfieldBoundary;
0953   }
0954 
0955   /// Get the maximum alignment in bits for a static variable with
0956   /// aligned attribute.
0957   unsigned getMaxAlignedAttribute() const { return MaxAlignedAttribute; }
0958 
0959   /// Check whether explicit bitfield alignment attributes should be
0960   //  honored, as in "__attribute__((aligned(2))) int b : 1;".
0961   bool useExplicitBitFieldAlignment() const {
0962     return UseExplicitBitFieldAlignment;
0963   }
0964 
0965   /// Check whether this target support '\#pragma options align=mac68k'.
0966   bool hasAlignMac68kSupport() const {
0967     return HasAlignMac68kSupport;
0968   }
0969 
0970   /// Return the user string for the specified integer type enum.
0971   ///
0972   /// For example, SignedShort -> "short".
0973   static const char *getTypeName(IntType T);
0974 
0975   /// Return the constant suffix for the specified integer type enum.
0976   ///
0977   /// For example, SignedLong -> "L".
0978   const char *getTypeConstantSuffix(IntType T) const;
0979 
0980   /// Return the printf format modifier for the specified
0981   /// integer type enum.
0982   ///
0983   /// For example, SignedLong -> "l".
0984   static const char *getTypeFormatModifier(IntType T);
0985 
0986   /// Check whether the given real type should use the "fpret" flavor of
0987   /// Objective-C message passing on this target.
0988   bool useObjCFPRetForRealType(FloatModeKind T) const {
0989     return (int)((FloatModeKind)RealTypeUsesObjCFPRetMask & T);
0990   }
0991 
0992   /// Check whether _Complex long double should use the "fp2ret" flavor
0993   /// of Objective-C message passing on this target.
0994   bool useObjCFP2RetForComplexLongDouble() const {
0995     return ComplexLongDoubleUsesFP2Ret;
0996   }
0997 
0998   /// Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used
0999   /// to convert to and from __fp16.
1000   /// FIXME: This function should be removed once all targets stop using the
1001   /// conversion intrinsics.
1002   virtual bool useFP16ConversionIntrinsics() const {
1003     return true;
1004   }
1005 
1006   /// Specify if mangling based on address space map should be used or
1007   /// not for language specific address spaces
1008   bool useAddressSpaceMapMangling() const {
1009     return UseAddrSpaceMapMangling;
1010   }
1011 
1012   ///===---- Other target property query methods --------------------------===//
1013 
1014   /// Appends the target-specific \#define values for this
1015   /// target set to the specified buffer.
1016   virtual void getTargetDefines(const LangOptions &Opts,
1017                                 MacroBuilder &Builder) const = 0;
1018 
1019   /// Return information about target-specific builtins for
1020   /// the current primary target, and info about which builtins are non-portable
1021   /// across the current set of primary and secondary targets.
1022   virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
1023 
1024   /// Returns target-specific min and max values VScale_Range.
1025   virtual std::optional<std::pair<unsigned, unsigned>>
1026   getVScaleRange(const LangOptions &LangOpts,
1027                  bool IsArmStreamingFunction) const {
1028     return std::nullopt;
1029   }
1030   /// The __builtin_clz* and __builtin_ctz* built-in
1031   /// functions are specified to have undefined results for zero inputs, but
1032   /// on targets that support these operations in a way that provides
1033   /// well-defined results for zero without loss of performance, it is a good
1034   /// idea to avoid optimizing based on that undef behavior.
1035   virtual bool isCLZForZeroUndef() const { return true; }
1036 
1037   /// Returns the kind of __builtin_va_list type that should be used
1038   /// with this target.
1039   virtual BuiltinVaListKind getBuiltinVaListKind() const = 0;
1040 
1041   /// Returns whether or not type \c __builtin_ms_va_list type is
1042   /// available on this target.
1043   bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; }
1044 
1045   /// Returns whether or not the AArch64 SVE built-in types are
1046   /// available on this target.
1047   bool hasAArch64SVETypes() const { return HasAArch64SVETypes; }
1048 
1049   /// Returns whether or not the RISC-V V built-in types are
1050   /// available on this target.
1051   bool hasRISCVVTypes() const { return HasRISCVVTypes; }
1052 
1053   /// Returns whether or not the AMDGPU unsafe floating point atomics are
1054   /// allowed.
1055   bool allowAMDGPUUnsafeFPAtomics() const { return AllowAMDGPUUnsafeFPAtomics; }
1056 
1057   /// For ARM targets returns a mask defining which coprocessors are configured
1058   /// as Custom Datapath.
1059   uint32_t getARMCDECoprocMask() const { return ARMCDECoprocMask; }
1060 
1061   /// Returns whether the passed in string is a valid clobber in an
1062   /// inline asm statement.
1063   ///
1064   /// This is used by Sema.
1065   bool isValidClobber(StringRef Name) const;
1066 
1067   /// Returns whether the passed in string is a valid register name
1068   /// according to GCC.
1069   ///
1070   /// This is used by Sema for inline asm statements.
1071   virtual bool isValidGCCRegisterName(StringRef Name) const;
1072 
1073   /// Returns the "normalized" GCC register name.
1074   ///
1075   /// ReturnCannonical true will return the register name without any additions
1076   /// such as "{}" or "%" in it's canonical form, for example:
1077   /// ReturnCanonical = true and Name = "rax", will return "ax".
1078   StringRef getNormalizedGCCRegisterName(StringRef Name,
1079                                          bool ReturnCanonical = false) const;
1080 
1081   virtual bool isSPRegName(StringRef) const { return false; }
1082 
1083   /// Extracts a register from the passed constraint (if it is a
1084   /// single-register constraint) and the asm label expression related to a
1085   /// variable in the input or output list of an inline asm statement.
1086   ///
1087   /// This function is used by Sema in order to diagnose conflicts between
1088   /// the clobber list and the input/output lists.
1089   virtual StringRef getConstraintRegister(StringRef Constraint,
1090                                           StringRef Expression) const {
1091     return "";
1092   }
1093 
1094   struct ConstraintInfo {
1095     enum {
1096       CI_None = 0x00,
1097       CI_AllowsMemory = 0x01,
1098       CI_AllowsRegister = 0x02,
1099       CI_ReadWrite = 0x04,         // "+r" output constraint (read and write).
1100       CI_HasMatchingInput = 0x08,  // This output operand has a matching input.
1101       CI_ImmediateConstant = 0x10, // This operand must be an immediate constant
1102       CI_EarlyClobber = 0x20,      // "&" output constraint (early clobber).
1103     };
1104     unsigned Flags;
1105     int TiedOperand;
1106     struct {
1107       int Min;
1108       int Max;
1109       bool isConstrained;
1110     } ImmRange;
1111     llvm::SmallSet<int, 4> ImmSet;
1112 
1113     std::string ConstraintStr;  // constraint: "=rm"
1114     std::string Name;           // Operand name: [foo] with no []'s.
1115   public:
1116     ConstraintInfo(StringRef ConstraintStr, StringRef Name)
1117         : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
1118           Name(Name.str()) {
1119       ImmRange.Min = ImmRange.Max = 0;
1120       ImmRange.isConstrained = false;
1121     }
1122 
1123     const std::string &getConstraintStr() const { return ConstraintStr; }
1124     const std::string &getName() const { return Name; }
1125     bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
1126     bool earlyClobber() { return (Flags & CI_EarlyClobber) != 0; }
1127     bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
1128     bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
1129 
1130     /// Return true if this output operand has a matching
1131     /// (tied) input operand.
1132     bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
1133 
1134     /// Return true if this input operand is a matching
1135     /// constraint that ties it to an output operand.
1136     ///
1137     /// If this returns true then getTiedOperand will indicate which output
1138     /// operand this is tied to.
1139     bool hasTiedOperand() const { return TiedOperand != -1; }
1140     unsigned getTiedOperand() const {
1141       assert(hasTiedOperand() && "Has no tied operand!");
1142       return (unsigned)TiedOperand;
1143     }
1144 
1145     bool requiresImmediateConstant() const {
1146       return (Flags & CI_ImmediateConstant) != 0;
1147     }
1148     bool isValidAsmImmediate(const llvm::APInt &Value) const {
1149       if (!ImmSet.empty())
1150         return Value.isSignedIntN(32) && ImmSet.contains(Value.getZExtValue());
1151       return !ImmRange.isConstrained ||
1152              (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max));
1153     }
1154 
1155     void setIsReadWrite() { Flags |= CI_ReadWrite; }
1156     void setEarlyClobber() { Flags |= CI_EarlyClobber; }
1157     void setAllowsMemory() { Flags |= CI_AllowsMemory; }
1158     void setAllowsRegister() { Flags |= CI_AllowsRegister; }
1159     void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
1160     void setRequiresImmediate(int Min, int Max) {
1161       Flags |= CI_ImmediateConstant;
1162       ImmRange.Min = Min;
1163       ImmRange.Max = Max;
1164       ImmRange.isConstrained = true;
1165     }
1166     void setRequiresImmediate(llvm::ArrayRef<int> Exacts) {
1167       Flags |= CI_ImmediateConstant;
1168       for (int Exact : Exacts)
1169         ImmSet.insert(Exact);
1170     }
1171     void setRequiresImmediate(int Exact) {
1172       Flags |= CI_ImmediateConstant;
1173       ImmSet.insert(Exact);
1174     }
1175     void setRequiresImmediate() {
1176       Flags |= CI_ImmediateConstant;
1177     }
1178 
1179     /// Indicate that this is an input operand that is tied to
1180     /// the specified output operand.
1181     ///
1182     /// Copy over the various constraint information from the output.
1183     void setTiedOperand(unsigned N, ConstraintInfo &Output) {
1184       Output.setHasMatchingInput();
1185       Flags = Output.Flags;
1186       TiedOperand = N;
1187       // Don't copy Name or constraint string.
1188     }
1189   };
1190 
1191   /// Validate register name used for global register variables.
1192   ///
1193   /// This function returns true if the register passed in RegName can be used
1194   /// for global register variables on this target. In addition, it returns
1195   /// true in HasSizeMismatch if the size of the register doesn't match the
1196   /// variable size passed in RegSize.
1197   virtual bool validateGlobalRegisterVariable(StringRef RegName,
1198                                               unsigned RegSize,
1199                                               bool &HasSizeMismatch) const {
1200     HasSizeMismatch = false;
1201     return true;
1202   }
1203 
1204   // validateOutputConstraint, validateInputConstraint - Checks that
1205   // a constraint is valid and provides information about it.
1206   // FIXME: These should return a real error instead of just true/false.
1207   bool validateOutputConstraint(ConstraintInfo &Info) const;
1208   bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,
1209                                ConstraintInfo &info) const;
1210 
1211   virtual bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
1212                                   StringRef /*Constraint*/,
1213                                   unsigned /*Size*/) const {
1214     return true;
1215   }
1216 
1217   virtual bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
1218                                  StringRef /*Constraint*/,
1219                                  unsigned /*Size*/) const {
1220     return true;
1221   }
1222   virtual bool
1223   validateConstraintModifier(StringRef /*Constraint*/,
1224                              char /*Modifier*/,
1225                              unsigned /*Size*/,
1226                              std::string &/*SuggestedModifier*/) const {
1227     return true;
1228   }
1229   virtual bool
1230   validateAsmConstraint(const char *&Name,
1231                         TargetInfo::ConstraintInfo &info) const = 0;
1232 
1233   bool resolveSymbolicName(const char *&Name,
1234                            ArrayRef<ConstraintInfo> OutputConstraints,
1235                            unsigned &Index) const;
1236 
1237   // Constraint parm will be left pointing at the last character of
1238   // the constraint.  In practice, it won't be changed unless the
1239   // constraint is longer than one character.
1240   virtual std::string convertConstraint(const char *&Constraint) const {
1241     // 'p' defaults to 'r', but can be overridden by targets.
1242     if (*Constraint == 'p')
1243       return std::string("r");
1244     return std::string(1, *Constraint);
1245   }
1246 
1247   /// Replace some escaped characters with another string based on
1248   /// target-specific rules
1249   virtual std::optional<std::string> handleAsmEscapedChar(char C) const {
1250     return std::nullopt;
1251   }
1252 
1253   /// Returns a string of target-specific clobbers, in LLVM format.
1254   virtual std::string_view getClobbers() const = 0;
1255 
1256   /// Returns true if NaN encoding is IEEE 754-2008.
1257   /// Only MIPS allows a different encoding.
1258   virtual bool isNan2008() const {
1259     return true;
1260   }
1261 
1262   /// Returns the target triple of the primary target.
1263   const llvm::Triple &getTriple() const {
1264     return Triple;
1265   }
1266 
1267   /// Returns the target ID if supported.
1268   virtual std::optional<std::string> getTargetID() const {
1269     return std::nullopt;
1270   }
1271 
1272   const char *getDataLayoutString() const {
1273     assert(!DataLayoutString.empty() && "Uninitialized DataLayout!");
1274     return DataLayoutString.c_str();
1275   }
1276 
1277   struct GCCRegAlias {
1278     const char * const Aliases[5];
1279     const char * const Register;
1280   };
1281 
1282   struct AddlRegName {
1283     const char * const Names[5];
1284     const unsigned RegNum;
1285   };
1286 
1287   /// Does this target support "protected" visibility?
1288   ///
1289   /// Any target which dynamic libraries will naturally support
1290   /// something like "default" (meaning that the symbol is visible
1291   /// outside this shared object) and "hidden" (meaning that it isn't)
1292   /// visibilities, but "protected" is really an ELF-specific concept
1293   /// with weird semantics designed around the convenience of dynamic
1294   /// linker implementations.  Which is not to suggest that there's
1295   /// consistent target-independent semantics for "default" visibility
1296   /// either; the entire thing is pretty badly mangled.
1297   virtual bool hasProtectedVisibility() const { return true; }
1298 
1299   /// Does this target aim for semantic compatibility with
1300   /// Microsoft C++ code using dllimport/export attributes?
1301   virtual bool shouldDLLImportComdatSymbols() const {
1302     return getTriple().isWindowsMSVCEnvironment() ||
1303            getTriple().isWindowsItaniumEnvironment() || getTriple().isPS();
1304   }
1305 
1306   // Does this target have PS4 specific dllimport/export handling?
1307   virtual bool hasPS4DLLImportExport() const {
1308     return getTriple().isPS() ||
1309            // Windows Itanium support allows for testing the SCEI flavour of
1310            // dllimport/export handling on a Windows system.
1311            (getTriple().isWindowsItaniumEnvironment() &&
1312             getTriple().getVendor() == llvm::Triple::SCEI);
1313   }
1314 
1315   /// Set forced language options.
1316   ///
1317   /// Apply changes to the target information with respect to certain
1318   /// language options which change the target configuration and adjust
1319   /// the language based on the target options where applicable.
1320   virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts);
1321 
1322   /// Initialize the map with the default set of target features for the
1323   /// CPU this should include all legal feature strings on the target.
1324   ///
1325   /// \return False on error (invalid features).
1326   virtual bool initFeatureMap(llvm::StringMap<bool> &Features,
1327                               DiagnosticsEngine &Diags, StringRef CPU,
1328                               const std::vector<std::string> &FeatureVec) const;
1329 
1330   /// Get the ABI currently in use.
1331   virtual StringRef getABI() const { return StringRef(); }
1332 
1333   /// Get the C++ ABI currently in use.
1334   TargetCXXABI getCXXABI() const {
1335     return TheCXXABI;
1336   }
1337 
1338   /// Target the specified CPU.
1339   ///
1340   /// \return  False on error (invalid CPU name).
1341   virtual bool setCPU(const std::string &Name) {
1342     return false;
1343   }
1344 
1345   /// Fill a SmallVectorImpl with the valid values to setCPU.
1346   virtual void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {}
1347 
1348   /// Fill a SmallVectorImpl with the valid values for tuning CPU.
1349   virtual void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const {
1350     fillValidCPUList(Values);
1351   }
1352 
1353   /// Determine whether this TargetInfo supports the given CPU name.
1354   virtual bool isValidCPUName(StringRef Name) const {
1355     return true;
1356   }
1357 
1358   /// Determine whether this TargetInfo supports the given CPU name for
1359   /// tuning.
1360   virtual bool isValidTuneCPUName(StringRef Name) const {
1361     return isValidCPUName(Name);
1362   }
1363 
1364   virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const;
1365 
1366   /// Determine whether this TargetInfo supports tune in target attribute.
1367   virtual bool supportsTargetAttributeTune() const {
1368     return false;
1369   }
1370 
1371   /// Use the specified ABI.
1372   ///
1373   /// \return False on error (invalid ABI name).
1374   virtual bool setABI(const std::string &Name) {
1375     return false;
1376   }
1377 
1378   /// Use the specified unit for FP math.
1379   ///
1380   /// \return False on error (invalid unit name).
1381   virtual bool setFPMath(StringRef Name) {
1382     return false;
1383   }
1384 
1385   /// Check if target has a given feature enabled
1386   virtual bool hasFeatureEnabled(const llvm::StringMap<bool> &Features,
1387                                  StringRef Name) const {
1388     return Features.lookup(Name);
1389   }
1390 
1391   /// Enable or disable a specific target feature;
1392   /// the feature name must be valid.
1393   virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
1394                                  StringRef Name,
1395                                  bool Enabled) const {
1396     Features[Name] = Enabled;
1397   }
1398 
1399   /// Determine whether this TargetInfo supports the given feature.
1400   virtual bool isValidFeatureName(StringRef Feature) const {
1401     return true;
1402   }
1403 
1404   /// Returns true if feature has an impact on target code
1405   /// generation.
1406   virtual bool doesFeatureAffectCodeGen(StringRef Feature) const {
1407     return true;
1408   }
1409 
1410   class BranchProtectionInfo {
1411   public:
1412     LangOptions::SignReturnAddressScopeKind SignReturnAddr;
1413     LangOptions::SignReturnAddressKeyKind SignKey;
1414     bool BranchTargetEnforcement;
1415     bool BranchProtectionPAuthLR;
1416     bool GuardedControlStack;
1417 
1418     const char *getSignReturnAddrStr() const {
1419       switch (SignReturnAddr) {
1420       case LangOptions::SignReturnAddressScopeKind::None:
1421         return "none";
1422       case LangOptions::SignReturnAddressScopeKind::NonLeaf:
1423         return "non-leaf";
1424       case LangOptions::SignReturnAddressScopeKind::All:
1425         return "all";
1426       }
1427       llvm_unreachable("Unexpected SignReturnAddressScopeKind");
1428     }
1429 
1430     const char *getSignKeyStr() const {
1431       switch (SignKey) {
1432       case LangOptions::SignReturnAddressKeyKind::AKey:
1433         return "a_key";
1434       case LangOptions::SignReturnAddressKeyKind::BKey:
1435         return "b_key";
1436       }
1437       llvm_unreachable("Unexpected SignReturnAddressKeyKind");
1438     }
1439 
1440     BranchProtectionInfo()
1441         : SignReturnAddr(LangOptions::SignReturnAddressScopeKind::None),
1442           SignKey(LangOptions::SignReturnAddressKeyKind::AKey),
1443           BranchTargetEnforcement(false), BranchProtectionPAuthLR(false),
1444           GuardedControlStack(false) {}
1445 
1446     BranchProtectionInfo(const LangOptions &LangOpts) {
1447       SignReturnAddr =
1448           LangOpts.hasSignReturnAddress()
1449               ? (LangOpts.isSignReturnAddressScopeAll()
1450                      ? LangOptions::SignReturnAddressScopeKind::All
1451                      : LangOptions::SignReturnAddressScopeKind::NonLeaf)
1452               : LangOptions::SignReturnAddressScopeKind::None;
1453       SignKey = LangOpts.isSignReturnAddressWithAKey()
1454                     ? LangOptions::SignReturnAddressKeyKind::AKey
1455                     : LangOptions::SignReturnAddressKeyKind::BKey;
1456       BranchTargetEnforcement = LangOpts.BranchTargetEnforcement;
1457       BranchProtectionPAuthLR = LangOpts.BranchProtectionPAuthLR;
1458       GuardedControlStack = LangOpts.GuardedControlStack;
1459     }
1460   };
1461 
1462   /// Determine if the Architecture in this TargetInfo supports branch
1463   /// protection
1464   virtual bool isBranchProtectionSupportedArch(StringRef Arch) const {
1465     return false;
1466   }
1467 
1468   /// Determine if this TargetInfo supports the given branch protection
1469   /// specification
1470   virtual bool validateBranchProtection(StringRef Spec, StringRef Arch,
1471                                         BranchProtectionInfo &BPI,
1472                                         const LangOptions &LO,
1473                                         StringRef &Err) const {
1474     Err = "";
1475     return false;
1476   }
1477 
1478   /// Perform initialization based on the user configured
1479   /// set of features (e.g., +sse4).
1480   ///
1481   /// The list is guaranteed to have at most one entry per feature.
1482   ///
1483   /// The target may modify the features list, to change which options are
1484   /// passed onwards to the backend.
1485   /// FIXME: This part should be fixed so that we can change handleTargetFeatures
1486   /// to merely a TargetInfo initialization routine.
1487   ///
1488   /// \return  False on error.
1489   virtual bool handleTargetFeatures(std::vector<std::string> &Features,
1490                                     DiagnosticsEngine &Diags) {
1491     return true;
1492   }
1493 
1494   /// Determine whether the given target has the given feature.
1495   virtual bool hasFeature(StringRef Feature) const {
1496     return false;
1497   }
1498 
1499   /// Determine whether the given target feature is read only.
1500   bool isReadOnlyFeature(StringRef Feature) const {
1501     return ReadOnlyFeatures.count(Feature);
1502   }
1503 
1504   /// Identify whether this target supports multiversioning of functions,
1505   /// which requires support for cpu_supports and cpu_is functionality.
1506   bool supportsMultiVersioning() const {
1507     return getTriple().isX86() || getTriple().isAArch64() ||
1508            getTriple().isRISCV();
1509   }
1510 
1511   /// Identify whether this target supports IFuncs.
1512   bool supportsIFunc() const {
1513     if (getTriple().isOSBinFormatMachO())
1514       return true;
1515     if (getTriple().isOSWindows() && getTriple().isAArch64())
1516       return true;
1517     if (getTriple().getArch() == llvm::Triple::ArchType::avr)
1518       return true;
1519     return getTriple().isOSBinFormatELF() &&
1520            ((getTriple().isOSLinux() && !getTriple().isMusl()) ||
1521             getTriple().isOSFreeBSD());
1522   }
1523 
1524   // Identify whether this target supports __builtin_cpu_supports and
1525   // __builtin_cpu_is.
1526   virtual bool supportsCpuSupports() const { return false; }
1527   virtual bool supportsCpuIs() const { return false; }
1528   virtual bool supportsCpuInit() const { return false; }
1529 
1530   // Validate the contents of the __builtin_cpu_supports(const char*)
1531   // argument.
1532   virtual bool validateCpuSupports(StringRef Name) const { return false; }
1533 
1534   // Return the target-specific priority for features/cpus/vendors so
1535   // that they can be properly sorted for checking.
1536   virtual uint64_t getFMVPriority(ArrayRef<StringRef> Features) const {
1537     return 0;
1538   }
1539 
1540   // Validate the contents of the __builtin_cpu_is(const char*)
1541   // argument.
1542   virtual bool validateCpuIs(StringRef Name) const { return false; }
1543 
1544   // Validate a cpu_dispatch/cpu_specific CPU option, which is a different list
1545   // from cpu_is, since it checks via features rather than CPUs directly.
1546   virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const {
1547     return false;
1548   }
1549 
1550   // Get the character to be added for mangling purposes for cpu_specific.
1551   virtual char CPUSpecificManglingCharacter(StringRef Name) const {
1552     llvm_unreachable(
1553         "cpu_specific Multiversioning not implemented on this target");
1554   }
1555 
1556   // Get the value for the 'tune-cpu' flag for a cpu_specific variant with the
1557   // programmer-specified 'Name'.
1558   virtual StringRef getCPUSpecificTuneName(StringRef Name) const {
1559     llvm_unreachable(
1560         "cpu_specific Multiversioning not implemented on this target");
1561   }
1562 
1563   // Get a list of the features that make up the CPU option for
1564   // cpu_specific/cpu_dispatch so that it can be passed to llvm as optimization
1565   // options.
1566   virtual void getCPUSpecificCPUDispatchFeatures(
1567       StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
1568     llvm_unreachable(
1569         "cpu_specific Multiversioning not implemented on this target");
1570   }
1571 
1572   // Get the cache line size of a given cpu. This method switches over
1573   // the given cpu and returns "std::nullopt" if the CPU is not found.
1574   virtual std::optional<unsigned> getCPUCacheLineSize() const {
1575     return std::nullopt;
1576   }
1577 
1578   // Returns maximal number of args passed in registers.
1579   unsigned getRegParmMax() const {
1580     assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
1581     return RegParmMax;
1582   }
1583 
1584   /// Whether the target supports thread-local storage.
1585   bool isTLSSupported() const {
1586     return TLSSupported;
1587   }
1588 
1589   /// Return the maximum alignment (in bits) of a TLS variable
1590   ///
1591   /// Gets the maximum alignment (in bits) of a TLS variable on this target.
1592   /// Returns zero if there is no such constraint.
1593   unsigned getMaxTLSAlign() const { return MaxTLSAlign; }
1594 
1595   /// Whether target supports variable-length arrays.
1596   bool isVLASupported() const { return VLASupported; }
1597 
1598   /// Whether the target supports SEH __try.
1599   bool isSEHTrySupported() const {
1600     return getTriple().isOSWindows() &&
1601            (getTriple().isX86() ||
1602             getTriple().getArch() == llvm::Triple::aarch64);
1603   }
1604 
1605   /// Return true if {|} are normal characters in the asm string.
1606   ///
1607   /// If this returns false (the default), then {abc|xyz} is syntax
1608   /// that says that when compiling for asm variant #0, "abc" should be
1609   /// generated, but when compiling for asm variant #1, "xyz" should be
1610   /// generated.
1611   bool hasNoAsmVariants() const {
1612     return NoAsmVariants;
1613   }
1614 
1615   /// Return the register number that __builtin_eh_return_regno would
1616   /// return with the specified argument.
1617   /// This corresponds with TargetLowering's getExceptionPointerRegister
1618   /// and getExceptionSelectorRegister in the backend.
1619   virtual int getEHDataRegisterNumber(unsigned RegNo) const {
1620     return -1;
1621   }
1622 
1623   /// Return the section to use for C++ static initialization functions.
1624   virtual const char *getStaticInitSectionSpecifier() const {
1625     return nullptr;
1626   }
1627 
1628   const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
1629   unsigned getTargetAddressSpace(LangAS AS) const {
1630     if (isTargetAddressSpace(AS))
1631       return toTargetAddressSpace(AS);
1632     return getAddressSpaceMap()[(unsigned)AS];
1633   }
1634 
1635   /// Determine whether the given pointer-authentication key is valid.
1636   ///
1637   /// The value has been coerced to type 'int'.
1638   virtual bool validatePointerAuthKey(const llvm::APSInt &value) const;
1639 
1640   /// Map from the address space field in builtin description strings to the
1641   /// language address space.
1642   virtual LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const {
1643     return getLangASFromTargetAS(AS);
1644   }
1645 
1646   /// Map from the address space field in builtin description strings to the
1647   /// language address space.
1648   virtual LangAS getCUDABuiltinAddressSpace(unsigned AS) const {
1649     return getLangASFromTargetAS(AS);
1650   }
1651 
1652   /// Return an AST address space which can be used opportunistically
1653   /// for constant global memory. It must be possible to convert pointers into
1654   /// this address space to LangAS::Default. If no such address space exists,
1655   /// this may return std::nullopt, and such optimizations will be disabled.
1656   virtual std::optional<LangAS> getConstantAddressSpace() const {
1657     return LangAS::Default;
1658   }
1659 
1660   // access target-specific GPU grid values that must be consistent between
1661   // host RTL (plugin), deviceRTL and clang.
1662   virtual const llvm::omp::GV &getGridValue() const {
1663     llvm_unreachable("getGridValue not implemented on this target");
1664   }
1665 
1666   /// Retrieve the name of the platform as it is used in the
1667   /// availability attribute.
1668   StringRef getPlatformName() const { return PlatformName; }
1669 
1670   /// Retrieve the minimum desired version of the platform, to
1671   /// which the program should be compiled.
1672   VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
1673 
1674   bool isBigEndian() const { return BigEndian; }
1675   bool isLittleEndian() const { return !BigEndian; }
1676 
1677   /// Whether the option -fextend-arguments={32,64} is supported on the target.
1678   virtual bool supportsExtendIntArgs() const { return false; }
1679 
1680   /// Controls if __arithmetic_fence is supported in the targeted backend.
1681   virtual bool checkArithmeticFenceSupported() const { return false; }
1682 
1683   /// Gets the default calling convention for the given target and
1684   /// declaration context.
1685   virtual CallingConv getDefaultCallingConv() const {
1686     // Not all targets will specify an explicit calling convention that we can
1687     // express.  This will always do the right thing, even though it's not
1688     // an explicit calling convention.
1689     return CC_C;
1690   }
1691 
1692   enum CallingConvCheckResult {
1693     CCCR_OK,
1694     CCCR_Warning,
1695     CCCR_Ignore,
1696     CCCR_Error,
1697   };
1698 
1699   /// Determines whether a given calling convention is valid for the
1700   /// target. A calling convention can either be accepted, produce a warning
1701   /// and be substituted with the default calling convention, or (someday)
1702   /// produce an error (such as using thiscall on a non-instance function).
1703   virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
1704     switch (CC) {
1705       default:
1706         return CCCR_Warning;
1707       case CC_C:
1708         return CCCR_OK;
1709     }
1710   }
1711 
1712   enum CallingConvKind {
1713     CCK_Default,
1714     CCK_ClangABI4OrPS4,
1715     CCK_MicrosoftWin64
1716   };
1717 
1718   virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;
1719 
1720   /// Controls whether explicitly defaulted (`= default`) special member
1721   /// functions disqualify something from being POD-for-the-purposes-of-layout.
1722   /// Historically, Clang didn't consider these acceptable for POD, but GCC
1723   /// does. So in newer Clang ABIs they are acceptable for POD to be compatible
1724   /// with GCC/Itanium ABI, and remains disqualifying for targets that need
1725   /// Clang backwards compatibility rather than GCC/Itanium ABI compatibility.
1726   virtual bool areDefaultedSMFStillPOD(const LangOptions&) const;
1727 
1728   /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
1729   /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
1730   virtual bool hasSjLjLowering() const {
1731     return false;
1732   }
1733 
1734   /// Check if the target supports CFProtection branch.
1735   virtual bool
1736   checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const;
1737 
1738   /// Get the target default CFBranchLabelScheme scheme
1739   virtual CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const;
1740 
1741   virtual bool
1742   checkCFBranchLabelSchemeSupported(const CFBranchLabelSchemeKind Scheme,
1743                                     DiagnosticsEngine &Diags) const;
1744 
1745   /// Check if the target supports CFProtection return.
1746   virtual bool
1747   checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const;
1748 
1749   /// Whether target allows to overalign ABI-specified preferred alignment
1750   virtual bool allowsLargerPreferedTypeAlignment() const { return true; }
1751 
1752   /// Whether target defaults to the `power` alignment rules of AIX.
1753   virtual bool defaultsToAIXPowerAlignment() const { return false; }
1754 
1755   /// Set supported OpenCL extensions and optional core features.
1756   virtual void setSupportedOpenCLOpts() {}
1757 
1758   virtual void supportAllOpenCLOpts(bool V = true) {
1759 #define OPENCLEXTNAME(Ext)                                                     \
1760   setFeatureEnabled(getTargetOpts().OpenCLFeaturesMap, #Ext, V);
1761 #include "clang/Basic/OpenCLExtensions.def"
1762   }
1763 
1764   /// Set supported OpenCL extensions as written on command line
1765   virtual void setCommandLineOpenCLOpts() {
1766     for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
1767       bool IsPrefixed = (Ext[0] == '+' || Ext[0] == '-');
1768       std::string Name = IsPrefixed ? Ext.substr(1) : Ext;
1769       bool V = IsPrefixed ? Ext[0] == '+' : true;
1770 
1771       if (Name == "all") {
1772         supportAllOpenCLOpts(V);
1773         continue;
1774       }
1775 
1776       getTargetOpts().OpenCLFeaturesMap[Name] = V;
1777     }
1778   }
1779 
1780   /// Get supported OpenCL extensions and optional core features.
1781   llvm::StringMap<bool> &getSupportedOpenCLOpts() {
1782     return getTargetOpts().OpenCLFeaturesMap;
1783   }
1784 
1785   /// Get const supported OpenCL extensions and optional core features.
1786   const llvm::StringMap<bool> &getSupportedOpenCLOpts() const {
1787     return getTargetOpts().OpenCLFeaturesMap;
1788   }
1789 
1790   /// Get address space for OpenCL type.
1791   virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const;
1792 
1793   /// \returns Target specific vtbl ptr address space.
1794   virtual unsigned getVtblPtrAddressSpace() const {
1795     return 0;
1796   }
1797 
1798   /// \returns If a target requires an address within a target specific address
1799   /// space \p AddressSpace to be converted in order to be used, then return the
1800   /// corresponding target specific DWARF address space.
1801   ///
1802   /// \returns Otherwise return std::nullopt and no conversion will be emitted
1803   /// in the DWARF.
1804   virtual std::optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace)
1805       const {
1806     return std::nullopt;
1807   }
1808 
1809   /// \returns The version of the SDK which was used during the compilation if
1810   /// one was specified, or an empty version otherwise.
1811   const llvm::VersionTuple &getSDKVersion() const {
1812     return getTargetOpts().SDKVersion;
1813   }
1814 
1815   /// Check the target is valid after it is fully initialized.
1816   virtual bool validateTarget(DiagnosticsEngine &Diags) const {
1817     return true;
1818   }
1819 
1820   /// Check that OpenCL target has valid options setting based on OpenCL
1821   /// version.
1822   virtual bool validateOpenCLTarget(const LangOptions &Opts,
1823                                     DiagnosticsEngine &Diags) const;
1824 
1825   virtual void setAuxTarget(const TargetInfo *Aux) {}
1826 
1827   /// Whether target allows debuginfo types for decl only variables/functions.
1828   virtual bool allowDebugInfoForExternalRef() const { return false; }
1829 
1830   /// Returns the darwin target variant triple, the variant of the deployment
1831   /// target for which the code is being compiled.
1832   const llvm::Triple *getDarwinTargetVariantTriple() const {
1833     return DarwinTargetVariantTriple ? &*DarwinTargetVariantTriple : nullptr;
1834   }
1835 
1836   /// Returns the version of the darwin target variant SDK which was used during
1837   /// the compilation if one was specified, or an empty version otherwise.
1838   const std::optional<VersionTuple> getDarwinTargetVariantSDKVersion() const {
1839     return !getTargetOpts().DarwinTargetVariantSDKVersion.empty()
1840                ? getTargetOpts().DarwinTargetVariantSDKVersion
1841                : std::optional<VersionTuple>();
1842   }
1843 
1844   /// Whether to support HIP image/texture API's.
1845   virtual bool hasHIPImageSupport() const { return true; }
1846 
1847   /// The first value in the pair is the minimum offset between two objects to
1848   /// avoid false sharing (destructive interference). The second value in the
1849   /// pair is maximum size of contiguous memory to promote true sharing
1850   /// (constructive interference). Neither of these values are considered part
1851   /// of the ABI and can be changed by targets at any time.
1852   virtual std::pair<unsigned, unsigned> hardwareInterferenceSizes() const {
1853     return std::make_pair(64, 64);
1854   }
1855 
1856 protected:
1857   /// Copy type and layout related info.
1858   void copyAuxTarget(const TargetInfo *Aux);
1859   virtual uint64_t getPointerWidthV(LangAS AddrSpace) const {
1860     return PointerWidth;
1861   }
1862   virtual uint64_t getPointerAlignV(LangAS AddrSpace) const {
1863     return PointerAlign;
1864   }
1865   virtual enum IntType getPtrDiffTypeV(LangAS AddrSpace) const {
1866     return PtrDiffType;
1867   }
1868   virtual ArrayRef<const char *> getGCCRegNames() const = 0;
1869   virtual ArrayRef<GCCRegAlias> getGCCRegAliases() const = 0;
1870   virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const { return {}; }
1871 
1872 private:
1873   // Assert the values for the fractional and integral bits for each fixed point
1874   // type follow the restrictions given in clause 6.2.6.3 of N1169.
1875   void CheckFixedPointBits() const;
1876 };
1877 
1878 namespace targets {
1879 std::unique_ptr<clang::TargetInfo>
1880 AllocateTarget(const llvm::Triple &Triple, const clang::TargetOptions &Opts);
1881 } // namespace targets
1882 
1883 }  // end namespace clang
1884 
1885 #endif