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