| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 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 |  | 
| Benjamin Kramer | 2f5db8b | 2014-08-13 16:25:19 +0000 | [diff] [blame] | 15 | #ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H | 
|  | 16 | #define LLVM_CLANG_LIB_CODEGEN_CGCALL_H | 
| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 17 |  | 
| Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 18 | #include "CGValue.h" | 
| Reid Kleckner | 23f4c4b | 2013-06-21 12:45:15 +0000 | [diff] [blame] | 19 | #include "EHScopeStack.h" | 
| Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 20 | #include "clang/AST/CanonicalType.h" | 
| Peter Collingbourne | ea21100 | 2018-02-05 23:09:13 +0000 | [diff] [blame] | 21 | #include "clang/AST/GlobalDecl.h" | 
| Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 22 | #include "clang/AST/Type.h" | 
| Chandler Carruth | ffd5551 | 2013-01-02 11:45:17 +0000 | [diff] [blame] | 23 | #include "llvm/IR/Value.h" | 
| Daniel Dunbar | 41cf9de | 2008-09-09 01:06:48 +0000 | [diff] [blame] | 24 |  | 
| Daniel Dunbar | 313321e | 2009-02-03 05:31:23 +0000 | [diff] [blame] | 25 | // FIXME: Restructure so we don't have to expose so much stuff. | 
|  | 26 | #include "ABIInfo.h" | 
|  | 27 |  | 
| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 28 | namespace llvm { | 
| Reid Kleckner | de86482 | 2017-03-21 16:57:30 +0000 | [diff] [blame] | 29 | class AttributeList; | 
|  | 30 | class Function; | 
|  | 31 | class Type; | 
|  | 32 | class Value; | 
| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 33 | } | 
|  | 34 |  | 
|  | 35 | namespace clang { | 
|  | 36 | class ASTContext; | 
|  | 37 | class Decl; | 
|  | 38 | class FunctionDecl; | 
|  | 39 | class ObjCMethodDecl; | 
| Daniel Dunbar | bc915f4 | 2008-09-09 23:14:03 +0000 | [diff] [blame] | 40 | class VarDecl; | 
| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 41 |  | 
|  | 42 | namespace CodeGen { | 
| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 43 |  | 
| Reid Kleckner | de86482 | 2017-03-21 16:57:30 +0000 | [diff] [blame] | 44 | /// Abstract information about a function or function prototype. | 
|  | 45 | class CGCalleeInfo { | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 46 | /// The function prototype of the callee. | 
| Reid Kleckner | de86482 | 2017-03-21 16:57:30 +0000 | [diff] [blame] | 47 | const FunctionProtoType *CalleeProtoTy; | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 48 | /// The function declaration of the callee. | 
| Reid Kleckner | de86482 | 2017-03-21 16:57:30 +0000 | [diff] [blame] | 49 | const Decl *CalleeDecl; | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 50 |  | 
| Reid Kleckner | de86482 | 2017-03-21 16:57:30 +0000 | [diff] [blame] | 51 | public: | 
|  | 52 | explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl(nullptr) {} | 
|  | 53 | CGCalleeInfo(const FunctionProtoType *calleeProtoTy, const Decl *calleeDecl) | 
|  | 54 | : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {} | 
|  | 55 | CGCalleeInfo(const FunctionProtoType *calleeProtoTy) | 
|  | 56 | : CalleeProtoTy(calleeProtoTy), CalleeDecl(nullptr) {} | 
|  | 57 | CGCalleeInfo(const Decl *calleeDecl) | 
|  | 58 | : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {} | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 59 |  | 
| Reid Kleckner | de86482 | 2017-03-21 16:57:30 +0000 | [diff] [blame] | 60 | const FunctionProtoType *getCalleeFunctionProtoType() const { | 
|  | 61 | return CalleeProtoTy; | 
|  | 62 | } | 
|  | 63 | const Decl *getCalleeDecl() const { return CalleeDecl; } | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 64 | }; | 
|  | 65 |  | 
|  | 66 | /// All available information about a concrete callee. | 
|  | 67 | class CGCallee { | 
|  | 68 | enum class SpecialKind : uintptr_t { | 
|  | 69 | Invalid, | 
|  | 70 | Builtin, | 
|  | 71 | PseudoDestructor, | 
| Peter Collingbourne | ea21100 | 2018-02-05 23:09:13 +0000 | [diff] [blame] | 72 | Virtual, | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 73 |  | 
| Peter Collingbourne | ea21100 | 2018-02-05 23:09:13 +0000 | [diff] [blame] | 74 | Last = Virtual | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 75 | }; | 
|  | 76 |  | 
| John McCall | aaae302 | 2016-11-07 21:13:27 +0000 | [diff] [blame] | 77 | struct BuiltinInfoStorage { | 
|  | 78 | const FunctionDecl *Decl; | 
|  | 79 | unsigned ID; | 
|  | 80 | }; | 
|  | 81 | struct PseudoDestructorInfoStorage { | 
|  | 82 | const CXXPseudoDestructorExpr *Expr; | 
|  | 83 | }; | 
| Peter Collingbourne | ea21100 | 2018-02-05 23:09:13 +0000 | [diff] [blame] | 84 | struct VirtualInfoStorage { | 
|  | 85 | const CallExpr *CE; | 
|  | 86 | GlobalDecl MD; | 
|  | 87 | Address Addr; | 
|  | 88 | llvm::FunctionType *FTy; | 
|  | 89 | }; | 
| John McCall | aaae302 | 2016-11-07 21:13:27 +0000 | [diff] [blame] | 90 |  | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 91 | SpecialKind KindOrFunctionPointer; | 
|  | 92 | union { | 
|  | 93 | CGCalleeInfo AbstractInfo; | 
| John McCall | aaae302 | 2016-11-07 21:13:27 +0000 | [diff] [blame] | 94 | BuiltinInfoStorage BuiltinInfo; | 
|  | 95 | PseudoDestructorInfoStorage PseudoDestructorInfo; | 
| Peter Collingbourne | ea21100 | 2018-02-05 23:09:13 +0000 | [diff] [blame] | 96 | VirtualInfoStorage VirtualInfo; | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 97 | }; | 
|  | 98 |  | 
|  | 99 | explicit CGCallee(SpecialKind kind) : KindOrFunctionPointer(kind) {} | 
|  | 100 |  | 
|  | 101 | CGCallee(const FunctionDecl *builtinDecl, unsigned builtinID) | 
|  | 102 | : KindOrFunctionPointer(SpecialKind::Builtin) { | 
|  | 103 | BuiltinInfo.Decl = builtinDecl; | 
|  | 104 | BuiltinInfo.ID = builtinID; | 
|  | 105 | } | 
|  | 106 |  | 
|  | 107 | public: | 
|  | 108 | CGCallee() : KindOrFunctionPointer(SpecialKind::Invalid) {} | 
|  | 109 |  | 
|  | 110 | /// Construct a callee.  Call this constructor directly when this | 
|  | 111 | /// isn't a direct call. | 
|  | 112 | CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr) | 
|  | 113 | : KindOrFunctionPointer(SpecialKind(uintptr_t(functionPtr))) { | 
|  | 114 | AbstractInfo = abstractInfo; | 
|  | 115 | assert(functionPtr && "configuring callee without function pointer"); | 
|  | 116 | assert(functionPtr->getType()->isPointerTy()); | 
|  | 117 | assert(functionPtr->getType()->getPointerElementType()->isFunctionTy()); | 
|  | 118 | } | 
|  | 119 |  | 
|  | 120 | static CGCallee forBuiltin(unsigned builtinID, | 
|  | 121 | const FunctionDecl *builtinDecl) { | 
|  | 122 | CGCallee result(SpecialKind::Builtin); | 
|  | 123 | result.BuiltinInfo.Decl = builtinDecl; | 
|  | 124 | result.BuiltinInfo.ID = builtinID; | 
|  | 125 | return result; | 
|  | 126 | } | 
|  | 127 |  | 
|  | 128 | static CGCallee forPseudoDestructor(const CXXPseudoDestructorExpr *E) { | 
|  | 129 | CGCallee result(SpecialKind::PseudoDestructor); | 
|  | 130 | result.PseudoDestructorInfo.Expr = E; | 
|  | 131 | return result; | 
|  | 132 | } | 
|  | 133 |  | 
|  | 134 | static CGCallee forDirect(llvm::Constant *functionPtr, | 
|  | 135 | const CGCalleeInfo &abstractInfo = CGCalleeInfo()) { | 
|  | 136 | return CGCallee(abstractInfo, functionPtr); | 
|  | 137 | } | 
|  | 138 |  | 
| Peter Collingbourne | ea21100 | 2018-02-05 23:09:13 +0000 | [diff] [blame] | 139 | static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, | 
|  | 140 | llvm::FunctionType *FTy) { | 
|  | 141 | CGCallee result(SpecialKind::Virtual); | 
|  | 142 | result.VirtualInfo.CE = CE; | 
|  | 143 | result.VirtualInfo.MD = MD; | 
|  | 144 | result.VirtualInfo.Addr = Addr; | 
|  | 145 | result.VirtualInfo.FTy = FTy; | 
|  | 146 | return result; | 
|  | 147 | } | 
|  | 148 |  | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 149 | bool isBuiltin() const { | 
|  | 150 | return KindOrFunctionPointer == SpecialKind::Builtin; | 
|  | 151 | } | 
|  | 152 | const FunctionDecl *getBuiltinDecl() const { | 
|  | 153 | assert(isBuiltin()); | 
|  | 154 | return BuiltinInfo.Decl; | 
|  | 155 | } | 
|  | 156 | unsigned getBuiltinID() const { | 
|  | 157 | assert(isBuiltin()); | 
|  | 158 | return BuiltinInfo.ID; | 
|  | 159 | } | 
|  | 160 |  | 
|  | 161 | bool isPseudoDestructor() const { | 
|  | 162 | return KindOrFunctionPointer == SpecialKind::PseudoDestructor; | 
|  | 163 | } | 
|  | 164 | const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const { | 
|  | 165 | assert(isPseudoDestructor()); | 
|  | 166 | return PseudoDestructorInfo.Expr; | 
|  | 167 | } | 
|  | 168 |  | 
|  | 169 | bool isOrdinary() const { | 
|  | 170 | return uintptr_t(KindOrFunctionPointer) > uintptr_t(SpecialKind::Last); | 
|  | 171 | } | 
| Peter Collingbourne | ea21100 | 2018-02-05 23:09:13 +0000 | [diff] [blame] | 172 | CGCalleeInfo getAbstractInfo() const { | 
|  | 173 | if (isVirtual()) | 
|  | 174 | return VirtualInfo.MD.getDecl(); | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 175 | assert(isOrdinary()); | 
|  | 176 | return AbstractInfo; | 
|  | 177 | } | 
|  | 178 | llvm::Value *getFunctionPointer() const { | 
|  | 179 | assert(isOrdinary()); | 
|  | 180 | return reinterpret_cast<llvm::Value*>(uintptr_t(KindOrFunctionPointer)); | 
|  | 181 | } | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 182 | void setFunctionPointer(llvm::Value *functionPtr) { | 
|  | 183 | assert(isOrdinary()); | 
|  | 184 | KindOrFunctionPointer = SpecialKind(uintptr_t(functionPtr)); | 
|  | 185 | } | 
| Peter Collingbourne | ea21100 | 2018-02-05 23:09:13 +0000 | [diff] [blame] | 186 |  | 
|  | 187 | bool isVirtual() const { | 
|  | 188 | return KindOrFunctionPointer == SpecialKind::Virtual; | 
|  | 189 | } | 
|  | 190 | const CallExpr *getVirtualCallExpr() const { | 
|  | 191 | assert(isVirtual()); | 
|  | 192 | return VirtualInfo.CE; | 
|  | 193 | } | 
|  | 194 | GlobalDecl getVirtualMethodDecl() const { | 
|  | 195 | assert(isVirtual()); | 
|  | 196 | return VirtualInfo.MD; | 
|  | 197 | } | 
|  | 198 | Address getThisAddress() const { | 
|  | 199 | assert(isVirtual()); | 
|  | 200 | return VirtualInfo.Addr; | 
|  | 201 | } | 
|  | 202 |  | 
|  | 203 | llvm::FunctionType *getFunctionType() const { | 
|  | 204 | if (isVirtual()) | 
|  | 205 | return VirtualInfo.FTy; | 
|  | 206 | return cast<llvm::FunctionType>( | 
|  | 207 | getFunctionPointer()->getType()->getPointerElementType()); | 
|  | 208 | } | 
| John McCall | 9831b84 | 2018-02-06 18:52:44 +0000 | [diff] [blame] | 209 |  | 
|  | 210 | /// If this is a delayed callee computation of some sort, prepare | 
|  | 211 | /// a concrete callee. | 
|  | 212 | CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const; | 
| John McCall | b92ab1a | 2016-10-26 23:46:34 +0000 | [diff] [blame] | 213 | }; | 
|  | 214 |  | 
| Eli Friedman | f4258eb | 2011-05-02 18:05:27 +0000 | [diff] [blame] | 215 | struct CallArg { | 
| Yaxun Liu | 5b330e8 | 2018-03-15 15:25:19 +0000 | [diff] [blame] | 216 | private: | 
|  | 217 | union { | 
|  | 218 | RValue RV; | 
|  | 219 | LValue LV; /// The argument is semantically a load from this l-value. | 
|  | 220 | }; | 
|  | 221 | bool HasLV; | 
|  | 222 |  | 
|  | 223 | /// A data-flow flag to make sure getRValue and/or copyInto are not | 
|  | 224 | /// called twice for duplicated IR emission. | 
|  | 225 | mutable bool IsUsed; | 
|  | 226 |  | 
|  | 227 | public: | 
| Eli Friedman | f4258eb | 2011-05-02 18:05:27 +0000 | [diff] [blame] | 228 | QualType Ty; | 
| Yaxun Liu | 5b330e8 | 2018-03-15 15:25:19 +0000 | [diff] [blame] | 229 | CallArg(RValue rv, QualType ty) | 
|  | 230 | : RV(rv), HasLV(false), IsUsed(false), Ty(ty) {} | 
|  | 231 | CallArg(LValue lv, QualType ty) | 
|  | 232 | : LV(lv), HasLV(true), IsUsed(false), Ty(ty) {} | 
|  | 233 | bool hasLValue() const { return HasLV; } | 
|  | 234 | QualType getType() const { return Ty; } | 
|  | 235 |  | 
|  | 236 | /// \returns an independent RValue. If the CallArg contains an LValue, | 
|  | 237 | /// a temporary copy is returned. | 
|  | 238 | RValue getRValue(CodeGenFunction &CGF) const; | 
|  | 239 |  | 
|  | 240 | LValue getKnownLValue() const { | 
|  | 241 | assert(HasLV && !IsUsed); | 
|  | 242 | return LV; | 
|  | 243 | } | 
|  | 244 | RValue getKnownRValue() const { | 
|  | 245 | assert(!HasLV && !IsUsed); | 
|  | 246 | return RV; | 
|  | 247 | } | 
|  | 248 | void setRValue(RValue _RV) { | 
|  | 249 | assert(!HasLV); | 
|  | 250 | RV = _RV; | 
|  | 251 | } | 
|  | 252 |  | 
|  | 253 | bool isAggregate() const { return HasLV || RV.isAggregate(); } | 
|  | 254 |  | 
|  | 255 | void copyInto(CodeGenFunction &CGF, Address A) const; | 
| Eli Friedman | f4258eb | 2011-05-02 18:05:27 +0000 | [diff] [blame] | 256 | }; | 
|  | 257 |  | 
| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 258 | /// CallArgList - Type for representing both the value and type of | 
|  | 259 | /// arguments in a call. | 
| John McCall | a738c25 | 2011-03-09 04:27:21 +0000 | [diff] [blame] | 260 | class CallArgList : | 
| Yaxun Liu | d938982 | 2018-03-14 15:02:28 +0000 | [diff] [blame] | 261 | public SmallVector<CallArg, 8> { | 
| John McCall | 32ea969 | 2011-03-11 20:59:21 +0000 | [diff] [blame] | 262 | public: | 
| Reid Kleckner | 7c2f9e8 | 2015-10-08 00:17:45 +0000 | [diff] [blame] | 263 | CallArgList() : StackBase(nullptr) {} | 
| Reid Kleckner | 314ef7b | 2014-02-01 00:04:45 +0000 | [diff] [blame] | 264 |  | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 265 | struct Writeback { | 
| John McCall | eff1884 | 2013-03-23 02:35:54 +0000 | [diff] [blame] | 266 | /// The original argument.  Note that the argument l-value | 
|  | 267 | /// is potentially null. | 
|  | 268 | LValue Source; | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 269 |  | 
|  | 270 | /// The temporary alloca. | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 271 | Address Temporary; | 
| John McCall | eff1884 | 2013-03-23 02:35:54 +0000 | [diff] [blame] | 272 |  | 
|  | 273 | /// A value to "use" after the writeback, or null. | 
|  | 274 | llvm::Value *ToUse; | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 275 | }; | 
|  | 276 |  | 
| Reid Kleckner | 23f4c4b | 2013-06-21 12:45:15 +0000 | [diff] [blame] | 277 | struct CallArgCleanup { | 
|  | 278 | EHScopeStack::stable_iterator Cleanup; | 
|  | 279 |  | 
|  | 280 | /// The "is active" insertion point.  This instruction is temporary and | 
|  | 281 | /// will be removed after insertion. | 
|  | 282 | llvm::Instruction *IsActiveIP; | 
|  | 283 | }; | 
|  | 284 |  | 
| Yaxun Liu | 5b330e8 | 2018-03-15 15:25:19 +0000 | [diff] [blame] | 285 | void add(RValue rvalue, QualType type) { push_back(CallArg(rvalue, type)); } | 
|  | 286 |  | 
|  | 287 | void addUncopiedAggregate(LValue LV, QualType type) { | 
|  | 288 | push_back(CallArg(LV, type)); | 
| John McCall | 32ea969 | 2011-03-11 20:59:21 +0000 | [diff] [blame] | 289 | } | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 290 |  | 
| Richard Smith | 762672a | 2016-09-28 19:09:10 +0000 | [diff] [blame] | 291 | /// Add all the arguments from another CallArgList to this one. After doing | 
|  | 292 | /// this, the old CallArgList retains its list of arguments, but must not | 
|  | 293 | /// be used to emit a call. | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 294 | void addFrom(const CallArgList &other) { | 
|  | 295 | insert(end(), other.begin(), other.end()); | 
|  | 296 | Writebacks.insert(Writebacks.end(), | 
|  | 297 | other.Writebacks.begin(), other.Writebacks.end()); | 
| Richard Smith | 762672a | 2016-09-28 19:09:10 +0000 | [diff] [blame] | 298 | CleanupsToDeactivate.insert(CleanupsToDeactivate.end(), | 
|  | 299 | other.CleanupsToDeactivate.begin(), | 
|  | 300 | other.CleanupsToDeactivate.end()); | 
|  | 301 | assert(!(StackBase && other.StackBase) && "can't merge stackbases"); | 
|  | 302 | if (!StackBase) | 
|  | 303 | StackBase = other.StackBase; | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 304 | } | 
|  | 305 |  | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 306 | void addWriteback(LValue srcLV, Address temporary, | 
| John McCall | eff1884 | 2013-03-23 02:35:54 +0000 | [diff] [blame] | 307 | llvm::Value *toUse) { | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 308 | Writeback writeback = { srcLV, temporary, toUse }; | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 309 | Writebacks.push_back(writeback); | 
|  | 310 | } | 
|  | 311 |  | 
|  | 312 | bool hasWritebacks() const { return !Writebacks.empty(); } | 
|  | 313 |  | 
| Aaron Ballman | 36a7fa8 | 2014-03-17 17:22:27 +0000 | [diff] [blame] | 314 | typedef llvm::iterator_range<SmallVectorImpl<Writeback>::const_iterator> | 
|  | 315 | writeback_const_range; | 
|  | 316 |  | 
|  | 317 | writeback_const_range writebacks() const { | 
|  | 318 | return writeback_const_range(Writebacks.begin(), Writebacks.end()); | 
|  | 319 | } | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 320 |  | 
| Reid Kleckner | 23f4c4b | 2013-06-21 12:45:15 +0000 | [diff] [blame] | 321 | void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup, | 
|  | 322 | llvm::Instruction *IsActiveIP) { | 
|  | 323 | CallArgCleanup ArgCleanup; | 
|  | 324 | ArgCleanup.Cleanup = Cleanup; | 
|  | 325 | ArgCleanup.IsActiveIP = IsActiveIP; | 
|  | 326 | CleanupsToDeactivate.push_back(ArgCleanup); | 
|  | 327 | } | 
|  | 328 |  | 
|  | 329 | ArrayRef<CallArgCleanup> getCleanupsToDeactivate() const { | 
|  | 330 | return CleanupsToDeactivate; | 
|  | 331 | } | 
|  | 332 |  | 
| Reid Kleckner | 314ef7b | 2014-02-01 00:04:45 +0000 | [diff] [blame] | 333 | void allocateArgumentMemory(CodeGenFunction &CGF); | 
|  | 334 | llvm::Instruction *getStackBase() const { return StackBase; } | 
| Nico Weber | 8cdb3f9 | 2015-08-25 18:43:32 +0000 | [diff] [blame] | 335 | void freeArgumentMemory(CodeGenFunction &CGF) const; | 
| Reid Kleckner | 314ef7b | 2014-02-01 00:04:45 +0000 | [diff] [blame] | 336 |  | 
| Adrian Prantl | 9fc8faf | 2018-05-09 01:00:01 +0000 | [diff] [blame] | 337 | /// Returns if we're using an inalloca struct to pass arguments in | 
| Reid Kleckner | 314ef7b | 2014-02-01 00:04:45 +0000 | [diff] [blame] | 338 | /// memory. | 
|  | 339 | bool isUsingInAlloca() const { return StackBase; } | 
|  | 340 |  | 
| John McCall | 31168b0 | 2011-06-15 23:02:42 +0000 | [diff] [blame] | 341 | private: | 
| Chris Lattner | 01cf8db | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 342 | SmallVector<Writeback, 1> Writebacks; | 
| Reid Kleckner | 23f4c4b | 2013-06-21 12:45:15 +0000 | [diff] [blame] | 343 |  | 
|  | 344 | /// Deactivate these cleanups immediately before making the call.  This | 
|  | 345 | /// is used to cleanup objects that are owned by the callee once the call | 
|  | 346 | /// occurs. | 
|  | 347 | SmallVector<CallArgCleanup, 1> CleanupsToDeactivate; | 
| Reid Kleckner | 314ef7b | 2014-02-01 00:04:45 +0000 | [diff] [blame] | 348 |  | 
|  | 349 | /// The stacksave call.  It dominates all of the argument evaluation. | 
|  | 350 | llvm::CallInst *StackBase; | 
| John McCall | a738c25 | 2011-03-09 04:27:21 +0000 | [diff] [blame] | 351 | }; | 
| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 352 |  | 
| Daniel Dunbar | bc915f4 | 2008-09-09 23:14:03 +0000 | [diff] [blame] | 353 | /// FunctionArgList - Type for representing both the decl and type | 
|  | 354 | /// of parameters to a function. The decl must be either a | 
|  | 355 | /// ParmVarDecl or ImplicitParamDecl. | 
| Chris Lattner | 01cf8db | 2011-07-20 06:58:45 +0000 | [diff] [blame] | 356 | class FunctionArgList : public SmallVector<const VarDecl*, 16> { | 
| John McCall | a738c25 | 2011-03-09 04:27:21 +0000 | [diff] [blame] | 357 | }; | 
| Mike Stump | 11289f4 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 358 |  | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 359 | /// ReturnValueSlot - Contains the address where the return value of a | 
| Anders Carlsson | 1749083 | 2009-12-24 20:40:36 +0000 | [diff] [blame] | 360 | /// function can be stored, and whether the address is volatile or not. | 
| Anders Carlsson | 0435ed5 | 2009-12-24 19:08:58 +0000 | [diff] [blame] | 361 | class ReturnValueSlot { | 
| Leny Kholodov | 6aab111 | 2015-06-08 10:23:49 +0000 | [diff] [blame] | 362 | llvm::PointerIntPair<llvm::Value *, 2, unsigned int> Value; | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 363 | CharUnits Alignment; | 
| Leny Kholodov | 6aab111 | 2015-06-08 10:23:49 +0000 | [diff] [blame] | 364 |  | 
|  | 365 | // Return value slot flags | 
|  | 366 | enum Flags { | 
|  | 367 | IS_VOLATILE = 0x1, | 
|  | 368 | IS_UNUSED = 0x2, | 
|  | 369 | }; | 
| Anders Carlsson | 0435ed5 | 2009-12-24 19:08:58 +0000 | [diff] [blame] | 370 |  | 
|  | 371 | public: | 
|  | 372 | ReturnValueSlot() {} | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 373 | ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused = false) | 
|  | 374 | : Value(Addr.isValid() ? Addr.getPointer() : nullptr, | 
|  | 375 | (IsVolatile ? IS_VOLATILE : 0) | (IsUnused ? IS_UNUSED : 0)), | 
|  | 376 | Alignment(Addr.isValid() ? Addr.getAlignment() : CharUnits::Zero()) {} | 
| Anders Carlsson | 0435ed5 | 2009-12-24 19:08:58 +0000 | [diff] [blame] | 377 |  | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 378 | bool isNull() const { return !getValue().isValid(); } | 
| Leny Kholodov | 6aab111 | 2015-06-08 10:23:49 +0000 | [diff] [blame] | 379 |  | 
|  | 380 | bool isVolatile() const { return Value.getInt() & IS_VOLATILE; } | 
| John McCall | 7f416cc | 2015-09-08 08:05:57 +0000 | [diff] [blame] | 381 | Address getValue() const { return Address(Value.getPointer(), Alignment); } | 
| Leny Kholodov | 6aab111 | 2015-06-08 10:23:49 +0000 | [diff] [blame] | 382 | bool isUnused() const { return Value.getInt() & IS_UNUSED; } | 
| Anders Carlsson | 0435ed5 | 2009-12-24 19:08:58 +0000 | [diff] [blame] | 383 | }; | 
| Fangrui Song | 6907ce2 | 2018-07-30 19:24:48 +0000 | [diff] [blame] | 384 |  | 
| Daniel Dunbar | 3d7c90b | 2008-09-08 21:33:45 +0000 | [diff] [blame] | 385 | }  // end namespace CodeGen | 
|  | 386 | }  // end namespace clang | 
|  | 387 |  | 
|  | 388 | #endif |