1 //==-- CGFunctionInfo.h - Representation of function argument/return types -==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Defines CGFunctionInfo and associated types used in representing the
11 // LLVM source types and ABI-coerced types for function arguments and
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_CLANG_CODEGEN_FUNCTION_INFO_H
17 #define LLVM_CLANG_CODEGEN_FUNCTION_INFO_H
19 #include "clang/AST/CanonicalType.h"
20 #include "clang/AST/Type.h"
21 #include "llvm/ADT/FoldingSet.h"
34 /// ABIArgInfo - Helper class to encapsulate information about how a
35 /// specific C type should be passed to or returned from a function.
39 /// Direct - Pass the argument directly using the normal converted LLVM
40 /// type, or by coercing to another specified type stored in
41 /// 'CoerceToType'). If an offset is specified (in UIntData), then the
42 /// argument passed is offset by some number of bytes in the memory
43 /// representation. A dummy argument is emitted before the real argument
44 /// if the specified type stored in "PaddingType" is not zero.
47 /// Extend - Valid only for integer argument types. Same as 'direct'
48 /// but also emit a zero/sign extension attribute.
51 /// Indirect - Pass the argument indirectly via a hidden pointer
52 /// with the specified alignment (0 indicates default alignment).
55 /// Ignore - Ignore the argument (treat as void). Useful for void and
59 /// Expand - Only valid for aggregate argument types. The structure should
60 /// be expanded into consecutive arguments for its constituent fields.
61 /// Currently expand is only allowed on structures whose fields
62 /// are all scalar types or are themselves expandable types.
65 /// InAlloca - Pass the argument directly using the LLVM inalloca attribute.
66 /// This is similar to 'direct', except it only applies to arguments stored
67 /// in memory and forbids any implicit copies. When applied to a return
68 /// type, it means the value is returned indirectly via an implicit sret
69 /// parameter stored in the argument struct.
76 llvm::Type *TypeData; // isDirect() || isExtend()
77 llvm::Type *PaddingType;
79 unsigned DirectOffset; // isDirect() || isExtend()
80 unsigned IndirectAlign; // isIndirect()
81 unsigned AllocaFieldIndex; // isInAlloca()
84 bool PaddingInReg : 1;
85 bool InAllocaSRet : 1; // isInAlloca()
86 bool IndirectByVal : 1; // isIndirect()
87 bool IndirectRealign : 1; // isIndirect()
88 bool SRetAfterThis : 1; // isIndirect()
89 bool InReg : 1; // isDirect() || isExtend() || isIndirect()
92 : PaddingType(nullptr), TheKind(K), PaddingInReg(false), InReg(false) {}
96 : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0),
97 TheKind(Direct), PaddingInReg(false), InReg(false) {}
99 static ABIArgInfo getDirect(llvm::Type *T = nullptr, unsigned Offset = 0,
100 llvm::Type *Padding = nullptr) {
101 auto AI = ABIArgInfo(Direct);
102 AI.setCoerceToType(T);
103 AI.setDirectOffset(Offset);
104 AI.setPaddingType(Padding);
107 static ABIArgInfo getDirectInReg(llvm::Type *T = nullptr) {
108 auto AI = getDirect(T);
112 static ABIArgInfo getExtend(llvm::Type *T = nullptr) {
113 auto AI = ABIArgInfo(Extend);
114 AI.setCoerceToType(T);
115 AI.setDirectOffset(0);
118 static ABIArgInfo getExtendInReg(llvm::Type *T = nullptr) {
119 auto AI = getExtend(T);
123 static ABIArgInfo getIgnore() {
124 return ABIArgInfo(Ignore);
126 static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true,
127 bool Realign = false,
128 llvm::Type *Padding = nullptr) {
129 auto AI = ABIArgInfo(Indirect);
130 AI.setIndirectAlign(Alignment);
131 AI.setIndirectByVal(ByVal);
132 AI.setIndirectRealign(Realign);
133 AI.setSRetAfterThis(false);
134 AI.setPaddingType(Padding);
137 static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true,
138 bool Realign = false) {
139 auto AI = getIndirect(Alignment, ByVal, Realign);
143 static ABIArgInfo getInAlloca(unsigned FieldIndex) {
144 auto AI = ABIArgInfo(InAlloca);
145 AI.setInAllocaFieldIndex(FieldIndex);
148 static ABIArgInfo getExpand() {
149 return ABIArgInfo(Expand);
151 static ABIArgInfo getExpandWithPadding(bool PaddingInReg,
152 llvm::Type *Padding) {
153 auto AI = getExpand();
154 AI.setPaddingInReg(PaddingInReg);
155 AI.setPaddingType(Padding);
159 Kind getKind() const { return TheKind; }
160 bool isDirect() const { return TheKind == Direct; }
161 bool isInAlloca() const { return TheKind == InAlloca; }
162 bool isExtend() const { return TheKind == Extend; }
163 bool isIgnore() const { return TheKind == Ignore; }
164 bool isIndirect() const { return TheKind == Indirect; }
165 bool isExpand() const { return TheKind == Expand; }
167 bool canHaveCoerceToType() const { return isDirect() || isExtend(); }
169 // Direct/Extend accessors
170 unsigned getDirectOffset() const {
171 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
174 void setDirectOffset(unsigned Offset) {
175 assert((isDirect() || isExtend()) && "Not a direct or extend kind");
176 DirectOffset = Offset;
179 llvm::Type *getPaddingType() const { return PaddingType; }
181 void setPaddingType(llvm::Type *T) { PaddingType = T; }
183 bool getPaddingInReg() const {
186 void setPaddingInReg(bool PIR) {
190 llvm::Type *getCoerceToType() const {
191 assert(canHaveCoerceToType() && "Invalid kind!");
195 void setCoerceToType(llvm::Type *T) {
196 assert(canHaveCoerceToType() && "Invalid kind!");
200 bool getInReg() const {
201 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
205 void setInReg(bool IR) {
206 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!");
210 // Indirect accessors
211 unsigned getIndirectAlign() const {
212 assert(isIndirect() && "Invalid kind!");
213 return IndirectAlign;
215 void setIndirectAlign(unsigned IA) {
216 assert(isIndirect() && "Invalid kind!");
220 bool getIndirectByVal() const {
221 assert(isIndirect() && "Invalid kind!");
222 return IndirectByVal;
224 void setIndirectByVal(unsigned IBV) {
225 assert(isIndirect() && "Invalid kind!");
229 bool getIndirectRealign() const {
230 assert(isIndirect() && "Invalid kind!");
231 return IndirectRealign;
233 void setIndirectRealign(bool IR) {
234 assert(isIndirect() && "Invalid kind!");
235 IndirectRealign = IR;
238 bool isSRetAfterThis() const {
239 assert(isIndirect() && "Invalid kind!");
240 return SRetAfterThis;
242 void setSRetAfterThis(bool AfterThis) {
243 assert(isIndirect() && "Invalid kind!");
244 SRetAfterThis = AfterThis;
247 unsigned getInAllocaFieldIndex() const {
248 assert(isInAlloca() && "Invalid kind!");
249 return AllocaFieldIndex;
251 void setInAllocaFieldIndex(unsigned FieldIndex) {
252 assert(isInAlloca() && "Invalid kind!");
253 AllocaFieldIndex = FieldIndex;
256 /// \brief Return true if this field of an inalloca struct should be returned
257 /// to implement a struct return calling convention.
258 bool getInAllocaSRet() const {
259 assert(isInAlloca() && "Invalid kind!");
263 void setInAllocaSRet(bool SRet) {
264 assert(isInAlloca() && "Invalid kind!");
271 /// A class for recording the number of arguments that a function
272 /// signature requires.
274 /// The number of required arguments, or ~0 if the signature does
275 /// not permit optional arguments.
276 unsigned NumRequired;
280 RequiredArgs(All_t _) : NumRequired(~0U) {}
281 explicit RequiredArgs(unsigned n) : NumRequired(n) {
285 /// Compute the arguments required by the given formal prototype,
286 /// given that there may be some additional, non-formal arguments
288 static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype,
289 unsigned additional) {
290 if (!prototype->isVariadic()) return All;
291 return RequiredArgs(prototype->getNumParams() + additional);
294 static RequiredArgs forPrototype(const FunctionProtoType *prototype) {
295 return forPrototypePlus(prototype, 0);
298 static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) {
299 return forPrototype(prototype.getTypePtr());
302 static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype,
303 unsigned additional) {
304 return forPrototypePlus(prototype.getTypePtr(), additional);
307 bool allowsOptionalArgs() const { return NumRequired != ~0U; }
308 unsigned getNumRequiredArgs() const {
309 assert(allowsOptionalArgs());
313 unsigned getOpaqueData() const { return NumRequired; }
314 static RequiredArgs getFromOpaqueData(unsigned value) {
315 if (value == ~0U) return All;
316 return RequiredArgs(value);
320 /// CGFunctionInfo - Class to encapsulate the information about a
321 /// function definition.
322 class CGFunctionInfo : public llvm::FoldingSetNode {
328 /// The LLVM::CallingConv to use for this function (as specified by the
330 unsigned CallingConvention : 8;
332 /// The LLVM::CallingConv to actually use for this function, which may
333 /// depend on the ABI.
334 unsigned EffectiveCallingConvention : 8;
336 /// The clang::CallingConv that this was originally created with.
337 unsigned ASTCallingConvention : 8;
339 /// Whether this is an instance method.
340 unsigned InstanceMethod : 1;
342 /// Whether this function is noreturn.
343 unsigned NoReturn : 1;
345 /// Whether this function is returns-retained.
346 unsigned ReturnsRetained : 1;
348 /// How many arguments to pass inreg.
349 unsigned HasRegParm : 1;
350 unsigned RegParm : 4;
352 RequiredArgs Required;
354 /// The struct representing all arguments passed in memory. Only used when
355 /// passing non-trivial types with inalloca. Not part of the profile.
356 llvm::StructType *ArgStruct;
359 ArgInfo *getArgsBuffer() {
360 return reinterpret_cast<ArgInfo*>(this+1);
362 const ArgInfo *getArgsBuffer() const {
363 return reinterpret_cast<const ArgInfo*>(this + 1);
366 CGFunctionInfo() : Required(RequiredArgs::All) {}
369 static CGFunctionInfo *create(unsigned llvmCC,
371 const FunctionType::ExtInfo &extInfo,
372 CanQualType resultType,
373 ArrayRef<CanQualType> argTypes,
374 RequiredArgs required);
376 typedef const ArgInfo *const_arg_iterator;
377 typedef ArgInfo *arg_iterator;
379 typedef llvm::iterator_range<arg_iterator> arg_range;
380 typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
382 arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
383 arg_const_range arguments() const {
384 return arg_const_range(arg_begin(), arg_end());
387 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }
388 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; }
389 arg_iterator arg_begin() { return getArgsBuffer() + 1; }
390 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; }
392 unsigned arg_size() const { return NumArgs; }
394 bool isVariadic() const { return Required.allowsOptionalArgs(); }
395 RequiredArgs getRequiredArgs() const { return Required; }
397 bool isInstanceMethod() const { return InstanceMethod; }
399 bool isNoReturn() const { return NoReturn; }
401 /// In ARC, whether this function retains its return value. This
402 /// is not always reliable for call sites.
403 bool isReturnsRetained() const { return ReturnsRetained; }
405 /// getASTCallingConvention() - Return the AST-specified calling
407 CallingConv getASTCallingConvention() const {
408 return CallingConv(ASTCallingConvention);
411 /// getCallingConvention - Return the user specified calling
412 /// convention, which has been translated into an LLVM CC.
413 unsigned getCallingConvention() const { return CallingConvention; }
415 /// getEffectiveCallingConvention - Return the actual calling convention to
416 /// use, which may depend on the ABI.
417 unsigned getEffectiveCallingConvention() const {
418 return EffectiveCallingConvention;
420 void setEffectiveCallingConvention(unsigned Value) {
421 EffectiveCallingConvention = Value;
424 bool getHasRegParm() const { return HasRegParm; }
425 unsigned getRegParm() const { return RegParm; }
427 FunctionType::ExtInfo getExtInfo() const {
428 return FunctionType::ExtInfo(isNoReturn(),
429 getHasRegParm(), getRegParm(),
430 getASTCallingConvention(),
431 isReturnsRetained());
434 CanQualType getReturnType() const { return getArgsBuffer()[0].type; }
436 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; }
437 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; }
439 /// \brief Return true if this function uses inalloca arguments.
440 bool usesInAlloca() const { return ArgStruct; }
442 /// \brief Get the struct type used to represent all the arguments in memory.
443 llvm::StructType *getArgStruct() const { return ArgStruct; }
444 void setArgStruct(llvm::StructType *Ty) { ArgStruct = Ty; }
446 void Profile(llvm::FoldingSetNodeID &ID) {
447 ID.AddInteger(getASTCallingConvention());
448 ID.AddBoolean(InstanceMethod);
449 ID.AddBoolean(NoReturn);
450 ID.AddBoolean(ReturnsRetained);
451 ID.AddBoolean(HasRegParm);
452 ID.AddInteger(RegParm);
453 ID.AddInteger(Required.getOpaqueData());
454 getReturnType().Profile(ID);
455 for (const auto &I : arguments())
458 static void Profile(llvm::FoldingSetNodeID &ID,
460 const FunctionType::ExtInfo &info,
461 RequiredArgs required,
462 CanQualType resultType,
463 ArrayRef<CanQualType> argTypes) {
464 ID.AddInteger(info.getCC());
465 ID.AddBoolean(InstanceMethod);
466 ID.AddBoolean(info.getNoReturn());
467 ID.AddBoolean(info.getProducesResult());
468 ID.AddBoolean(info.getHasRegParm());
469 ID.AddInteger(info.getRegParm());
470 ID.AddInteger(required.getOpaqueData());
471 resultType.Profile(ID);
472 for (ArrayRef<CanQualType>::iterator
473 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) {
479 } // end namespace CodeGen
480 } // end namespace clang