clang 24.0.0git
Sparc.cpp
Go to the documentation of this file.
1//===- Sparc.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#include <algorithm>
12
13using namespace clang;
14using namespace clang::CodeGen;
15
16//===----------------------------------------------------------------------===//
17// SPARC v8 ABI Implementation.
18// Based on the SPARC Compliance Definition version 2.4.1.
19//
20// Ensures that complex values are passed in registers.
21//
22namespace {
23class SparcV8ABIInfo : public DefaultABIInfo {
24public:
25 SparcV8ABIInfo(CodeGenTypes &CGT)
26 : DefaultABIInfo(CGT),
27 IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
28 LangOptions::ClangABI::Ver23)) {}
29
30private:
31 /// Whether how `_Complex` values are passed and returned is GCC-compatible.
32 bool IsComplexGnuABI;
33
34 ABIArgInfo classifyComplexType(const ComplexType *Ty, bool IsRet) const;
35 ABIArgInfo classifyReturnType(QualType RetTy) const;
36 ABIArgInfo classifyArgumentType(QualType Ty) const;
37 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
38 AggValueSlot Slot) const override;
39 void computeInfo(CGFunctionInfo &FI) const override;
40};
41} // end anonymous namespace
42
43ABIArgInfo SparcV8ABIInfo::classifyComplexType(const ComplexType *CT,
44 bool IsRet) const {
45 QualType ElementTy = CT->getElementType();
46
47 if (IsComplexGnuABI && ElementTy->isIntegerType()) {
48 // The default path already does the right thing for `long long _Complex`.
49 uint64_t ElementTypeSize = getContext().getTypeSize(ElementTy);
50 if (ElementTypeSize <= 32) {
51 // Coerce to an integer to get the correct scalar-like behavior.
53 llvm::IntegerType::get(getVMContext(), 2 * ElementTypeSize));
54 }
55 }
56
57 // Any other complex value is passed indirectly, but returned in registers.
58 if (!IsRet)
59 return getNaturalAlignIndirect(QualType(CT, 0),
60 getDataLayout().getAllocaAddrSpace());
61
62 // long double _Complex is special, it is marked as inreg.
63 const auto *BT = ElementTy->getAs<BuiltinType>();
64 if (BT && BT->getKind() == BuiltinType::LongDouble)
66
67 return ABIArgInfo::getDirect();
68}
69
70ABIArgInfo SparcV8ABIInfo::classifyReturnType(QualType Ty) const {
71 if (const auto *CT = Ty->getAs<ComplexType>())
72 return classifyComplexType(CT, /*IsRet=*/true);
73
74 if (const auto *VT = Ty->getAs<VectorType>()) {
75 uint64_t Size = getContext().getTypeSize(Ty);
76 // Return float vectors and larger integer vectors indirectly.
77 if (VT->getElementType()->isRealFloatingType() || Size > 64)
78 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
79
80 // Return smaller integer vectors via float registers.
81 llvm::Type *FloatTy = llvm::Type::getFloatTy(getVMContext());
82 llvm::Type *DoubleTy = llvm::Type::getDoubleTy(getVMContext());
83 llvm::Type *CoerceTy = Size <= 32 ? FloatTy : DoubleTy;
84 return ABIArgInfo::getDirect(CoerceTy);
85 }
86
87 if (const auto *BT = Ty->getAs<BuiltinType>();
88 BT && BT->getKind() == BuiltinType::LongDouble &&
89 getContext().getTypeSize(Ty) > 64)
90 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
91 /*ByVal=*/false);
92
94}
95
96ABIArgInfo SparcV8ABIInfo::classifyArgumentType(QualType Ty) const {
97 if (const auto *CT = Ty->getAs<ComplexType>())
98 return classifyComplexType(CT, /*IsRet=*/false);
99
100 // Pass floating-point vectors and vectors larger than 64 bits by reference.
101 if (const auto *VT = Ty->getAs<VectorType>()) {
102 uint64_t SizeInBits = getContext().getTypeSize(Ty);
103 if (VT->getElementType()->isRealFloatingType() || SizeInBits > 64)
104 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
105 }
106
107 const auto *BT = Ty->getAs<BuiltinType>();
108 if (BT && BT->getKind() == BuiltinType::LongDouble &&
109 getContext().getTypeSize(Ty) > 64)
110 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
111
113}
114
115void SparcV8ABIInfo::computeInfo(CGFunctionInfo &FI) const {
117 for (auto &Arg : FI.arguments())
118 Arg.info = classifyArgumentType(Arg.type);
119}
120
121RValue SparcV8ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
122 QualType Ty, AggValueSlot Slot) const {
123 CharUnits SlotSize = CharUnits::fromQuantity(4);
124 auto TInfo = getContext().getTypeInfoInChars(Ty);
125
126 // E.g. long double, larger _Complex and aggregate values are indirect.
127 bool IsIndirect = classifyArgumentType(Ty).isIndirect();
128
129 // An alignment higher than the slot size is not respected.
130 bool AllowHigherAlign = false;
131
132 // Force values smaller than a slot (e.g. _Complex char)
133 // into the right-most bytes.
134 bool ForceRightAdjust = true;
135
136 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, TInfo, SlotSize,
137 AllowHigherAlign, Slot, ForceRightAdjust);
138}
139
140namespace {
141class SparcV8TargetCodeGenInfo : public TargetCodeGenInfo {
142public:
143 SparcV8TargetCodeGenInfo(CodeGenTypes &CGT)
144 : TargetCodeGenInfo(std::make_unique<SparcV8ABIInfo>(CGT)) {}
145
146 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
147 llvm::Value *Address) const override {
148 int Offset;
150 Offset = 12;
151 else
152 Offset = 8;
153 return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
154 llvm::ConstantInt::get(CGF.Int32Ty, Offset));
155 }
156
157 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
158 llvm::Value *Address) const override {
159 int Offset;
161 Offset = -12;
162 else
163 Offset = -8;
164 return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
165 llvm::ConstantInt::get(CGF.Int32Ty, Offset));
166 }
167};
168} // end anonymous namespace
169
170//===----------------------------------------------------------------------===//
171// SPARC v9 ABI Implementation.
172// Based on the SPARC Compliance Definition version 2.4.1.
173//
174// Function arguments a mapped to a nominal "parameter array" and promoted to
175// registers depending on their type. Each argument occupies 8 or 16 bytes in
176// the array, structs larger than 16 bytes are passed indirectly.
177//
178// One case requires special care:
179//
180// struct mixed {
181// int i;
182// float f;
183// };
184//
185// When a struct mixed is passed by value, it only occupies 8 bytes in the
186// parameter array, but the int is passed in an integer register, and the float
187// is passed in a floating point register. This is represented as two arguments
188// with the LLVM IR inreg attribute:
189//
190// declare void f(i32 inreg %i, float inreg %f)
191//
192// The code generator will only allocate 4 bytes from the parameter array for
193// the inreg arguments. All other arguments are allocated a multiple of 8
194// bytes.
195//
196namespace {
197class SparcV9ABIInfo : public ABIInfo {
198public:
199 SparcV9ABIInfo(CodeGenTypes &CGT)
200 : ABIInfo(CGT),
201 IsComplexGnuABI(!CGT.getContext().getLangOpts().isCompatibleWith(
202 LangOptions::ClangABI::Ver23)) {}
203
204private:
205 /// Whether how `_Complex` values are passed and returned is GCC-compatible.
206 bool IsComplexGnuABI;
207
208 ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit,
209 unsigned &RegOffset, bool IsVarArg) const;
210 void computeInfo(CGFunctionInfo &FI) const override;
211 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
212 AggValueSlot Slot) const override;
213
214 // Coercion type builder for structs passed in registers. The coercion type
215 // serves two purposes:
216 //
217 // 1. Pad structs to a multiple of 64 bits, so they are passed 'left-aligned'
218 // in registers.
219 // 2. Expose aligned floating point elements as first-level elements, so the
220 // code generator knows to pass them in floating point registers.
221 //
222 // We also compute the InReg flag which indicates that the struct contains
223 // aligned 32-bit floats.
224 //
225 struct CoerceBuilder {
226 llvm::LLVMContext &Context;
227 const llvm::DataLayout &DL;
228 SmallVector<llvm::Type*, 8> Elems;
230 bool InReg;
231 bool IsVarArg;
232
233 CoerceBuilder(llvm::LLVMContext &c, const llvm::DataLayout &dl,
234 bool IsVarArg)
235 : Context(c), DL(dl), Size(0), InReg(false), IsVarArg(IsVarArg) {}
236
237 // Pad Elems with integers until Size is ToSize.
238 void pad(uint64_t ToSize) {
239 assert(ToSize >= Size && "Cannot remove elements");
240 if (ToSize == Size)
241 return;
242
243 // Finish the current 64-bit word.
244 uint64_t Aligned = llvm::alignTo(Size, 64);
245 if (Aligned > Size && Aligned <= ToSize) {
246 Elems.push_back(llvm::IntegerType::get(Context, Aligned - Size));
247 Size = Aligned;
248 }
249
250 // Add whole 64-bit words.
251 while (Size + 64 <= ToSize) {
252 Elems.push_back(llvm::Type::getInt64Ty(Context));
253 Size += 64;
254 }
255
256 // Final in-word padding.
257 if (Size < ToSize) {
258 Elems.push_back(llvm::IntegerType::get(Context, ToSize - Size));
259 Size = ToSize;
260 }
261 }
262
263 // Add a floating point element at Offset.
264 void addFloat(uint64_t Offset, llvm::Type *Ty, unsigned Bits) {
265 // Varargs are treated as integers.
266 if (IsVarArg)
267 return;
268 // Unaligned floats are treated as integers.
269 if (Offset % Bits)
270 return;
271 // The InReg flag is only required if there are any floats < 64 bits.
272 if (Bits < 64)
273 InReg = true;
274 pad(Offset);
275 Elems.push_back(Ty);
276 Size = Offset + Bits;
277 }
278
279 // Add a struct type to the coercion type, starting at Offset (in bits).
280 void addStruct(uint64_t Offset, llvm::StructType *StrTy) {
281 const llvm::StructLayout *Layout = DL.getStructLayout(StrTy);
282 for (unsigned i = 0, e = StrTy->getNumElements(); i != e; ++i) {
283 llvm::Type *ElemTy = StrTy->getElementType(i);
284 uint64_t ElemOffset = Offset + Layout->getElementOffsetInBits(i);
285 switch (ElemTy->getTypeID()) {
286 case llvm::Type::StructTyID:
287 addStruct(ElemOffset, cast<llvm::StructType>(ElemTy));
288 break;
289 case llvm::Type::FloatTyID:
290 addFloat(ElemOffset, ElemTy, 32);
291 break;
292 case llvm::Type::DoubleTyID:
293 addFloat(ElemOffset, ElemTy, 64);
294 break;
295 case llvm::Type::FP128TyID:
296 addFloat(ElemOffset, ElemTy, 128);
297 break;
298 case llvm::Type::PointerTyID:
299 if (ElemOffset % 64 == 0) {
300 pad(ElemOffset);
301 Elems.push_back(ElemTy);
302 Size += 64;
303 }
304 break;
305 default:
306 break;
307 }
308 }
309 }
310
311 // Check if Ty is a usable substitute for the coercion type.
312 bool isUsableType(llvm::StructType *Ty) const {
313 return llvm::ArrayRef(Elems) == Ty->elements();
314 }
315
316 // Get the coercion type as a literal struct type.
317 llvm::Type *getType() const {
318 if (Elems.size() == 1)
319 return Elems.front();
320 else
321 return llvm::StructType::get(Context, Elems);
322 }
323 };
324};
325} // end anonymous namespace
326
327ABIArgInfo SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit,
328 unsigned &RegOffset,
329 bool IsVarArg) const {
330 if (Ty->isVoidType())
331 return ABIArgInfo::getIgnore();
332
333 auto &Context = getContext();
334 auto &VMContext = getVMContext();
335
336 // FIXME: the GCC-style `aligned` attribute on typedefs is not taken into
337 // account here, because the canonicalized type no longer has that
338 // information. Hence such over-aligned typedefs are not ABI-compatible with
339 // GCC.
340 //
341 // This is different from the `aligned` attribute on structs or fields, which
342 // is taken into account.
343 unsigned Alignment = Context.getTypeAlign(Ty);
344 uint64_t Size = Context.getTypeSize(Ty);
345
346 // Anything too big to fit in registers is passed with an explicit indirect
347 // pointer / sret pointer.
348 if (Size > SizeLimit) {
349 RegOffset += 1;
350 return getNaturalAlignIndirect(
351 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
352 /*ByVal=*/false);
353 }
354
355 // An argument that is passed in registers but has an alignment higher than 8
356 // bytes must be register-aligned. Insert a dummy i64 argument to fill the
357 // odd-numbered register.
358 //
359 // See SCD 2.4.1, pages 3P-11 and 3P-12.
360 llvm::Type *Padding = (Alignment > 64 && RegOffset % 2 != 0)
361 ? llvm::Type::getInt64Ty(VMContext)
362 : nullptr;
363 unsigned PaddingSlots = Padding ? 1 : 0;
364 unsigned SizeSlots = llvm::divideCeil(Size, 64);
365
366 // Treat an enum type as its underlying type.
367 if (const auto *ED = Ty->getAsEnumDecl())
368 Ty = ED->getIntegerType();
369
370 // Integer types smaller than a register are extended.
371 if (Size < 64 && Ty->isIntegerType()) {
372 RegOffset += PaddingSlots + SizeSlots;
373 return ABIArgInfo::getExtend(Ty, /*T=*/nullptr, Padding);
374 }
375
376 if (const auto *EIT = Ty->getAs<BitIntType>())
377 if (EIT->getNumBits() < 64) {
378 RegOffset += PaddingSlots + SizeSlots;
379 return ABIArgInfo::getExtend(Ty, /*T=*/nullptr, Padding);
380 }
381
382 // When being GCC-compatible, cast a complex char, short and int to an integer
383 // type of the right size to get the correct scalar-like behavior. Other
384 // complex types fall through and are treated like a struct containing the
385 // real and imaginary parts, e.g. `{ i64, i64 }` or `{ double, double }`.
386 if (IsComplexGnuABI) {
387 const auto *CT = Ty->getAs<ComplexType>();
388 if (CT && CT->getElementType()->isIntegerType()) {
389 uint64_t ElementTypeSize = Context.getTypeSize(CT->getElementType());
390 if (ElementTypeSize <= 32) {
391 RegOffset += 1;
393 llvm::IntegerType::get(VMContext, 2 * ElementTypeSize),
394 /*Offset=*/0, Padding);
395 }
396 }
397 }
398
399 // Other non-aggregates go in registers.
400 if (!isAggregateTypeForABI(Ty)) {
401 RegOffset += PaddingSlots + SizeSlots;
402 return ABIArgInfo::getDirect(/*T=*/nullptr, /*Offset=*/0, Padding);
403 }
404
405 // If a C++ object has either a non-trivial copy constructor or a non-trivial
406 // destructor, it is passed with an explicit indirect pointer / sret pointer.
407 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
408 RegOffset += 1;
409 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
411 }
412
413 // This is a small aggregate type that should be passed in registers.
414 // Build a coercion type from the LLVM struct type.
415 llvm::StructType *StrTy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
416 if (!StrTy) {
417 RegOffset += PaddingSlots + SizeSlots;
418 return ABIArgInfo::getDirect(/*T=*/nullptr, /*Offset=*/0, Padding);
419 }
420
421 CoerceBuilder CB(VMContext, getDataLayout(), IsVarArg);
422 CB.addStruct(0, StrTy);
423 // All structs, even empty ones, should take up a register argument slot,
424 // so pin the minimum struct size to one bit.
425 CB.pad(llvm::alignTo(
426 std::max(CB.DL.getTypeSizeInBits(StrTy).getKnownMinValue(), uint64_t(1)),
427 64));
428 RegOffset += PaddingSlots + CB.Size / 64;
429
430 // Try to use the original type for coercion.
431 llvm::Type *CoerceTy = CB.isUsableType(StrTy) ? StrTy : CB.getType();
432
433 ABIArgInfo AAI = ABIArgInfo::getDirect(CoerceTy, 0, Padding);
434 AAI.setInReg(CB.InReg);
435 return AAI;
436}
437
438RValue SparcV9ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
439 QualType Ty, AggValueSlot Slot) const {
440 CharUnits SlotSize = CharUnits::fromQuantity(8);
441 auto TInfo = getContext().getTypeInfoInChars(Ty);
442
443 // Zero-sized types have a width of one byte for parameter passing purposes.
444 TInfo.Width = std::max(TInfo.Width, CharUnits::fromQuantity(1));
445
446 // Small _Complex types are right-adjusted, but small aggregates are not.
447 bool ForceRightAdjust = Ty->isAnyComplexType();
448
449 // Arguments bigger than 2*SlotSize bytes are passed indirectly.
450 return emitVoidPtrVAArg(CGF, VAListAddr, Ty,
451 /*IsIndirect=*/TInfo.Width > 2 * SlotSize, TInfo,
452 SlotSize,
453 /*AllowHigherAlign=*/true, Slot, ForceRightAdjust);
454}
455
456void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const {
457 unsigned RetOffset = 0;
458 ABIArgInfo RetType =
459 classifyType(FI.getReturnType(), 32 * 8, RetOffset, /*IsVarArg=*/false);
460 FI.getReturnInfo() = RetType;
461
462 // Indirect returns will have its pointer passed as an argument.
463 unsigned ArgOffset = RetType.isIndirect() ? RetOffset : 0;
464 for (auto [ArgNo, I] : llvm::enumerate(FI.arguments())) {
465 bool IsVarArg = ArgNo >= FI.getNumRequiredArgs();
466 I.info = classifyType(I.type, 16 * 8, ArgOffset, IsVarArg);
467 }
468}
469
470namespace {
471class SparcV9TargetCodeGenInfo : public TargetCodeGenInfo {
472public:
473 SparcV9TargetCodeGenInfo(CodeGenTypes &CGT)
474 : TargetCodeGenInfo(std::make_unique<SparcV9ABIInfo>(CGT)) {}
475
476 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
477 return 14;
478 }
479
480 bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
481 llvm::Value *Address) const override;
482
483 llvm::Value *decodeReturnAddress(CodeGen::CodeGenFunction &CGF,
484 llvm::Value *Address) const override {
485 return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
486 llvm::ConstantInt::get(CGF.Int32Ty, 8));
487 }
488
489 llvm::Value *encodeReturnAddress(CodeGen::CodeGenFunction &CGF,
490 llvm::Value *Address) const override {
491 return CGF.Builder.CreateGEP(CGF.Int8Ty, Address,
492 llvm::ConstantInt::get(CGF.Int32Ty, -8));
493 }
494};
495} // end anonymous namespace
496
497bool
498SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
499 llvm::Value *Address) const {
500 // This is calculated from the LLVM and GCC tables and verified
501 // against gcc output. AFAIK all ABIs use the same encoding.
502
503 CodeGen::CGBuilderTy &Builder = CGF.Builder;
504
505 llvm::IntegerType *i8 = CGF.Int8Ty;
506 llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
507 llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
508
509 // 0-31: the 8-byte general-purpose registers
510 AssignToArrayRange(Builder, Address, Eight8, 0, 31);
511
512 // 32-63: f0-31, the 4-byte floating-point registers
513 AssignToArrayRange(Builder, Address, Four8, 32, 63);
514
515 // Y = 64
516 // PSR = 65
517 // WIM = 66
518 // TBR = 67
519 // PC = 68
520 // NPC = 69
521 // FSR = 70
522 // CSR = 71
523 AssignToArrayRange(Builder, Address, Eight8, 64, 71);
524
525 // 72-87: d0-15, the 8-byte floating-point registers
526 AssignToArrayRange(Builder, Address, Eight8, 72, 87);
527
528 return false;
529}
530
531std::unique_ptr<TargetCodeGenInfo>
533 return std::make_unique<SparcV8TargetCodeGenInfo>(CGM.getTypes());
534}
535
536std::unique_ptr<TargetCodeGenInfo>
538 return std::make_unique<SparcV9TargetCodeGenInfo>(CGM.getTypes());
539}
TokenType getType() const
Returns the token's type, e.g.
static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type, bool forReturn)
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:58
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)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr, llvm::Type *Padding=nullptr)
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Definition CGBuilder.h:302
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
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
const CGFunctionInfo * CurFnInfo
This class organizes the cross-function state that is used while generating LLVM code.
DefaultABIInfo - The default implementation for ABI specific details.
Definition ABIInfoImpl.h:21
ABIArgInfo classifyArgumentType(QualType RetTy) const
ABIArgInfo classifyReturnType(QualType RetTy) const
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3361
QualType getElementType() const
Definition TypeBase.h:3371
bool isVoidType() const
Definition TypeBase.h:9067
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition TypeBase.h:9111
bool isAnyComplexType() const
Definition TypeBase.h:8817
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
Definition Type.h:53
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9294
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)
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array, llvm::Value *Value, unsigned FirstIndex, unsigned LastIndex)
std::unique_ptr< TargetCodeGenInfo > createSparcV8TargetCodeGenInfo(CodeGenModule &CGM)
Definition Sparc.cpp:532
std::unique_ptr< TargetCodeGenInfo > createSparcV9TargetCodeGenInfo(CodeGenModule &CGM)
Definition Sparc.cpp:537
constexpr bool isIntegerType(PrimType T)
Definition PrimType.h:53
Top level wrappers for InstallAPI frontend operations.
U cast(CodeGen::Address addr)
Definition Address.h:327
unsigned long uint64_t
#define false
Definition stdbool.h:26
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64