CGFunctionInfo.h revision 263508
1//==-- CGFunctionInfo.h - Representation of function argument/return types -==// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Defines CGFunctionInfo and associated types used in representing the 11// LLVM source types and ABI-coerced types for function arguments and 12// return values. 13// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_CLANG_CODEGEN_FUNCTION_INFO_H 17#define LLVM_CLANG_CODEGEN_FUNCTION_INFO_H 18 19#include "clang/AST/CanonicalType.h" 20#include "clang/AST/Type.h" 21#include "llvm/ADT/FoldingSet.h" 22 23#include <cassert> 24 25namespace llvm { 26 class Type; 27} 28 29namespace clang { 30namespace CodeGen { 31 32/// ABIArgInfo - Helper class to encapsulate information about how a 33/// specific C type should be passed to or returned from a function. 34class ABIArgInfo { 35public: 36 enum Kind { 37 /// Direct - Pass the argument directly using the normal converted LLVM 38 /// type, or by coercing to another specified type stored in 39 /// 'CoerceToType'). If an offset is specified (in UIntData), then the 40 /// argument passed is offset by some number of bytes in the memory 41 /// representation. A dummy argument is emitted before the real argument 42 /// if the specified type stored in "PaddingType" is not zero. 43 Direct, 44 45 /// Extend - Valid only for integer argument types. Same as 'direct' 46 /// but also emit a zero/sign extension attribute. 47 Extend, 48 49 /// Indirect - Pass the argument indirectly via a hidden pointer 50 /// with the specified alignment (0 indicates default alignment). 51 Indirect, 52 53 /// Ignore - Ignore the argument (treat as void). Useful for void and 54 /// empty structs. 55 Ignore, 56 57 /// Expand - Only valid for aggregate argument types. The structure should 58 /// be expanded into consecutive arguments for its constituent fields. 59 /// Currently expand is only allowed on structures whose fields 60 /// are all scalar types or are themselves expandable types. 61 Expand, 62 63 KindFirst=Direct, KindLast=Expand 64 }; 65 66private: 67 Kind TheKind; 68 llvm::Type *TypeData; 69 llvm::Type *PaddingType; 70 unsigned UIntData; 71 bool BoolData0; 72 bool BoolData1; 73 bool InReg; 74 bool PaddingInReg; 75 76 ABIArgInfo(Kind K, llvm::Type *TD, unsigned UI, bool B0, bool B1, bool IR, 77 bool PIR, llvm::Type* P) 78 : TheKind(K), TypeData(TD), PaddingType(P), UIntData(UI), BoolData0(B0), 79 BoolData1(B1), InReg(IR), PaddingInReg(PIR) {} 80 81public: 82 ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {} 83 84 static ABIArgInfo getDirect(llvm::Type *T = 0, unsigned Offset = 0, 85 llvm::Type *Padding = 0) { 86 return ABIArgInfo(Direct, T, Offset, false, false, false, false, Padding); 87 } 88 static ABIArgInfo getDirectInReg(llvm::Type *T = 0) { 89 return ABIArgInfo(Direct, T, 0, false, false, true, false, 0); 90 } 91 static ABIArgInfo getExtend(llvm::Type *T = 0) { 92 return ABIArgInfo(Extend, T, 0, false, false, false, false, 0); 93 } 94 static ABIArgInfo getExtendInReg(llvm::Type *T = 0) { 95 return ABIArgInfo(Extend, T, 0, false, false, true, false, 0); 96 } 97 static ABIArgInfo getIgnore() { 98 return ABIArgInfo(Ignore, 0, 0, false, false, false, false, 0); 99 } 100 static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true 101 , bool Realign = false 102 , llvm::Type *Padding = 0) { 103 return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, false, false, 104 Padding); 105 } 106 static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true 107 , bool Realign = false) { 108 return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign, true, false, 0); 109 } 110 static ABIArgInfo getExpand() { 111 return ABIArgInfo(Expand, 0, 0, false, false, false, false, 0); 112 } 113 static ABIArgInfo getExpandWithPadding(bool PaddingInReg, 114 llvm::Type *Padding) { 115 return ABIArgInfo(Expand, 0, 0, false, false, false, PaddingInReg, 116 Padding); 117 } 118 119 Kind getKind() const { return TheKind; } 120 bool isDirect() const { return TheKind == Direct; } 121 bool isExtend() const { return TheKind == Extend; } 122 bool isIgnore() const { return TheKind == Ignore; } 123 bool isIndirect() const { return TheKind == Indirect; } 124 bool isExpand() const { return TheKind == Expand; } 125 126 bool canHaveCoerceToType() const { 127 return TheKind == Direct || TheKind == Extend; 128 } 129 130 // Direct/Extend accessors 131 unsigned getDirectOffset() const { 132 assert((isDirect() || isExtend()) && "Not a direct or extend kind"); 133 return UIntData; 134 } 135 136 llvm::Type *getPaddingType() const { 137 return PaddingType; 138 } 139 140 bool getPaddingInReg() const { 141 return PaddingInReg; 142 } 143 144 llvm::Type *getCoerceToType() const { 145 assert(canHaveCoerceToType() && "Invalid kind!"); 146 return TypeData; 147 } 148 149 void setCoerceToType(llvm::Type *T) { 150 assert(canHaveCoerceToType() && "Invalid kind!"); 151 TypeData = T; 152 } 153 154 bool getInReg() const { 155 assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); 156 return InReg; 157 } 158 159 // Indirect accessors 160 unsigned getIndirectAlign() const { 161 assert(TheKind == Indirect && "Invalid kind!"); 162 return UIntData; 163 } 164 165 bool getIndirectByVal() const { 166 assert(TheKind == Indirect && "Invalid kind!"); 167 return BoolData0; 168 } 169 170 bool getIndirectRealign() const { 171 assert(TheKind == Indirect && "Invalid kind!"); 172 return BoolData1; 173 } 174 175 void dump() const; 176}; 177 178/// A class for recording the number of arguments that a function 179/// signature requires. 180class RequiredArgs { 181 /// The number of required arguments, or ~0 if the signature does 182 /// not permit optional arguments. 183 unsigned NumRequired; 184public: 185 enum All_t { All }; 186 187 RequiredArgs(All_t _) : NumRequired(~0U) {} 188 explicit RequiredArgs(unsigned n) : NumRequired(n) { 189 assert(n != ~0U); 190 } 191 192 /// Compute the arguments required by the given formal prototype, 193 /// given that there may be some additional, non-formal arguments 194 /// in play. 195 static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, 196 unsigned additional) { 197 if (!prototype->isVariadic()) return All; 198 return RequiredArgs(prototype->getNumArgs() + additional); 199 } 200 201 static RequiredArgs forPrototype(const FunctionProtoType *prototype) { 202 return forPrototypePlus(prototype, 0); 203 } 204 205 static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { 206 return forPrototype(prototype.getTypePtr()); 207 } 208 209 static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, 210 unsigned additional) { 211 return forPrototypePlus(prototype.getTypePtr(), additional); 212 } 213 214 bool allowsOptionalArgs() const { return NumRequired != ~0U; } 215 unsigned getNumRequiredArgs() const { 216 assert(allowsOptionalArgs()); 217 return NumRequired; 218 } 219 220 unsigned getOpaqueData() const { return NumRequired; } 221 static RequiredArgs getFromOpaqueData(unsigned value) { 222 if (value == ~0U) return All; 223 return RequiredArgs(value); 224 } 225}; 226 227/// CGFunctionInfo - Class to encapsulate the information about a 228/// function definition. 229class CGFunctionInfo : public llvm::FoldingSetNode { 230 struct ArgInfo { 231 CanQualType type; 232 ABIArgInfo info; 233 }; 234 235 /// The LLVM::CallingConv to use for this function (as specified by the 236 /// user). 237 unsigned CallingConvention : 8; 238 239 /// The LLVM::CallingConv to actually use for this function, which may 240 /// depend on the ABI. 241 unsigned EffectiveCallingConvention : 8; 242 243 /// The clang::CallingConv that this was originally created with. 244 unsigned ASTCallingConvention : 8; 245 246 /// Whether this function is noreturn. 247 unsigned NoReturn : 1; 248 249 /// Whether this function is returns-retained. 250 unsigned ReturnsRetained : 1; 251 252 /// How many arguments to pass inreg. 253 unsigned HasRegParm : 1; 254 unsigned RegParm : 4; 255 256 RequiredArgs Required; 257 258 unsigned NumArgs; 259 ArgInfo *getArgsBuffer() { 260 return reinterpret_cast<ArgInfo*>(this+1); 261 } 262 const ArgInfo *getArgsBuffer() const { 263 return reinterpret_cast<const ArgInfo*>(this + 1); 264 } 265 266 CGFunctionInfo() : Required(RequiredArgs::All) {} 267 268public: 269 static CGFunctionInfo *create(unsigned llvmCC, 270 const FunctionType::ExtInfo &extInfo, 271 CanQualType resultType, 272 ArrayRef<CanQualType> argTypes, 273 RequiredArgs required); 274 275 typedef const ArgInfo *const_arg_iterator; 276 typedef ArgInfo *arg_iterator; 277 278 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } 279 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; } 280 arg_iterator arg_begin() { return getArgsBuffer() + 1; } 281 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; } 282 283 unsigned arg_size() const { return NumArgs; } 284 285 bool isVariadic() const { return Required.allowsOptionalArgs(); } 286 RequiredArgs getRequiredArgs() const { return Required; } 287 288 bool isNoReturn() const { return NoReturn; } 289 290 /// In ARC, whether this function retains its return value. This 291 /// is not always reliable for call sites. 292 bool isReturnsRetained() const { return ReturnsRetained; } 293 294 /// getASTCallingConvention() - Return the AST-specified calling 295 /// convention. 296 CallingConv getASTCallingConvention() const { 297 return CallingConv(ASTCallingConvention); 298 } 299 300 /// getCallingConvention - Return the user specified calling 301 /// convention, which has been translated into an LLVM CC. 302 unsigned getCallingConvention() const { return CallingConvention; } 303 304 /// getEffectiveCallingConvention - Return the actual calling convention to 305 /// use, which may depend on the ABI. 306 unsigned getEffectiveCallingConvention() const { 307 return EffectiveCallingConvention; 308 } 309 void setEffectiveCallingConvention(unsigned Value) { 310 EffectiveCallingConvention = Value; 311 } 312 313 bool getHasRegParm() const { return HasRegParm; } 314 unsigned getRegParm() const { return RegParm; } 315 316 FunctionType::ExtInfo getExtInfo() const { 317 return FunctionType::ExtInfo(isNoReturn(), 318 getHasRegParm(), getRegParm(), 319 getASTCallingConvention(), 320 isReturnsRetained()); 321 } 322 323 CanQualType getReturnType() const { return getArgsBuffer()[0].type; } 324 325 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } 326 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } 327 328 void Profile(llvm::FoldingSetNodeID &ID) { 329 ID.AddInteger(getASTCallingConvention()); 330 ID.AddBoolean(NoReturn); 331 ID.AddBoolean(ReturnsRetained); 332 ID.AddBoolean(HasRegParm); 333 ID.AddInteger(RegParm); 334 ID.AddInteger(Required.getOpaqueData()); 335 getReturnType().Profile(ID); 336 for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it) 337 it->type.Profile(ID); 338 } 339 static void Profile(llvm::FoldingSetNodeID &ID, 340 const FunctionType::ExtInfo &info, 341 RequiredArgs required, 342 CanQualType resultType, 343 ArrayRef<CanQualType> argTypes) { 344 ID.AddInteger(info.getCC()); 345 ID.AddBoolean(info.getNoReturn()); 346 ID.AddBoolean(info.getProducesResult()); 347 ID.AddBoolean(info.getHasRegParm()); 348 ID.AddInteger(info.getRegParm()); 349 ID.AddInteger(required.getOpaqueData()); 350 resultType.Profile(ID); 351 for (ArrayRef<CanQualType>::iterator 352 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { 353 i->Profile(ID); 354 } 355 } 356}; 357 358} // end namespace CodeGen 359} // end namespace clang 360 361#endif 362