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 }