1 //===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
3 // 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
7 //===----------------------------------------------------------------------===//
9 // These classes wrap the information about a call or function
10 // definition used to handle ABI compliancy.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H
15 #define LLVM_CLANG_LIB_CODEGEN_CGCALL_H
18 #include "EHScopeStack.h"
19 #include "clang/AST/ASTFwd.h"
20 #include "clang/AST/CanonicalType.h"
21 #include "clang/AST/GlobalDecl.h"
22 #include "clang/AST/Type.h"
23 #include "llvm/IR/Value.h"
37 /// Abstract information about a function or function prototype.
39 /// The function prototype of the callee.
40 const FunctionProtoType
*CalleeProtoTy
;
41 /// The function declaration of the callee.
42 GlobalDecl CalleeDecl
;
45 explicit CGCalleeInfo() : CalleeProtoTy(nullptr) {}
46 CGCalleeInfo(const FunctionProtoType
*calleeProtoTy
, GlobalDecl calleeDecl
)
47 : CalleeProtoTy(calleeProtoTy
), CalleeDecl(calleeDecl
) {}
48 CGCalleeInfo(const FunctionProtoType
*calleeProtoTy
)
49 : CalleeProtoTy(calleeProtoTy
) {}
50 CGCalleeInfo(GlobalDecl calleeDecl
)
51 : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl
) {}
53 const FunctionProtoType
*getCalleeFunctionProtoType() const {
56 const GlobalDecl
getCalleeDecl() const { return CalleeDecl
; }
59 /// All available information about a concrete callee.
61 enum class SpecialKind
: uintptr_t {
70 struct BuiltinInfoStorage
{
71 const FunctionDecl
*Decl
;
74 struct PseudoDestructorInfoStorage
{
75 const CXXPseudoDestructorExpr
*Expr
;
77 struct VirtualInfoStorage
{
81 llvm::FunctionType
*FTy
;
84 SpecialKind KindOrFunctionPointer
;
86 CGCalleeInfo AbstractInfo
;
87 BuiltinInfoStorage BuiltinInfo
;
88 PseudoDestructorInfoStorage PseudoDestructorInfo
;
89 VirtualInfoStorage VirtualInfo
;
92 explicit CGCallee(SpecialKind kind
) : KindOrFunctionPointer(kind
) {}
94 CGCallee(const FunctionDecl
*builtinDecl
, unsigned builtinID
)
95 : KindOrFunctionPointer(SpecialKind::Builtin
) {
96 BuiltinInfo
.Decl
= builtinDecl
;
97 BuiltinInfo
.ID
= builtinID
;
101 CGCallee() : KindOrFunctionPointer(SpecialKind::Invalid
) {}
103 /// Construct a callee. Call this constructor directly when this
104 /// isn't a direct call.
105 CGCallee(const CGCalleeInfo
&abstractInfo
, llvm::Value
*functionPtr
)
106 : KindOrFunctionPointer(
107 SpecialKind(reinterpret_cast<uintptr_t>(functionPtr
))) {
108 AbstractInfo
= abstractInfo
;
109 assert(functionPtr
&& "configuring callee without function pointer");
110 assert(functionPtr
->getType()->isPointerTy());
111 assert(functionPtr
->getType()->isOpaquePointerTy() ||
112 functionPtr
->getType()->getNonOpaquePointerElementType()
116 static CGCallee
forBuiltin(unsigned builtinID
,
117 const FunctionDecl
*builtinDecl
) {
118 CGCallee
result(SpecialKind::Builtin
);
119 result
.BuiltinInfo
.Decl
= builtinDecl
;
120 result
.BuiltinInfo
.ID
= builtinID
;
124 static CGCallee
forPseudoDestructor(const CXXPseudoDestructorExpr
*E
) {
125 CGCallee
result(SpecialKind::PseudoDestructor
);
126 result
.PseudoDestructorInfo
.Expr
= E
;
130 static CGCallee
forDirect(llvm::Constant
*functionPtr
,
131 const CGCalleeInfo
&abstractInfo
= CGCalleeInfo()) {
132 return CGCallee(abstractInfo
, functionPtr
);
135 static CGCallee
forDirect(llvm::FunctionCallee functionPtr
,
136 const CGCalleeInfo
&abstractInfo
= CGCalleeInfo()) {
137 return CGCallee(abstractInfo
, functionPtr
.getCallee());
140 static CGCallee
forVirtual(const CallExpr
*CE
, GlobalDecl MD
, Address Addr
,
141 llvm::FunctionType
*FTy
) {
142 CGCallee
result(SpecialKind::Virtual
);
143 result
.VirtualInfo
.CE
= CE
;
144 result
.VirtualInfo
.MD
= MD
;
145 result
.VirtualInfo
.Addr
= Addr
;
146 result
.VirtualInfo
.FTy
= FTy
;
150 bool isBuiltin() const {
151 return KindOrFunctionPointer
== SpecialKind::Builtin
;
153 const FunctionDecl
*getBuiltinDecl() const {
155 return BuiltinInfo
.Decl
;
157 unsigned getBuiltinID() const {
159 return BuiltinInfo
.ID
;
162 bool isPseudoDestructor() const {
163 return KindOrFunctionPointer
== SpecialKind::PseudoDestructor
;
165 const CXXPseudoDestructorExpr
*getPseudoDestructorExpr() const {
166 assert(isPseudoDestructor());
167 return PseudoDestructorInfo
.Expr
;
170 bool isOrdinary() const {
171 return uintptr_t(KindOrFunctionPointer
) > uintptr_t(SpecialKind::Last
);
173 CGCalleeInfo
getAbstractInfo() const {
175 return VirtualInfo
.MD
;
176 assert(isOrdinary());
179 llvm::Value
*getFunctionPointer() const {
180 assert(isOrdinary());
181 return reinterpret_cast<llvm::Value
*>(uintptr_t(KindOrFunctionPointer
));
183 void setFunctionPointer(llvm::Value
*functionPtr
) {
184 assert(isOrdinary());
185 KindOrFunctionPointer
=
186 SpecialKind(reinterpret_cast<uintptr_t>(functionPtr
));
189 bool isVirtual() const {
190 return KindOrFunctionPointer
== SpecialKind::Virtual
;
192 const CallExpr
*getVirtualCallExpr() const {
194 return VirtualInfo
.CE
;
196 GlobalDecl
getVirtualMethodDecl() const {
198 return VirtualInfo
.MD
;
200 Address
getThisAddress() const {
202 return VirtualInfo
.Addr
;
204 llvm::FunctionType
*getVirtualFunctionType() const {
206 return VirtualInfo
.FTy
;
209 /// If this is a delayed callee computation of some sort, prepare
210 /// a concrete callee.
211 CGCallee
prepareConcreteCallee(CodeGenFunction
&CGF
) const;
218 LValue LV
; /// The argument is semantically a load from this l-value.
222 /// A data-flow flag to make sure getRValue and/or copyInto are not
223 /// called twice for duplicated IR emission.
228 CallArg(RValue rv
, QualType ty
)
229 : RV(rv
), HasLV(false), IsUsed(false), Ty(ty
) {}
230 CallArg(LValue lv
, QualType ty
)
231 : LV(lv
), HasLV(true), IsUsed(false), Ty(ty
) {}
232 bool hasLValue() const { return HasLV
; }
233 QualType
getType() const { return Ty
; }
235 /// \returns an independent RValue. If the CallArg contains an LValue,
236 /// a temporary copy is returned.
237 RValue
getRValue(CodeGenFunction
&CGF
) const;
239 LValue
getKnownLValue() const {
240 assert(HasLV
&& !IsUsed
);
243 RValue
getKnownRValue() const {
244 assert(!HasLV
&& !IsUsed
);
247 void setRValue(RValue _RV
) {
252 bool isAggregate() const { return HasLV
|| RV
.isAggregate(); }
254 void copyInto(CodeGenFunction
&CGF
, Address A
) const;
257 /// CallArgList - Type for representing both the value and type of
258 /// arguments in a call.
259 class CallArgList
: public SmallVector
<CallArg
, 8> {
261 CallArgList() : StackBase(nullptr) {}
264 /// The original argument. Note that the argument l-value
265 /// is potentially null.
268 /// The temporary alloca.
271 /// A value to "use" after the writeback, or null.
275 struct CallArgCleanup
{
276 EHScopeStack::stable_iterator Cleanup
;
278 /// The "is active" insertion point. This instruction is temporary and
279 /// will be removed after insertion.
280 llvm::Instruction
*IsActiveIP
;
283 void add(RValue rvalue
, QualType type
) { push_back(CallArg(rvalue
, type
)); }
285 void addUncopiedAggregate(LValue LV
, QualType type
) {
286 push_back(CallArg(LV
, type
));
289 /// Add all the arguments from another CallArgList to this one. After doing
290 /// this, the old CallArgList retains its list of arguments, but must not
291 /// be used to emit a call.
292 void addFrom(const CallArgList
&other
) {
293 insert(end(), other
.begin(), other
.end());
294 Writebacks
.insert(Writebacks
.end(), other
.Writebacks
.begin(),
295 other
.Writebacks
.end());
296 CleanupsToDeactivate
.insert(CleanupsToDeactivate
.end(),
297 other
.CleanupsToDeactivate
.begin(),
298 other
.CleanupsToDeactivate
.end());
299 assert(!(StackBase
&& other
.StackBase
) && "can't merge stackbases");
301 StackBase
= other
.StackBase
;
304 void addWriteback(LValue srcLV
, Address temporary
, llvm::Value
*toUse
) {
305 Writeback writeback
= {srcLV
, temporary
, toUse
};
306 Writebacks
.push_back(writeback
);
309 bool hasWritebacks() const { return !Writebacks
.empty(); }
311 typedef llvm::iterator_range
<SmallVectorImpl
<Writeback
>::const_iterator
>
312 writeback_const_range
;
314 writeback_const_range
writebacks() const {
315 return writeback_const_range(Writebacks
.begin(), Writebacks
.end());
318 void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup
,
319 llvm::Instruction
*IsActiveIP
) {
320 CallArgCleanup ArgCleanup
;
321 ArgCleanup
.Cleanup
= Cleanup
;
322 ArgCleanup
.IsActiveIP
= IsActiveIP
;
323 CleanupsToDeactivate
.push_back(ArgCleanup
);
326 ArrayRef
<CallArgCleanup
> getCleanupsToDeactivate() const {
327 return CleanupsToDeactivate
;
330 void allocateArgumentMemory(CodeGenFunction
&CGF
);
331 llvm::Instruction
*getStackBase() const { return StackBase
; }
332 void freeArgumentMemory(CodeGenFunction
&CGF
) const;
334 /// Returns if we're using an inalloca struct to pass arguments in
336 bool isUsingInAlloca() const { return StackBase
; }
339 SmallVector
<Writeback
, 1> Writebacks
;
341 /// Deactivate these cleanups immediately before making the call. This
342 /// is used to cleanup objects that are owned by the callee once the call
344 SmallVector
<CallArgCleanup
, 1> CleanupsToDeactivate
;
346 /// The stacksave call. It dominates all of the argument evaluation.
347 llvm::CallInst
*StackBase
;
350 /// FunctionArgList - Type for representing both the decl and type
351 /// of parameters to a function. The decl must be either a
352 /// ParmVarDecl or ImplicitParamDecl.
353 class FunctionArgList
: public SmallVector
<const VarDecl
*, 16> {};
355 /// ReturnValueSlot - Contains the address where the return value of a
356 /// function can be stored, and whether the address is volatile or not.
357 class ReturnValueSlot
{
358 Address Addr
= Address::invalid();
360 // Return value slot flags
361 unsigned IsVolatile
: 1;
362 unsigned IsUnused
: 1;
363 unsigned IsExternallyDestructed
: 1;
367 : IsVolatile(false), IsUnused(false), IsExternallyDestructed(false) {}
368 ReturnValueSlot(Address Addr
, bool IsVolatile
, bool IsUnused
= false,
369 bool IsExternallyDestructed
= false)
370 : Addr(Addr
), IsVolatile(IsVolatile
), IsUnused(IsUnused
),
371 IsExternallyDestructed(IsExternallyDestructed
) {}
373 bool isNull() const { return !Addr
.isValid(); }
374 bool isVolatile() const { return IsVolatile
; }
375 Address
getValue() const { return Addr
; }
376 bool isUnused() const { return IsUnused
; }
377 bool isExternallyDestructed() const { return IsExternallyDestructed
; }
380 } // end namespace CodeGen
381 } // end namespace clang