TargetInfo.h revision 344779
1193326Sed//===--- TargetInfo.h - Expose information about the target -----*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9239462Sdim///
10239462Sdim/// \file
11341825Sdim/// Defines the clang::TargetInfo interface.
12239462Sdim///
13193326Sed//===----------------------------------------------------------------------===//
14193326Sed
15193326Sed#ifndef LLVM_CLANG_BASIC_TARGETINFO_H
16193326Sed#define LLVM_CLANG_BASIC_TARGETINFO_H
17193326Sed
18249423Sdim#include "clang/Basic/AddressSpaces.h"
19226633Sdim#include "clang/Basic/LLVM.h"
20249423Sdim#include "clang/Basic/Specifiers.h"
21276479Sdim#include "clang/Basic/TargetCXXABI.h"
22249423Sdim#include "clang/Basic/TargetOptions.h"
23309124Sdim#include "llvm/ADT/APInt.h"
24221345Sdim#include "llvm/ADT/IntrusiveRefCntPtr.h"
25321369Sdim#include "llvm/ADT/Optional.h"
26296417Sdim#include "llvm/ADT/SmallSet.h"
27193326Sed#include "llvm/ADT/StringMap.h"
28221345Sdim#include "llvm/ADT/StringRef.h"
29198092Srdivacky#include "llvm/ADT/Triple.h"
30309124Sdim#include "llvm/IR/DataLayout.h"
31218893Sdim#include "llvm/Support/DataTypes.h"
32341825Sdim#include "llvm/Support/VersionTuple.h"
33193326Sed#include <cassert>
34249423Sdim#include <string>
35193326Sed#include <vector>
36193326Sed
37198092Srdivackynamespace llvm {
38198092Srdivackystruct fltSemantics;
39198092Srdivacky}
40193326Sed
41193326Sednamespace clang {
42226633Sdimclass DiagnosticsEngine;
43199482Srdivackyclass LangOptions;
44314564Sdimclass CodeGenOptions;
45202379Srdivackyclass MacroBuilder;
46314564Sdimclass QualType;
47198092Srdivackyclass SourceLocation;
48193326Sedclass SourceManager;
49199482Srdivacky
50193326Sednamespace Builtin { struct Info; }
51198092Srdivacky
52341825Sdim/// Exposes information about the current target.
53193326Sed///
54234353Sdimclass TargetInfo : public RefCountedBase<TargetInfo> {
55276479Sdim  std::shared_ptr<TargetOptions> TargetOpts;
56198092Srdivacky  llvm::Triple Triple;
57193326Sedprotected:
58193326Sed  // Target values set by the ctor of the actual target implementation.  Default
59193326Sed  // values are specified by the TargetInfo constructor.
60234353Sdim  bool BigEndian;
61193326Sed  bool TLSSupported;
62327952Sdim  bool VLASupported;
63207619Srdivacky  bool NoAsmVariants;  // True if {|} are normal characters.
64341825Sdim  bool HasLegalHalfType; // True if the backend supports operations on the half
65341825Sdim                         // LLVM IR type.
66309124Sdim  bool HasFloat128;
67344779Sdim  bool HasFloat16;
68193326Sed  unsigned char PointerWidth, PointerAlign;
69218893Sdim  unsigned char BoolWidth, BoolAlign;
70193326Sed  unsigned char IntWidth, IntAlign;
71226633Sdim  unsigned char HalfWidth, HalfAlign;
72193326Sed  unsigned char FloatWidth, FloatAlign;
73193326Sed  unsigned char DoubleWidth, DoubleAlign;
74309124Sdim  unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align;
75210299Sed  unsigned char LargeArrayMinWidth, LargeArrayAlign;
76193326Sed  unsigned char LongWidth, LongAlign;
77193326Sed  unsigned char LongLongWidth, LongLongAlign;
78341825Sdim
79341825Sdim  // Fixed point bit widths
80341825Sdim  unsigned char ShortAccumWidth, ShortAccumAlign;
81341825Sdim  unsigned char AccumWidth, AccumAlign;
82341825Sdim  unsigned char LongAccumWidth, LongAccumAlign;
83341825Sdim  unsigned char ShortFractWidth, ShortFractAlign;
84341825Sdim  unsigned char FractWidth, FractAlign;
85341825Sdim  unsigned char LongFractWidth, LongFractAlign;
86341825Sdim
87341825Sdim  // If true, unsigned fixed point types have the same number of fractional bits
88341825Sdim  // as their signed counterparts, forcing the unsigned types to have one extra
89341825Sdim  // bit of padding. Otherwise, unsigned fixed point types have
90341825Sdim  // one more fractional bit than its corresponding signed type. This is false
91341825Sdim  // by default.
92341825Sdim  bool PaddingOnUnsignedFixedPoint;
93341825Sdim
94341825Sdim  // Fixed point integral and fractional bit sizes
95341825Sdim  // Saturated types share the same integral/fractional bits as their
96341825Sdim  // corresponding unsaturated types.
97341825Sdim  // For simplicity, the fractional bits in a _Fract type will be one less the
98341825Sdim  // width of that _Fract type. This leaves all signed _Fract types having no
99341825Sdim  // padding and unsigned _Fract types will only have 1 bit of padding after the
100341825Sdim  // sign if PaddingOnUnsignedFixedPoint is set.
101341825Sdim  unsigned char ShortAccumScale;
102341825Sdim  unsigned char AccumScale;
103341825Sdim  unsigned char LongAccumScale;
104341825Sdim
105234353Sdim  unsigned char SuitableAlign;
106288943Sdim  unsigned char DefaultAlignForAttributeAligned;
107251662Sdim  unsigned char MinGlobalAlign;
108226633Sdim  unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
109239462Sdim  unsigned short MaxVectorAlign;
110288943Sdim  unsigned short MaxTLSAlign;
111288943Sdim  unsigned short SimdDefaultAlign;
112314564Sdim  unsigned short NewAlign;
113309124Sdim  std::unique_ptr<llvm::DataLayout> DataLayout;
114218893Sdim  const char *MCountName;
115226633Sdim  const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
116309124Sdim    *LongDoubleFormat, *Float128Format;
117193326Sed  unsigned char RegParmMax, SSERegParmMax;
118249423Sdim  TargetCXXABI TheCXXABI;
119327952Sdim  const LangASMap *AddrSpaceMap;
120193326Sed
121226633Sdim  mutable StringRef PlatformName;
122221345Sdim  mutable VersionTuple PlatformMinVersion;
123221345Sdim
124208600Srdivacky  unsigned HasAlignMac68kSupport : 1;
125210299Sed  unsigned RealTypeUsesObjCFPRet : 3;
126234353Sdim  unsigned ComplexLongDoubleUsesFP2Ret : 1;
127208600Srdivacky
128296417Sdim  unsigned HasBuiltinMSVaList : 1;
129296417Sdim
130314564Sdim  unsigned IsRenderScriptTarget : 1;
131314564Sdim
132193326Sed  // TargetInfo Constructor.  Default initializes all fields.
133261991Sdim  TargetInfo(const llvm::Triple &T);
134198092Srdivacky
135309124Sdim  void resetDataLayout(StringRef DL) {
136309124Sdim    DataLayout.reset(new llvm::DataLayout(DL));
137309124Sdim  }
138309124Sdim
139198092Srdivackypublic:
140341825Sdim  /// Construct a target for the given options.
141201361Srdivacky  ///
142201361Srdivacky  /// \param Opts - The options to use to initialize the target. The target may
143201361Srdivacky  /// modify the options to canonicalize the target feature information to match
144201361Srdivacky  /// what the backend expects.
145276479Sdim  static TargetInfo *
146276479Sdim  CreateTargetInfo(DiagnosticsEngine &Diags,
147276479Sdim                   const std::shared_ptr<TargetOptions> &Opts);
148193326Sed
149193326Sed  virtual ~TargetInfo();
150193326Sed
151341825Sdim  /// Retrieve the target options.
152296417Sdim  TargetOptions &getTargetOpts() const {
153243830Sdim    assert(TargetOpts && "Missing target options");
154296417Sdim    return *TargetOpts;
155243830Sdim  }
156243830Sdim
157193326Sed  ///===---- Target Data Type Query Methods -------------------------------===//
158193326Sed  enum IntType {
159193326Sed    NoInt = 0,
160261991Sdim    SignedChar,
161261991Sdim    UnsignedChar,
162193326Sed    SignedShort,
163193326Sed    UnsignedShort,
164193326Sed    SignedInt,
165193326Sed    UnsignedInt,
166193326Sed    SignedLong,
167193326Sed    UnsignedLong,
168193326Sed    SignedLongLong,
169193326Sed    UnsignedLongLong
170193326Sed  };
171210299Sed
172210299Sed  enum RealType {
173261991Sdim    NoFloat = 255,
174210299Sed    Float = 0,
175210299Sed    Double,
176309124Sdim    LongDouble,
177309124Sdim    Float128
178210299Sed  };
179210299Sed
180341825Sdim  /// The different kinds of __builtin_va_list types defined by
181239462Sdim  /// the target implementation.
182239462Sdim  enum BuiltinVaListKind {
183239462Sdim    /// typedef char* __builtin_va_list;
184239462Sdim    CharPtrBuiltinVaList = 0,
185239462Sdim
186239462Sdim    /// typedef void* __builtin_va_list;
187239462Sdim    VoidPtrBuiltinVaList,
188239462Sdim
189321369Sdim    /// __builtin_va_list as defined by the AArch64 ABI
190249423Sdim    /// http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055a/IHI0055A_aapcs64.pdf
191249423Sdim    AArch64ABIBuiltinVaList,
192249423Sdim
193239462Sdim    /// __builtin_va_list as defined by the PNaCl ABI:
194239462Sdim    /// http://www.chromium.org/nativeclient/pnacl/bitcode-abi#TOC-Machine-Types
195239462Sdim    PNaClABIBuiltinVaList,
196239462Sdim
197239462Sdim    /// __builtin_va_list as defined by the Power ABI:
198239462Sdim    /// https://www.power.org
199239462Sdim    ///        /resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Embedded.pdf
200239462Sdim    PowerABIBuiltinVaList,
201239462Sdim
202239462Sdim    /// __builtin_va_list as defined by the x86-64 ABI:
203321369Sdim    /// http://refspecs.linuxbase.org/elf/x86_64-abi-0.21.pdf
204243830Sdim    X86_64ABIBuiltinVaList,
205243830Sdim
206243830Sdim    /// __builtin_va_list as defined by ARM AAPCS ABI
207243830Sdim    /// http://infocenter.arm.com
208243830Sdim    //        /help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
209251662Sdim    AAPCSABIBuiltinVaList,
210251662Sdim
211251662Sdim    // typedef struct __va_list_tag
212251662Sdim    //   {
213251662Sdim    //     long __gpr;
214251662Sdim    //     long __fpr;
215251662Sdim    //     void *__overflow_arg_area;
216251662Sdim    //     void *__reg_save_area;
217251662Sdim    //   } va_list[1];
218251662Sdim    SystemZBuiltinVaList
219239462Sdim  };
220239462Sdim
221193326Sedprotected:
222276479Sdim  IntType SizeType, IntMaxType, PtrDiffType, IntPtrType, WCharType,
223243830Sdim          WIntType, Char16Type, Char32Type, Int64Type, SigAtomicType,
224243830Sdim          ProcessIDType;
225207619Srdivacky
226341825Sdim  /// Whether Objective-C's built-in boolean type should be signed char.
227239462Sdim  ///
228234982Sdim  /// Otherwise, when this flag is not set, the normal built-in boolean type is
229234982Sdim  /// used.
230234982Sdim  unsigned UseSignedCharForObjCBool : 1;
231234982Sdim
232207619Srdivacky  /// Control whether the alignment of bit-field types is respected when laying
233207619Srdivacky  /// out structures. If true, then the alignment of the bit-field type will be
234207619Srdivacky  /// used to (a) impact the alignment of the containing structure, and (b)
235207619Srdivacky  /// ensure that the individual bit-field will not straddle an alignment
236207619Srdivacky  /// boundary.
237207619Srdivacky  unsigned UseBitFieldTypeAlignment : 1;
238207619Srdivacky
239341825Sdim  /// Whether zero length bitfields (e.g., int : 0;) force alignment of
240239462Sdim  /// the next bitfield.
241239462Sdim  ///
242239462Sdim  /// If the alignment of the zero length bitfield is greater than the member
243239462Sdim  /// that follows it, `bar', `bar' will be aligned as the type of the
244239462Sdim  /// zero-length bitfield.
245226633Sdim  unsigned UseZeroLengthBitfieldAlignment : 1;
246226633Sdim
247341825Sdim  ///  Whether explicit bit field alignment attributes are honored.
248309124Sdim  unsigned UseExplicitBitFieldAlignment : 1;
249309124Sdim
250226633Sdim  /// If non-zero, specifies a fixed alignment value for bitfields that follow
251226633Sdim  /// zero length bitfield, regardless of the zero length bitfield type.
252226633Sdim  unsigned ZeroLengthBitfieldBoundary;
253226633Sdim
254341825Sdim  /// Specify if mangling based on address space map should be used or
255261991Sdim  /// not for language specific address spaces
256261991Sdim  bool UseAddrSpaceMapMangling;
257261991Sdim
258193326Sedpublic:
259193326Sed  IntType getSizeType() const { return SizeType; }
260321369Sdim  IntType getSignedSizeType() const {
261321369Sdim    switch (SizeType) {
262321369Sdim    case UnsignedShort:
263321369Sdim      return SignedShort;
264321369Sdim    case UnsignedInt:
265321369Sdim      return SignedInt;
266321369Sdim    case UnsignedLong:
267321369Sdim      return SignedLong;
268321369Sdim    case UnsignedLongLong:
269321369Sdim      return SignedLongLong;
270321369Sdim    default:
271321369Sdim      llvm_unreachable("Invalid SizeType");
272321369Sdim    }
273321369Sdim  }
274193326Sed  IntType getIntMaxType() const { return IntMaxType; }
275276479Sdim  IntType getUIntMaxType() const {
276276479Sdim    return getCorrespondingUnsignedType(IntMaxType);
277276479Sdim  }
278193326Sed  IntType getPtrDiffType(unsigned AddrSpace) const {
279193326Sed    return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
280193326Sed  }
281327952Sdim  IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
282327952Sdim    return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
283327952Sdim  }
284193326Sed  IntType getIntPtrType() const { return IntPtrType; }
285276479Sdim  IntType getUIntPtrType() const {
286276479Sdim    return getCorrespondingUnsignedType(IntPtrType);
287276479Sdim  }
288193326Sed  IntType getWCharType() const { return WCharType; }
289198398Srdivacky  IntType getWIntType() const { return WIntType; }
290198092Srdivacky  IntType getChar16Type() const { return Char16Type; }
291198092Srdivacky  IntType getChar32Type() const { return Char32Type; }
292195341Sed  IntType getInt64Type() const { return Int64Type; }
293276479Sdim  IntType getUInt64Type() const {
294276479Sdim    return getCorrespondingUnsignedType(Int64Type);
295276479Sdim  }
296199990Srdivacky  IntType getSigAtomicType() const { return SigAtomicType; }
297243830Sdim  IntType getProcessIDType() const { return ProcessIDType; }
298193326Sed
299276479Sdim  static IntType getCorrespondingUnsignedType(IntType T) {
300276479Sdim    switch (T) {
301276479Sdim    case SignedChar:
302276479Sdim      return UnsignedChar;
303276479Sdim    case SignedShort:
304276479Sdim      return UnsignedShort;
305276479Sdim    case SignedInt:
306276479Sdim      return UnsignedInt;
307276479Sdim    case SignedLong:
308276479Sdim      return UnsignedLong;
309276479Sdim    case SignedLongLong:
310276479Sdim      return UnsignedLongLong;
311276479Sdim    default:
312276479Sdim      llvm_unreachable("Unexpected signed integer type");
313276479Sdim    }
314276479Sdim  }
315276479Sdim
316344779Sdim  /// In the event this target uses the same number of fractional bits for its
317344779Sdim  /// unsigned types as it does with its signed counterparts, there will be
318344779Sdim  /// exactly one bit of padding.
319344779Sdim  /// Return true if unsigned fixed point types have padding for this target.
320344779Sdim  bool doUnsignedFixedPointTypesHavePadding() const {
321344779Sdim    return PaddingOnUnsignedFixedPoint;
322344779Sdim  }
323344779Sdim
324341825Sdim  /// Return the width (in bits) of the specified integer type enum.
325239462Sdim  ///
326239462Sdim  /// For example, SignedInt -> getIntWidth().
327198398Srdivacky  unsigned getTypeWidth(IntType T) const;
328198398Srdivacky
329341825Sdim  /// Return integer type with specified width.
330296417Sdim  virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const;
331261991Sdim
332341825Sdim  /// Return the smallest integer type with at least the specified width.
333296417Sdim  virtual IntType getLeastIntTypeByWidth(unsigned BitWidth,
334296417Sdim                                         bool IsSigned) const;
335276479Sdim
336341825Sdim  /// Return floating point type with specified width.
337261991Sdim  RealType getRealTypeByWidth(unsigned BitWidth) const;
338261991Sdim
339341825Sdim  /// Return the alignment (in bits) of the specified integer type enum.
340239462Sdim  ///
341239462Sdim  /// For example, SignedInt -> getIntAlign().
342199482Srdivacky  unsigned getTypeAlign(IntType T) const;
343199482Srdivacky
344341825Sdim  /// Returns true if the type is signed; false otherwise.
345218893Sdim  static bool isTypeSigned(IntType T);
346198398Srdivacky
347341825Sdim  /// Return the width of pointers on this target, for the
348193326Sed  /// specified address space.
349193326Sed  uint64_t getPointerWidth(unsigned AddrSpace) const {
350193326Sed    return AddrSpace == 0 ? PointerWidth : getPointerWidthV(AddrSpace);
351193326Sed  }
352193326Sed  uint64_t getPointerAlign(unsigned AddrSpace) const {
353193326Sed    return AddrSpace == 0 ? PointerAlign : getPointerAlignV(AddrSpace);
354193326Sed  }
355198092Srdivacky
356341825Sdim  /// Return the maximum width of pointers on this target.
357314564Sdim  virtual uint64_t getMaxPointerWidth() const {
358314564Sdim    return PointerWidth;
359314564Sdim  }
360314564Sdim
361341825Sdim  /// Get integer value for null pointer.
362314564Sdim  /// \param AddrSpace address space of pointee in source language.
363327952Sdim  virtual uint64_t getNullPointerValue(LangAS AddrSpace) const { return 0; }
364314564Sdim
365341825Sdim  /// Return the size of '_Bool' and C++ 'bool' for this target, in bits.
366218893Sdim  unsigned getBoolWidth() const { return BoolWidth; }
367239462Sdim
368341825Sdim  /// Return the alignment of '_Bool' and C++ 'bool' for this target.
369218893Sdim  unsigned getBoolAlign() const { return BoolAlign; }
370198092Srdivacky
371198092Srdivacky  unsigned getCharWidth() const { return 8; } // FIXME
372198092Srdivacky  unsigned getCharAlign() const { return 8; } // FIXME
373198092Srdivacky
374341825Sdim  /// Return the size of 'signed short' and 'unsigned short' for this
375239462Sdim  /// target, in bits.
376193326Sed  unsigned getShortWidth() const { return 16; } // FIXME
377239462Sdim
378341825Sdim  /// Return the alignment of 'signed short' and 'unsigned short' for
379239462Sdim  /// this target.
380193326Sed  unsigned getShortAlign() const { return 16; } // FIXME
381198092Srdivacky
382193326Sed  /// getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for
383193326Sed  /// this target, in bits.
384193326Sed  unsigned getIntWidth() const { return IntWidth; }
385193326Sed  unsigned getIntAlign() const { return IntAlign; }
386198092Srdivacky
387193326Sed  /// getLongWidth/Align - Return the size of 'signed long' and 'unsigned long'
388193326Sed  /// for this target, in bits.
389193326Sed  unsigned getLongWidth() const { return LongWidth; }
390193326Sed  unsigned getLongAlign() const { return LongAlign; }
391198092Srdivacky
392193326Sed  /// getLongLongWidth/Align - Return the size of 'signed long long' and
393193326Sed  /// 'unsigned long long' for this target, in bits.
394193326Sed  unsigned getLongLongWidth() const { return LongLongWidth; }
395193326Sed  unsigned getLongLongAlign() const { return LongLongAlign; }
396198092Srdivacky
397341825Sdim  /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
398341825Sdim  /// 'unsigned short _Accum' for this target, in bits.
399341825Sdim  unsigned getShortAccumWidth() const { return ShortAccumWidth; }
400341825Sdim  unsigned getShortAccumAlign() const { return ShortAccumAlign; }
401341825Sdim
402341825Sdim  /// getAccumWidth/Align - Return the size of 'signed _Accum' and
403341825Sdim  /// 'unsigned _Accum' for this target, in bits.
404341825Sdim  unsigned getAccumWidth() const { return AccumWidth; }
405341825Sdim  unsigned getAccumAlign() const { return AccumAlign; }
406341825Sdim
407341825Sdim  /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and
408341825Sdim  /// 'unsigned long _Accum' for this target, in bits.
409341825Sdim  unsigned getLongAccumWidth() const { return LongAccumWidth; }
410341825Sdim  unsigned getLongAccumAlign() const { return LongAccumAlign; }
411341825Sdim
412341825Sdim  /// getShortFractWidth/Align - Return the size of 'signed short _Fract' and
413341825Sdim  /// 'unsigned short _Fract' for this target, in bits.
414341825Sdim  unsigned getShortFractWidth() const { return ShortFractWidth; }
415341825Sdim  unsigned getShortFractAlign() const { return ShortFractAlign; }
416341825Sdim
417341825Sdim  /// getFractWidth/Align - Return the size of 'signed _Fract' and
418341825Sdim  /// 'unsigned _Fract' for this target, in bits.
419341825Sdim  unsigned getFractWidth() const { return FractWidth; }
420341825Sdim  unsigned getFractAlign() const { return FractAlign; }
421341825Sdim
422341825Sdim  /// getLongFractWidth/Align - Return the size of 'signed long _Fract' and
423341825Sdim  /// 'unsigned long _Fract' for this target, in bits.
424341825Sdim  unsigned getLongFractWidth() const { return LongFractWidth; }
425341825Sdim  unsigned getLongFractAlign() const { return LongFractAlign; }
426341825Sdim
427341825Sdim  /// getShortAccumScale/IBits - Return the number of fractional/integral bits
428341825Sdim  /// in a 'signed short _Accum' type.
429341825Sdim  unsigned getShortAccumScale() const { return ShortAccumScale; }
430341825Sdim  unsigned getShortAccumIBits() const {
431341825Sdim    return ShortAccumWidth - ShortAccumScale - 1;
432341825Sdim  }
433341825Sdim
434341825Sdim  /// getAccumScale/IBits - Return the number of fractional/integral bits
435341825Sdim  /// in a 'signed _Accum' type.
436341825Sdim  unsigned getAccumScale() const { return AccumScale; }
437341825Sdim  unsigned getAccumIBits() const { return AccumWidth - AccumScale - 1; }
438341825Sdim
439341825Sdim  /// getLongAccumScale/IBits - Return the number of fractional/integral bits
440341825Sdim  /// in a 'signed long _Accum' type.
441341825Sdim  unsigned getLongAccumScale() const { return LongAccumScale; }
442341825Sdim  unsigned getLongAccumIBits() const {
443341825Sdim    return LongAccumWidth - LongAccumScale - 1;
444341825Sdim  }
445341825Sdim
446341825Sdim  /// getUnsignedShortAccumScale/IBits - Return the number of
447341825Sdim  /// fractional/integral bits in a 'unsigned short _Accum' type.
448341825Sdim  unsigned getUnsignedShortAccumScale() const {
449341825Sdim    return PaddingOnUnsignedFixedPoint ? ShortAccumScale : ShortAccumScale + 1;
450341825Sdim  }
451341825Sdim  unsigned getUnsignedShortAccumIBits() const {
452341825Sdim    return PaddingOnUnsignedFixedPoint
453341825Sdim               ? getShortAccumIBits()
454341825Sdim               : ShortAccumWidth - getUnsignedShortAccumScale();
455341825Sdim  }
456341825Sdim
457341825Sdim  /// getUnsignedAccumScale/IBits - Return the number of fractional/integral
458341825Sdim  /// bits in a 'unsigned _Accum' type.
459341825Sdim  unsigned getUnsignedAccumScale() const {
460341825Sdim    return PaddingOnUnsignedFixedPoint ? AccumScale : AccumScale + 1;
461341825Sdim  }
462341825Sdim  unsigned getUnsignedAccumIBits() const {
463341825Sdim    return PaddingOnUnsignedFixedPoint ? getAccumIBits()
464341825Sdim                                       : AccumWidth - getUnsignedAccumScale();
465341825Sdim  }
466341825Sdim
467341825Sdim  /// getUnsignedLongAccumScale/IBits - Return the number of fractional/integral
468341825Sdim  /// bits in a 'unsigned long _Accum' type.
469341825Sdim  unsigned getUnsignedLongAccumScale() const {
470341825Sdim    return PaddingOnUnsignedFixedPoint ? LongAccumScale : LongAccumScale + 1;
471341825Sdim  }
472341825Sdim  unsigned getUnsignedLongAccumIBits() const {
473341825Sdim    return PaddingOnUnsignedFixedPoint
474341825Sdim               ? getLongAccumIBits()
475341825Sdim               : LongAccumWidth - getUnsignedLongAccumScale();
476341825Sdim  }
477341825Sdim
478341825Sdim  /// getShortFractScale - Return the number of fractional bits
479341825Sdim  /// in a 'signed short _Fract' type.
480341825Sdim  unsigned getShortFractScale() const { return ShortFractWidth - 1; }
481341825Sdim
482341825Sdim  /// getFractScale - Return the number of fractional bits
483341825Sdim  /// in a 'signed _Fract' type.
484341825Sdim  unsigned getFractScale() const { return FractWidth - 1; }
485341825Sdim
486341825Sdim  /// getLongFractScale - Return the number of fractional bits
487341825Sdim  /// in a 'signed long _Fract' type.
488341825Sdim  unsigned getLongFractScale() const { return LongFractWidth - 1; }
489341825Sdim
490341825Sdim  /// getUnsignedShortFractScale - Return the number of fractional bits
491341825Sdim  /// in a 'unsigned short _Fract' type.
492341825Sdim  unsigned getUnsignedShortFractScale() const {
493341825Sdim    return PaddingOnUnsignedFixedPoint ? getShortFractScale()
494341825Sdim                                       : getShortFractScale() + 1;
495341825Sdim  }
496341825Sdim
497341825Sdim  /// getUnsignedFractScale - Return the number of fractional bits
498341825Sdim  /// in a 'unsigned _Fract' type.
499341825Sdim  unsigned getUnsignedFractScale() const {
500341825Sdim    return PaddingOnUnsignedFixedPoint ? getFractScale() : getFractScale() + 1;
501341825Sdim  }
502341825Sdim
503341825Sdim  /// getUnsignedLongFractScale - Return the number of fractional bits
504341825Sdim  /// in a 'unsigned long _Fract' type.
505341825Sdim  unsigned getUnsignedLongFractScale() const {
506341825Sdim    return PaddingOnUnsignedFixedPoint ? getLongFractScale()
507341825Sdim                                       : getLongFractScale() + 1;
508341825Sdim  }
509341825Sdim
510341825Sdim  /// Determine whether the __int128 type is supported on this target.
511296417Sdim  virtual bool hasInt128Type() const {
512341825Sdim    return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
513296417Sdim  } // FIXME
514249423Sdim
515341825Sdim  /// Determine whether _Float16 is supported on this target.
516341825Sdim  virtual bool hasLegalHalfType() const { return HasLegalHalfType; }
517341825Sdim
518341825Sdim  /// Determine whether the __float128 type is supported on this target.
519309124Sdim  virtual bool hasFloat128Type() const { return HasFloat128; }
520309124Sdim
521344779Sdim  /// Determine whether the _Float16 type is supported on this target.
522344779Sdim  virtual bool hasFloat16Type() const { return HasFloat16; }
523344779Sdim
524341825Sdim  /// Return the alignment that is suitable for storing any
525234353Sdim  /// object with a fundamental alignment requirement.
526234353Sdim  unsigned getSuitableAlign() const { return SuitableAlign; }
527234353Sdim
528341825Sdim  /// Return the default alignment for __attribute__((aligned)) on
529288943Sdim  /// this target, to be used if no alignment value is specified.
530288943Sdim  unsigned getDefaultAlignForAttributeAligned() const {
531288943Sdim    return DefaultAlignForAttributeAligned;
532288943Sdim  }
533288943Sdim
534251662Sdim  /// getMinGlobalAlign - Return the minimum alignment of a global variable,
535251662Sdim  /// unless its alignment is explicitly reduced via attributes.
536251662Sdim  unsigned getMinGlobalAlign() const { return MinGlobalAlign; }
537251662Sdim
538314564Sdim  /// Return the largest alignment for which a suitably-sized allocation with
539314564Sdim  /// '::operator new(size_t)' is guaranteed to produce a correctly-aligned
540314564Sdim  /// pointer.
541314564Sdim  unsigned getNewAlign() const {
542314564Sdim    return NewAlign ? NewAlign : std::max(LongDoubleAlign, LongLongAlign);
543314564Sdim  }
544314564Sdim
545198092Srdivacky  /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
546193326Sed  /// bits.
547199482Srdivacky  unsigned getWCharWidth() const { return getTypeWidth(WCharType); }
548199482Srdivacky  unsigned getWCharAlign() const { return getTypeAlign(WCharType); }
549193326Sed
550198092Srdivacky  /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
551198092Srdivacky  /// bits.
552199482Srdivacky  unsigned getChar16Width() const { return getTypeWidth(Char16Type); }
553199482Srdivacky  unsigned getChar16Align() const { return getTypeAlign(Char16Type); }
554198092Srdivacky
555198092Srdivacky  /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
556198092Srdivacky  /// bits.
557199482Srdivacky  unsigned getChar32Width() const { return getTypeWidth(Char32Type); }
558199482Srdivacky  unsigned getChar32Align() const { return getTypeAlign(Char32Type); }
559198092Srdivacky
560226633Sdim  /// getHalfWidth/Align/Format - Return the size/align/format of 'half'.
561226633Sdim  unsigned getHalfWidth() const { return HalfWidth; }
562226633Sdim  unsigned getHalfAlign() const { return HalfAlign; }
563226633Sdim  const llvm::fltSemantics &getHalfFormat() const { return *HalfFormat; }
564226633Sdim
565193326Sed  /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
566193326Sed  unsigned getFloatWidth() const { return FloatWidth; }
567193326Sed  unsigned getFloatAlign() const { return FloatAlign; }
568193326Sed  const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; }
569193326Sed
570193326Sed  /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'.
571193326Sed  unsigned getDoubleWidth() const { return DoubleWidth; }
572193326Sed  unsigned getDoubleAlign() const { return DoubleAlign; }
573193326Sed  const llvm::fltSemantics &getDoubleFormat() const { return *DoubleFormat; }
574193326Sed
575193326Sed  /// getLongDoubleWidth/Align/Format - Return the size/align/format of 'long
576193326Sed  /// double'.
577193326Sed  unsigned getLongDoubleWidth() const { return LongDoubleWidth; }
578193326Sed  unsigned getLongDoubleAlign() const { return LongDoubleAlign; }
579193326Sed  const llvm::fltSemantics &getLongDoubleFormat() const {
580193326Sed    return *LongDoubleFormat;
581193326Sed  }
582198092Srdivacky
583309124Sdim  /// getFloat128Width/Align/Format - Return the size/align/format of
584309124Sdim  /// '__float128'.
585309124Sdim  unsigned getFloat128Width() const { return 128; }
586309124Sdim  unsigned getFloat128Align() const { return Float128Align; }
587309124Sdim  const llvm::fltSemantics &getFloat128Format() const {
588309124Sdim    return *Float128Format;
589309124Sdim  }
590309124Sdim
591341825Sdim  /// Return true if the 'long double' type should be mangled like
592288943Sdim  /// __float128.
593288943Sdim  virtual bool useFloat128ManglingForLongDouble() const { return false; }
594288943Sdim
595341825Sdim  /// Return the value for the C99 FLT_EVAL_METHOD macro.
596234353Sdim  virtual unsigned getFloatEvalMethod() const { return 0; }
597234353Sdim
598210299Sed  // getLargeArrayMinWidth/Align - Return the minimum array size that is
599210299Sed  // 'large' and its alignment.
600210299Sed  unsigned getLargeArrayMinWidth() const { return LargeArrayMinWidth; }
601210299Sed  unsigned getLargeArrayAlign() const { return LargeArrayAlign; }
602210299Sed
603341825Sdim  /// Return the maximum width lock-free atomic operation which will
604239462Sdim  /// ever be supported for the given target
605226633Sdim  unsigned getMaxAtomicPromoteWidth() const { return MaxAtomicPromoteWidth; }
606341825Sdim  /// Return the maximum width lock-free atomic operation which can be
607239462Sdim  /// inlined given the supported features of the given target.
608226633Sdim  unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
609341825Sdim  /// Set the maximum inline or promote width lock-free atomic operation
610327952Sdim  /// for the given target.
611327952Sdim  virtual void setMaxAtomicWidth() {}
612341825Sdim  /// Returns true if the given target supports lock-free atomic
613280031Sdim  /// operations at the specified width and alignment.
614280031Sdim  virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits,
615280031Sdim                                uint64_t AlignmentInBits) const {
616280031Sdim    return AtomicSizeInBits <= AlignmentInBits &&
617280031Sdim           AtomicSizeInBits <= getMaxAtomicInlineWidth() &&
618280031Sdim           (AtomicSizeInBits <= getCharWidth() ||
619280031Sdim            llvm::isPowerOf2_64(AtomicSizeInBits / getCharWidth()));
620280031Sdim  }
621226633Sdim
622341825Sdim  /// Return the maximum vector alignment supported for the given target.
623239462Sdim  unsigned getMaxVectorAlign() const { return MaxVectorAlign; }
624341825Sdim  /// Return default simd alignment for the given target. Generally, this
625288943Sdim  /// value is type-specific, but this alignment can be used for most of the
626288943Sdim  /// types for the given target.
627288943Sdim  unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; }
628239462Sdim
629341825Sdim  /// Return the size of intmax_t and uintmax_t for this target, in bits.
630193326Sed  unsigned getIntMaxTWidth() const {
631199482Srdivacky    return getTypeWidth(IntMaxType);
632193326Sed  }
633198092Srdivacky
634249423Sdim  // Return the size of unwind_word for this target.
635309124Sdim  virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); }
636249423Sdim
637341825Sdim  /// Return the "preferred" register width on this target.
638309124Sdim  virtual unsigned getRegisterWidth() const {
639224145Sdim    // Currently we assume the register width on the target matches the pointer
640224145Sdim    // width, we can introduce a new variable for this if/when some target wants
641224145Sdim    // it.
642261991Sdim    return PointerWidth;
643224145Sdim  }
644224145Sdim
645341825Sdim  /// Returns the name of the mcount instrumentation function.
646218893Sdim  const char *getMCountName() const {
647218893Sdim    return MCountName;
648218893Sdim  }
649218893Sdim
650341825Sdim  /// Check if the Objective-C built-in boolean type should be signed
651239462Sdim  /// char.
652239462Sdim  ///
653239462Sdim  /// Otherwise, if this returns false, the normal built-in boolean type
654239462Sdim  /// should also be used for Objective-C.
655234982Sdim  bool useSignedCharForObjCBool() const {
656234982Sdim    return UseSignedCharForObjCBool;
657234982Sdim  }
658234982Sdim  void noSignedCharForObjCBool() {
659234982Sdim    UseSignedCharForObjCBool = false;
660234982Sdim  }
661234982Sdim
662341825Sdim  /// Check whether the alignment of bit-field types is respected
663239462Sdim  /// when laying out structures.
664207619Srdivacky  bool useBitFieldTypeAlignment() const {
665207619Srdivacky    return UseBitFieldTypeAlignment;
666207619Srdivacky  }
667207619Srdivacky
668341825Sdim  /// Check whether zero length bitfields should force alignment of
669239462Sdim  /// the next member.
670226633Sdim  bool useZeroLengthBitfieldAlignment() const {
671226633Sdim    return UseZeroLengthBitfieldAlignment;
672226633Sdim  }
673226633Sdim
674341825Sdim  /// Get the fixed alignment value in bits for a member that follows
675239462Sdim  /// a zero length bitfield.
676226633Sdim  unsigned getZeroLengthBitfieldBoundary() const {
677226633Sdim    return ZeroLengthBitfieldBoundary;
678226633Sdim  }
679226633Sdim
680341825Sdim  /// Check whether explicit bitfield alignment attributes should be
681309124Sdim  //  honored, as in "__attribute__((aligned(2))) int b : 1;".
682309124Sdim  bool useExplicitBitFieldAlignment() const {
683309124Sdim    return UseExplicitBitFieldAlignment;
684309124Sdim  }
685309124Sdim
686341825Sdim  /// Check whether this target support '\#pragma options align=mac68k'.
687208600Srdivacky  bool hasAlignMac68kSupport() const {
688208600Srdivacky    return HasAlignMac68kSupport;
689208600Srdivacky  }
690208600Srdivacky
691341825Sdim  /// Return the user string for the specified integer type enum.
692239462Sdim  ///
693193326Sed  /// For example, SignedShort -> "short".
694193326Sed  static const char *getTypeName(IntType T);
695198092Srdivacky
696341825Sdim  /// Return the constant suffix for the specified integer type enum.
697239462Sdim  ///
698239462Sdim  /// For example, SignedLong -> "L".
699276479Sdim  const char *getTypeConstantSuffix(IntType T) const;
700198398Srdivacky
701341825Sdim  /// Return the printf format modifier for the specified
702276479Sdim  /// integer type enum.
703276479Sdim  ///
704276479Sdim  /// For example, SignedLong -> "l".
705276479Sdim  static const char *getTypeFormatModifier(IntType T);
706276479Sdim
707341825Sdim  /// Check whether the given real type should use the "fpret" flavor of
708239462Sdim  /// Objective-C message passing on this target.
709210299Sed  bool useObjCFPRetForRealType(RealType T) const {
710210299Sed    return RealTypeUsesObjCFPRet & (1 << T);
711210299Sed  }
712210299Sed
713341825Sdim  /// Check whether _Complex long double should use the "fp2ret" flavor
714239462Sdim  /// of Objective-C message passing on this target.
715234353Sdim  bool useObjCFP2RetForComplexLongDouble() const {
716234353Sdim    return ComplexLongDoubleUsesFP2Ret;
717234353Sdim  }
718234353Sdim
719327952Sdim  /// Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used
720327952Sdim  /// to convert to and from __fp16.
721327952Sdim  /// FIXME: This function should be removed once all targets stop using the
722327952Sdim  /// conversion intrinsics.
723327952Sdim  virtual bool useFP16ConversionIntrinsics() const {
724327952Sdim    return true;
725327952Sdim  }
726327952Sdim
727341825Sdim  /// Specify if mangling based on address space map should be used or
728261991Sdim  /// not for language specific address spaces
729261991Sdim  bool useAddressSpaceMapMangling() const {
730261991Sdim    return UseAddrSpaceMapMangling;
731261991Sdim  }
732261991Sdim
733193326Sed  ///===---- Other target property query methods --------------------------===//
734198092Srdivacky
735341825Sdim  /// Appends the target-specific \#define values for this
736193326Sed  /// target set to the specified buffer.
737193326Sed  virtual void getTargetDefines(const LangOptions &Opts,
738202379Srdivacky                                MacroBuilder &Builder) const = 0;
739198092Srdivacky
740198398Srdivacky
741239462Sdim  /// Return information about target-specific builtins for
742193326Sed  /// the current primary target, and info about which builtins are non-portable
743193326Sed  /// across the current set of primary and secondary targets.
744296417Sdim  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
745193326Sed
746239462Sdim  /// The __builtin_clz* and __builtin_ctz* built-in
747234353Sdim  /// functions are specified to have undefined results for zero inputs, but
748234353Sdim  /// on targets that support these operations in a way that provides
749234353Sdim  /// well-defined results for zero without loss of performance, it is a good
750234353Sdim  /// idea to avoid optimizing based on that undef behavior.
751234353Sdim  virtual bool isCLZForZeroUndef() const { return true; }
752234353Sdim
753341825Sdim  /// Returns the kind of __builtin_va_list type that should be used
754239462Sdim  /// with this target.
755239462Sdim  virtual BuiltinVaListKind getBuiltinVaListKind() const = 0;
756193326Sed
757296417Sdim  /// Returns whether or not type \c __builtin_ms_va_list type is
758296417Sdim  /// available on this target.
759296417Sdim  bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; }
760296417Sdim
761314564Sdim  /// Returns true for RenderScript.
762314564Sdim  bool isRenderScriptTarget() const { return IsRenderScriptTarget; }
763314564Sdim
764341825Sdim  /// Returns whether the passed in string is a valid clobber in an
765239462Sdim  /// inline asm statement.
766239462Sdim  ///
767239462Sdim  /// This is used by Sema.
768226633Sdim  bool isValidClobber(StringRef Name) const;
769224145Sdim
770341825Sdim  /// Returns whether the passed in string is a valid register name
771239462Sdim  /// according to GCC.
772239462Sdim  ///
773239462Sdim  /// This is used by Sema for inline asm statements.
774341825Sdim  virtual bool isValidGCCRegisterName(StringRef Name) const;
775193326Sed
776341825Sdim  /// Returns the "normalized" GCC register name.
777239462Sdim  ///
778314564Sdim  /// ReturnCannonical true will return the register name without any additions
779314564Sdim  /// such as "{}" or "%" in it's canonical form, for example:
780314564Sdim  /// ReturnCanonical = true and Name = "rax", will return "ax".
781314564Sdim  StringRef getNormalizedGCCRegisterName(StringRef Name,
782314564Sdim                                         bool ReturnCanonical = false) const;
783341825Sdim
784341825Sdim  /// Extracts a register from the passed constraint (if it is a
785341825Sdim  /// single-register constraint) and the asm label expression related to a
786341825Sdim  /// variable in the input or output list of an inline asm statement.
787341825Sdim  ///
788341825Sdim  /// This function is used by Sema in order to diagnose conflicts between
789341825Sdim  /// the clobber list and the input/output lists.
790341825Sdim  virtual StringRef getConstraintRegister(StringRef Constraint,
791341825Sdim                                          StringRef Expression) const {
792314564Sdim    return "";
793314564Sdim  }
794198092Srdivacky
795193326Sed  struct ConstraintInfo {
796193326Sed    enum {
797193326Sed      CI_None = 0x00,
798193326Sed      CI_AllowsMemory = 0x01,
799193326Sed      CI_AllowsRegister = 0x02,
800280031Sdim      CI_ReadWrite = 0x04,         // "+r" output constraint (read and write).
801280031Sdim      CI_HasMatchingInput = 0x08,  // This output operand has a matching input.
802280031Sdim      CI_ImmediateConstant = 0x10, // This operand must be an immediate constant
803280031Sdim      CI_EarlyClobber = 0x20,      // "&" output constraint (early clobber).
804193326Sed    };
805193326Sed    unsigned Flags;
806193326Sed    int TiedOperand;
807280031Sdim    struct {
808280031Sdim      int Min;
809280031Sdim      int Max;
810280031Sdim    } ImmRange;
811296417Sdim    llvm::SmallSet<int, 4> ImmSet;
812198092Srdivacky
813193326Sed    std::string ConstraintStr;  // constraint: "=rm"
814193326Sed    std::string Name;           // Operand name: [foo] with no []'s.
815193326Sed  public:
816226633Sdim    ConstraintInfo(StringRef ConstraintStr, StringRef Name)
817280031Sdim        : Flags(0), TiedOperand(-1), ConstraintStr(ConstraintStr.str()),
818280031Sdim          Name(Name.str()) {
819280031Sdim      ImmRange.Min = ImmRange.Max = 0;
820280031Sdim    }
821193326Sed
822193326Sed    const std::string &getConstraintStr() const { return ConstraintStr; }
823193326Sed    const std::string &getName() const { return Name; }
824193326Sed    bool isReadWrite() const { return (Flags & CI_ReadWrite) != 0; }
825280031Sdim    bool earlyClobber() { return (Flags & CI_EarlyClobber) != 0; }
826193326Sed    bool allowsRegister() const { return (Flags & CI_AllowsRegister) != 0; }
827193326Sed    bool allowsMemory() const { return (Flags & CI_AllowsMemory) != 0; }
828198092Srdivacky
829341825Sdim    /// Return true if this output operand has a matching
830193326Sed    /// (tied) input operand.
831193326Sed    bool hasMatchingInput() const { return (Flags & CI_HasMatchingInput) != 0; }
832198092Srdivacky
833341825Sdim    /// Return true if this input operand is a matching
834239462Sdim    /// constraint that ties it to an output operand.
835239462Sdim    ///
836239462Sdim    /// If this returns true then getTiedOperand will indicate which output
837239462Sdim    /// operand this is tied to.
838193326Sed    bool hasTiedOperand() const { return TiedOperand != -1; }
839193326Sed    unsigned getTiedOperand() const {
840193326Sed      assert(hasTiedOperand() && "Has no tied operand!");
841193326Sed      return (unsigned)TiedOperand;
842193326Sed    }
843198092Srdivacky
844280031Sdim    bool requiresImmediateConstant() const {
845280031Sdim      return (Flags & CI_ImmediateConstant) != 0;
846280031Sdim    }
847296417Sdim    bool isValidAsmImmediate(const llvm::APInt &Value) const {
848296417Sdim      return (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)) ||
849296417Sdim             ImmSet.count(Value.getZExtValue()) != 0;
850296417Sdim    }
851280031Sdim
852193326Sed    void setIsReadWrite() { Flags |= CI_ReadWrite; }
853280031Sdim    void setEarlyClobber() { Flags |= CI_EarlyClobber; }
854193326Sed    void setAllowsMemory() { Flags |= CI_AllowsMemory; }
855193326Sed    void setAllowsRegister() { Flags |= CI_AllowsRegister; }
856193326Sed    void setHasMatchingInput() { Flags |= CI_HasMatchingInput; }
857280031Sdim    void setRequiresImmediate(int Min, int Max) {
858280031Sdim      Flags |= CI_ImmediateConstant;
859280031Sdim      ImmRange.Min = Min;
860280031Sdim      ImmRange.Max = Max;
861280031Sdim    }
862296417Sdim    void setRequiresImmediate(llvm::ArrayRef<int> Exacts) {
863296417Sdim      Flags |= CI_ImmediateConstant;
864296417Sdim      for (int Exact : Exacts)
865296417Sdim        ImmSet.insert(Exact);
866296417Sdim    }
867296417Sdim    void setRequiresImmediate(int Exact) {
868296417Sdim      Flags |= CI_ImmediateConstant;
869296417Sdim      ImmSet.insert(Exact);
870296417Sdim    }
871296417Sdim    void setRequiresImmediate() {
872296417Sdim      Flags |= CI_ImmediateConstant;
873296417Sdim      ImmRange.Min = INT_MIN;
874296417Sdim      ImmRange.Max = INT_MAX;
875296417Sdim    }
876198092Srdivacky
877341825Sdim    /// Indicate that this is an input operand that is tied to
878296417Sdim    /// the specified output operand.
879239462Sdim    ///
880239462Sdim    /// Copy over the various constraint information from the output.
881193326Sed    void setTiedOperand(unsigned N, ConstraintInfo &Output) {
882193326Sed      Output.setHasMatchingInput();
883193326Sed      Flags = Output.Flags;
884193326Sed      TiedOperand = N;
885193326Sed      // Don't copy Name or constraint string.
886193326Sed    }
887193326Sed  };
888193326Sed
889341825Sdim  /// Validate register name used for global register variables.
890296417Sdim  ///
891296417Sdim  /// This function returns true if the register passed in RegName can be used
892296417Sdim  /// for global register variables on this target. In addition, it returns
893296417Sdim  /// true in HasSizeMismatch if the size of the register doesn't match the
894296417Sdim  /// variable size passed in RegSize.
895296417Sdim  virtual bool validateGlobalRegisterVariable(StringRef RegName,
896296417Sdim                                              unsigned RegSize,
897296417Sdim                                              bool &HasSizeMismatch) const {
898296417Sdim    HasSizeMismatch = false;
899296417Sdim    return true;
900296417Sdim  }
901288943Sdim
902193326Sed  // validateOutputConstraint, validateInputConstraint - Checks that
903193326Sed  // a constraint is valid and provides information about it.
904193326Sed  // FIXME: These should return a real error instead of just true/false.
905193326Sed  bool validateOutputConstraint(ConstraintInfo &Info) const;
906296417Sdim  bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,
907193326Sed                               ConstraintInfo &info) const;
908280031Sdim
909280031Sdim  virtual bool validateOutputSize(StringRef /*Constraint*/,
910280031Sdim                                  unsigned /*Size*/) const {
911280031Sdim    return true;
912280031Sdim  }
913280031Sdim
914249423Sdim  virtual bool validateInputSize(StringRef /*Constraint*/,
915249423Sdim                                 unsigned /*Size*/) const {
916249423Sdim    return true;
917249423Sdim  }
918280031Sdim  virtual bool
919280031Sdim  validateConstraintModifier(StringRef /*Constraint*/,
920280031Sdim                             char /*Modifier*/,
921280031Sdim                             unsigned /*Size*/,
922280031Sdim                             std::string &/*SuggestedModifier*/) const {
923243830Sdim    return true;
924243830Sdim  }
925296417Sdim  virtual bool
926296417Sdim  validateAsmConstraint(const char *&Name,
927296417Sdim                        TargetInfo::ConstraintInfo &info) const = 0;
928296417Sdim
929193326Sed  bool resolveSymbolicName(const char *&Name,
930296417Sdim                           ArrayRef<ConstraintInfo> OutputConstraints,
931296417Sdim                           unsigned &Index) const;
932198092Srdivacky
933223017Sdim  // Constraint parm will be left pointing at the last character of
934223017Sdim  // the constraint.  In practice, it won't be changed unless the
935223017Sdim  // constraint is longer than one character.
936223017Sdim  virtual std::string convertConstraint(const char *&Constraint) const {
937218893Sdim    // 'p' defaults to 'r', but can be overridden by targets.
938223017Sdim    if (*Constraint == 'p')
939218893Sdim      return std::string("r");
940223017Sdim    return std::string(1, *Constraint);
941193326Sed  }
942198092Srdivacky
943341825Sdim  /// Returns a string of target-specific clobbers, in LLVM format.
944296417Sdim  virtual const char *getClobbers() const = 0;
945296417Sdim
946341825Sdim  /// Returns true if NaN encoding is IEEE 754-2008.
947288943Sdim  /// Only MIPS allows a different encoding.
948288943Sdim  virtual bool isNan2008() const {
949288943Sdim    return true;
950288943Sdim  }
951288943Sdim
952341825Sdim  /// Returns the target triple of the primary target.
953198092Srdivacky  const llvm::Triple &getTriple() const {
954198092Srdivacky    return Triple;
955193326Sed  }
956198092Srdivacky
957309124Sdim  const llvm::DataLayout &getDataLayout() const {
958309124Sdim    assert(DataLayout && "Uninitialized DataLayout!");
959309124Sdim    return *DataLayout;
960193326Sed  }
961193326Sed
962193326Sed  struct GCCRegAlias {
963193326Sed    const char * const Aliases[5];
964193326Sed    const char * const Register;
965193326Sed  };
966193326Sed
967224145Sdim  struct AddlRegName {
968224145Sdim    const char * const Names[5];
969224145Sdim    const unsigned RegNum;
970224145Sdim  };
971224145Sdim
972341825Sdim  /// Does this target support "protected" visibility?
973234353Sdim  ///
974234353Sdim  /// Any target which dynamic libraries will naturally support
975234353Sdim  /// something like "default" (meaning that the symbol is visible
976234353Sdim  /// outside this shared object) and "hidden" (meaning that it isn't)
977234353Sdim  /// visibilities, but "protected" is really an ELF-specific concept
978239462Sdim  /// with weird semantics designed around the convenience of dynamic
979234353Sdim  /// linker implementations.  Which is not to suggest that there's
980234353Sdim  /// consistent target-independent semantics for "default" visibility
981234353Sdim  /// either; the entire thing is pretty badly mangled.
982234353Sdim  virtual bool hasProtectedVisibility() const { return true; }
983234353Sdim
984341825Sdim  /// An optional hook that targets can implement to perform semantic
985239462Sdim  /// checking on attribute((section("foo"))) specifiers.
986239462Sdim  ///
987239462Sdim  /// In this case, "foo" is passed in to be checked.  If the section
988239462Sdim  /// specifier is invalid, the backend should return a non-empty string
989198092Srdivacky  /// that indicates the problem.
990198092Srdivacky  ///
991198092Srdivacky  /// This hook is a simple quality of implementation feature to catch errors
992198092Srdivacky  /// and give good diagnostics in cases when the assembler or code generator
993198092Srdivacky  /// would otherwise reject the section specifier.
994198092Srdivacky  ///
995226633Sdim  virtual std::string isValidSectionSpecifier(StringRef SR) const {
996198092Srdivacky    return "";
997193326Sed  }
998193326Sed
999341825Sdim  /// Set forced language options.
1000239462Sdim  ///
1001199482Srdivacky  /// Apply changes to the target information with respect to certain
1002321369Sdim  /// language options which change the target configuration and adjust
1003321369Sdim  /// the language based on the target options where applicable.
1004321369Sdim  virtual void adjust(LangOptions &Opts);
1005193326Sed
1006341825Sdim  /// Adjust target options based on codegen options.
1007314564Sdim  virtual void adjustTargetOptions(const CodeGenOptions &CGOpts,
1008314564Sdim                                   TargetOptions &TargetOpts) const {}
1009314564Sdim
1010341825Sdim  /// Initialize the map with the default set of target features for the
1011296417Sdim  /// CPU this should include all legal feature strings on the target.
1012296417Sdim  ///
1013296417Sdim  /// \return False on error (invalid features).
1014296417Sdim  virtual bool initFeatureMap(llvm::StringMap<bool> &Features,
1015296417Sdim                              DiagnosticsEngine &Diags, StringRef CPU,
1016296417Sdim                              const std::vector<std::string> &FeatureVec) const;
1017193326Sed
1018341825Sdim  /// Get the ABI currently in use.
1019276479Sdim  virtual StringRef getABI() const { return StringRef(); }
1020198092Srdivacky
1021341825Sdim  /// Get the C++ ABI currently in use.
1022249423Sdim  TargetCXXABI getCXXABI() const {
1023249423Sdim    return TheCXXABI;
1024210299Sed  }
1025210299Sed
1026341825Sdim  /// Target the specified CPU.
1027201361Srdivacky  ///
1028239462Sdim  /// \return  False on error (invalid CPU name).
1029201361Srdivacky  virtual bool setCPU(const std::string &Name) {
1030226633Sdim    return false;
1031201361Srdivacky  }
1032201361Srdivacky
1033341825Sdim  /// Fill a SmallVectorImpl with the valid values to setCPU.
1034341825Sdim  virtual void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {}
1035341825Sdim
1036327952Sdim  /// brief Determine whether this TargetInfo supports the given CPU name.
1037327952Sdim  virtual bool isValidCPUName(StringRef Name) const {
1038327952Sdim    return true;
1039327952Sdim  }
1040327952Sdim
1041341825Sdim  /// Use the specified ABI.
1042198092Srdivacky  ///
1043239462Sdim  /// \return False on error (invalid ABI name).
1044198092Srdivacky  virtual bool setABI(const std::string &Name) {
1045198092Srdivacky    return false;
1046198092Srdivacky  }
1047198092Srdivacky
1048341825Sdim  /// Use the specified unit for FP math.
1049261991Sdim  ///
1050261991Sdim  /// \return False on error (invalid unit name).
1051261991Sdim  virtual bool setFPMath(StringRef Name) {
1052261991Sdim    return false;
1053261991Sdim  }
1054261991Sdim
1055341825Sdim  /// Enable or disable a specific target feature;
1056193326Sed  /// the feature name must be valid.
1057261991Sdim  virtual void setFeatureEnabled(llvm::StringMap<bool> &Features,
1058234353Sdim                                 StringRef Name,
1059193326Sed                                 bool Enabled) const {
1060261991Sdim    Features[Name] = Enabled;
1061193326Sed  }
1062193326Sed
1063341825Sdim  /// Determine whether this TargetInfo supports the given feature.
1064327952Sdim  virtual bool isValidFeatureName(StringRef Feature) const {
1065327952Sdim    return true;
1066327952Sdim  }
1067327952Sdim
1068341825Sdim  /// Perform initialization based on the user configured
1069239462Sdim  /// set of features (e.g., +sse4).
1070201361Srdivacky  ///
1071239462Sdim  /// The list is guaranteed to have at most one entry per feature.
1072239462Sdim  ///
1073201361Srdivacky  /// The target may modify the features list, to change which options are
1074201361Srdivacky  /// passed onwards to the backend.
1075296417Sdim  /// FIXME: This part should be fixed so that we can change handleTargetFeatures
1076296417Sdim  /// to merely a TargetInfo initialization routine.
1077261991Sdim  ///
1078261991Sdim  /// \return  False on error.
1079261991Sdim  virtual bool handleTargetFeatures(std::vector<std::string> &Features,
1080261991Sdim                                    DiagnosticsEngine &Diags) {
1081261991Sdim    return true;
1082193326Sed  }
1083193326Sed
1084341825Sdim  /// Determine whether the given target has the given feature.
1085234353Sdim  virtual bool hasFeature(StringRef Feature) const {
1086234353Sdim    return false;
1087234353Sdim  }
1088296417Sdim
1089344779Sdim  /// Identify whether this target supports multiversioning of functions,
1090341825Sdim  /// which requires support for cpu_supports and cpu_is functionality.
1091344779Sdim  bool supportsMultiVersioning() const {
1092344779Sdim    return getTriple().getArch() == llvm::Triple::x86 ||
1093344779Sdim           getTriple().getArch() == llvm::Triple::x86_64;
1094344779Sdim  }
1095341825Sdim
1096344779Sdim  /// Identify whether this target supports IFuncs.
1097344779Sdim  bool supportsIFunc() const { return getTriple().isOSBinFormatELF(); }
1098344779Sdim
1099341825Sdim  // Validate the contents of the __builtin_cpu_supports(const char*)
1100296417Sdim  // argument.
1101296417Sdim  virtual bool validateCpuSupports(StringRef Name) const { return false; }
1102296417Sdim
1103341825Sdim  // Return the target-specific priority for features/cpus/vendors so
1104341825Sdim  // that they can be properly sorted for checking.
1105341825Sdim  virtual unsigned multiVersionSortPriority(StringRef Name) const {
1106341825Sdim    return 0;
1107341825Sdim  }
1108341825Sdim
1109341825Sdim  // Validate the contents of the __builtin_cpu_is(const char*)
1110327952Sdim  // argument.
1111327952Sdim  virtual bool validateCpuIs(StringRef Name) const { return false; }
1112327952Sdim
1113341825Sdim  // Validate a cpu_dispatch/cpu_specific CPU option, which is a different list
1114341825Sdim  // from cpu_is, since it checks via features rather than CPUs directly.
1115341825Sdim  virtual bool validateCPUSpecificCPUDispatch(StringRef Name) const {
1116341825Sdim    return false;
1117341825Sdim  }
1118341825Sdim
1119341825Sdim  // Get the character to be added for mangling purposes for cpu_specific.
1120341825Sdim  virtual char CPUSpecificManglingCharacter(StringRef Name) const {
1121341825Sdim    llvm_unreachable(
1122341825Sdim        "cpu_specific Multiversioning not implemented on this target");
1123341825Sdim  }
1124341825Sdim
1125341825Sdim  // Get a list of the features that make up the CPU option for
1126341825Sdim  // cpu_specific/cpu_dispatch so that it can be passed to llvm as optimization
1127341825Sdim  // options.
1128341825Sdim  virtual void getCPUSpecificCPUDispatchFeatures(
1129341825Sdim      StringRef Name, llvm::SmallVectorImpl<StringRef> &Features) const {
1130341825Sdim    llvm_unreachable(
1131341825Sdim        "cpu_specific Multiversioning not implemented on this target");
1132341825Sdim  }
1133341825Sdim
1134341825Sdim  // Returns maximal number of args passed in registers.
1135193326Sed  unsigned getRegParmMax() const {
1136224145Sdim    assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle");
1137193326Sed    return RegParmMax;
1138193326Sed  }
1139193326Sed
1140341825Sdim  /// Whether the target supports thread-local storage.
1141198092Srdivacky  bool isTLSSupported() const {
1142193326Sed    return TLSSupported;
1143193326Sed  }
1144218893Sdim
1145341825Sdim  /// Return the maximum alignment (in bits) of a TLS variable
1146288943Sdim  ///
1147288943Sdim  /// Gets the maximum alignment (in bits) of a TLS variable on this target.
1148288943Sdim  /// Returns zero if there is no such constraint.
1149288943Sdim  unsigned short getMaxTLSAlign() const {
1150288943Sdim    return MaxTLSAlign;
1151288943Sdim  }
1152288943Sdim
1153341825Sdim  /// Whether target supports variable-length arrays.
1154327952Sdim  bool isVLASupported() const { return VLASupported; }
1155327952Sdim
1156341825Sdim  /// Whether the target supports SEH __try.
1157288943Sdim  bool isSEHTrySupported() const {
1158288943Sdim    return getTriple().isOSWindows() &&
1159288943Sdim           (getTriple().getArch() == llvm::Triple::x86 ||
1160341825Sdim            getTriple().getArch() == llvm::Triple::x86_64 ||
1161341825Sdim            getTriple().getArch() == llvm::Triple::aarch64);
1162288943Sdim  }
1163288943Sdim
1164341825Sdim  /// Return true if {|} are normal characters in the asm string.
1165239462Sdim  ///
1166239462Sdim  /// If this returns false (the default), then {abc|xyz} is syntax
1167207619Srdivacky  /// that says that when compiling for asm variant #0, "abc" should be
1168207619Srdivacky  /// generated, but when compiling for asm variant #1, "xyz" should be
1169207619Srdivacky  /// generated.
1170207619Srdivacky  bool hasNoAsmVariants() const {
1171207619Srdivacky    return NoAsmVariants;
1172207619Srdivacky  }
1173218893Sdim
1174341825Sdim  /// Return the register number that __builtin_eh_return_regno would
1175239462Sdim  /// return with the specified argument.
1176309124Sdim  /// This corresponds with TargetLowering's getExceptionPointerRegister
1177309124Sdim  /// and getExceptionSelectorRegister in the backend.
1178198092Srdivacky  virtual int getEHDataRegisterNumber(unsigned RegNo) const {
1179218893Sdim    return -1;
1180198092Srdivacky  }
1181218893Sdim
1182341825Sdim  /// Return the section to use for C++ static initialization functions.
1183210299Sed  virtual const char *getStaticInitSectionSpecifier() const {
1184276479Sdim    return nullptr;
1185210299Sed  }
1186221345Sdim
1187327952Sdim  const LangASMap &getAddressSpaceMap() const { return *AddrSpaceMap; }
1188221345Sdim
1189344779Sdim  /// Map from the address space field in builtin description strings to the
1190344779Sdim  /// language address space.
1191344779Sdim  virtual LangAS getOpenCLBuiltinAddressSpace(unsigned AS) const {
1192344779Sdim    return getLangASFromTargetAS(AS);
1193344779Sdim  }
1194344779Sdim
1195344779Sdim  /// Map from the address space field in builtin description strings to the
1196344779Sdim  /// language address space.
1197344779Sdim  virtual LangAS getCUDABuiltinAddressSpace(unsigned AS) const {
1198344779Sdim    return getLangASFromTargetAS(AS);
1199344779Sdim  }
1200344779Sdim
1201341825Sdim  /// Return an AST address space which can be used opportunistically
1202321369Sdim  /// for constant global memory. It must be possible to convert pointers into
1203321369Sdim  /// this address space to LangAS::Default. If no such address space exists,
1204321369Sdim  /// this may return None, and such optimizations will be disabled.
1205327952Sdim  virtual llvm::Optional<LangAS> getConstantAddressSpace() const {
1206321369Sdim    return LangAS::Default;
1207321369Sdim  }
1208321369Sdim
1209341825Sdim  /// Retrieve the name of the platform as it is used in the
1210221345Sdim  /// availability attribute.
1211226633Sdim  StringRef getPlatformName() const { return PlatformName; }
1212221345Sdim
1213341825Sdim  /// Retrieve the minimum desired version of the platform, to
1214221345Sdim  /// which the program should be compiled.
1215221345Sdim  VersionTuple getPlatformMinVersion() const { return PlatformMinVersion; }
1216221345Sdim
1217234353Sdim  bool isBigEndian() const { return BigEndian; }
1218314564Sdim  bool isLittleEndian() const { return !BigEndian; }
1219234353Sdim
1220249423Sdim  enum CallingConvMethodType {
1221249423Sdim    CCMT_Unknown,
1222249423Sdim    CCMT_Member,
1223249423Sdim    CCMT_NonMember
1224249423Sdim  };
1225249423Sdim
1226341825Sdim  /// Gets the default calling convention for the given target and
1227243830Sdim  /// declaration context.
1228249423Sdim  virtual CallingConv getDefaultCallingConv(CallingConvMethodType MT) const {
1229243830Sdim    // Not all targets will specify an explicit calling convention that we can
1230243830Sdim    // express.  This will always do the right thing, even though it's not
1231243830Sdim    // an explicit calling convention.
1232249423Sdim    return CC_C;
1233243830Sdim  }
1234243830Sdim
1235243830Sdim  enum CallingConvCheckResult {
1236243830Sdim    CCCR_OK,
1237288943Sdim    CCCR_Warning,
1238288943Sdim    CCCR_Ignore,
1239243830Sdim  };
1240243830Sdim
1241341825Sdim  /// Determines whether a given calling convention is valid for the
1242296417Sdim  /// target. A calling convention can either be accepted, produce a warning
1243243830Sdim  /// and be substituted with the default calling convention, or (someday)
1244243830Sdim  /// produce an error (such as using thiscall on a non-instance function).
1245243830Sdim  virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const {
1246243830Sdim    switch (CC) {
1247243830Sdim      default:
1248243830Sdim        return CCCR_Warning;
1249243830Sdim      case CC_C:
1250243830Sdim        return CCCR_OK;
1251243830Sdim    }
1252243830Sdim  }
1253243830Sdim
1254341825Sdim  enum CallingConvKind {
1255341825Sdim    CCK_Default,
1256341825Sdim    CCK_ClangABI4OrPS4,
1257341825Sdim    CCK_MicrosoftWin64
1258341825Sdim  };
1259341825Sdim
1260341825Sdim  virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const;
1261341825Sdim
1262283526Sdim  /// Controls if __builtin_longjmp / __builtin_setjmp can be lowered to
1263283526Sdim  /// llvm.eh.sjlj.longjmp / llvm.eh.sjlj.setjmp.
1264283526Sdim  virtual bool hasSjLjLowering() const {
1265283526Sdim    return false;
1266283526Sdim  }
1267283526Sdim
1268341825Sdim  /// Check if the target supports CFProtection branch.
1269341825Sdim  virtual bool
1270341825Sdim  checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const;
1271341825Sdim
1272341825Sdim  /// Check if the target supports CFProtection branch.
1273341825Sdim  virtual bool
1274341825Sdim  checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const;
1275341825Sdim
1276341825Sdim  /// Whether target allows to overalign ABI-specified preferred alignment
1277309124Sdim  virtual bool allowsLargerPreferedTypeAlignment() const { return true; }
1278309124Sdim
1279341825Sdim  /// Set supported OpenCL extensions and optional core features.
1280309124Sdim  virtual void setSupportedOpenCLOpts() {}
1281309124Sdim
1282341825Sdim  /// Set supported OpenCL extensions as written on command line
1283314564Sdim  virtual void setOpenCLExtensionOpts() {
1284314564Sdim    for (const auto &Ext : getTargetOpts().OpenCLExtensionsAsWritten) {
1285314564Sdim      getTargetOpts().SupportedOpenCLOptions.support(Ext);
1286314564Sdim    }
1287314564Sdim  }
1288314564Sdim
1289341825Sdim  /// Get supported OpenCL extensions and optional core features.
1290309124Sdim  OpenCLOptions &getSupportedOpenCLOpts() {
1291309124Sdim    return getTargetOpts().SupportedOpenCLOptions;
1292309124Sdim  }
1293309124Sdim
1294341825Sdim  /// Get const supported OpenCL extensions and optional core features.
1295309124Sdim  const OpenCLOptions &getSupportedOpenCLOpts() const {
1296309124Sdim      return getTargetOpts().SupportedOpenCLOptions;
1297309124Sdim  }
1298309124Sdim
1299327952Sdim  enum OpenCLTypeKind {
1300327952Sdim    OCLTK_Default,
1301327952Sdim    OCLTK_ClkEvent,
1302327952Sdim    OCLTK_Event,
1303327952Sdim    OCLTK_Image,
1304327952Sdim    OCLTK_Pipe,
1305327952Sdim    OCLTK_Queue,
1306327952Sdim    OCLTK_ReserveID,
1307327952Sdim    OCLTK_Sampler,
1308327952Sdim  };
1309314564Sdim
1310341825Sdim  /// Get address space for OpenCL type.
1311327952Sdim  virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const;
1312327952Sdim
1313321369Sdim  /// \returns Target specific vtbl ptr address space.
1314321369Sdim  virtual unsigned getVtblPtrAddressSpace() const {
1315321369Sdim    return 0;
1316321369Sdim  }
1317321369Sdim
1318321369Sdim  /// \returns If a target requires an address within a target specific address
1319321369Sdim  /// space \p AddressSpace to be converted in order to be used, then return the
1320321369Sdim  /// corresponding target specific DWARF address space.
1321321369Sdim  ///
1322321369Sdim  /// \returns Otherwise return None and no conversion will be emitted in the
1323321369Sdim  /// DWARF.
1324321369Sdim  virtual Optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const {
1325321369Sdim    return None;
1326321369Sdim  }
1327321369Sdim
1328344779Sdim  /// \returns The version of the SDK which was used during the compilation if
1329344779Sdim  /// one was specified, or an empty version otherwise.
1330344779Sdim  const llvm::VersionTuple &getSDKVersion() const {
1331344779Sdim    return getTargetOpts().SDKVersion;
1332344779Sdim  }
1333344779Sdim
1334341825Sdim  /// Check the target is valid after it is fully initialized.
1335309124Sdim  virtual bool validateTarget(DiagnosticsEngine &Diags) const {
1336309124Sdim    return true;
1337309124Sdim  }
1338309124Sdim
1339193326Sedprotected:
1340193326Sed  virtual uint64_t getPointerWidthV(unsigned AddrSpace) const {
1341193326Sed    return PointerWidth;
1342193326Sed  }
1343193326Sed  virtual uint64_t getPointerAlignV(unsigned AddrSpace) const {
1344193326Sed    return PointerAlign;
1345193326Sed  }
1346193326Sed  virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const {
1347193326Sed    return PtrDiffType;
1348193326Sed  }
1349296417Sdim  virtual ArrayRef<const char *> getGCCRegNames() const = 0;
1350296417Sdim  virtual ArrayRef<GCCRegAlias> getGCCRegAliases() const = 0;
1351296417Sdim  virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const {
1352296417Sdim    return None;
1353224145Sdim  }
1354341825Sdim
1355341825Sdim private:
1356341825Sdim  // Assert the values for the fractional and integral bits for each fixed point
1357341825Sdim  // type follow the restrictions given in clause 6.2.6.3 of N1169.
1358341825Sdim  void CheckFixedPointBits() const;
1359193326Sed};
1360193326Sed
1361193326Sed}  // end namespace clang
1362193326Sed
1363193326Sed#endif
1364