1//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===// 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// These classes wrap the information about a call or function 11// definition used to handle ABI compliancy. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef CLANG_CODEGEN_CGCALL_H 16#define CLANG_CODEGEN_CGCALL_H 17 18#include "CGValue.h" 19#include "clang/AST/CanonicalType.h" 20#include "clang/AST/Type.h" 21#include "llvm/ADT/FoldingSet.h" 22#include "llvm/IR/Value.h" 23 24// FIXME: Restructure so we don't have to expose so much stuff. 25#include "ABIInfo.h" 26 27namespace llvm { 28 class AttributeSet; 29 class Function; 30 class Type; 31 class Value; 32} 33 34namespace clang { 35 class ASTContext; 36 class Decl; 37 class FunctionDecl; 38 class ObjCMethodDecl; 39 class VarDecl; 40 41namespace CodeGen { 42 typedef SmallVector<llvm::AttributeSet, 8> AttributeListType; 43 44 struct CallArg { 45 RValue RV; 46 QualType Ty; 47 bool NeedsCopy; 48 CallArg(RValue rv, QualType ty, bool needscopy) 49 : RV(rv), Ty(ty), NeedsCopy(needscopy) 50 { } 51 }; 52 53 /// CallArgList - Type for representing both the value and type of 54 /// arguments in a call. 55 class CallArgList : 56 public SmallVector<CallArg, 16> { 57 public: 58 struct Writeback { 59 /// The original argument. 60 llvm::Value *Address; 61 62 /// The pointee type of the original argument. 63 QualType AddressType; 64 65 /// The temporary alloca. 66 llvm::Value *Temporary; 67 }; 68 69 void add(RValue rvalue, QualType type, bool needscopy = false) { 70 push_back(CallArg(rvalue, type, needscopy)); 71 } 72 73 void addFrom(const CallArgList &other) { 74 insert(end(), other.begin(), other.end()); 75 Writebacks.insert(Writebacks.end(), 76 other.Writebacks.begin(), other.Writebacks.end()); 77 } 78 79 void addWriteback(llvm::Value *address, QualType addressType, 80 llvm::Value *temporary) { 81 Writeback writeback; 82 writeback.Address = address; 83 writeback.AddressType = addressType; 84 writeback.Temporary = temporary; 85 Writebacks.push_back(writeback); 86 } 87 88 bool hasWritebacks() const { return !Writebacks.empty(); } 89 90 typedef SmallVectorImpl<Writeback>::const_iterator writeback_iterator; 91 writeback_iterator writeback_begin() const { return Writebacks.begin(); } 92 writeback_iterator writeback_end() const { return Writebacks.end(); } 93 94 private: 95 SmallVector<Writeback, 1> Writebacks; 96 }; 97 98 /// A class for recording the number of arguments that a function 99 /// signature requires. 100 class RequiredArgs { 101 /// The number of required arguments, or ~0 if the signature does 102 /// not permit optional arguments. 103 unsigned NumRequired; 104 public: 105 enum All_t { All }; 106 107 RequiredArgs(All_t _) : NumRequired(~0U) {} 108 explicit RequiredArgs(unsigned n) : NumRequired(n) { 109 assert(n != ~0U); 110 } 111 112 /// Compute the arguments required by the given formal prototype, 113 /// given that there may be some additional, non-formal arguments 114 /// in play. 115 static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, 116 unsigned additional) { 117 if (!prototype->isVariadic()) return All; 118 return RequiredArgs(prototype->getNumArgs() + additional); 119 } 120 121 static RequiredArgs forPrototype(const FunctionProtoType *prototype) { 122 return forPrototypePlus(prototype, 0); 123 } 124 125 static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { 126 return forPrototype(prototype.getTypePtr()); 127 } 128 129 static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, 130 unsigned additional) { 131 return forPrototypePlus(prototype.getTypePtr(), additional); 132 } 133 134 bool allowsOptionalArgs() const { return NumRequired != ~0U; } 135 unsigned getNumRequiredArgs() const { 136 assert(allowsOptionalArgs()); 137 return NumRequired; 138 } 139 140 unsigned getOpaqueData() const { return NumRequired; } 141 static RequiredArgs getFromOpaqueData(unsigned value) { 142 if (value == ~0U) return All; 143 return RequiredArgs(value); 144 } 145 }; 146 147 /// FunctionArgList - Type for representing both the decl and type 148 /// of parameters to a function. The decl must be either a 149 /// ParmVarDecl or ImplicitParamDecl. 150 class FunctionArgList : public SmallVector<const VarDecl*, 16> { 151 }; 152 153 /// CGFunctionInfo - Class to encapsulate the information about a 154 /// function definition. 155 class CGFunctionInfo : public llvm::FoldingSetNode { 156 struct ArgInfo { 157 CanQualType type; 158 ABIArgInfo info; 159 }; 160 161 /// The LLVM::CallingConv to use for this function (as specified by the 162 /// user). 163 unsigned CallingConvention : 8; 164 165 /// The LLVM::CallingConv to actually use for this function, which may 166 /// depend on the ABI. 167 unsigned EffectiveCallingConvention : 8; 168 169 /// The clang::CallingConv that this was originally created with. 170 unsigned ASTCallingConvention : 8; 171 172 /// Whether this function is noreturn. 173 unsigned NoReturn : 1; 174 175 /// Whether this function is returns-retained. 176 unsigned ReturnsRetained : 1; 177 178 /// How many arguments to pass inreg. 179 unsigned HasRegParm : 1; 180 unsigned RegParm : 4; 181 182 RequiredArgs Required; 183 184 unsigned NumArgs; 185 ArgInfo *getArgsBuffer() { 186 return reinterpret_cast<ArgInfo*>(this+1); 187 } 188 const ArgInfo *getArgsBuffer() const { 189 return reinterpret_cast<const ArgInfo*>(this + 1); 190 } 191 192 CGFunctionInfo() : Required(RequiredArgs::All) {} 193 194 public: 195 static CGFunctionInfo *create(unsigned llvmCC, 196 const FunctionType::ExtInfo &extInfo, 197 CanQualType resultType, 198 ArrayRef<CanQualType> argTypes, 199 RequiredArgs required); 200 201 typedef const ArgInfo *const_arg_iterator; 202 typedef ArgInfo *arg_iterator; 203 204 const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; } 205 const_arg_iterator arg_end() const { return getArgsBuffer() + 1 + NumArgs; } 206 arg_iterator arg_begin() { return getArgsBuffer() + 1; } 207 arg_iterator arg_end() { return getArgsBuffer() + 1 + NumArgs; } 208 209 unsigned arg_size() const { return NumArgs; } 210 211 bool isVariadic() const { return Required.allowsOptionalArgs(); } 212 RequiredArgs getRequiredArgs() const { return Required; } 213 214 bool isNoReturn() const { return NoReturn; } 215 216 /// In ARC, whether this function retains its return value. This 217 /// is not always reliable for call sites. 218 bool isReturnsRetained() const { return ReturnsRetained; } 219 220 /// getASTCallingConvention() - Return the AST-specified calling 221 /// convention. 222 CallingConv getASTCallingConvention() const { 223 return CallingConv(ASTCallingConvention); 224 } 225 226 /// getCallingConvention - Return the user specified calling 227 /// convention, which has been translated into an LLVM CC. 228 unsigned getCallingConvention() const { return CallingConvention; } 229 230 /// getEffectiveCallingConvention - Return the actual calling convention to 231 /// use, which may depend on the ABI. 232 unsigned getEffectiveCallingConvention() const { 233 return EffectiveCallingConvention; 234 } 235 void setEffectiveCallingConvention(unsigned Value) { 236 EffectiveCallingConvention = Value; 237 } 238 239 bool getHasRegParm() const { return HasRegParm; } 240 unsigned getRegParm() const { return RegParm; } 241 242 FunctionType::ExtInfo getExtInfo() const { 243 return FunctionType::ExtInfo(isNoReturn(), 244 getHasRegParm(), getRegParm(), 245 getASTCallingConvention(), 246 isReturnsRetained()); 247 } 248 249 CanQualType getReturnType() const { return getArgsBuffer()[0].type; } 250 251 ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } 252 const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } 253 254 void Profile(llvm::FoldingSetNodeID &ID) { 255 ID.AddInteger(getASTCallingConvention()); 256 ID.AddBoolean(NoReturn); 257 ID.AddBoolean(ReturnsRetained); 258 ID.AddBoolean(HasRegParm); 259 ID.AddInteger(RegParm); 260 ID.AddInteger(Required.getOpaqueData()); 261 getReturnType().Profile(ID); 262 for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it) 263 it->type.Profile(ID); 264 } 265 static void Profile(llvm::FoldingSetNodeID &ID, 266 const FunctionType::ExtInfo &info, 267 RequiredArgs required, 268 CanQualType resultType, 269 ArrayRef<CanQualType> argTypes) { 270 ID.AddInteger(info.getCC()); 271 ID.AddBoolean(info.getNoReturn()); 272 ID.AddBoolean(info.getProducesResult()); 273 ID.AddBoolean(info.getHasRegParm()); 274 ID.AddInteger(info.getRegParm()); 275 ID.AddInteger(required.getOpaqueData()); 276 resultType.Profile(ID); 277 for (ArrayRef<CanQualType>::iterator 278 i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { 279 i->Profile(ID); 280 } 281 } 282 }; 283 284 /// ReturnValueSlot - Contains the address where the return value of a 285 /// function can be stored, and whether the address is volatile or not. 286 class ReturnValueSlot { 287 llvm::PointerIntPair<llvm::Value *, 1, bool> Value; 288 289 public: 290 ReturnValueSlot() {} 291 ReturnValueSlot(llvm::Value *Value, bool IsVolatile) 292 : Value(Value, IsVolatile) {} 293 294 bool isNull() const { return !getValue(); } 295 296 bool isVolatile() const { return Value.getInt(); } 297 llvm::Value *getValue() const { return Value.getPointer(); } 298 }; 299 300} // end namespace CodeGen 301} // end namespace clang 302 303#endif 304