clang  19.0.0git
LoongArch.cpp
Go to the documentation of this file.
1 //===- LoongArch.cpp ------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ABIInfoImpl.h"
10 #include "TargetInfo.h"
11 
12 using namespace clang;
13 using namespace clang::CodeGen;
14 
15 // LoongArch ABI Implementation. Documented at
16 // https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html
17 //
18 //===----------------------------------------------------------------------===//
19 
20 namespace {
21 class LoongArchABIInfo : public DefaultABIInfo {
22 private:
23  // Size of the integer ('r') registers in bits.
24  unsigned GRLen;
25  // Size of the floating point ('f') registers in bits.
26  unsigned FRLen;
27  // Number of general-purpose argument registers.
28  static const int NumGARs = 8;
29  // Number of floating-point argument registers.
30  static const int NumFARs = 8;
31  bool detectFARsEligibleStructHelper(QualType Ty, CharUnits CurOff,
32  llvm::Type *&Field1Ty,
33  CharUnits &Field1Off,
34  llvm::Type *&Field2Ty,
35  CharUnits &Field2Off) const;
36 
37 public:
38  LoongArchABIInfo(CodeGen::CodeGenTypes &CGT, unsigned GRLen, unsigned FRLen)
39  : DefaultABIInfo(CGT), GRLen(GRLen), FRLen(FRLen) {}
40 
41  void computeInfo(CGFunctionInfo &FI) const override;
42 
43  ABIArgInfo classifyArgumentType(QualType Ty, bool IsFixed, int &GARsLeft,
44  int &FARsLeft) const;
46 
47  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
48  QualType Ty) const override;
49 
50  ABIArgInfo extendType(QualType Ty) const;
51 
52  bool detectFARsEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
53  CharUnits &Field1Off, llvm::Type *&Field2Ty,
54  CharUnits &Field2Off, int &NeededArgGPRs,
55  int &NeededArgFPRs) const;
56  ABIArgInfo coerceAndExpandFARsEligibleStruct(llvm::Type *Field1Ty,
57  CharUnits Field1Off,
58  llvm::Type *Field2Ty,
59  CharUnits Field2Off) const;
60 };
61 } // end anonymous namespace
62 
63 void LoongArchABIInfo::computeInfo(CGFunctionInfo &FI) const {
64  QualType RetTy = FI.getReturnType();
65  if (!getCXXABI().classifyReturnType(FI))
66  FI.getReturnInfo() = classifyReturnType(RetTy);
67 
68  // IsRetIndirect is true if classifyArgumentType indicated the value should
69  // be passed indirect, or if the type size is a scalar greater than 2*GRLen
70  // and not a complex type with elements <= FRLen. e.g. fp128 is passed direct
71  // in LLVM IR, relying on the backend lowering code to rewrite the argument
72  // list and pass indirectly on LA32.
73  bool IsRetIndirect = FI.getReturnInfo().getKind() == ABIArgInfo::Indirect;
74  if (!IsRetIndirect && RetTy->isScalarType() &&
75  getContext().getTypeSize(RetTy) > (2 * GRLen)) {
76  if (RetTy->isComplexType() && FRLen) {
77  QualType EltTy = RetTy->castAs<ComplexType>()->getElementType();
78  IsRetIndirect = getContext().getTypeSize(EltTy) > FRLen;
79  } else {
80  // This is a normal scalar > 2*GRLen, such as fp128 on LA32.
81  IsRetIndirect = true;
82  }
83  }
84 
85  // We must track the number of GARs and FARs used in order to conform to the
86  // LoongArch ABI. As GAR usage is different for variadic arguments, we must
87  // also track whether we are examining a vararg or not.
88  int GARsLeft = IsRetIndirect ? NumGARs - 1 : NumGARs;
89  int FARsLeft = FRLen ? NumFARs : 0;
90  int NumFixedArgs = FI.getNumRequiredArgs();
91 
92  int ArgNum = 0;
93  for (auto &ArgInfo : FI.arguments()) {
94  ArgInfo.info = classifyArgumentType(
95  ArgInfo.type, /*IsFixed=*/ArgNum < NumFixedArgs, GARsLeft, FARsLeft);
96  ArgNum++;
97  }
98 }
99 
100 // Returns true if the struct is a potential candidate to be passed in FARs (and
101 // GARs). If this function returns true, the caller is responsible for checking
102 // that if there is only a single field then that field is a float.
103 bool LoongArchABIInfo::detectFARsEligibleStructHelper(
104  QualType Ty, CharUnits CurOff, llvm::Type *&Field1Ty, CharUnits &Field1Off,
105  llvm::Type *&Field2Ty, CharUnits &Field2Off) const {
106  bool IsInt = Ty->isIntegralOrEnumerationType();
107  bool IsFloat = Ty->isRealFloatingType();
108 
109  if (IsInt || IsFloat) {
110  uint64_t Size = getContext().getTypeSize(Ty);
111  if (IsInt && Size > GRLen)
112  return false;
113  // Can't be eligible if larger than the FP registers. Half precision isn't
114  // currently supported on LoongArch and the ABI hasn't been confirmed, so
115  // default to the integer ABI in that case.
116  if (IsFloat && (Size > FRLen || Size < 32))
117  return false;
118  // Can't be eligible if an integer type was already found (int+int pairs
119  // are not eligible).
120  if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
121  return false;
122  if (!Field1Ty) {
123  Field1Ty = CGT.ConvertType(Ty);
124  Field1Off = CurOff;
125  return true;
126  }
127  if (!Field2Ty) {
128  Field2Ty = CGT.ConvertType(Ty);
129  Field2Off = CurOff;
130  return true;
131  }
132  return false;
133  }
134 
135  if (auto CTy = Ty->getAs<ComplexType>()) {
136  if (Field1Ty)
137  return false;
138  QualType EltTy = CTy->getElementType();
139  if (getContext().getTypeSize(EltTy) > FRLen)
140  return false;
141  Field1Ty = CGT.ConvertType(EltTy);
142  Field1Off = CurOff;
143  Field2Ty = Field1Ty;
144  Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy);
145  return true;
146  }
147 
148  if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
149  uint64_t ArraySize = ATy->getZExtSize();
150  QualType EltTy = ATy->getElementType();
151  // Non-zero-length arrays of empty records make the struct ineligible to be
152  // passed via FARs in C++.
153  if (const auto *RTy = EltTy->getAs<RecordType>()) {
154  if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
155  isEmptyRecord(getContext(), EltTy, true, true))
156  return false;
157  }
158  CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
159  for (uint64_t i = 0; i < ArraySize; ++i) {
160  if (!detectFARsEligibleStructHelper(EltTy, CurOff, Field1Ty, Field1Off,
161  Field2Ty, Field2Off))
162  return false;
163  CurOff += EltSize;
164  }
165  return true;
166  }
167 
168  if (const auto *RTy = Ty->getAs<RecordType>()) {
169  // Structures with either a non-trivial destructor or a non-trivial
170  // copy constructor are not eligible for the FP calling convention.
171  if (getRecordArgABI(Ty, CGT.getCXXABI()))
172  return false;
173  const RecordDecl *RD = RTy->getDecl();
174  if (isEmptyRecord(getContext(), Ty, true, true) &&
175  (!RD->isUnion() || !isa<CXXRecordDecl>(RD)))
176  return true;
177  // Unions aren't eligible unless they're empty in C (which is caught above).
178  if (RD->isUnion())
179  return false;
180  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
181  // If this is a C++ record, check the bases first.
182  if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
183  for (const CXXBaseSpecifier &B : CXXRD->bases()) {
184  const auto *BDecl =
185  cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl());
186  if (!detectFARsEligibleStructHelper(
187  B.getType(), CurOff + Layout.getBaseClassOffset(BDecl),
188  Field1Ty, Field1Off, Field2Ty, Field2Off))
189  return false;
190  }
191  }
192  for (const FieldDecl *FD : RD->fields()) {
193  QualType QTy = FD->getType();
194  if (FD->isBitField()) {
195  unsigned BitWidth = FD->getBitWidthValue(getContext());
196  // Zero-width bitfields are ignored.
197  if (BitWidth == 0)
198  continue;
199  // Allow a bitfield with a type greater than GRLen as long as the
200  // bitwidth is GRLen or less.
201  if (getContext().getTypeSize(QTy) > GRLen && BitWidth <= GRLen) {
202  QTy = getContext().getIntTypeForBitwidth(GRLen, false);
203  }
204  }
205 
206  if (!detectFARsEligibleStructHelper(
207  QTy,
208  CurOff + getContext().toCharUnitsFromBits(
209  Layout.getFieldOffset(FD->getFieldIndex())),
210  Field1Ty, Field1Off, Field2Ty, Field2Off))
211  return false;
212  }
213  return Field1Ty != nullptr;
214  }
215 
216  return false;
217 }
218 
219 // Determine if a struct is eligible to be passed in FARs (and GARs) (i.e., when
220 // flattened it contains a single fp value, fp+fp, or int+fp of appropriate
221 // size). If so, NeededFARs and NeededGARs are incremented appropriately.
222 bool LoongArchABIInfo::detectFARsEligibleStruct(
223  QualType Ty, llvm::Type *&Field1Ty, CharUnits &Field1Off,
224  llvm::Type *&Field2Ty, CharUnits &Field2Off, int &NeededGARs,
225  int &NeededFARs) const {
226  Field1Ty = nullptr;
227  Field2Ty = nullptr;
228  NeededGARs = 0;
229  NeededFARs = 0;
230  if (!detectFARsEligibleStructHelper(Ty, CharUnits::Zero(), Field1Ty,
231  Field1Off, Field2Ty, Field2Off))
232  return false;
233  if (!Field1Ty)
234  return false;
235  // Not really a candidate if we have a single int but no float.
236  if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
237  return false;
238  if (Field1Ty && Field1Ty->isFloatingPointTy())
239  NeededFARs++;
240  else if (Field1Ty)
241  NeededGARs++;
242  if (Field2Ty && Field2Ty->isFloatingPointTy())
243  NeededFARs++;
244  else if (Field2Ty)
245  NeededGARs++;
246  return true;
247 }
248 
249 // Call getCoerceAndExpand for the two-element flattened struct described by
250 // Field1Ty, Field1Off, Field2Ty, Field2Off. This method will create an
251 // appropriate coerceToType and unpaddedCoerceToType.
252 ABIArgInfo LoongArchABIInfo::coerceAndExpandFARsEligibleStruct(
253  llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty,
254  CharUnits Field2Off) const {
255  SmallVector<llvm::Type *, 3> CoerceElts;
256  SmallVector<llvm::Type *, 2> UnpaddedCoerceElts;
257  if (!Field1Off.isZero())
258  CoerceElts.push_back(llvm::ArrayType::get(
259  llvm::Type::getInt8Ty(getVMContext()), Field1Off.getQuantity()));
260 
261  CoerceElts.push_back(Field1Ty);
262  UnpaddedCoerceElts.push_back(Field1Ty);
263 
264  if (!Field2Ty) {
266  llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.isZero()),
267  UnpaddedCoerceElts[0]);
268  }
269 
270  CharUnits Field2Align =
271  CharUnits::fromQuantity(getDataLayout().getABITypeAlign(Field2Ty));
272  CharUnits Field1End =
273  Field1Off +
274  CharUnits::fromQuantity(getDataLayout().getTypeStoreSize(Field1Ty));
275  CharUnits Field2OffNoPadNoPack = Field1End.alignTo(Field2Align);
276 
277  CharUnits Padding = CharUnits::Zero();
278  if (Field2Off > Field2OffNoPadNoPack)
279  Padding = Field2Off - Field2OffNoPadNoPack;
280  else if (Field2Off != Field2Align && Field2Off > Field1End)
281  Padding = Field2Off - Field1End;
282 
283  bool IsPacked = !Field2Off.isMultipleOf(Field2Align);
284 
285  if (!Padding.isZero())
286  CoerceElts.push_back(llvm::ArrayType::get(
287  llvm::Type::getInt8Ty(getVMContext()), Padding.getQuantity()));
288 
289  CoerceElts.push_back(Field2Ty);
290  UnpaddedCoerceElts.push_back(Field2Ty);
291 
293  llvm::StructType::get(getVMContext(), CoerceElts, IsPacked),
294  llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked));
295 }
296 
298  int &GARsLeft,
299  int &FARsLeft) const {
300  assert(GARsLeft <= NumGARs && "GAR tracking underflow");
302 
303  // Structures with either a non-trivial destructor or a non-trivial
304  // copy constructor are always passed indirectly.
305  if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
306  if (GARsLeft)
307  GARsLeft -= 1;
308  return getNaturalAlignIndirect(Ty, /*ByVal=*/RAA ==
310  }
311 
312  uint64_t Size = getContext().getTypeSize(Ty);
313 
314  // Ignore empty struct or union whose size is zero, e.g. `struct { }` in C or
315  // `struct { int a[0]; }` in C++. In C++, `struct { }` is empty but it's size
316  // is 1 byte and g++ doesn't ignore it; clang++ matches this behaviour.
317  if (isEmptyRecord(getContext(), Ty, true) && Size == 0)
318  return ABIArgInfo::getIgnore();
319 
320  // Pass floating point values via FARs if possible.
321  if (IsFixed && Ty->isFloatingType() && !Ty->isComplexType() &&
322  FRLen >= Size && FARsLeft) {
323  FARsLeft--;
324  return ABIArgInfo::getDirect();
325  }
326 
327  // Complex types for the *f or *d ABI must be passed directly rather than
328  // using CoerceAndExpand.
329  if (IsFixed && Ty->isComplexType() && FRLen && FARsLeft >= 2) {
330  QualType EltTy = Ty->castAs<ComplexType>()->getElementType();
331  if (getContext().getTypeSize(EltTy) <= FRLen) {
332  FARsLeft -= 2;
333  return ABIArgInfo::getDirect();
334  }
335  }
336 
337  if (IsFixed && FRLen && Ty->isStructureOrClassType()) {
338  llvm::Type *Field1Ty = nullptr;
339  llvm::Type *Field2Ty = nullptr;
340  CharUnits Field1Off = CharUnits::Zero();
341  CharUnits Field2Off = CharUnits::Zero();
342  int NeededGARs = 0;
343  int NeededFARs = 0;
344  bool IsCandidate = detectFARsEligibleStruct(
345  Ty, Field1Ty, Field1Off, Field2Ty, Field2Off, NeededGARs, NeededFARs);
346  if (IsCandidate && NeededGARs <= GARsLeft && NeededFARs <= FARsLeft) {
347  GARsLeft -= NeededGARs;
348  FARsLeft -= NeededFARs;
349  return coerceAndExpandFARsEligibleStruct(Field1Ty, Field1Off, Field2Ty,
350  Field2Off);
351  }
352  }
353 
354  uint64_t NeededAlign = getContext().getTypeAlign(Ty);
355  // Determine the number of GARs needed to pass the current argument
356  // according to the ABI. 2*GRLen-aligned varargs are passed in "aligned"
357  // register pairs, so may consume 3 registers.
358  int NeededGARs = 1;
359  if (!IsFixed && NeededAlign == 2 * GRLen)
360  NeededGARs = 2 + (GARsLeft % 2);
361  else if (Size > GRLen && Size <= 2 * GRLen)
362  NeededGARs = 2;
363 
364  if (NeededGARs > GARsLeft)
365  NeededGARs = GARsLeft;
366 
367  GARsLeft -= NeededGARs;
368 
369  if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) {
370  // Treat an enum type as its underlying type.
371  if (const EnumType *EnumTy = Ty->getAs<EnumType>())
372  Ty = EnumTy->getDecl()->getIntegerType();
373 
374  // All integral types are promoted to GRLen width.
375  if (Size < GRLen && Ty->isIntegralOrEnumerationType())
376  return extendType(Ty);
377 
378  if (const auto *EIT = Ty->getAs<BitIntType>()) {
379  if (EIT->getNumBits() < GRLen)
380  return extendType(Ty);
381  if (EIT->getNumBits() > 128 ||
382  (!getContext().getTargetInfo().hasInt128Type() &&
383  EIT->getNumBits() > 64))
384  return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
385  }
386 
387  return ABIArgInfo::getDirect();
388  }
389 
390  // Aggregates which are <= 2*GRLen will be passed in registers if possible,
391  // so coerce to integers.
392  if (Size <= 2 * GRLen) {
393  // Use a single GRLen int if possible, 2*GRLen if 2*GRLen alignment is
394  // required, and a 2-element GRLen array if only GRLen alignment is
395  // required.
396  if (Size <= GRLen) {
397  return ABIArgInfo::getDirect(
398  llvm::IntegerType::get(getVMContext(), GRLen));
399  }
400  if (getContext().getTypeAlign(Ty) == 2 * GRLen) {
401  return ABIArgInfo::getDirect(
402  llvm::IntegerType::get(getVMContext(), 2 * GRLen));
403  }
404  return ABIArgInfo::getDirect(
405  llvm::ArrayType::get(llvm::IntegerType::get(getVMContext(), GRLen), 2));
406  }
407  return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
408 }
409 
411  if (RetTy->isVoidType())
412  return ABIArgInfo::getIgnore();
413  // The rules for return and argument types are the same, so defer to
414  // classifyArgumentType.
415  int GARsLeft = 2;
416  int FARsLeft = FRLen ? 2 : 0;
417  return classifyArgumentType(RetTy, /*IsFixed=*/true, GARsLeft, FARsLeft);
418 }
419 
420 Address LoongArchABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
421  QualType Ty) const {
422  CharUnits SlotSize = CharUnits::fromQuantity(GRLen / 8);
423 
424  // Empty records are ignored for parameter passing purposes.
425  if (isEmptyRecord(getContext(), Ty, true))
426  return Address(CGF.Builder.CreateLoad(VAListAddr),
427  CGF.ConvertTypeForMem(Ty), SlotSize);
428 
429  auto TInfo = getContext().getTypeInfoInChars(Ty);
430 
431  // Arguments bigger than 2*GRLen bytes are passed indirectly.
432  return emitVoidPtrVAArg(CGF, VAListAddr, Ty,
433  /*IsIndirect=*/TInfo.Width > 2 * SlotSize, TInfo,
434  SlotSize,
435  /*AllowHigherAlign=*/true);
436 }
437 
438 ABIArgInfo LoongArchABIInfo::extendType(QualType Ty) const {
439  int TySize = getContext().getTypeSize(Ty);
440  // LA64 ABI requires unsigned 32 bit integers to be sign extended.
441  if (GRLen == 64 && Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
442  return ABIArgInfo::getSignExtend(Ty);
443  return ABIArgInfo::getExtend(Ty);
444 }
445 
446 namespace {
447 class LoongArchTargetCodeGenInfo : public TargetCodeGenInfo {
448 public:
449  LoongArchTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, unsigned GRLen,
450  unsigned FRLen)
452  std::make_unique<LoongArchABIInfo>(CGT, GRLen, FRLen)) {}
453 };
454 } // namespace
455 
456 std::unique_ptr<TargetCodeGenInfo>
458  unsigned FLen) {
459  return std::make_unique<LoongArchTargetCodeGenInfo>(CGM.getTypes(), GRLen,
460  FLen);
461 }
static CharUnits getTypeStoreSize(CodeGenModule &CGM, llvm::Type *type)
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Definition: RecordLayout.h:200
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:249
A fixed int type of a specified bitwidth.
Definition: Type.h:7254
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition: CharUnits.h:122
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
Definition: CharUnits.h:143
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
Definition: CharUnits.h:201
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition: CharUnits.h:53
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIgnore()
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)
static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition: Address.h:111
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition: CGBuilder.h:108
RecordArgABI
Specify how one should pass an argument of a record type.
Definition: CGCXXABI.h:150
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
Definition: CGCXXABI.h:158
CGFunctionInfo - Class to encapsulate the information about a function definition.
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
unsigned getNumRequiredArgs() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertTypeForMem(QualType T)
This class organizes the cross-function state that is used while generating LLVM code.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
Definition: CodeGenTypes.h:54
DefaultABIInfo - The default implementation for ABI specific details.
Definition: ABIInfoImpl.h:21
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition: TargetInfo.h:46
Complex values, per C99 6.2.5p11.
Definition: Type.h:3098
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3568
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5587
Represents a member of a struct/union/class.
Definition: Decl.h:3060
A (possibly-)qualified type.
Definition: Type.h:940
Represents a struct/union/class.
Definition: Decl.h:4171
field_range fields() const
Definition: Decl.h:4377
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5561
RecordDecl * getDecl() const
Definition: Type.h:5571
bool isUnion() const
Definition: Decl.h:3793
bool isVoidType() const
Definition: Type.h:7939
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
Definition: Type.cpp:677
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
Definition: Type.cpp:2216
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8227
bool isScalarType() const
Definition: Type.h:8038
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:8054
bool isStructureOrClassType() const
Definition: Type.cpp:657
bool isVectorType() const
Definition: Type.h:7730
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2265
bool isFloatingType() const
Definition: Type.cpp:2248
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8160
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
std::unique_ptr< TargetCodeGenInfo > createLoongArchTargetCodeGenInfo(CodeGenModule &CGM, unsigned GRLen, unsigned FLen)
Definition: LoongArch.cpp:457
The JSON file list parser is used to communicate input to InstallAPI.
unsigned long uint64_t
Definition: Format.h:5433