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 llvm::SmallVector<llvm::AttributeWithIndex, 8> AttributeListType; 46 47 struct CallArg { 48 RValue RV; 49 QualType Ty; 50 bool NeedsCopy; 51 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 llvm::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 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 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 91 bool hasWritebacks() const { return !Writebacks.empty(); } 92 93 typedef llvm::SmallVectorImpl<Writeback>::const_iterator writeback_iterator; 94 writeback_iterator writeback_begin() const { return Writebacks.begin(); } 95 writeback_iterator writeback_end() const { return Writebacks.end(); } 96 97 private: 98 llvm::SmallVector<Writeback, 1> Writebacks; 99 }; 100 101 /// FunctionArgList - Type for representing both the decl and type 102 /// of parameters to a function. The decl must be either a 103 /// ParmVarDecl or ImplicitParamDecl. 104 class FunctionArgList : public llvm::SmallVector<const VarDecl*, 16> { 105 }; 106 107 /// CGFunctionInfo - Class to encapsulate the information about a 108 /// function definition. 109 class CGFunctionInfo : public llvm::FoldingSetNode { 110 struct ArgInfo { 111 CanQualType type; 112 ABIArgInfo info; 113 }; 114 115 /// The LLVM::CallingConv to use for this function (as specified by the 116 /// user). 117 unsigned CallingConvention; 118 119 /// The LLVM::CallingConv to actually use for this function, which may 120 /// depend on the ABI. 121 unsigned EffectiveCallingConvention; 122 123 /// Whether this function is noreturn. 124 bool NoReturn; 125 126 /// Whether this function is returns-retained. 127 bool ReturnsRetained; 128 129 unsigned NumArgs; 130 ArgInfo *Args; 131 132 /// How many arguments to pass inreg. 133 bool HasRegParm; 134 unsigned RegParm; 135 136 public: 137 typedef const ArgInfo *const_arg_iterator; 138 typedef ArgInfo *arg_iterator; 139 140 CGFunctionInfo(unsigned CallingConvention, bool NoReturn, 141 bool ReturnsRetained, bool HasRegParm, unsigned RegParm, 142 CanQualType ResTy, 143 const CanQualType *ArgTys, unsigned NumArgTys); 144 ~CGFunctionInfo() { delete[] Args; } 145 146 const_arg_iterator arg_begin() const { return Args + 1; } 147 const_arg_iterator arg_end() const { return Args + 1 + NumArgs; } 148 arg_iterator arg_begin() { return Args + 1; } 149 arg_iterator arg_end() { return Args + 1 + NumArgs; } 150 151 unsigned arg_size() const { return NumArgs; } 152 153 bool isNoReturn() const { return NoReturn; } 154 155 /// In ARR, whether this function retains its return value. This 156 /// is not always reliable for call sites. 157 bool isReturnsRetained() const { return ReturnsRetained; } 158 159 /// getCallingConvention - Return the user specified calling 160 /// convention. 161 unsigned getCallingConvention() const { return CallingConvention; } 162 163 /// getEffectiveCallingConvention - Return the actual calling convention to 164 /// use, which may depend on the ABI. 165 unsigned getEffectiveCallingConvention() const { 166 return EffectiveCallingConvention; 167 } 168 void setEffectiveCallingConvention(unsigned Value) { 169 EffectiveCallingConvention = Value; 170 } 171 172 bool getHasRegParm() const { return HasRegParm; } 173 unsigned getRegParm() const { return RegParm; } 174 175 CanQualType getReturnType() const { return Args[0].type; } 176 177 ABIArgInfo &getReturnInfo() { return Args[0].info; } 178 const ABIArgInfo &getReturnInfo() const { return Args[0].info; } 179 180 void Profile(llvm::FoldingSetNodeID &ID) { 181 ID.AddInteger(getCallingConvention()); 182 ID.AddBoolean(NoReturn); 183 ID.AddBoolean(ReturnsRetained); 184 ID.AddBoolean(HasRegParm); 185 ID.AddInteger(RegParm); 186 getReturnType().Profile(ID); 187 for (arg_iterator it = arg_begin(), ie = arg_end(); it != ie; ++it) 188 it->type.Profile(ID); 189 } 190 template<class Iterator> 191 static void Profile(llvm::FoldingSetNodeID &ID, 192 const FunctionType::ExtInfo &Info, 193 CanQualType ResTy, 194 Iterator begin, 195 Iterator end) { 196 ID.AddInteger(Info.getCC()); 197 ID.AddBoolean(Info.getNoReturn()); 198 ID.AddBoolean(Info.getProducesResult()); 199 ID.AddBoolean(Info.getHasRegParm()); 200 ID.AddInteger(Info.getRegParm()); 201 ResTy.Profile(ID); 202 for (; begin != end; ++begin) { 203 CanQualType T = *begin; // force iterator to be over canonical types 204 T.Profile(ID); 205 } 206 } 207 }; 208 209 /// ReturnValueSlot - Contains the address where the return value of a 210 /// function can be stored, and whether the address is volatile or not. 211 class ReturnValueSlot { 212 llvm::PointerIntPair<llvm::Value *, 1, bool> Value; 213 214 public: 215 ReturnValueSlot() {} 216 ReturnValueSlot(llvm::Value *Value, bool IsVolatile) 217 : Value(Value, IsVolatile) {} 218 219 bool isNull() const { return !getValue(); } 220 221 bool isVolatile() const { return Value.getInt(); } 222 llvm::Value *getValue() const { return Value.getPointer(); } 223 }; 224 225 } // end namespace CodeGen 226 } // end namespace clang 227 228 #endif 229