1193326Sed//===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===//
2193326Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193326Sed//
7193326Sed//===----------------------------------------------------------------------===//
8239462Sdim///
9239462Sdim/// \file
10341825Sdim/// Defines the clang::TargetInfo interface.
11239462Sdim///
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
15193326Sed#define LLVM_CLANG_BASIC_TARGETINFO_H
16193326Sed
17249423Sdim#include "clang/Basic/AddressSpaces.h"
18226633Sdim#include "clang/Basic/LLVM.h"
19360784Sdim#include "clang/Basic/CodeGenOptions.h"
20249423Sdim#include "clang/Basic/Specifiers.h"
21276479Sdim#include "clang/Basic/TargetCXXABI.h"
22249423Sdim#include "clang/Basic/TargetOptions.h"
23360784Sdim#include "llvm/ADT/APFloat.h"
24309124Sdim#include "llvm/ADT/APInt.h"
25360784Sdim#include "llvm/ADT/ArrayRef.h"
26221345Sdim#include "llvm/ADT/IntrusiveRefCntPtr.h"
27321369Sdim#include "llvm/ADT/Optional.h"
28296417Sdim#include "llvm/ADT/SmallSet.h"
29193326Sed#include "llvm/ADT/StringMap.h"
30221345Sdim#include "llvm/ADT/StringRef.h"
31198092Srdivacky#include "llvm/ADT/Triple.h"
32218893Sdim#include "llvm/Support/DataTypes.h"
33341825Sdim#include "llvm/Support/VersionTuple.h"
34193326Sed#include <cassert>
35249423Sdim#include <string>
36193326Sed#include <vector>
37193326Sed
38198092Srdivackynamespace llvm {
39198092Srdivackystruct fltSemantics;
40360784Sdimclass DataLayout;
41198092Srdivacky}
42193326Sed
43193326Sednamespace clang {
44226633Sdimclass DiagnosticsEngine;
45199482Srdivackyclass LangOptions;
46314564Sdimclass CodeGenOptions;
47202379Srdivackyclass MacroBuilder;
48314564Sdimclass QualType;
49198092Srdivackyclass SourceLocation;
50193326Sedclass SourceManager;
51199482Srdivacky
52193326Sednamespace Builtin { struct Info; }
53198092Srdivacky
54353358Sdim/// Fields controlling how types are laid out in memory; these may need to
55353358Sdim/// be copied for targets like AMDGPU that base their ABIs on an auxiliary
56353358Sdim/// CPU target.
57353358Sdimstruct TransferrableTargetInfo {
58193326Sed  unsigned char PointerWidth, PointerAlign;
59218893Sdim  unsigned char BoolWidth, BoolAlign;
60193326Sed  unsigned char IntWidth, IntAlign;
61226633Sdim  unsigned char HalfWidth, HalfAlign;
62193326Sed  unsigned char FloatWidth, FloatAlign;
63193326Sed  unsigned char DoubleWidth, DoubleAlign;
64309124Sdim  unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align;
65210299Sed  unsigned char LargeArrayMinWidth, LargeArrayAlign;
66193326Sed  unsigned char LongWidth, LongAlign;
67193326Sed  unsigned char LongLongWidth, LongLongAlign;
68341825Sdim
69341825Sdim  // Fixed point bit widths
70341825Sdim  unsigned char ShortAccumWidth, ShortAccumAlign;
71341825Sdim  unsigned char AccumWidth, AccumAlign;
72341825Sdim  unsigned char LongAccumWidth, LongAccumAlign;
73341825Sdim  unsigned char ShortFractWidth, ShortFractAlign;
74341825Sdim  unsigned char FractWidth, FractAlign;
75341825Sdim  unsigned char LongFractWidth, LongFractAlign;
76341825Sdim
77341825Sdim  // If true, unsigned fixed point types have the same number of fractional bits
78341825Sdim  // as their signed counterparts, forcing the unsigned types to have one extra
79341825Sdim  // bit of padding. Otherwise, unsigned fixed point types have
80341825Sdim  // one more fractional bit than its corresponding signed type. This is false
81341825Sdim  // by default.
82341825Sdim  bool PaddingOnUnsignedFixedPoint;
83341825Sdim
84341825Sdim  // Fixed point integral and fractional bit sizes
85341825Sdim  // Saturated types share the same integral/fractional bits as their
86341825Sdim  // corresponding unsaturated types.
87341825Sdim  // For simplicity, the fractional bits in a _Fract type will be one less the
88341825Sdim  // width of that _Fract type. This leaves all signed _Fract types having no
89341825Sdim  // padding and unsigned _Fract types will only have 1 bit of padding after the
90341825Sdim  // sign if PaddingOnUnsignedFixedPoint is set.
91341825Sdim  unsigned char ShortAccumScale;
92341825Sdim  unsigned char AccumScale;
93341825Sdim  unsigned char LongAccumScale;
94341825Sdim
95234353Sdim  unsigned char SuitableAlign;
96288943Sdim  unsigned char DefaultAlignForAttributeAligned;
97251662Sdim  unsigned char MinGlobalAlign;
98353358Sdim
99353358Sdim  unsigned short NewAlign;
100239462Sdim  unsigned short MaxVectorAlign;
101288943Sdim  unsigned short MaxTLSAlign;
102353358Sdim
103353358Sdim  const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
104353358Sdim    *LongDoubleFormat, *Float128Format;
105353358Sdim
106353358Sdim  ///===---- Target Data Type Query Methods -------------------------------===//
107353358Sdim  enum IntType {
108353358Sdim    NoInt = 0,
109353358Sdim    SignedChar,
110353358Sdim    UnsignedChar,
111353358Sdim    SignedShort,
112353358Sdim    UnsignedShort,
113353358Sdim    SignedInt,
114353358Sdim    UnsignedInt,
115353358Sdim    SignedLong,
116353358Sdim    UnsignedLong,
117353358Sdim    SignedLongLong,
118353358Sdim    UnsignedLongLong
119353358Sdim  };
120353358Sdim
121353358Sdim  enum RealType {
122353358Sdim    NoFloat = 255,
123353358Sdim    Float = 0,
124353358Sdim    Double,
125353358Sdim    LongDouble,
126353358Sdim    Float128
127353358Sdim  };
128353358Sdimprotected:
129353358Sdim  IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType,
130353358Sdim          WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
131353358Sdim          ProcessIDType;
132353358Sdim
133353358Sdim  /// Whether Objective-C's built-in boolean type should be signed char.
134353358Sdim  ///
135353358Sdim  /// Otherwise, when this flag is not set, the normal built-in boolean type is
136353358Sdim  /// used.
137353358Sdim  unsigned UseSignedCharForObjCBool : 1;
138353358Sdim
139353358Sdim  /// Control whether the alignment of bit-field types is respected when laying
140353358Sdim  /// out structures. If true, then the alignment of the bit-field type will be
141353358Sdim  /// used to (a) impact the alignment of the containing structure, and (b)
142353358Sdim  /// ensure that the individual bit-field will not straddle an alignment
143353358Sdim  /// boundary.
144353358Sdim  unsigned UseBitFieldTypeAlignment : 1;
145353358Sdim
146353358Sdim  /// Whether zero length bitfields (e.g., int : 0;) force alignment of
147353358Sdim  /// the next bitfield.
148353358Sdim  ///
149353358Sdim  /// If the alignment of the zero length bitfield is greater than the member
150353358Sdim  /// that follows it, `bar', `bar' will be aligned as the type of the
151353358Sdim  /// zero-length bitfield.
152353358Sdim  unsigned UseZeroLengthBitfieldAlignment : 1;
153353358Sdim
154353358Sdim  ///  Whether explicit bit field alignment attributes are honored.
155353358Sdim  unsigned UseExplicitBitFieldAlignment : 1;
156353358Sdim
157353358Sdim  /// If non-zero, specifies a fixed alignment value for bitfields that follow
158353358Sdim  /// zero length bitfield, regardless of the zero length bitfield type.
159353358Sdim  unsigned ZeroLengthBitfieldBoundary;
160353358Sdim};
161353358Sdim
162353358Sdim/// Exposes information about the current target.
163353358Sdim///
164353358Sdimclass TargetInfo : public virtual TransferrableTargetInfo,
165353358Sdim                   public RefCountedBase<TargetInfo> {
166353358Sdim  std::shared_ptr<TargetOptions> TargetOpts;
167353358Sdim  llvm::Triple Triple;
168353358Sdimprotected:
169353358Sdim  // Target values set by the ctor of the actual target implementation.  Default
170353358Sdim  // values are specified by the TargetInfo constructor.
171353358Sdim  bool BigEndian;
172353358Sdim  bool TLSSupported;
173353358Sdim  bool VLASupported;
174353358Sdim  bool NoAsmVariants;  // True if {|} are normal characters.
175353358Sdim  bool HasLegalHalfType; // True if the backend supports operations on the half
176353358Sdim                         // LLVM IR type.
177353358Sdim  bool HasFloat128;
178353358Sdim  bool HasFloat16;
179353358Sdim
180353358Sdim  unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
181288943Sdim  unsigned short SimdDefaultAlign;
182309124Sdim  std::unique_ptr<llvm::DataLayout> DataLayout;
183218893Sdim  const char *MCountName;
184193326Sed  unsigned char RegParmMax, SSERegParmMax;
185249423Sdim  TargetCXXABI TheCXXABI;
186327952Sdim  const LangASMap *AddrSpaceMap;
187193326Sed
188226633Sdim  mutable StringRef PlatformName;
189221345Sdim  mutable VersionTuple PlatformMinVersion;
190221345Sdim
191208600Srdivacky  unsigned HasAlignMac68kSupport : 1;
192210299Sed  unsigned RealTypeUsesObjCFPRet : 3;
193234353Sdim  unsigned ComplexLongDoubleUsesFP2Ret : 1;
194208600Srdivacky
195296417Sdim  unsigned HasBuiltinMSVaList : 1;
196296417Sdim
197314564Sdim  unsigned IsRenderScriptTarget : 1;
198314564Sdim
199360784Sdim  unsigned HasAArch64SVETypes : 1;
200360784Sdim
201193326Sed  // TargetInfo Constructor.  Default initializes all fields.
202261991Sdim  TargetInfo(const llvm::Triple &T);
203198092Srdivacky
204360784Sdim  void resetDataLayout(StringRef DL);
205309124Sdim
206198092Srdivackypublic:
207341825Sdim  /// Construct a target for the given options.
208201361Srdivacky  ///
209201361Srdivacky  /// \param Opts - The options to use to initialize the target. The target may
210201361Srdivacky  /// modify the options to canonicalize the target feature information to match
211201361Srdivacky  /// what the backend expects.
212276479Sdim  static TargetInfo *
213276479Sdim  CreateTargetInfo(DiagnosticsEngine &Diags,
214276479Sdim                   const std::shared_ptr<TargetOptions> &Opts);
215193326Sed
216193326Sed  virtual ~TargetInfo();
217193326Sed
218341825Sdim  /// Retrieve the target options.
219296417Sdim  TargetOptions &getTargetOpts() const {
220243830Sdim    assert(TargetOpts && "Missing target options");
221296417Sdim    return *TargetOpts;
222243830Sdim  }
223243830Sdim
224341825Sdim  /// The different kinds of __builtin_va_list types defined by
225239462Sdim  /// the target implementation.
226239462Sdim  enum BuiltinVaListKind {
227239462Sdim    /// typedef char* __builtin_va_list;
228239462Sdim    CharPtrBuiltinVaList = 0,
229239462Sdim
230239462Sdim    /// typedef void* __builtin_va_list;
231239462Sdim    VoidPtrBuiltinVaList,
232239462Sdim
233321369Sdim    /// __builtin_va_list as defined by the AArch64 ABI
234249423Sdim    /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
235249423Sdim    AArch64ABIBuiltinVaList,
236249423Sdim
237239462Sdim    /// __builtin_va_list as defined by the PNaCl ABI:
238239462Sdim    /// http://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Machine-Types
239239462Sdim    PNaClABIBuiltinVaList,
240239462Sdim
241239462Sdim    /// __builtin_va_list as defined by the Power ABI:
242239462Sdim    /// https://www.power.org
243239462Sdim    ///        /resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf
244239462Sdim    PowerABIBuiltinVaList,
245239462Sdim
246239462Sdim    /// __builtin_va_list as defined by the x86-64 ABI:
247321369Sdim    /// http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf
248243830Sdim    X86_64ABIBuiltinVaList,
249243830Sdim
250243830Sdim    /// __builtin_va_list as defined by ARM AAPCS ABI
251243830Sdim    /// http://infocenter.arm.com
252243830Sdim    //        /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
253251662Sdim    AAPCSABIBuiltinVaList,
254251662Sdim
255251662Sdim    // typedef struct __va_list_tag
256251662Sdim    //   {
257251662Sdim    //     long __gpr;
258251662Sdim    //     long __fpr;
259251662Sdim    //     void *__overflow_arg_area;
260251662Sdim    //     void *__reg_save_area;
261251662Sdim    //   } va_list[1];
262251662Sdim    SystemZBuiltinVaList
263239462Sdim  };
264239462Sdim
265193326Sedprotected:
266341825Sdim  /// Specify if mangling based on address space map should be used or
267261991Sdim  /// not for language specific address spaces
268261991Sdim  bool UseAddrSpaceMapMangling;
269261991Sdim
270193326Sedpublic:
271193326Sed  IntType getSizeType() const { return SizeType; }
272321369Sdim  IntType getSignedSizeType() const {
273321369Sdim    switch (SizeType) {
274321369Sdim    case UnsignedShort:
275321369Sdim      return SignedShort;
276321369Sdim    case UnsignedInt:
277321369Sdim      return SignedInt;
278321369Sdim    case UnsignedLong:
279321369Sdim      return SignedLong;
280321369Sdim    case UnsignedLongLong:
281321369Sdim      return SignedLongLong;
282321369Sdim    default:
283321369Sdim      llvm_unreachable("Invalid SizeType");
284321369Sdim    }
285321369Sdim  }
286193326Sed  IntType getIntMaxType() const { return IntMaxType; }
287276479Sdim  IntType getUIntMaxType() const {
288276479Sdim    return getCorrespondingUnsignedType(IntMaxType);
289276479Sdim  }
290193326Sed  IntType getPtrDiffType(unsigned AddrSpace) const {
291193326Sed    return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
292193326Sed  }
293327952Sdim  IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
294327952Sdim    return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
295327952Sdim  }
296193326Sed  IntType getIntPtrType() const { return IntPtrType; }
297276479Sdim  IntType getUIntPtrType() const {
298276479Sdim    return getCorrespondingUnsignedType(IntPtrType);
299276479Sdim  }
300193326Sed  IntType getWCharType() const { return WCharType; }
301198398Srdivacky  IntType getWIntType() const { return WIntType; }
302198092Srdivacky  IntType getChar16Type() const { return Char16Type; }
303198092Srdivacky  IntType getChar32Type() const { return Char32Type; }
304195341Sed  IntType getInt64Type() const { return Int64Type; }
305276479Sdim  IntType getUInt64Type() const {
306276479Sdim    return getCorrespondingUnsignedType(Int64Type);
307276479Sdim  }
308199990Srdivacky  IntType getSigAtomicType() const { return SigAtomicType; }
309243830Sdim  IntType getProcessIDType() const { return ProcessIDType; }
310193326Sed
311276479Sdim  static IntType getCorrespondingUnsignedType(IntType T) {
312276479Sdim    switch (T) {
313276479Sdim    case SignedChar:
314276479Sdim      return UnsignedChar;
315276479Sdim    case SignedShort:
316276479Sdim      return UnsignedShort;
317276479Sdim    case SignedInt:
318276479Sdim      return UnsignedInt;
319276479Sdim    case SignedLong:
320276479Sdim      return UnsignedLong;
321276479Sdim    case SignedLongLong:
322276479Sdim      return UnsignedLongLong;
323276479Sdim    default:
324276479Sdim      llvm_unreachable("Unexpected signed integer type");
325276479Sdim    }
326276479Sdim  }
327276479Sdim
328344779Sdim  /// In the event this target uses the same number of fractional bits for its
329344779Sdim  /// unsigned types as it does with its signed counterparts, there will be
330344779Sdim  /// exactly one bit of padding.
331344779Sdim  /// Return true if unsigned fixed point types have padding for this target.
332344779Sdim  bool doUnsignedFixedPointTypesHavePadding() const {
333344779Sdim    return PaddingOnUnsignedFixedPoint;
334344779Sdim  }
335344779Sdim
336341825Sdim  /// Return the width (in bits) of the specified integer type enum.
337239462Sdim  ///
338239462Sdim  /// For example, SignedInt -> getIntWidth().
339198398Srdivacky  unsigned getTypeWidth(IntType T) const;
340198398Srdivacky
341341825Sdim  /// Return integer type with specified width.
342296417Sdim  virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
343261991Sdim
344341825Sdim  /// Return the smallest integer type with at least the specified width.
345296417Sdim  virtual IntType getLeastIntTypeByWidth(unsigned BitWidth,
346296417Sdim                                         bool IsSigned) const;
347276479Sdim
348341825Sdim  /// Return floating point type with specified width.
349261991Sdim  RealType getRealTypeByWidth(unsigned BitWidth) const;
350261991Sdim
351341825Sdim  /// Return the alignment (in bits) of the specified integer type enum.
352239462Sdim  ///
353239462Sdim  /// For example, SignedInt -> getIntAlign().
354199482Srdivacky  unsigned getTypeAlign(IntType T) const;
355199482Srdivacky
356341825Sdim  /// Returns true if the type is signed; false otherwise.
357218893Sdim  static bool isTypeSigned(IntType T);
358198398Srdivacky
359341825Sdim  /// Return the width of pointers on this target, for the
360193326Sed  /// specified address space.
361193326Sed  uint64_t getPointerWidth(unsigned AddrSpace) const {
362193326Sed    return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
363193326Sed  }
364193326Sed  uint64_t getPointerAlign(unsigned AddrSpace) const {
365193326Sed    return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
366193326Sed  }
367198092Srdivacky
368341825Sdim  /// Return the maximum width of pointers on this target.
369314564Sdim  virtual uint64_t getMaxPointerWidth() const {
370314564Sdim    return PointerWidth;
371314564Sdim  }
372314564Sdim
373341825Sdim  /// Get integer value for null pointer.
374314564Sdim  /// \param AddrSpace address space of pointee in source language.
375327952Sdim  virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; }
376314564Sdim
377341825Sdim  /// Return the size of '_Bool' and C++ 'bool' for this target, in bits.
378218893Sdim  unsigned getBoolWidth() const { return BoolWidth; }
379239462Sdim
380341825Sdim  /// Return the alignment of '_Bool' and C++ 'bool' for this target.
381218893Sdim  unsigned getBoolAlign() const { return BoolAlign; }
382198092Srdivacky
383198092Srdivacky  unsigned getCharWidth() const { return 8; } // FIXME
384198092Srdivacky  unsigned getCharAlign() const { return 8; } // FIXME
385198092Srdivacky
386341825Sdim  /// Return the size of 'signed short' and 'unsigned short' for this
387239462Sdim  /// target, in bits.
388193326Sed  unsigned getShortWidth() const { return 16; } // FIXME
389239462Sdim
390341825Sdim  /// Return the alignment of 'signed short' and 'unsigned short' for
391239462Sdim  /// this target.
392193326Sed  unsigned getShortAlign() const { return 16; } // FIXME
393198092Srdivacky
394193326Sed  /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
395193326Sed  /// this target, in bits.
396193326Sed  unsigned getIntWidth() const { return IntWidth; }
397193326Sed  unsigned getIntAlign() const { return IntAlign; }
398198092Srdivacky
399193326Sed  /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
400193326Sed  /// for this target, in bits.
401193326Sed  unsigned getLongWidth() const { return LongWidth; }
402193326Sed  unsigned getLongAlign() const { return LongAlign; }
403198092Srdivacky
404193326Sed  /// getLongLongWidth/Align - Return the size of 'signed long long' and
405193326Sed  /// 'unsigned long long' for this target, in bits.
406193326Sed  unsigned getLongLongWidth() const { return LongLongWidth; }
407193326Sed  unsigned getLongLongAlign() const { return LongLongAlign; }
408198092Srdivacky
409341825Sdim  /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
410341825Sdim  /// 'unsigned short _Accum' for this target, in bits.
411341825Sdim  unsigned getShortAccumWidth() const { return ShortAccumWidth; }
412341825Sdim  unsigned getShortAccumAlign() const { return ShortAccumAlign; }
413341825Sdim
414341825Sdim  /// getAccumWidth/Align - Return the size of 'signed _Accum' and
415341825Sdim  /// 'unsigned _Accum' for this target, in bits.
416341825Sdim  unsigned getAccumWidth() const { return AccumWidth; }
417341825Sdim  unsigned getAccumAlign() const { return AccumAlign; }
418341825Sdim
419341825Sdim  /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and
420341825Sdim  /// 'unsigned long _Accum' for this target, in bits.
421341825Sdim  unsigned getLongAccumWidth() const { return LongAccumWidth; }
422341825Sdim  unsigned getLongAccumAlign() const { return LongAccumAlign; }
423341825Sdim
424341825Sdim  /// getShortFractWidth/Align - Return the size of 'signed short _Fract' and
425341825Sdim  /// 'unsigned short _Fract' for this target, in bits.
426341825Sdim  unsigned getShortFractWidth() const { return ShortFractWidth; }
427341825Sdim  unsigned getShortFractAlign() const { return ShortFractAlign; }
428341825Sdim
429341825Sdim  /// getFractWidth/Align - Return the size of 'signed _Fract' and
430341825Sdim  /// 'unsigned _Fract' for this target, in bits.
431341825Sdim  unsigned getFractWidth() const { return FractWidth; }
432341825Sdim  unsigned getFractAlign() const { return FractAlign; }
433341825Sdim
434341825Sdim  /// getLongFractWidth/Align - Return the size of 'signed long _Fract' and
435341825Sdim  /// 'unsigned long _Fract' for this target, in bits.
436341825Sdim  unsigned getLongFractWidth() const { return LongFractWidth; }
437341825Sdim  unsigned getLongFractAlign() const { return LongFractAlign; }
438341825Sdim
439341825Sdim  /// getShortAccumScale/IBits - Return the number of fractional/integral bits
440341825Sdim  /// in a 'signed short _Accum' type.
441341825Sdim  unsigned getShortAccumScale() const { return ShortAccumScale; }
442341825Sdim  unsigned getShortAccumIBits() const {
443341825Sdim    return ShortAccumWidth - ShortAccumScale - 1;
444341825Sdim  }
445341825Sdim
446341825Sdim  /// getAccumScale/IBits - Return the number of fractional/integral bits
447341825Sdim  /// in a 'signed _Accum' type.
448341825Sdim  unsigned getAccumScale() const { return AccumScale; }
449341825Sdim  unsigned getAccumIBits() const { return AccumWidth - AccumScale - 1; }
450341825Sdim
451341825Sdim  /// getLongAccumScale/IBits - Return the number of fractional/integral bits
452341825Sdim  /// in a 'signed long _Accum' type.
453341825Sdim  unsigned getLongAccumScale() const { return LongAccumScale; }
454341825Sdim  unsigned getLongAccumIBits() const {
455341825Sdim    return LongAccumWidth - LongAccumScale - 1;
456341825Sdim  }
457341825Sdim
458341825Sdim  /// getUnsignedShortAccumScale/IBits - Return the number of
459341825Sdim  /// fractional/integral bits in a 'unsigned short _Accum' type.
460341825Sdim  unsigned getUnsignedShortAccumScale() const {
461341825Sdim    return PaddingOnUnsignedFixedPoint ? ShortAccumScale : ShortAccumScale + 1;
462341825Sdim  }
463341825Sdim  unsigned getUnsignedShortAccumIBits() const {
464341825Sdim    return PaddingOnUnsignedFixedPoint
465341825Sdim               ? getShortAccumIBits()
466341825Sdim               : ShortAccumWidth - getUnsignedShortAccumScale();
467341825Sdim  }
468341825Sdim
469341825Sdim  /// getUnsignedAccumScale/IBits - Return the number of fractional/integral
470341825Sdim  /// bits in a 'unsigned _Accum' type.
471341825Sdim  unsigned getUnsignedAccumScale() const {
472341825Sdim    return PaddingOnUnsignedFixedPoint ? AccumScale : AccumScale + 1;
473341825Sdim  }
474341825Sdim  unsigned getUnsignedAccumIBits() const {
475341825Sdim    return PaddingOnUnsignedFixedPoint ? getAccumIBits()
476341825Sdim                                       : AccumWidth - getUnsignedAccumScale();
477341825Sdim  }
478341825Sdim
479341825Sdim  /// getUnsignedLongAccumScale/IBits - Return the number of fractional/integral
480341825Sdim  /// bits in a 'unsigned long _Accum' type.
481341825Sdim  unsigned getUnsignedLongAccumScale() const {
482341825Sdim    return PaddingOnUnsignedFixedPoint ? LongAccumScale : LongAccumScale + 1;
483341825Sdim  }
484341825Sdim  unsigned getUnsignedLongAccumIBits() const {
485341825Sdim    return PaddingOnUnsignedFixedPoint
486341825Sdim               ? getLongAccumIBits()
487341825Sdim               : LongAccumWidth - getUnsignedLongAccumScale();
488341825Sdim  }
489341825Sdim
490341825Sdim  /// getShortFractScale - Return the number of fractional bits
491341825Sdim  /// in a 'signed short _Fract' type.
492341825Sdim  unsigned getShortFractScale() const { return ShortFractWidth - 1; }
493341825Sdim
494341825Sdim  /// getFractScale - Return the number of fractional bits
495341825Sdim  /// in a 'signed _Fract' type.
496341825Sdim  unsigned getFractScale() const { return FractWidth - 1; }
497341825Sdim
498341825Sdim  /// getLongFractScale - Return the number of fractional bits
499341825Sdim  /// in a 'signed long _Fract' type.
500341825Sdim  unsigned getLongFractScale() const { return LongFractWidth - 1; }
501341825Sdim
502341825Sdim  /// getUnsignedShortFractScale - Return the number of fractional bits
503341825Sdim  /// in a 'unsigned short _Fract' type.
504341825Sdim  unsigned getUnsignedShortFractScale() const {
505341825Sdim    return PaddingOnUnsignedFixedPoint ? getShortFractScale()
506341825Sdim                                       : getShortFractScale() + 1;
507341825Sdim  }
508341825Sdim
509341825Sdim  /// getUnsignedFractScale - Return the number of fractional bits
510341825Sdim  /// in a 'unsigned _Fract' type.
511341825Sdim  unsigned getUnsignedFractScale() const {
512341825Sdim    return PaddingOnUnsignedFixedPoint ? getFractScale() : getFractScale() + 1;
513341825Sdim  }
514341825Sdim
515341825Sdim  /// getUnsignedLongFractScale - Return the number of fractional bits
516341825Sdim  /// in a 'unsigned long _Fract' type.
517341825Sdim  unsigned getUnsignedLongFractScale() const {
518341825Sdim    return PaddingOnUnsignedFixedPoint ? getLongFractScale()
519341825Sdim                                       : getLongFractScale() + 1;
520341825Sdim  }
521341825Sdim
522341825Sdim  /// Determine whether the __int128 type is supported on this target.
523296417Sdim  virtual bool hasInt128Type() const {
524341825Sdim    return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
525296417Sdim  } // FIXME
526249423Sdim
527341825Sdim  /// Determine whether _Float16 is supported on this target.
528341825Sdim  virtual bool hasLegalHalfType() const { return HasLegalHalfType; }
529341825Sdim
530341825Sdim  /// Determine whether the __float128 type is supported on this target.
531309124Sdim  virtual bool hasFloat128Type() const { return HasFloat128; }
532309124Sdim
533344779Sdim  /// Determine whether the _Float16 type is supported on this target.
534344779Sdim  virtual bool hasFloat16Type() const { return HasFloat16; }
535344779Sdim
536341825Sdim  /// Return the alignment that is suitable for storing any
537234353Sdim  /// object with a fundamental alignment requirement.
538234353Sdim  unsigned getSuitableAlign() const { return SuitableAlign; }
539234353Sdim
540341825Sdim  /// Return the default alignment for __attribute__((aligned)) on
541288943Sdim  /// this target, to be used if no alignment value is specified.
542288943Sdim  unsigned getDefaultAlignForAttributeAligned() const {
543288943Sdim    return DefaultAlignForAttributeAligned;
544288943Sdim  }
545288943Sdim
546251662Sdim  /// getMinGlobalAlign - Return the minimum alignment of a global variable,
547251662Sdim  /// unless its alignment is explicitly reduced via attributes.
548353358Sdim  virtual unsigned getMinGlobalAlign (uint64_t) const {
549353358Sdim    return MinGlobalAlign;
550353358Sdim  }
551251662Sdim
552314564Sdim  /// Return the largest alignment for which a suitably-sized allocation with
553314564Sdim  /// '::operator new(size_t)' is guaranteed to produce a correctly-aligned
554314564Sdim  /// pointer.
555314564Sdim  unsigned getNewAlign() const {
556314564Sdim    return NewAlign ? NewAlign : std::max(LongDoubleAlign, LongLongAlign);
557314564Sdim  }
558314564Sdim
559198092Srdivacky  /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
560193326Sed  /// bits.
561199482Srdivacky  unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
562199482Srdivacky  unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
563193326Sed
564198092Srdivacky  /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
565198092Srdivacky  /// bits.
566199482Srdivacky  unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
567199482Srdivacky  unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
568198092Srdivacky
569198092Srdivacky  /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
570198092Srdivacky  /// bits.
571199482Srdivacky  unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
572199482Srdivacky  unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
573198092Srdivacky
574226633Sdim  /// getHalfWidth/Align/Format - Return the size/align/format of 'half'.
575226633Sdim  unsigned getHalfWidth() const { return HalfWidth; }
576226633Sdim  unsigned getHalfAlign() const { return HalfAlign; }
577226633Sdim  const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; }
578226633Sdim
579193326Sed  /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
580193326Sed  unsigned getFloatWidth() const { return FloatWidth; }
581193326Sed  unsigned getFloatAlign() const { return FloatAlign; }
582193326Sed  const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
583193326Sed
584193326Sed  /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
585193326Sed  unsigned getDoubleWidth() const { return DoubleWidth; }
586193326Sed  unsigned getDoubleAlign() const { return DoubleAlign; }
587193326Sed  const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
588193326Sed
589193326Sed  /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
590193326Sed  /// double'.
591193326Sed  unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
592193326Sed  unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
593193326Sed  const llvm::fltSemantics &getLongDoubleFormat() const {
594193326Sed    return *LongDoubleFormat;
595193326Sed  }
596198092Srdivacky
597309124Sdim  /// getFloat128Width/Align/Format - Return the size/align/format of
598309124Sdim  /// '__float128'.
599309124Sdim  unsigned getFloat128Width() const { return 128; }
600309124Sdim  unsigned getFloat128Align() const { return Float128Align; }
601309124Sdim  const llvm::fltSemantics &getFloat128Format() const {
602309124Sdim    return *Float128Format;
603309124Sdim  }
604309124Sdim
605353358Sdim  /// Return the mangled code of long double.
606353358Sdim  virtual const char *getLongDoubleMangling() const { return "e"; }
607288943Sdim
608353358Sdim  /// Return the mangled code of __float128.
609353358Sdim  virtual const char *getFloat128Mangling() const { return "g"; }
610353358Sdim
611341825Sdim  /// Return the value for the C99 FLT_EVAL_METHOD macro.
612234353Sdim  virtual unsigned getFloatEvalMethod() const { return 0; }
613234353Sdim
614210299Sed  // getLargeArrayMinWidth/Align - Return the minimum array size that is
615210299Sed  // 'large' and its alignment.
616210299Sed  unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
617210299Sed  unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
618210299Sed
619341825Sdim  /// Return the maximum width lock-free atomic operation which will
620239462Sdim  /// ever be supported for the given target
621226633Sdim  unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; }
622341825Sdim  /// Return the maximum width lock-free atomic operation which can be
623239462Sdim  /// inlined given the supported features of the given target.
624226633Sdim  unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
625341825Sdim  /// Set the maximum inline or promote width lock-free atomic operation
626327952Sdim  /// for the given target.
627327952Sdim  virtual void setMaxAtomicWidth() {}
628341825Sdim  /// Returns true if the given target supports lock-free atomic
629280031Sdim  /// operations at the specified width and alignment.
630280031Sdim  virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits,
631280031Sdim                                uint64_t AlignmentInBits) const {
632280031Sdim    return AtomicSizeInBits <= AlignmentInBits &&
633280031Sdim           AtomicSizeInBits <= getMaxAtomicInlineWidth() &&
634280031Sdim           (AtomicSizeInBits <= getCharWidth() ||
635280031Sdim            llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth()));
636280031Sdim  }
637226633Sdim
638341825Sdim  /// Return the maximum vector alignment supported for the given target.
639239462Sdim  unsigned getMaxVectorAlign() const { return MaxVectorAlign; }
640341825Sdim  /// Return default simd alignment for the given target. Generally, this
641288943Sdim  /// value is type-specific, but this alignment can be used for most of the
642288943Sdim  /// types for the given target.
643288943Sdim  unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; }
644239462Sdim
645353358Sdim  /// Return the alignment (in bits) of the thrown exception object. This is
646353358Sdim  /// only meaningful for targets that allocate C++ exceptions in a system
647353358Sdim  /// runtime, such as those using the Itanium C++ ABI.
648353358Sdim  virtual unsigned getExnObjectAlignment() const {
649353358Sdim    // Itanium says that an _Unwind_Exception has to be "double-word"
650353358Sdim    // aligned (and thus the end of it is also so-aligned), meaning 16
651353358Sdim    // bytes.  Of course, that was written for the actual Itanium,
652353358Sdim    // which is a 64-bit platform.  Classically, the ABI doesn't really
653353358Sdim    // specify the alignment on other platforms, but in practice
654353358Sdim    // libUnwind declares the struct with __attribute__((aligned)), so
655353358Sdim    // we assume that alignment here.  (It's generally 16 bytes, but
656353358Sdim    // some targets overwrite it.)
657353358Sdim    return getDefaultAlignForAttributeAligned();
658353358Sdim  }
659353358Sdim
660341825Sdim  /// Return the size of intmax_t and uintmax_t for this target, in bits.
661193326Sed  unsigned getIntMaxTWidth() const {
662199482Srdivacky    return getTypeWidth(IntMaxType);
663193326Sed  }
664198092Srdivacky
665249423Sdim  // Return the size of unwind_word for this target.
666309124Sdim  virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
667249423Sdim
668341825Sdim  /// Return the "preferred" register width on this target.
669309124Sdim  virtual unsigned getRegisterWidth() const {
670224145Sdim    // Currently we assume the register width on the target matches the pointer
671224145Sdim    // width, we can introduce a new variable for this if/when some target wants
672224145Sdim    // it.
673261991Sdim    return PointerWidth;
674224145Sdim  }
675224145Sdim
676341825Sdim  /// Returns the name of the mcount instrumentation function.
677218893Sdim  const char *getMCountName() const {
678218893Sdim    return MCountName;
679218893Sdim  }
680218893Sdim
681341825Sdim  /// Check if the Objective-C built-in boolean type should be signed
682239462Sdim  /// char.
683239462Sdim  ///
684239462Sdim  /// Otherwise, if this returns false, the normal built-in boolean type
685239462Sdim  /// should also be used for Objective-C.
686234982Sdim  bool useSignedCharForObjCBool() const {
687234982Sdim    return UseSignedCharForObjCBool;
688234982Sdim  }
689234982Sdim  void noSignedCharForObjCBool() {
690234982Sdim    UseSignedCharForObjCBool = false;
691234982Sdim  }
692234982Sdim
693341825Sdim  /// Check whether the alignment of bit-field types is respected
694239462Sdim  /// when laying out structures.
695207619Srdivacky  bool useBitFieldTypeAlignment() const {
696207619Srdivacky    return UseBitFieldTypeAlignment;
697207619Srdivacky  }
698207619Srdivacky
699341825Sdim  /// Check whether zero length bitfields should force alignment of
700239462Sdim  /// the next member.
701226633Sdim  bool useZeroLengthBitfieldAlignment() const {
702226633Sdim    return UseZeroLengthBitfieldAlignment;
703226633Sdim  }
704226633Sdim
705341825Sdim  /// Get the fixed alignment value in bits for a member that follows
706239462Sdim  /// a zero length bitfield.
707226633Sdim  unsigned getZeroLengthBitfieldBoundary() const {
708226633Sdim    return ZeroLengthBitfieldBoundary;
709226633Sdim  }
710226633Sdim
711341825Sdim  /// Check whether explicit bitfield alignment attributes should be
712309124Sdim  //  honored, as in "__attribute__((aligned(2))) int b : 1;".
713309124Sdim  bool useExplicitBitFieldAlignment() const {
714309124Sdim    return UseExplicitBitFieldAlignment;
715309124Sdim  }
716309124Sdim
717341825Sdim  /// Check whether this target support '\#pragma options align=mac68k'.
718208600Srdivacky  bool hasAlignMac68kSupport() const {
719208600Srdivacky    return HasAlignMac68kSupport;
720208600Srdivacky  }
721208600Srdivacky
722341825Sdim  /// Return the user string for the specified integer type enum.
723239462Sdim  ///
724193326Sed  /// For example, SignedShort -> "short".
725193326Sed  static const char *getTypeName(IntType T);
726198092Srdivacky
727341825Sdim  /// Return the constant suffix for the specified integer type enum.
728239462Sdim  ///
729239462Sdim  /// For example, SignedLong -> "L".
730276479Sdim  const char *getTypeConstantSuffix(IntType T) const;
731198398Srdivacky
732341825Sdim  /// Return the printf format modifier for the specified
733276479Sdim  /// integer type enum.
734276479Sdim  ///
735276479Sdim  /// For example, SignedLong -> "l".
736276479Sdim  static const char *getTypeFormatModifier(IntType T);
737276479Sdim
738341825Sdim  /// Check whether the given real type should use the "fpret" flavor of
739239462Sdim  /// Objective-C message passing on this target.
740210299Sed  bool useObjCFPRetForRealType(RealType T) const {
741210299Sed    return RealTypeUsesObjCFPRet & (1 << T);
742210299Sed  }
743210299Sed
744341825Sdim  /// Check whether _Complex long double should use the "fp2ret" flavor
745239462Sdim  /// of Objective-C message passing on this target.
746234353Sdim  bool useObjCFP2RetForComplexLongDouble() const {
747234353Sdim    return ComplexLongDoubleUsesFP2Ret;
748234353Sdim  }
749234353Sdim
750327952Sdim  /// Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used
751327952Sdim  /// to convert to and from __fp16.
752327952Sdim  /// FIXME: This function should be removed once all targets stop using the
753327952Sdim  /// conversion intrinsics.
754327952Sdim  virtual bool useFP16ConversionIntrinsics() const {
755327952Sdim    return true;
756327952Sdim  }
757327952Sdim
758341825Sdim  /// Specify if mangling based on address space map should be used or
759261991Sdim  /// not for language specific address spaces
760261991Sdim  bool useAddressSpaceMapMangling() const {
761261991Sdim    return UseAddrSpaceMapMangling;
762261991Sdim  }
763261991Sdim
764193326Sed  ///===---- Other target property query methods --------------------------===//
765198092Srdivacky
766341825Sdim  /// Appends the target-specific \#define values for this
767193326Sed  /// target set to the specified buffer.
768193326Sed  virtual void getTargetDefines(const LangOptions &Opts,
769202379Srdivacky                                MacroBuilder &Builder) const = 0;
770198092Srdivacky
771198398Srdivacky
772239462Sdim  /// Return information about target-specific builtins for
773193326Sed  /// the current primary target, and info about which builtins are non-portable
774193326Sed  /// across the current set of primary and secondary targets.
775296417Sdim  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
776193326Sed
777239462Sdim  /// The __builtin_clz* and __builtin_ctz* built-in
778234353Sdim  /// functions are specified to have undefined results for zero inputs, but
779234353Sdim  /// on targets that support these operations in a way that provides
780234353Sdim  /// well-defined results for zero without loss of performance, it is a good
781234353Sdim  /// idea to avoid optimizing based on that undef behavior.
782234353Sdim  virtual bool isCLZForZeroUndef() const { return true; }
783234353Sdim
784341825Sdim  /// Returns the kind of __builtin_va_list type that should be used
785239462Sdim  /// with this target.
786239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const = 0;
787193326Sed
788296417Sdim  /// Returns whether or not type \c __builtin_ms_va_list type is
789296417Sdim  /// available on this target.
790296417Sdim  bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; }
791296417Sdim
792314564Sdim  /// Returns true for RenderScript.
793314564Sdim  bool isRenderScriptTarget() const { return IsRenderScriptTarget; }
794314564Sdim
795360784Sdim  /// Returns whether or not the AArch64 SVE built-in types are
796360784Sdim  /// available on this target.
797360784Sdim  bool hasAArch64SVETypes() const { return HasAArch64SVETypes; }
798360784Sdim
799341825Sdim  /// Returns whether the passed in string is a valid clobber in an
800239462Sdim  /// inline asm statement.
801239462Sdim  ///
802239462Sdim  /// This is used by Sema.
803226633Sdim  bool isValidClobber(StringRef Name) const;
804224145Sdim
805341825Sdim  /// Returns whether the passed in string is a valid register name
806239462Sdim  /// according to GCC.
807239462Sdim  ///
808239462Sdim  /// This is used by Sema for inline asm statements.
809341825Sdim  virtual bool isValidGCCRegisterName(StringRef Name) const;
810193326Sed
811341825Sdim  /// Returns the "normalized" GCC register name.
812239462Sdim  ///
813314564Sdim  /// ReturnCannonical true will return the register name without any additions
814314564Sdim  /// such as "{}" or "%" in it's canonical form, for example:
815314564Sdim  /// ReturnCanonical = true and Name = "rax", will return "ax".
816314564Sdim  StringRef getNormalizedGCCRegisterName(StringRef Name,
817314564Sdim                                         bool ReturnCanonical = false) const;
818341825Sdim
819341825Sdim  /// Extracts a register from the passed constraint (if it is a
820341825Sdim  /// single-register constraint) and the asm label expression related to a
821341825Sdim  /// variable in the input or output list of an inline asm statement.
822341825Sdim  ///
823341825Sdim  /// This function is used by Sema in order to diagnose conflicts between
824341825Sdim  /// the clobber list and the input/output lists.
825341825Sdim  virtual StringRef getConstraintRegister(StringRef Constraint,
826341825Sdim                                          StringRef Expression) const {
827314564Sdim    return "";
828314564Sdim  }
829198092Srdivacky
830193326Sed  struct ConstraintInfo {
831193326Sed    enum {
832193326Sed      CI_None = 0x00,
833193326Sed      CI_AllowsMemory = 0x01,
834193326Sed      CI_AllowsRegister = 0x02,
835280031Sdim      CI_ReadWrite = 0x04,         // "+r" output constraint (read and write).
836280031Sdim      CI_HasMatchingInput = 0x08,  // This output operand has a matching input.
837280031Sdim      CI_ImmediateConstant = 0x10, // This operand must be an immediate constant
838280031Sdim      CI_EarlyClobber = 0x20,      // "&" output constraint (early clobber).
839193326Sed    };
840193326Sed    unsigned Flags;
841193326Sed    int TiedOperand;
842280031Sdim    struct {
843280031Sdim      int Min;
844280031Sdim      int Max;
845344896Sdim      bool isConstrained;
846280031Sdim    } ImmRange;
847296417Sdim    llvm::SmallSet<int, 4> ImmSet;
848198092Srdivacky
849193326Sed    std::string ConstraintStr;  // constraint: "=rm"
850193326Sed    std::string Name;           // Operand name: [foo] with no []'s.
851193326Sed  public:
852226633Sdim    ConstraintInfo(StringRef ConstraintStr, StringRef Name)
853280031Sdim        : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
854280031Sdim          Name(Name.str()) {
855280031Sdim      ImmRange.Min = ImmRange.Max = 0;
856344896Sdim      ImmRange.isConstrained = false;
857280031Sdim    }
858193326Sed
859193326Sed    const std::string &getConstraintStr() const { return ConstraintStr; }
860193326Sed    const std::string &getName() const { return Name; }
861193326Sed    bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
862280031Sdim    bool earlyClobber() { return (Flags & CI_EarlyClobber) != 0; }
863193326Sed    bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
864193326Sed    bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
865198092Srdivacky
866341825Sdim    /// Return true if this output operand has a matching
867193326Sed    /// (tied) input operand.
868193326Sed    bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
869198092Srdivacky
870341825Sdim    /// Return true if this input operand is a matching
871239462Sdim    /// constraint that ties it to an output operand.
872239462Sdim    ///
873239462Sdim    /// If this returns true then getTiedOperand will indicate which output
874239462Sdim    /// operand this is tied to.
875193326Sed    bool hasTiedOperand() const { return TiedOperand != -1; }
876193326Sed    unsigned getTiedOperand() const {
877193326Sed      assert(hasTiedOperand() && "Has no tied operand!");
878193326Sed      return (unsigned)TiedOperand;
879193326Sed    }
880198092Srdivacky
881280031Sdim    bool requiresImmediateConstant() const {
882280031Sdim      return (Flags & CI_ImmediateConstant) != 0;
883280031Sdim    }
884296417Sdim    bool isValidAsmImmediate(const llvm::APInt &Value) const {
885344896Sdim      if (!ImmSet.empty())
886353358Sdim        return Value.isSignedIntN(32) &&
887353358Sdim               ImmSet.count(Value.getZExtValue()) != 0;
888353358Sdim      return !ImmRange.isConstrained ||
889353358Sdim             (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max));
890296417Sdim    }
891280031Sdim
892193326Sed    void setIsReadWrite() { Flags |= CI_ReadWrite; }
893280031Sdim    void setEarlyClobber() { Flags |= CI_EarlyClobber; }
894193326Sed    void setAllowsMemory() { Flags |= CI_AllowsMemory; }
895193326Sed    void setAllowsRegister() { Flags |= CI_AllowsRegister; }
896193326Sed    void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
897280031Sdim    void setRequiresImmediate(int Min, int Max) {
898280031Sdim      Flags |= CI_ImmediateConstant;
899280031Sdim      ImmRange.Min = Min;
900280031Sdim      ImmRange.Max = Max;
901344896Sdim      ImmRange.isConstrained = true;
902280031Sdim    }
903296417Sdim    void setRequiresImmediate(llvm::ArrayRef<int> Exacts) {
904296417Sdim      Flags |= CI_ImmediateConstant;
905296417Sdim      for (int Exact : Exacts)
906296417Sdim        ImmSet.insert(Exact);
907296417Sdim    }
908296417Sdim    void setRequiresImmediate(int Exact) {
909296417Sdim      Flags |= CI_ImmediateConstant;
910296417Sdim      ImmSet.insert(Exact);
911296417Sdim    }
912296417Sdim    void setRequiresImmediate() {
913296417Sdim      Flags |= CI_ImmediateConstant;
914296417Sdim    }
915198092Srdivacky
916341825Sdim    /// Indicate that this is an input operand that is tied to
917296417Sdim    /// the specified output operand.
918239462Sdim    ///
919239462Sdim    /// Copy over the various constraint information from the output.
920193326Sed    void setTiedOperand(unsigned N, ConstraintInfo &Output) {
921193326Sed      Output.setHasMatchingInput();
922193326Sed      Flags = Output.Flags;
923193326Sed      TiedOperand = N;
924193326Sed      // Don't copy Name or constraint string.
925193326Sed    }
926193326Sed  };
927193326Sed
928341825Sdim  /// Validate register name used for global register variables.
929296417Sdim  ///
930296417Sdim  /// This function returns true if the register passed in RegName can be used
931296417Sdim  /// for global register variables on this target. In addition, it returns
932296417Sdim  /// true in HasSizeMismatch if the size of the register doesn't match the
933296417Sdim  /// variable size passed in RegSize.
934296417Sdim  virtual bool validateGlobalRegisterVariable(StringRef RegName,
935296417Sdim                                              unsigned RegSize,
936296417Sdim                                              bool &HasSizeMismatch) const {
937296417Sdim    HasSizeMismatch = false;
938296417Sdim    return true;
939296417Sdim  }
940288943Sdim
941193326Sed  // validateOutputConstraint, validateInputConstraint - Checks that
942193326Sed  // a constraint is valid and provides information about it.
943193326Sed  // FIXME: These should return a real error instead of just true/false.
944193326Sed  bool validateOutputConstraint(ConstraintInfo &Info) const;
945296417Sdim  bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,
946193326Sed                               ConstraintInfo &info) const;
947280031Sdim
948360784Sdim  virtual bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
949360784Sdim                                  StringRef /*Constraint*/,
950280031Sdim                                  unsigned /*Size*/) const {
951280031Sdim    return true;
952280031Sdim  }
953280031Sdim
954360784Sdim  virtual bool validateInputSize(const llvm::StringMap<bool> &FeatureMap,
955360784Sdim                                 StringRef /*Constraint*/,
956249423Sdim                                 unsigned /*Size*/) const {
957249423Sdim    return true;
958249423Sdim  }
959280031Sdim  virtual bool
960280031Sdim  validateConstraintModifier(StringRef /*Constraint*/,
961280031Sdim                             char /*Modifier*/,
962280031Sdim                             unsigned /*Size*/,
963280031Sdim                             std::string &/*SuggestedModifier*/) const {
964243830Sdim    return true;
965243830Sdim  }
966296417Sdim  virtual bool
967296417Sdim  validateAsmConstraint(const char *&Name,
968296417Sdim                        TargetInfo::ConstraintInfo &info) const = 0;
969296417Sdim
970193326Sed  bool resolveSymbolicName(const char *&Name,
971296417Sdim                           ArrayRef<ConstraintInfo> OutputConstraints,
972296417Sdim                           unsigned &Index) const;
973198092Srdivacky
974223017Sdim  // Constraint parm will be left pointing at the last character of
975223017Sdim  // the constraint.  In practice, it won't be changed unless the
976223017Sdim  // constraint is longer than one character.
977223017Sdim  virtual std::string convertConstraint(const char *&Constraint) const {
978218893Sdim    // 'p' defaults to 'r', but can be overridden by targets.
979223017Sdim    if (*Constraint == 'p')
980218893Sdim      return std::string("r");
981223017Sdim    return std::string(1, *Constraint);
982193326Sed  }
983198092Srdivacky
984341825Sdim  /// Returns a string of target-specific clobbers, in LLVM format.
985296417Sdim  virtual const char *getClobbers() const = 0;
986296417Sdim
987341825Sdim  /// Returns true if NaN encoding is IEEE 754-2008.
988288943Sdim  /// Only MIPS allows a different encoding.
989288943Sdim  virtual bool isNan2008() const {
990288943Sdim    return true;
991288943Sdim  }
992288943Sdim
993341825Sdim  /// Returns the target triple of the primary target.
994198092Srdivacky  const llvm::Triple &getTriple() const {
995198092Srdivacky    return Triple;
996193326Sed  }
997198092Srdivacky
998309124Sdim  const llvm::DataLayout &getDataLayout() const {
999309124Sdim    assert(DataLayout && "Uninitialized DataLayout!");
1000309124Sdim    return *DataLayout;
1001193326Sed  }
1002193326Sed
1003193326Sed  struct GCCRegAlias {
1004193326Sed    const char * const Aliases[5];
1005193326Sed    const char * const Register;
1006193326Sed  };
1007193326Sed
1008224145Sdim  struct AddlRegName {
1009224145Sdim    const char * const Names[5];
1010224145Sdim    const unsigned RegNum;
1011224145Sdim  };
1012224145Sdim
1013341825Sdim  /// Does this target support "protected" visibility?
1014234353Sdim  ///
1015234353Sdim  /// Any target which dynamic libraries will naturally support
1016234353Sdim  /// something like "default" (meaning that the symbol is visible
1017234353Sdim  /// outside this shared object) and "hidden" (meaning that it isn't)
1018234353Sdim  /// visibilities, but "protected" is really an ELF-specific concept
1019239462Sdim  /// with weird semantics designed around the convenience of dynamic
1020234353Sdim  /// linker implementations.  Which is not to suggest that there's
1021234353Sdim  /// consistent target-independent semantics for "default" visibility
1022234353Sdim  /// either; the entire thing is pretty badly mangled.
1023234353Sdim  virtual bool hasProtectedVisibility() const { return true; }
1024234353Sdim
1025341825Sdim  /// An optional hook that targets can implement to perform semantic
1026239462Sdim  /// checking on attribute((section("foo"))) specifiers.
1027239462Sdim  ///
1028239462Sdim  /// In this case, "foo" is passed in to be checked.  If the section
1029239462Sdim  /// specifier is invalid, the backend should return a non-empty string
1030198092Srdivacky  /// that indicates the problem.
1031198092Srdivacky  ///
1032198092Srdivacky  /// This hook is a simple quality of implementation feature to catch errors
1033198092Srdivacky  /// and give good diagnostics in cases when the assembler or code generator
1034198092Srdivacky  /// would otherwise reject the section specifier.
1035198092Srdivacky  ///
1036226633Sdim  virtual std::string isValidSectionSpecifier(StringRef SR) const {
1037198092Srdivacky    return "";
1038193326Sed  }
1039193326Sed
1040341825Sdim  /// Set forced language options.
1041239462Sdim  ///
1042199482Srdivacky  /// Apply changes to the target information with respect to certain
1043321369Sdim  /// language options which change the target configuration and adjust
1044321369Sdim  /// the language based on the target options where applicable.
1045321369Sdim  virtual void adjust(LangOptions &Opts);
1046193326Sed
1047341825Sdim  /// Adjust target options based on codegen options.
1048314564Sdim  virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
1049314564Sdim                                   TargetOptions &TargetOpts) const {}
1050314564Sdim
1051341825Sdim  /// Initialize the map with the default set of target features for the
1052296417Sdim  /// CPU this should include all legal feature strings on the target.
1053296417Sdim  ///
1054296417Sdim  /// \return False on error (invalid features).
1055296417Sdim  virtual bool initFeatureMap(llvm::StringMap<bool> &Features,
1056296417Sdim                              DiagnosticsEngine &Diags, StringRef CPU,
1057296417Sdim                              const std::vector<std::string> &FeatureVec) const;
1058193326Sed
1059341825Sdim  /// Get the ABI currently in use.
1060276479Sdim  virtual StringRef getABI() const { return StringRef(); }
1061198092Srdivacky
1062341825Sdim  /// Get the C++ ABI currently in use.
1063249423Sdim  TargetCXXABI getCXXABI() const {
1064249423Sdim    return TheCXXABI;
1065210299Sed  }
1066210299Sed
1067341825Sdim  /// Target the specified CPU.
1068201361Srdivacky  ///
1069239462Sdim  /// \return  False on error (invalid CPU name).
1070201361Srdivacky  virtual bool setCPU(const std::string &Name) {
1071226633Sdim    return false;
1072201361Srdivacky  }
1073201361Srdivacky
1074341825Sdim  /// Fill a SmallVectorImpl with the valid values to setCPU.
1075341825Sdim  virtual void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {}
1076341825Sdim
1077327952Sdim  /// brief Determine whether this TargetInfo supports the given CPU name.
1078327952Sdim  virtual bool isValidCPUName(StringRef Name) const {
1079327952Sdim    return true;
1080327952Sdim  }
1081327952Sdim
1082341825Sdim  /// Use the specified ABI.
1083198092Srdivacky  ///
1084239462Sdim  /// \return False on error (invalid ABI name).
1085198092Srdivacky  virtual bool setABI(const std::string &Name) {
1086198092Srdivacky    return false;
1087198092Srdivacky  }
1088198092Srdivacky
1089341825Sdim  /// Use the specified unit for FP math.
1090261991Sdim  ///
1091261991Sdim  /// \return False on error (invalid unit name).
1092261991Sdim  virtual bool setFPMath(StringRef Name) {
1093261991Sdim    return false;
1094261991Sdim  }
1095261991Sdim
1096341825Sdim  /// Enable or disable a specific target feature;
1097193326Sed  /// the feature name must be valid.
1098261991Sdim  virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
1099234353Sdim                                 StringRef Name,
1100193326Sed                                 bool Enabled) const {
1101261991Sdim    Features[Name] = Enabled;
1102193326Sed  }
1103193326Sed
1104341825Sdim  /// Determine whether this TargetInfo supports the given feature.
1105327952Sdim  virtual bool isValidFeatureName(StringRef Feature) const {
1106327952Sdim    return true;
1107327952Sdim  }
1108327952Sdim
1109360784Sdim  struct BranchProtectionInfo {
1110360784Sdim    CodeGenOptions::SignReturnAddressScope SignReturnAddr =
1111360784Sdim        CodeGenOptions::SignReturnAddressScope::None;
1112360784Sdim    CodeGenOptions::SignReturnAddressKeyValue SignKey =
1113360784Sdim        CodeGenOptions::SignReturnAddressKeyValue::AKey;
1114360784Sdim    bool BranchTargetEnforcement = false;
1115360784Sdim  };
1116360784Sdim
1117360784Sdim  /// Determine if this TargetInfo supports the given branch protection
1118360784Sdim  /// specification
1119360784Sdim  virtual bool validateBranchProtection(StringRef Spec,
1120360784Sdim                                        BranchProtectionInfo &BPI,
1121360784Sdim                                        StringRef &Err) const {
1122360784Sdim    Err = "";
1123360784Sdim    return false;
1124360784Sdim  }
1125360784Sdim
1126341825Sdim  /// Perform initialization based on the user configured
1127239462Sdim  /// set of features (e.g., +sse4).
1128201361Srdivacky  ///
1129239462Sdim  /// The list is guaranteed to have at most one entry per feature.
1130239462Sdim  ///
1131201361Srdivacky  /// The target may modify the features list, to change which options are
1132201361Srdivacky  /// passed onwards to the backend.
1133296417Sdim  /// FIXME: This part should be fixed so that we can change handleTargetFeatures
1134296417Sdim  /// to merely a TargetInfo initialization routine.
1135261991Sdim  ///
1136261991Sdim  /// \return  False on error.
1137261991Sdim  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
1138261991Sdim                                    DiagnosticsEngine &Diags) {
1139261991Sdim    return true;
1140193326Sed  }
1141193326Sed
1142341825Sdim  /// Determine whether the given target has the given feature.
1143234353Sdim  virtual bool hasFeature(StringRef Feature) const {
1144234353Sdim    return false;
1145234353Sdim  }
1146296417Sdim
1147344779Sdim  /// Identify whether this target supports multiversioning of functions,
1148341825Sdim  /// which requires support for cpu_supports and cpu_is functionality.
1149360784Sdim  bool supportsMultiVersioning() const { return getTriple().isX86(); }
1150341825Sdim
1151344779Sdim  /// Identify whether this target supports IFuncs.
1152344779Sdim  bool supportsIFunc() const { return getTriple().isOSBinFormatELF(); }
1153344779Sdim
1154341825Sdim  // Validate the contents of the __builtin_cpu_supports(const char*)
1155296417Sdim  // argument.
1156296417Sdim  virtual bool validateCpuSupports(StringRef Name) const { return false; }
1157296417Sdim
1158341825Sdim  // Return the target-specific priority for features/cpus/vendors so
1159341825Sdim  // that they can be properly sorted for checking.
1160341825Sdim  virtual unsigned multiVersionSortPriority(StringRef Name) const {
1161341825Sdim    return 0;
1162341825Sdim  }
1163341825Sdim
1164341825Sdim  // Validate the contents of the __builtin_cpu_is(const char*)
1165327952Sdim  // argument.
1166327952Sdim  virtual bool validateCpuIs(StringRef Name) const { return false; }
1167327952Sdim
1168341825Sdim  // Validate a cpu_dispatch/cpu_specific CPU option, which is a different list
1169341825Sdim  // from cpu_is, since it checks via features rather than CPUs directly.
1170341825Sdim  virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const {
1171341825Sdim    return false;
1172341825Sdim  }
1173341825Sdim
1174341825Sdim  // Get the character to be added for mangling purposes for cpu_specific.
1175341825Sdim  virtual char CPUSpecificManglingCharacter(StringRef Name) const {
1176341825Sdim    llvm_unreachable(
1177341825Sdim        "cpu_specific Multiversioning not implemented on this target");
1178341825Sdim  }
1179341825Sdim
1180341825Sdim  // Get a list of the features that make up the CPU option for
1181341825Sdim  // cpu_specific/cpu_dispatch so that it can be passed to llvm as optimization
1182341825Sdim  // options.
1183341825Sdim  virtual void getCPUSpecificCPUDispatchFeatures(
1184341825Sdim      StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
1185341825Sdim    llvm_unreachable(
1186341825Sdim        "cpu_specific Multiversioning not implemented on this target");
1187341825Sdim  }
1188341825Sdim
1189341825Sdim  // Returns maximal number of args passed in registers.
1190193326Sed  unsigned getRegParmMax() const {
1191224145Sdim    assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
1192193326Sed    return RegParmMax;
1193193326Sed  }
1194193326Sed
1195341825Sdim  /// Whether the target supports thread-local storage.
1196198092Srdivacky  bool isTLSSupported() const {
1197193326Sed    return TLSSupported;
1198193326Sed  }
1199218893Sdim
1200341825Sdim  /// Return the maximum alignment (in bits) of a TLS variable
1201288943Sdim  ///
1202288943Sdim  /// Gets the maximum alignment (in bits) of a TLS variable on this target.
1203288943Sdim  /// Returns zero if there is no such constraint.
1204288943Sdim  unsigned short getMaxTLSAlign() const {
1205288943Sdim    return MaxTLSAlign;
1206288943Sdim  }
1207288943Sdim
1208341825Sdim  /// Whether target supports variable-length arrays.
1209327952Sdim  bool isVLASupported() const { return VLASupported; }
1210327952Sdim
1211341825Sdim  /// Whether the target supports SEH __try.
1212288943Sdim  bool isSEHTrySupported() const {
1213288943Sdim    return getTriple().isOSWindows() &&
1214360784Sdim           (getTriple().isX86() ||
1215341825Sdim            getTriple().getArch() == llvm::Triple::aarch64);
1216288943Sdim  }
1217288943Sdim
1218341825Sdim  /// Return true if {|} are normal characters in the asm string.
1219239462Sdim  ///
1220239462Sdim  /// If this returns false (the default), then {abc|xyz} is syntax
1221207619Srdivacky  /// that says that when compiling for asm variant #0, "abc" should be
1222207619Srdivacky  /// generated, but when compiling for asm variant #1, "xyz" should be
1223207619Srdivacky  /// generated.
1224207619Srdivacky  bool hasNoAsmVariants() const {
1225207619Srdivacky    return NoAsmVariants;
1226207619Srdivacky  }
1227218893Sdim
1228341825Sdim  /// Return the register number that __builtin_eh_return_regno would
1229239462Sdim  /// return with the specified argument.
1230309124Sdim  /// This corresponds with TargetLowering's getExceptionPointerRegister
1231309124Sdim  /// and getExceptionSelectorRegister in the backend.
1232198092Srdivacky  virtual int getEHDataRegisterNumber(unsigned RegNo) const {
1233218893Sdim    return -1;
1234198092Srdivacky  }
1235218893Sdim
1236341825Sdim  /// Return the section to use for C++ static initialization functions.
1237210299Sed  virtual const char *getStaticInitSectionSpecifier() const {
1238276479Sdim    return nullptr;
1239210299Sed  }
1240221345Sdim
1241327952Sdim  const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
1242221345Sdim
1243344779Sdim  /// Map from the address space field in builtin description strings to the
1244344779Sdim  /// language address space.
1245344779Sdim  virtual LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const {
1246344779Sdim    return getLangASFromTargetAS(AS);
1247344779Sdim  }
1248344779Sdim
1249344779Sdim  /// Map from the address space field in builtin description strings to the
1250344779Sdim  /// language address space.
1251344779Sdim  virtual LangAS getCUDABuiltinAddressSpace(unsigned AS) const {
1252344779Sdim    return getLangASFromTargetAS(AS);
1253344779Sdim  }
1254344779Sdim
1255341825Sdim  /// Return an AST address space which can be used opportunistically
1256321369Sdim  /// for constant global memory. It must be possible to convert pointers into
1257321369Sdim  /// this address space to LangAS::Default. If no such address space exists,
1258321369Sdim  /// this may return None, and such optimizations will be disabled.
1259327952Sdim  virtual llvm::Optional<LangAS> getConstantAddressSpace() const {
1260321369Sdim    return LangAS::Default;
1261321369Sdim  }
1262321369Sdim
1263341825Sdim  /// Retrieve the name of the platform as it is used in the
1264221345Sdim  /// availability attribute.
1265226633Sdim  StringRef getPlatformName() const { return PlatformName; }
1266221345Sdim
1267341825Sdim  /// Retrieve the minimum desired version of the platform, to
1268221345Sdim  /// which the program should be compiled.
1269221345Sdim  VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
1270221345Sdim
1271234353Sdim  bool isBigEndian() const { return BigEndian; }
1272314564Sdim  bool isLittleEndian() const { return !BigEndian; }
1273234353Sdim
1274341825Sdim  /// Gets the default calling convention for the given target and
1275243830Sdim  /// declaration context.
1276353358Sdim  virtual CallingConv getDefaultCallingConv() const {
1277243830Sdim    // Not all targets will specify an explicit calling convention that we can
1278243830Sdim    // express.  This will always do the right thing, even though it's not
1279243830Sdim    // an explicit calling convention.
1280249423Sdim    return CC_C;
1281243830Sdim  }
1282243830Sdim
1283243830Sdim  enum CallingConvCheckResult {
1284243830Sdim    CCCR_OK,
1285288943Sdim    CCCR_Warning,
1286288943Sdim    CCCR_Ignore,
1287360784Sdim    CCCR_Error,
1288243830Sdim  };
1289243830Sdim
1290341825Sdim  /// Determines whether a given calling convention is valid for the
1291296417Sdim  /// target. A calling convention can either be accepted, produce a warning
1292243830Sdim  /// and be substituted with the default calling convention, or (someday)
1293243830Sdim  /// produce an error (such as using thiscall on a non-instance function).
1294243830Sdim  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
1295243830Sdim    switch (CC) {
1296243830Sdim      default:
1297243830Sdim        return CCCR_Warning;
1298243830Sdim      case CC_C:
1299243830Sdim        return CCCR_OK;
1300243830Sdim    }
1301243830Sdim  }
1302243830Sdim
1303341825Sdim  enum CallingConvKind {
1304341825Sdim    CCK_Default,
1305341825Sdim    CCK_ClangABI4OrPS4,
1306341825Sdim    CCK_MicrosoftWin64
1307341825Sdim  };
1308341825Sdim
1309341825Sdim  virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;
1310341825Sdim
1311283526Sdim  /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
1312283526Sdim  /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
1313283526Sdim  virtual bool hasSjLjLowering() const {
1314283526Sdim    return false;
1315283526Sdim  }
1316283526Sdim
1317341825Sdim  /// Check if the target supports CFProtection branch.
1318341825Sdim  virtual bool
1319341825Sdim  checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const;
1320341825Sdim
1321341825Sdim  /// Check if the target supports CFProtection branch.
1322341825Sdim  virtual bool
1323341825Sdim  checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const;
1324341825Sdim
1325341825Sdim  /// Whether target allows to overalign ABI-specified preferred alignment
1326309124Sdim  virtual bool allowsLargerPreferedTypeAlignment() const { return true; }
1327309124Sdim
1328341825Sdim  /// Set supported OpenCL extensions and optional core features.
1329309124Sdim  virtual void setSupportedOpenCLOpts() {}
1330309124Sdim
1331341825Sdim  /// Set supported OpenCL extensions as written on command line
1332314564Sdim  virtual void setOpenCLExtensionOpts() {
1333314564Sdim    for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
1334314564Sdim      getTargetOpts().SupportedOpenCLOptions.support(Ext);
1335314564Sdim    }
1336314564Sdim  }
1337314564Sdim
1338341825Sdim  /// Get supported OpenCL extensions and optional core features.
1339309124Sdim  OpenCLOptions &getSupportedOpenCLOpts() {
1340309124Sdim    return getTargetOpts().SupportedOpenCLOptions;
1341309124Sdim  }
1342309124Sdim
1343341825Sdim  /// Get const supported OpenCL extensions and optional core features.
1344309124Sdim  const OpenCLOptions &getSupportedOpenCLOpts() const {
1345309124Sdim      return getTargetOpts().SupportedOpenCLOptions;
1346309124Sdim  }
1347309124Sdim
1348327952Sdim  enum OpenCLTypeKind {
1349327952Sdim    OCLTK_Default,
1350327952Sdim    OCLTK_ClkEvent,
1351327952Sdim    OCLTK_Event,
1352327952Sdim    OCLTK_Image,
1353327952Sdim    OCLTK_Pipe,
1354327952Sdim    OCLTK_Queue,
1355327952Sdim    OCLTK_ReserveID,
1356327952Sdim    OCLTK_Sampler,
1357327952Sdim  };
1358314564Sdim
1359341825Sdim  /// Get address space for OpenCL type.
1360327952Sdim  virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const;
1361327952Sdim
1362321369Sdim  /// \returns Target specific vtbl ptr address space.
1363321369Sdim  virtual unsigned getVtblPtrAddressSpace() const {
1364321369Sdim    return 0;
1365321369Sdim  }
1366321369Sdim
1367321369Sdim  /// \returns If a target requires an address within a target specific address
1368321369Sdim  /// space \p AddressSpace to be converted in order to be used, then return the
1369321369Sdim  /// corresponding target specific DWARF address space.
1370321369Sdim  ///
1371321369Sdim  /// \returns Otherwise return None and no conversion will be emitted in the
1372321369Sdim  /// DWARF.
1373321369Sdim  virtual Optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const {
1374321369Sdim    return None;
1375321369Sdim  }
1376321369Sdim
1377344779Sdim  /// \returns The version of the SDK which was used during the compilation if
1378344779Sdim  /// one was specified, or an empty version otherwise.
1379344779Sdim  const llvm::VersionTuple &getSDKVersion() const {
1380344779Sdim    return getTargetOpts().SDKVersion;
1381344779Sdim  }
1382344779Sdim
1383341825Sdim  /// Check the target is valid after it is fully initialized.
1384309124Sdim  virtual bool validateTarget(DiagnosticsEngine &Diags) const {
1385309124Sdim    return true;
1386309124Sdim  }
1387309124Sdim
1388353358Sdim  virtual void setAuxTarget(const TargetInfo *Aux) {}
1389353358Sdim
1390360784Sdim  /// Whether target allows debuginfo types for decl only variables.
1391360784Sdim  virtual bool allowDebugInfoForExternalVar() const { return false; }
1392360784Sdim
1393193326Sedprotected:
1394353358Sdim  /// Copy type and layout related info.
1395353358Sdim  void copyAuxTarget(const TargetInfo *Aux);
1396193326Sed  virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
1397193326Sed    return PointerWidth;
1398193326Sed  }
1399193326Sed  virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
1400193326Sed    return PointerAlign;
1401193326Sed  }
1402193326Sed  virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const {
1403193326Sed    return PtrDiffType;
1404193326Sed  }
1405296417Sdim  virtual ArrayRef<const char *> getGCCRegNames() const = 0;
1406296417Sdim  virtual ArrayRef<GCCRegAlias> getGCCRegAliases() const = 0;
1407296417Sdim  virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const {
1408296417Sdim    return None;
1409224145Sdim  }
1410341825Sdim
1411341825Sdim private:
1412341825Sdim  // Assert the values for the fractional and integral bits for each fixed point
1413341825Sdim  // type follow the restrictions given in clause 6.2.6.3 of N1169.
1414341825Sdim  void CheckFixedPointBits() const;
1415193326Sed};
1416193326Sed
1417193326Sed}  // end namespace clang
1418193326Sed
1419193326Sed#endif
1420