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