clang: lib/CodeGen/ABIInfoImpl.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
10
11using namespace clang;
13
14
16
19
21
22
25
27 }
28
29
31 Ty = EnumTy->getDecl()->getIntegerType();
32
35 if (EIT->getNumBits() >
40
44}
45
49
52
53
55 RetTy = EnumTy->getDecl()->getIntegerType();
56
58 if (EIT->getNumBits() >
63
66}
67
73}
74
80 Slot);
81}
82
84 llvm::Value *Array, llvm::Value *Value,
85 unsigned FirstIndex, unsigned LastIndex) {
86
87 for (unsigned I = FirstIndex; I <= LastIndex; ++I) {
88 llvm::Value *Cell =
89 Builder.CreateConstInBoundsGEP1_32(Builder.getInt8Ty(), Array, I);
91 }
92}
93
97}
98
102}
103
107 if (!RD) {
111 }
112 return CXXABI.getRecordArgABI(RD);
113}
114
117 if (!RT)
120}
121
125
127 if (!isa(RT->getDecl()) &&
128 !RT->getDecl()->canPassInRegisters()) {
130 return true;
131 }
132
133 return CXXABI.classifyReturnType(FI);
134}
135
138 const RecordDecl *UD = UT->getDecl();
139 if (UD->hasAttr()) {
140 assert(!UD->field_empty() && "sema created an empty transparent union");
142 }
143 }
144 return Ty;
145}
146
148 llvm::Value *Ptr,
150
151 llvm::Value *RoundUp = CGF.Builder.CreateConstInBoundsGEP1_32(
153 return CGF.Builder.CreateIntrinsic(
154 llvm::Intrinsic::ptrmask, {Ptr->getType(), CGF.IntPtrTy},
156 nullptr, Ptr->getName() + ".aligned");
157}
158
161 llvm::Type *DirectTy, CharUnits DirectSize,
163 bool AllowHigherAlign, bool ForceRightAdjust) {
164
165
168
169 llvm::Value *Ptr = CGF.Builder.CreateLoad(VAListAddr, "argp.cur");
170
171
173 if (AllowHigherAlign && DirectAlign > SlotSize) {
175 CGF.Int8Ty, DirectAlign);
176 } else {
178 }
179
180
185
186
187
188 if (DirectSize < SlotSize && CGF.CGM.getDataLayout().isBigEndian() &&
189 (!DirectTy->isStructTy() || ForceRightAdjust)) {
191 }
192
194}
195
197 QualType ValueTy, bool IsIndirect,
201 bool ForceRightAdjust) {
202
203 CharUnits DirectSize, DirectAlign;
204 if (IsIndirect) {
207 } else {
208 DirectSize = ValueInfo.Width;
209 DirectAlign = ValueInfo.Align;
210 }
211
212
213 llvm::Type *DirectTy = CGF.ConvertTypeForMem(ValueTy), *ElementTy = DirectTy;
214 if (IsIndirect) {
215 unsigned AllocaAS = CGF.CGM.getDataLayout().getAllocaAddrSpace();
216 DirectTy = llvm::PointerType::get(CGF.getLLVMContext(), AllocaAS);
217 }
218
220 DirectAlign, SlotSizeAndAlign,
221 AllowHigherAlign, ForceRightAdjust);
222
223 if (IsIndirect) {
225 }
226
228}
229
231 llvm::BasicBlock *Block1, Address Addr2,
232 llvm::BasicBlock *Block2,
233 const llvm::Twine &Name) {
235 llvm::PHINode *PHI = CGF.Builder.CreatePHI(Addr1.getType(), 2, Name);
240}
241
243 bool AllowArrays, bool AsIfNoUniqueAddr) {
245 return true;
246
248
249
250
251 bool WasArray = false;
252 if (AllowArrays)
254 if (AT->isZeroSize())
255 return true;
256 FT = AT->getElementType();
257
258
259 WasArray = true;
260 }
261
263 if (!RT)
264 return false;
265
266
267
268
269
270
271
272
273
274
275
276 if (isa(RT->getDecl()) &&
277 (WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr())))
278 return false;
279
280 return isEmptyRecord(Context, FT, AllowArrays, AsIfNoUniqueAddr);
281}
282
284 bool AsIfNoUniqueAddr) {
286 if (!RT)
287 return false;
290 return false;
291
292
293 if (const CXXRecordDecl *CXXRD = dyn_cast(RD))
294 for (const auto &I : CXXRD->bases())
295 if ((Context, I.getType(), true, AsIfNoUniqueAddr))
296 return false;
297
298 for (const auto *I : RD->fields())
299 if ((Context, I, AllowArrays, AsIfNoUniqueAddr))
300 return false;
301 return true;
302}
303
307 return true;
308
310 return false;
311
313}
314
317 if (!RT)
318 return false;
319
321
322
323 if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) {
324 if (CXXRD->isDynamicClass())
325 return false;
326
327 for (const auto &I : CXXRD->bases())
329 return false;
330 }
331
332 for (const auto *I : RD->fields())
334 return false;
335
336 return true;
337}
338
341 if (!RT)
342 return nullptr;
343
346 return nullptr;
347
349
350
351 if (const CXXRecordDecl *CXXRD = dyn_cast(RD)) {
352 for (const auto &I : CXXRD->bases()) {
353
355 continue;
356
357
359 return nullptr;
360
361
362
365 return nullptr;
366 }
367 }
368
369
370 for (const auto *FD : RD->fields()) {
372
373
375 continue;
376
377
378
380 return nullptr;
381
382
384 if (AT->getZExtSize() != 1)
385 break;
386 FT = AT->getElementType();
387 }
388
391 } else {
394 return nullptr;
395 }
396 }
397
398
399
401 return nullptr;
402
404}
405
408
409
410
411
412
413
414
415
416
417 llvm::Value *Val;
418
421 "Unexpected PaddingType seen in arginfo in generic VAArg emitter!");
422 assert(
424 "Unexpected IndirectRealign seen in arginfo in generic VAArg emitter!");
425
427 CharUnits TyAlignForABI = TyInfo.Align;
428
430 llvm::Type *BaseTy = llvm::PointerType::getUnqual(ElementTy);
431 llvm::Value *Addr =
433 return Address(Addr, ElementTy, TyAlignForABI);
434 } else {
436 "Unexpected ArgInfo Kind in generic VAArg emitter!");
437
439 "Unexpected InReg seen in arginfo in generic VAArg emitter!");
441 "Unexpected PaddingType seen in arginfo in generic VAArg emitter!");
443 "Unexpected DirectOffset seen in arginfo in generic VAArg emitter!");
445 "Unexpected CoerceToType seen in arginfo in generic VAArg emitter!");
446
451 return Temp;
452 }
453}
454
457}
458
461 if (!RT)
462 return false;
464
465
466 if (const CXXRecordDecl *CXXRD = dyn_cast(RD))
467 for (const auto &I : CXXRD->bases())
469 return false;
470
471 for (const auto *i : RD->fields()) {
473
475 return true;
476
478 return true;
479 }
480
481 return false;
482}
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
QualType getBuiltinVaListType() const
Retrieve the type of the __builtin_va_list type.
TypeInfoChars getTypeInfoInChars(const Type *T) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const TargetInfo & getTargetInfo() const
A fixed int type of a specified bitwidth.
Implements C++ ABI-specific semantic analysis functions.
Represents a C++ struct/union/class.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
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 ...
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
bool getIndirectRealign() const
static ABIArgInfo getIgnore()
unsigned getDirectOffset() const
llvm::Type * getPaddingType() const
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 * getCoerceToType() const
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
CodeGen::CodeGenTypes & CGT
CodeGen::CGCXXABI & getCXXABI() const
ASTContext & getContext() const
bool isPromotableIntegerTypeForABI(QualType Ty) const
CodeGen::ABIArgInfo getNaturalAlignIndirect(QualType Ty, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr) const
A convenience method to return an indirect ABIArgInfo with an expected alignment equal to the ABI ali...
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::PointerType * getType() const
Return the type of the pointer value.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Implements C++ ABI-specific code generation functions.
RecordArgABI
Specify how one should pass an argument of a record type.
@ RAA_Default
Pass it using the normal C aggregate rules for the ABI, potentially introducing extra copies and pass...
@ RAA_Indirect
Pass it as a pointer to temporary memory.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertTypeForMem(QualType T)
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
ASTContext & getContext() const
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
llvm::LLVMContext & getLLVMContext()
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
const llvm::DataLayout & getDataLayout() const
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
ABIArgInfo classifyArgumentType(QualType RetTy) const
RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, AggValueSlot Slot) const override
EmitVAArg - Emit the target dependent code to load a value of.
ABIArgInfo classifyReturnType(QualType RetTy) const
virtual ~DefaultABIInfo()
void computeInfo(CGFunctionInfo &FI) const override
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
Represents the canonical version of C arrays with a specified constant size.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Represents a member of a struct/union/class.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
bool isZeroLengthBitField() const
Is this a zero-length bit-field? Such bit-fields aren't really bit-fields at all and instead act as a...
A (possibly-)qualified type.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Represents a struct/union/class.
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
bool hasFlexibleArrayMember() const
field_range fields() const
field_iterator field_begin() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
virtual bool hasInt128Type() const
Determine whether the __int128 type is supported on this target.
The base class of the type hierarchy.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isMemberFunctionPointerType() const
const T * getAs() const
Member-template getAs'.
Represents a GCC generic vector type.
bool isEmptyRecordForLayout(const ASTContext &Context, QualType T)
isEmptyRecordForLayout - Return true iff a structure contains only empty base classes (per isEmptyRec...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
Address EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, const ABIArgInfo &AI)
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr, llvm::Type *DirectTy, CharUnits DirectSize, CharUnits DirectAlign, CharUnits SlotSize, bool AllowHigherAlign, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty)
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 ...
Address emitMergePHI(CodeGenFunction &CGF, Address Addr1, llvm::BasicBlock *Block1, Address Addr2, llvm::BasicBlock *Block2, const llvm::Twine &Name="")
bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyField - Return true iff a the field is "empty", that is it is an unnamed bit-field or an (arra...
llvm::Value * emitRoundPointerUpToAlignment(CodeGenFunction &CGF, llvm::Value *Ptr, CharUnits Align)
bool isAggregateTypeForABI(QualType T)
const Type * isSingleElementStruct(QualType T, ASTContext &Context)
isSingleElementStruct - Determine if a structure is a "single element struct", i.e.
llvm::Type * getVAListElementType(CodeGenFunction &CGF)
void AssignToArrayRange(CodeGen::CGBuilderTy &Builder, llvm::Value *Array, llvm::Value *Value, unsigned FirstIndex, unsigned LastIndex)
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.
bool isSIMDVectorType(ASTContext &Context, QualType Ty)
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getPointerSize() const
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const