blob: 509ca43a978489b6470f0905eeb416866944950a [file] [log] [blame]
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +00001//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +00006//
7//===----------------------------------------------------------------------===//
8//
9// These classes wrap the information about a call or function
10// definition used to handle ABI compliancy.
11//
12//===----------------------------------------------------------------------===//
13
Benjamin Kramer2f5db8b2014-08-13 16:25:19 +000014#ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H
15#define LLVM_CLANG_LIB_CODEGEN_CGCALL_H
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +000016
Chandler Carruth3a022472012-12-04 09:13:33 +000017#include "CGValue.h"
Reid Kleckner23f4c4b2013-06-21 12:45:15 +000018#include "EHScopeStack.h"
Reid Kleckner8a81daa2019-12-09 17:03:47 -080019#include "clang/AST/ASTFwd.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "clang/AST/CanonicalType.h"
Peter Collingbourneea211002018-02-05 23:09:13 +000021#include "clang/AST/GlobalDecl.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000022#include "clang/AST/Type.h"
Chandler Carruthffd55512013-01-02 11:45:17 +000023#include "llvm/IR/Value.h"
Daniel Dunbar41cf9de2008-09-09 01:06:48 +000024
Daniel Dunbar313321e2009-02-03 05:31:23 +000025// FIXME: Restructure so we don't have to expose so much stuff.
26#include "ABIInfo.h"
27
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +000028namespace llvm {
Reid Klecknerde864822017-03-21 16:57:30 +000029class AttributeList;
30class Function;
31class Type;
32class Value;
Akira Hatanakac1d29272019-10-30 17:51:45 -070033} // namespace llvm
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +000034
35namespace clang {
Akira Hatanakac1d29272019-10-30 17:51:45 -070036class ASTContext;
37class Decl;
38class FunctionDecl;
39class ObjCMethodDecl;
40class VarDecl;
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +000041
42namespace CodeGen {
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +000043
Reid Klecknerde864822017-03-21 16:57:30 +000044/// Abstract information about a function or function prototype.
45class CGCalleeInfo {
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000046 /// The function prototype of the callee.
Reid Klecknerde864822017-03-21 16:57:30 +000047 const FunctionProtoType *CalleeProtoTy;
Adrian Prantl9fc8faf2018-05-09 01:00:01 +000048 /// The function declaration of the callee.
Erich Keanede6480a32018-11-13 15:48:08 +000049 GlobalDecl CalleeDecl;
John McCallb92ab1a2016-10-26 23:46:34 +000050
Reid Klecknerde864822017-03-21 16:57:30 +000051public:
Erich Keanede6480a32018-11-13 15:48:08 +000052 explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl() {}
53 CGCalleeInfo(const FunctionProtoType *calleeProtoTy, GlobalDecl calleeDecl)
Reid Klecknerde864822017-03-21 16:57:30 +000054 : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
55 CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
Erich Keanede6480a32018-11-13 15:48:08 +000056 : CalleeProtoTy(calleeProtoTy), CalleeDecl() {}
57 CGCalleeInfo(GlobalDecl calleeDecl)
Reid Klecknerde864822017-03-21 16:57:30 +000058 : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}
John McCallb92ab1a2016-10-26 23:46:34 +000059
Reid Klecknerde864822017-03-21 16:57:30 +000060 const FunctionProtoType *getCalleeFunctionProtoType() const {
61 return CalleeProtoTy;
62 }
Erich Keanede6480a32018-11-13 15:48:08 +000063 const GlobalDecl getCalleeDecl() const { return CalleeDecl; }
Akira Hatanakac1d29272019-10-30 17:51:45 -070064};
65
66/// All available information about a concrete callee.
67class CGCallee {
68 enum class SpecialKind : uintptr_t {
69 Invalid,
70 Builtin,
71 PseudoDestructor,
72 Virtual,
73
74 Last = Virtual
John McCallb92ab1a2016-10-26 23:46:34 +000075 };
76
Akira Hatanakac1d29272019-10-30 17:51:45 -070077 struct BuiltinInfoStorage {
78 const FunctionDecl *Decl;
79 unsigned ID;
80 };
81 struct PseudoDestructorInfoStorage {
82 const CXXPseudoDestructorExpr *Expr;
83 };
84 struct VirtualInfoStorage {
85 const CallExpr *CE;
86 GlobalDecl MD;
87 Address Addr;
88 llvm::FunctionType *FTy;
89 };
John McCallb92ab1a2016-10-26 23:46:34 +000090
Akira Hatanakac1d29272019-10-30 17:51:45 -070091 SpecialKind KindOrFunctionPointer;
92 union {
93 CGCalleeInfo AbstractInfo;
94 BuiltinInfoStorage BuiltinInfo;
95 PseudoDestructorInfoStorage PseudoDestructorInfo;
96 VirtualInfoStorage VirtualInfo;
97 };
John McCallb92ab1a2016-10-26 23:46:34 +000098
Akira Hatanakac1d29272019-10-30 17:51:45 -070099 explicit CGCallee(SpecialKind kind) : KindOrFunctionPointer(kind) {}
John McCallaaae3022016-11-07 21:13:27 +0000100
Akira Hatanakac1d29272019-10-30 17:51:45 -0700101 CGCallee(const FunctionDecl *builtinDecl, unsigned builtinID)
102 : KindOrFunctionPointer(SpecialKind::Builtin) {
103 BuiltinInfo.Decl = builtinDecl;
104 BuiltinInfo.ID = builtinID;
105 }
John McCallb92ab1a2016-10-26 23:46:34 +0000106
Akira Hatanakac1d29272019-10-30 17:51:45 -0700107public:
108 CGCallee() : KindOrFunctionPointer(SpecialKind::Invalid) {}
John McCallb92ab1a2016-10-26 23:46:34 +0000109
Akira Hatanakac1d29272019-10-30 17:51:45 -0700110 /// 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 }
John McCallb92ab1a2016-10-26 23:46:34 +0000119
Akira Hatanakac1d29272019-10-30 17:51:45 -0700120 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 }
John McCallb92ab1a2016-10-26 23:46:34 +0000127
Akira Hatanakac1d29272019-10-30 17:51:45 -0700128 static CGCallee forPseudoDestructor(const CXXPseudoDestructorExpr *E) {
129 CGCallee result(SpecialKind::PseudoDestructor);
130 result.PseudoDestructorInfo.Expr = E;
131 return result;
132 }
John McCallb92ab1a2016-10-26 23:46:34 +0000133
Akira Hatanakac1d29272019-10-30 17:51:45 -0700134 static CGCallee forDirect(llvm::Constant *functionPtr,
135 const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
136 return CGCallee(abstractInfo, functionPtr);
137 }
John McCallb92ab1a2016-10-26 23:46:34 +0000138
Akira Hatanakac1d29272019-10-30 17:51:45 -0700139 static CGCallee forDirect(llvm::FunctionCallee functionPtr,
140 const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
141 return CGCallee(abstractInfo, functionPtr.getCallee());
142 }
John McCallb92ab1a2016-10-26 23:46:34 +0000143
Akira Hatanakac1d29272019-10-30 17:51:45 -0700144 static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr,
145 llvm::FunctionType *FTy) {
146 CGCallee result(SpecialKind::Virtual);
147 result.VirtualInfo.CE = CE;
148 result.VirtualInfo.MD = MD;
149 result.VirtualInfo.Addr = Addr;
150 result.VirtualInfo.FTy = FTy;
151 return result;
152 }
John McCallb92ab1a2016-10-26 23:46:34 +0000153
Akira Hatanakac1d29272019-10-30 17:51:45 -0700154 bool isBuiltin() const {
155 return KindOrFunctionPointer == SpecialKind::Builtin;
156 }
157 const FunctionDecl *getBuiltinDecl() const {
158 assert(isBuiltin());
159 return BuiltinInfo.Decl;
160 }
161 unsigned getBuiltinID() const {
162 assert(isBuiltin());
163 return BuiltinInfo.ID;
164 }
James Y Knight9871db02019-02-05 16:42:33 +0000165
Akira Hatanakac1d29272019-10-30 17:51:45 -0700166 bool isPseudoDestructor() const {
167 return KindOrFunctionPointer == SpecialKind::PseudoDestructor;
168 }
169 const CXXPseudoDestructorExpr *getPseudoDestructorExpr() const {
170 assert(isPseudoDestructor());
171 return PseudoDestructorInfo.Expr;
172 }
Peter Collingbourneea211002018-02-05 23:09:13 +0000173
Akira Hatanakac1d29272019-10-30 17:51:45 -0700174 bool isOrdinary() const {
175 return uintptr_t(KindOrFunctionPointer) > uintptr_t(SpecialKind::Last);
176 }
177 CGCalleeInfo getAbstractInfo() const {
178 if (isVirtual())
Peter Collingbourneea211002018-02-05 23:09:13 +0000179 return VirtualInfo.MD;
Akira Hatanakac1d29272019-10-30 17:51:45 -0700180 assert(isOrdinary());
181 return AbstractInfo;
182 }
183 llvm::Value *getFunctionPointer() const {
184 assert(isOrdinary());
185 return reinterpret_cast<llvm::Value *>(uintptr_t(KindOrFunctionPointer));
186 }
187 void setFunctionPointer(llvm::Value *functionPtr) {
188 assert(isOrdinary());
189 KindOrFunctionPointer = SpecialKind(uintptr_t(functionPtr));
190 }
John McCall9831b842018-02-06 18:52:44 +0000191
Akira Hatanakac1d29272019-10-30 17:51:45 -0700192 bool isVirtual() const {
193 return KindOrFunctionPointer == SpecialKind::Virtual;
194 }
195 const CallExpr *getVirtualCallExpr() const {
196 assert(isVirtual());
197 return VirtualInfo.CE;
198 }
199 GlobalDecl getVirtualMethodDecl() const {
200 assert(isVirtual());
201 return VirtualInfo.MD;
202 }
203 Address getThisAddress() const {
204 assert(isVirtual());
205 return VirtualInfo.Addr;
206 }
207 llvm::FunctionType *getVirtualFunctionType() const {
208 assert(isVirtual());
209 return VirtualInfo.FTy;
210 }
211
212 /// If this is a delayed callee computation of some sort, prepare
213 /// a concrete callee.
214 CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const;
215};
216
217struct CallArg {
218private:
219 union {
220 RValue RV;
221 LValue LV; /// The argument is semantically a load from this l-value.
222 };
223 bool HasLV;
224
225 /// A data-flow flag to make sure getRValue and/or copyInto are not
226 /// called twice for duplicated IR emission.
227 mutable bool IsUsed;
228
229public:
230 QualType Ty;
231 CallArg(RValue rv, QualType ty)
232 : RV(rv), HasLV(false), IsUsed(false), Ty(ty) {}
233 CallArg(LValue lv, QualType ty)
234 : LV(lv), HasLV(true), IsUsed(false), Ty(ty) {}
235 bool hasLValue() const { return HasLV; }
236 QualType getType() const { return Ty; }
237
238 /// \returns an independent RValue. If the CallArg contains an LValue,
239 /// a temporary copy is returned.
240 RValue getRValue(CodeGenFunction &CGF) const;
241
242 LValue getKnownLValue() const {
243 assert(HasLV && !IsUsed);
244 return LV;
245 }
246 RValue getKnownRValue() const {
247 assert(!HasLV && !IsUsed);
248 return RV;
249 }
250 void setRValue(RValue _RV) {
251 assert(!HasLV);
252 RV = _RV;
253 }
254
255 bool isAggregate() const { return HasLV || RV.isAggregate(); }
256
257 void copyInto(CodeGenFunction &CGF, Address A) const;
258};
259
260/// CallArgList - Type for representing both the value and type of
261/// arguments in a call.
262class CallArgList : public SmallVector<CallArg, 8> {
263public:
264 CallArgList() : StackBase(nullptr) {}
265
266 struct Writeback {
267 /// The original argument. Note that the argument l-value
268 /// is potentially null.
269 LValue Source;
270
271 /// The temporary alloca.
272 Address Temporary;
273
274 /// A value to "use" after the writeback, or null.
275 llvm::Value *ToUse;
John McCallb92ab1a2016-10-26 23:46:34 +0000276 };
277
Akira Hatanakac1d29272019-10-30 17:51:45 -0700278 struct CallArgCleanup {
279 EHScopeStack::stable_iterator Cleanup;
Yaxun Liu5b330e82018-03-15 15:25:19 +0000280
Akira Hatanakac1d29272019-10-30 17:51:45 -0700281 /// The "is active" insertion point. This instruction is temporary and
282 /// will be removed after insertion.
283 llvm::Instruction *IsActiveIP;
Eli Friedmanf4258eb2011-05-02 18:05:27 +0000284 };
285
Akira Hatanakac1d29272019-10-30 17:51:45 -0700286 void add(RValue rvalue, QualType type) { push_back(CallArg(rvalue, type)); }
Reid Kleckner314ef7b2014-02-01 00:04:45 +0000287
Akira Hatanakac1d29272019-10-30 17:51:45 -0700288 void addUncopiedAggregate(LValue LV, QualType type) {
289 push_back(CallArg(LV, type));
290 }
John McCall31168b02011-06-15 23:02:42 +0000291
Akira Hatanakac1d29272019-10-30 17:51:45 -0700292 /// Add all the arguments from another CallArgList to this one. After doing
293 /// this, the old CallArgList retains its list of arguments, but must not
294 /// be used to emit a call.
295 void addFrom(const CallArgList &other) {
296 insert(end(), other.begin(), other.end());
297 Writebacks.insert(Writebacks.end(), other.Writebacks.begin(),
298 other.Writebacks.end());
299 CleanupsToDeactivate.insert(CleanupsToDeactivate.end(),
300 other.CleanupsToDeactivate.begin(),
301 other.CleanupsToDeactivate.end());
302 assert(!(StackBase && other.StackBase) && "can't merge stackbases");
303 if (!StackBase)
304 StackBase = other.StackBase;
305 }
John McCalleff18842013-03-23 02:35:54 +0000306
Akira Hatanakac1d29272019-10-30 17:51:45 -0700307 void addWriteback(LValue srcLV, Address temporary, llvm::Value *toUse) {
308 Writeback writeback = {srcLV, temporary, toUse};
309 Writebacks.push_back(writeback);
310 }
John McCall31168b02011-06-15 23:02:42 +0000311
Akira Hatanakac1d29272019-10-30 17:51:45 -0700312 bool hasWritebacks() const { return !Writebacks.empty(); }
Reid Kleckner23f4c4b2013-06-21 12:45:15 +0000313
Akira Hatanakac1d29272019-10-30 17:51:45 -0700314 typedef llvm::iterator_range<SmallVectorImpl<Writeback>::const_iterator>
Aaron Ballman36a7fa82014-03-17 17:22:27 +0000315 writeback_const_range;
316
Akira Hatanakac1d29272019-10-30 17:51:45 -0700317 writeback_const_range writebacks() const {
318 return writeback_const_range(Writebacks.begin(), Writebacks.end());
319 }
John McCall31168b02011-06-15 23:02:42 +0000320
Akira Hatanakac1d29272019-10-30 17:51:45 -0700321 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 }
Reid Kleckner23f4c4b2013-06-21 12:45:15 +0000328
Akira Hatanakac1d29272019-10-30 17:51:45 -0700329 ArrayRef<CallArgCleanup> getCleanupsToDeactivate() const {
330 return CleanupsToDeactivate;
331 }
Reid Kleckner23f4c4b2013-06-21 12:45:15 +0000332
Akira Hatanakac1d29272019-10-30 17:51:45 -0700333 void allocateArgumentMemory(CodeGenFunction &CGF);
334 llvm::Instruction *getStackBase() const { return StackBase; }
335 void freeArgumentMemory(CodeGenFunction &CGF) const;
Reid Kleckner314ef7b2014-02-01 00:04:45 +0000336
Akira Hatanakac1d29272019-10-30 17:51:45 -0700337 /// Returns if we're using an inalloca struct to pass arguments in
338 /// memory.
339 bool isUsingInAlloca() const { return StackBase; }
Reid Kleckner314ef7b2014-02-01 00:04:45 +0000340
Akira Hatanakac1d29272019-10-30 17:51:45 -0700341private:
342 SmallVector<Writeback, 1> Writebacks;
Reid Kleckner23f4c4b2013-06-21 12:45:15 +0000343
Akira Hatanakac1d29272019-10-30 17:51:45 -0700344 /// 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 Kleckner314ef7b2014-02-01 00:04:45 +0000348
Akira Hatanakac1d29272019-10-30 17:51:45 -0700349 /// The stacksave call. It dominates all of the argument evaluation.
350 llvm::CallInst *StackBase;
351};
352
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.
356class FunctionArgList : public SmallVector<const VarDecl *, 16> {};
357
358/// ReturnValueSlot - Contains the address where the return value of a
359/// function can be stored, and whether the address is volatile or not.
360class ReturnValueSlot {
Akira Hatanakad35a4542019-11-20 18:13:44 -0800361 Address Addr = Address::invalid();
Akira Hatanakac1d29272019-10-30 17:51:45 -0700362
363 // Return value slot flags
Akira Hatanakad35a4542019-11-20 18:13:44 -0800364 unsigned IsVolatile : 1;
365 unsigned IsUnused : 1;
366 unsigned IsExternallyDestructed : 1;
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +0000367
Akira Hatanakac1d29272019-10-30 17:51:45 -0700368public:
Akira Hatanakad35a4542019-11-20 18:13:44 -0800369 ReturnValueSlot()
370 : IsVolatile(false), IsUnused(false), IsExternallyDestructed(false) {}
371 ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused = false,
372 bool IsExternallyDestructed = false)
373 : Addr(Addr), IsVolatile(IsVolatile), IsUnused(IsUnused),
374 IsExternallyDestructed(IsExternallyDestructed) {}
Anders Carlsson0435ed52009-12-24 19:08:58 +0000375
Akira Hatanakad35a4542019-11-20 18:13:44 -0800376 bool isNull() const { return !Addr.isValid(); }
377 bool isVolatile() const { return IsVolatile; }
378 Address getValue() const { return Addr; }
379 bool isUnused() const { return IsUnused; }
380 bool isExternallyDestructed() const { return IsExternallyDestructed; }
Akira Hatanakac1d29272019-10-30 17:51:45 -0700381};
Fangrui Song6907ce22018-07-30 19:24:48 +0000382
Akira Hatanakac1d29272019-10-30 17:51:45 -0700383} // end namespace CodeGen
384} // end namespace clang
Daniel Dunbar3d7c90b2008-09-08 21:33:45 +0000385
386#endif