clang 20.0.0git
CGCall.h
Go to the documentation of this file.
1//===----- CGCall.h - Encapsulate calling convention details ----*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// These classes wrap the information about a call or function
10// definition used to handle ABI compliancy.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_LIB_CODEGEN_CGCALL_H
15#define LLVM_CLANG_LIB_CODEGEN_CGCALL_H
16
17#include "CGPointerAuthInfo.h"
18#include "CGValue.h"
19#include "EHScopeStack.h"
20#include "clang/AST/ASTFwd.h"
23#include "clang/AST/Type.h"
24#include "llvm/ADT/STLForwardCompat.h"
25#include "llvm/IR/Value.h"
26
27namespace llvm {
28class Type;
29class Value;
30} // namespace llvm
31
32namespace clang {
33class Decl;
34class FunctionDecl;
35class TargetOptions;
36class VarDecl;
37
38namespace CodeGen {
39
40/// Abstract information about a function or function prototype.
42 /// The function prototype of the callee.
43 const FunctionProtoType *CalleeProtoTy;
44 /// The function declaration of the callee.
45 GlobalDecl CalleeDecl;
46
47public:
48 explicit CGCalleeInfo() : CalleeProtoTy(nullptr) {}
49 CGCalleeInfo(const FunctionProtoType *calleeProtoTy, GlobalDecl calleeDecl)
50 : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {}
51 CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
52 : CalleeProtoTy(calleeProtoTy) {}
54 : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {}
55
57 return CalleeProtoTy;
58 }
59 const GlobalDecl getCalleeDecl() const { return CalleeDecl; }
60};
61
62/// All available information about a concrete callee.
63class CGCallee {
64 enum class SpecialKind : uintptr_t {
65 Invalid,
66 Builtin,
67 PseudoDestructor,
68 Virtual,
69
71 };
72
73 struct OrdinaryInfoStorage {
74 CGCalleeInfo AbstractInfo;
75 CGPointerAuthInfo PointerAuthInfo;
76 };
77 struct BuiltinInfoStorage {
78 const FunctionDecl *Decl;
79 unsigned ID;
80 };
81 struct PseudoDestructorInfoStorage {
83 };
84 struct VirtualInfoStorage {
85 const CallExpr *CE;
86 GlobalDecl MD;
87 Address Addr;
88 llvm::FunctionType *FTy;
89 };
90
91 SpecialKind KindOrFunctionPointer;
92 union {
93 OrdinaryInfoStorage OrdinaryInfo;
94 BuiltinInfoStorage BuiltinInfo;
95 PseudoDestructorInfoStorage PseudoDestructorInfo;
96 VirtualInfoStorage VirtualInfo;
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
107public:
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 /* FIXME: make parameter pointerAuthInfo mandatory */
114 const CGPointerAuthInfo &pointerAuthInfo = CGPointerAuthInfo())
115 : KindOrFunctionPointer(
116 SpecialKind(reinterpret_cast<uintptr_t>(functionPtr))) {
117 OrdinaryInfo.AbstractInfo = abstractInfo;
118 OrdinaryInfo.PointerAuthInfo = pointerAuthInfo;
119 assert(functionPtr && "configuring callee without function pointer");
120 assert(functionPtr->getType()->isPointerTy());
121 }
122
123 static CGCallee forBuiltin(unsigned builtinID,
124 const FunctionDecl *builtinDecl) {
125 CGCallee result(SpecialKind::Builtin);
126 result.BuiltinInfo.Decl = builtinDecl;
127 result.BuiltinInfo.ID = builtinID;
128 return result;
129 }
130
132 CGCallee result(SpecialKind::PseudoDestructor);
133 result.PseudoDestructorInfo.Expr = E;
134 return result;
135 }
136
137 static CGCallee forDirect(llvm::Constant *functionPtr,
138 const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
139 return CGCallee(abstractInfo, functionPtr);
140 }
141
142 static CGCallee forDirect(llvm::FunctionCallee functionPtr,
143 const CGCalleeInfo &abstractInfo = CGCalleeInfo()) {
144 return CGCallee(abstractInfo, functionPtr.getCallee());
145 }
146
147 static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr,
148 llvm::FunctionType *FTy) {
149 CGCallee result(SpecialKind::Virtual);
150 result.VirtualInfo.CE = CE;
151 result.VirtualInfo.MD = MD;
152 result.VirtualInfo.Addr = Addr;
153 result.VirtualInfo.FTy = FTy;
154 return result;
155 }
156
157 bool isBuiltin() const {
158 return KindOrFunctionPointer == SpecialKind::Builtin;
159 }
161 assert(isBuiltin());
162 return BuiltinInfo.Decl;
163 }
164 unsigned getBuiltinID() const {
165 assert(isBuiltin());
166 return BuiltinInfo.ID;
167 }
168
169 bool isPseudoDestructor() const {
170 return KindOrFunctionPointer == SpecialKind::PseudoDestructor;
171 }
173 assert(isPseudoDestructor());
174 return PseudoDestructorInfo.Expr;
175 }
176
177 bool isOrdinary() const {
178 return uintptr_t(KindOrFunctionPointer) > uintptr_t(SpecialKind::Last);
179 }
181 if (isVirtual())
182 return VirtualInfo.MD;
183 assert(isOrdinary());
184 return OrdinaryInfo.AbstractInfo;
185 }
187 assert(isOrdinary());
188 return OrdinaryInfo.PointerAuthInfo;
189 }
190 llvm::Value *getFunctionPointer() const {
191 assert(isOrdinary());
192 return reinterpret_cast<llvm::Value *>(uintptr_t(KindOrFunctionPointer));
193 }
194 void setFunctionPointer(llvm::Value *functionPtr) {
195 assert(isOrdinary());
196 KindOrFunctionPointer =
197 SpecialKind(reinterpret_cast<uintptr_t>(functionPtr));
198 }
200 assert(isOrdinary());
201 OrdinaryInfo.PointerAuthInfo = PointerAuth;
202 }
203
204 bool isVirtual() const {
205 return KindOrFunctionPointer == SpecialKind::Virtual;
206 }
208 assert(isVirtual());
209 return VirtualInfo.CE;
210 }
212 assert(isVirtual());
213 return VirtualInfo.MD;
214 }
216 assert(isVirtual());
217 return VirtualInfo.Addr;
218 }
219 llvm::FunctionType *getVirtualFunctionType() const {
220 assert(isVirtual());
221 return VirtualInfo.FTy;
222 }
223
224 /// If this is a delayed callee computation of some sort, prepare
225 /// a concrete callee.
227};
228
229struct CallArg {
230private:
231 union {
233 LValue LV; /// The argument is semantically a load from this l-value.
234 };
235 bool HasLV;
236
237 /// A data-flow flag to make sure getRValue and/or copyInto are not
238 /// called twice for duplicated IR emission.
239 mutable bool IsUsed;
240
241public:
244 : RV(rv), HasLV(false), IsUsed(false), Ty(ty) {}
246 : LV(lv), HasLV(true), IsUsed(false), Ty(ty) {}
247 bool hasLValue() const { return HasLV; }
248 QualType getType() const { return Ty; }
249
250 /// \returns an independent RValue. If the CallArg contains an LValue,
251 /// a temporary copy is returned.
252 RValue getRValue(CodeGenFunction &CGF) const;
253
255 assert(HasLV && !IsUsed);
256 return LV;
257 }
259 assert(!HasLV && !IsUsed);
260 return RV;
261 }
262 void setRValue(RValue _RV) {
263 assert(!HasLV);
264 RV = _RV;
265 }
266
267 bool isAggregate() const { return HasLV || RV.isAggregate(); }
268
269 void copyInto(CodeGenFunction &CGF, Address A) const;
270};
271
272/// CallArgList - Type for representing both the value and type of
273/// arguments in a call.
274class CallArgList : public SmallVector<CallArg, 8> {
275public:
276 CallArgList() = default;
277
278 struct Writeback {
279 /// The original argument. Note that the argument l-value
280 /// is potentially null.
282
283 /// The temporary alloca.
285
286 /// A value to "use" after the writeback, or null.
287 llvm::Value *ToUse;
288 };
289
292
293 /// The "is active" insertion point. This instruction is temporary and
294 /// will be removed after insertion.
295 llvm::Instruction *IsActiveIP;
296 };
297
298 void add(RValue rvalue, QualType type) { push_back(CallArg(rvalue, type)); }
299
301 push_back(CallArg(LV, type));
302 }
303
304 /// Add all the arguments from another CallArgList to this one. After doing
305 /// this, the old CallArgList retains its list of arguments, but must not
306 /// be used to emit a call.
307 void addFrom(const CallArgList &other) {
308 insert(end(), other.begin(), other.end());
309 Writebacks.insert(Writebacks.end(), other.Writebacks.begin(),
310 other.Writebacks.end());
311 CleanupsToDeactivate.insert(CleanupsToDeactivate.end(),
312 other.CleanupsToDeactivate.begin(),
313 other.CleanupsToDeactivate.end());
314 assert(!(StackBase && other.StackBase) && "can't merge stackbases");
315 if (!StackBase)
316 StackBase = other.StackBase;
317 }
318
319 void addWriteback(LValue srcLV, Address temporary, llvm::Value *toUse) {
320 Writeback writeback = {srcLV, temporary, toUse};
321 Writebacks.push_back(writeback);
322 }
323
324 bool hasWritebacks() const { return !Writebacks.empty(); }
325
326 typedef llvm::iterator_range<SmallVectorImpl<Writeback>::const_iterator>
328
330 return writeback_const_range(Writebacks.begin(), Writebacks.end());
331 }
332
334 llvm::Instruction *IsActiveIP) {
335 CallArgCleanup ArgCleanup;
336 ArgCleanup.Cleanup = Cleanup;
337 ArgCleanup.IsActiveIP = IsActiveIP;
338 CleanupsToDeactivate.push_back(ArgCleanup);
339 }
340
342 return CleanupsToDeactivate;
343 }
344
346 llvm::Instruction *getStackBase() const { return StackBase; }
347 void freeArgumentMemory(CodeGenFunction &CGF) const;
348
349 /// Returns if we're using an inalloca struct to pass arguments in
350 /// memory.
351 bool isUsingInAlloca() const { return StackBase; }
352
353private:
354 SmallVector<Writeback, 1> Writebacks;
355
356 /// Deactivate these cleanups immediately before making the call. This
357 /// is used to cleanup objects that are owned by the callee once the call
358 /// occurs.
359 SmallVector<CallArgCleanup, 1> CleanupsToDeactivate;
360
361 /// The stacksave call. It dominates all of the argument evaluation.
362 llvm::CallInst *StackBase = nullptr;
363};
364
365/// FunctionArgList - Type for representing both the decl and type
366/// of parameters to a function. The decl must be either a
367/// ParmVarDecl or ImplicitParamDecl.
368class FunctionArgList : public SmallVector<const VarDecl *, 16> {};
369
370/// ReturnValueSlot - Contains the address where the return value of a
371/// function can be stored, and whether the address is volatile or not.
373 Address Addr = Address::invalid();
374
375 // Return value slot flags
376 LLVM_PREFERRED_TYPE(bool)
377 unsigned IsVolatile : 1;
378 LLVM_PREFERRED_TYPE(bool)
379 unsigned IsUnused : 1;
380 LLVM_PREFERRED_TYPE(bool)
381 unsigned IsExternallyDestructed : 1;
382
383public:
385 : IsVolatile(false), IsUnused(false), IsExternallyDestructed(false) {}
386 ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused = false,
387 bool IsExternallyDestructed = false)
388 : Addr(Addr), IsVolatile(IsVolatile), IsUnused(IsUnused),
389 IsExternallyDestructed(IsExternallyDestructed) {}
390
391 bool isNull() const { return !Addr.isValid(); }
392 bool isVolatile() const { return IsVolatile; }
393 Address getValue() const { return Addr; }
394 bool isUnused() const { return IsUnused; }
395 bool isExternallyDestructed() const { return IsExternallyDestructed; }
396 Address getAddress() const { return Addr; }
397};
398
399/// Adds attributes to \p F according to our \p CodeGenOpts and \p LangOpts, as
400/// though we had emitted it ourselves. We remove any attributes on F that
401/// conflict with the attributes we add here.
402///
403/// This is useful for adding attrs to bitcode modules that you want to link
404/// with but don't control, such as CUDA's libdevice. When linking with such
405/// a bitcode library, you might want to set e.g. its functions'
406/// "unsafe-fp-math" attribute to match the attr of the functions you're
407/// codegen'ing. Otherwise, LLVM will interpret the bitcode module's lack of
408/// unsafe-fp-math attrs as tantamount to unsafe-fp-math=false, and then LLVM
409/// will propagate unsafe-fp-math=false up to every transitive caller of a
410/// function in the bitcode library!
411///
412/// With the exception of fast-math attrs, this will only make the attributes
413/// on the function more conservative. But it's unsafe to call this on a
414/// function which relies on particular fast-math attributes for correctness.
415/// It's up to you to ensure that this is safe.
416void mergeDefaultFunctionDefinitionAttributes(llvm::Function &F,
417 const CodeGenOptions &CodeGenOpts,
418 const LangOptions &LangOpts,
419 const TargetOptions &TargetOpts,
420 bool WillInternalize);
421
422enum class FnInfoOpts {
423 None = 0,
424 IsInstanceMethod = 1 << 0,
425 IsChainCall = 1 << 1,
426 IsDelegateCall = 1 << 2,
427};
428
430 return static_cast<FnInfoOpts>(llvm::to_underlying(A) |
431 llvm::to_underlying(B));
432}
433
435 return static_cast<FnInfoOpts>(llvm::to_underlying(A) &
436 llvm::to_underlying(B));
437}
438
440 A = A | B;
441 return A;
442}
443
445 A = A & B;
446 return A;
447}
448
449} // end namespace CodeGen
450} // end namespace clang
451
452#endif
Forward declaration of all AST node types.
MatchType Type
Expr * E
C Language Family Type Representation.
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition: ExprCXX.h:2617
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2830
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition: Address.h:128
static Address invalid()
Definition: Address.h:176
bool isValid() const
Definition: Address.h:177
Abstract information about a function or function prototype.
Definition: CGCall.h:41
const GlobalDecl getCalleeDecl() const
Definition: CGCall.h:59
CGCalleeInfo(const FunctionProtoType *calleeProtoTy)
Definition: CGCall.h:51
CGCalleeInfo(const FunctionProtoType *calleeProtoTy, GlobalDecl calleeDecl)
Definition: CGCall.h:49
const FunctionProtoType * getCalleeFunctionProtoType() const
Definition: CGCall.h:56
CGCalleeInfo(GlobalDecl calleeDecl)
Definition: CGCall.h:53
All available information about a concrete callee.
Definition: CGCall.h:63
CGCalleeInfo getAbstractInfo() const
Definition: CGCall.h:180
CGCallee prepareConcreteCallee(CodeGenFunction &CGF) const
If this is a delayed callee computation of some sort, prepare a concrete callee.
Definition: CGCall.cpp:6016
VirtualInfoStorage VirtualInfo
Definition: CGCall.h:96
void setPointerAuthInfo(CGPointerAuthInfo PointerAuth)
Definition: CGCall.h:199
bool isVirtual() const
Definition: CGCall.h:204
const CXXPseudoDestructorExpr * getPseudoDestructorExpr() const
Definition: CGCall.h:172
bool isOrdinary() const
Definition: CGCall.h:177
Address getThisAddress() const
Definition: CGCall.h:215
const CallExpr * getVirtualCallExpr() const
Definition: CGCall.h:207
CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr, const CGPointerAuthInfo &pointerAuthInfo=CGPointerAuthInfo())
Construct a callee.
Definition: CGCall.h:112
BuiltinInfoStorage BuiltinInfo
Definition: CGCall.h:94
bool isPseudoDestructor() const
Definition: CGCall.h:169
llvm::Value * getFunctionPointer() const
Definition: CGCall.h:190
PseudoDestructorInfoStorage PseudoDestructorInfo
Definition: CGCall.h:95
static CGCallee forBuiltin(unsigned builtinID, const FunctionDecl *builtinDecl)
Definition: CGCall.h:123
unsigned getBuiltinID() const
Definition: CGCall.h:164
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
Definition: CGCall.h:147
void setFunctionPointer(llvm::Value *functionPtr)
Definition: CGCall.h:194
static CGCallee forDirect(llvm::FunctionCallee functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Definition: CGCall.h:142
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Definition: CGCall.h:137
bool isBuiltin() const
Definition: CGCall.h:157
llvm::FunctionType * getVirtualFunctionType() const
Definition: CGCall.h:219
OrdinaryInfoStorage OrdinaryInfo
Definition: CGCall.h:93
const FunctionDecl * getBuiltinDecl() const
Definition: CGCall.h:160
const CGPointerAuthInfo & getPointerAuthInfo() const
Definition: CGCall.h:186
static CGCallee forPseudoDestructor(const CXXPseudoDestructorExpr *E)
Definition: CGCall.h:131
GlobalDecl getVirtualMethodDecl() const
Definition: CGCall.h:211
CallArgList - Type for representing both the value and type of arguments in a call.
Definition: CGCall.h:274
llvm::Instruction * getStackBase() const
Definition: CGCall.h:346
void addUncopiedAggregate(LValue LV, QualType type)
Definition: CGCall.h:300
llvm::iterator_range< SmallVectorImpl< Writeback >::const_iterator > writeback_const_range
Definition: CGCall.h:327
void addArgCleanupDeactivation(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *IsActiveIP)
Definition: CGCall.h:333
ArrayRef< CallArgCleanup > getCleanupsToDeactivate() const
Definition: CGCall.h:341
bool hasWritebacks() const
Definition: CGCall.h:324
void add(RValue rvalue, QualType type)
Definition: CGCall.h:298
bool isUsingInAlloca() const
Returns if we're using an inalloca struct to pass arguments in memory.
Definition: CGCall.h:351
void allocateArgumentMemory(CodeGenFunction &CGF)
Definition: CGCall.cpp:4345
void freeArgumentMemory(CodeGenFunction &CGF) const
Definition: CGCall.cpp:4352
writeback_const_range writebacks() const
Definition: CGCall.h:329
void addWriteback(LValue srcLV, Address temporary, llvm::Value *toUse)
Definition: CGCall.h:319
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
Definition: CGCall.h:307
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
A saved depth on the scope stack.
Definition: EHScopeStack.h:101
FunctionArgList - Type for representing both the decl and type of parameters to a function.
Definition: CGCall.h:368
LValue - This represents an lvalue references.
Definition: CGValue.h:182
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
Definition: CGValue.h:42
bool isAggregate() const
Definition: CGValue.h:66
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Definition: CGCall.h:372
Address getValue() const
Definition: CGCall.h:393
bool isExternallyDestructed() const
Definition: CGCall.h:395
ReturnValueSlot(Address Addr, bool IsVolatile, bool IsUnused=false, bool IsExternallyDestructed=false)
Definition: CGCall.h:386
Address getAddress() const
Definition: CGCall.h:396
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
This represents one expression.
Definition: Expr.h:110
Represents a function declaration or definition.
Definition: Decl.h:1932
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5002
GlobalDecl - represents a global declaration.
Definition: GlobalDecl.h:56
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:476
A (possibly-)qualified type.
Definition: Type.h:941
Options for controlling the target.
Definition: TargetOptions.h:26
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
FnInfoOpts operator|=(FnInfoOpts A, FnInfoOpts B)
Definition: CGCall.h:439
FnInfoOpts operator&(FnInfoOpts A, FnInfoOpts B)
Definition: CGCall.h:434
FnInfoOpts operator&=(FnInfoOpts A, FnInfoOpts B)
Definition: CGCall.h:444
void mergeDefaultFunctionDefinitionAttributes(llvm::Function &F, const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts, const TargetOptions &TargetOpts, bool WillInternalize)
Adds attributes to F according to our CodeGenOpts and LangOpts, as though we had emitted it ourselves...
Definition: CGCall.cpp:2052
BlockFlags operator|(BlockLiteralFlags l, BlockLiteralFlags r)
Definition: CGBlocks.h:83
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
__UINTPTR_TYPE__ uintptr_t
An unsigned integer type with the property that any valid pointer to void can be converted to this ty...
#define true
Definition: stdbool.h:25
#define false
Definition: stdbool.h:26
llvm::Instruction * IsActiveIP
The "is active" insertion point.
Definition: CGCall.h:295
EHScopeStack::stable_iterator Cleanup
Definition: CGCall.h:291
llvm::Value * ToUse
A value to "use" after the writeback, or null.
Definition: CGCall.h:287
LValue Source
The original argument.
Definition: CGCall.h:281
Address Temporary
The temporary alloca.
Definition: CGCall.h:284
LValue getKnownLValue() const
Definition: CGCall.h:254
RValue getKnownRValue() const
Definition: CGCall.h:258
QualType getType() const
Definition: CGCall.h:248
bool isAggregate() const
Definition: CGCall.h:267
CallArg(LValue lv, QualType ty)
Definition: CGCall.h:245
void setRValue(RValue _RV)
Definition: CGCall.h:262
void copyInto(CodeGenFunction &CGF, Address A) const
Definition: CGCall.cpp:4645
CallArg(RValue rv, QualType ty)
Definition: CGCall.h:243
bool hasLValue() const
Definition: CGCall.h:247
RValue getRValue(CodeGenFunction &CGF) const
Definition: CGCall.cpp:4635