Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CIR/CodeGen/CIRGenCall.h
213799 views
1
//===----------------------------------------------------------------------===//
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 CLANG_LIB_CODEGEN_CIRGENCALL_H
15
#define CLANG_LIB_CODEGEN_CIRGENCALL_H
16
17
#include "CIRGenValue.h"
18
#include "mlir/IR/Operation.h"
19
#include "clang/AST/GlobalDecl.h"
20
#include "llvm/ADT/SmallVector.h"
21
22
namespace clang::CIRGen {
23
24
class CIRGenFunction;
25
26
/// Abstract information about a function or function prototype.
27
class CIRGenCalleeInfo {
28
const clang::FunctionProtoType *calleeProtoTy;
29
clang::GlobalDecl calleeDecl;
30
31
public:
32
explicit CIRGenCalleeInfo() : calleeProtoTy(nullptr), calleeDecl() {}
33
CIRGenCalleeInfo(const clang::FunctionProtoType *calleeProtoTy,
34
clang::GlobalDecl calleeDecl)
35
: calleeProtoTy(calleeProtoTy), calleeDecl(calleeDecl) {}
36
CIRGenCalleeInfo(clang::GlobalDecl calleeDecl)
37
: calleeProtoTy(nullptr), calleeDecl(calleeDecl) {}
38
39
const clang::FunctionProtoType *getCalleeFunctionProtoType() const {
40
return calleeProtoTy;
41
}
42
clang::GlobalDecl getCalleeDecl() const { return calleeDecl; }
43
};
44
45
class CIRGenCallee {
46
enum class SpecialKind : uintptr_t {
47
Invalid,
48
Builtin,
49
50
Last = Builtin,
51
};
52
53
struct BuiltinInfoStorage {
54
const clang::FunctionDecl *decl;
55
unsigned id;
56
};
57
58
SpecialKind kindOrFunctionPtr;
59
60
union {
61
CIRGenCalleeInfo abstractInfo;
62
BuiltinInfoStorage builtinInfo;
63
};
64
65
explicit CIRGenCallee(SpecialKind kind) : kindOrFunctionPtr(kind) {}
66
67
public:
68
CIRGenCallee() : kindOrFunctionPtr(SpecialKind::Invalid) {}
69
70
CIRGenCallee(const CIRGenCalleeInfo &abstractInfo, mlir::Operation *funcPtr)
71
: kindOrFunctionPtr(SpecialKind(reinterpret_cast<uintptr_t>(funcPtr))),
72
abstractInfo(abstractInfo) {
73
assert(funcPtr && "configuring callee without function pointer");
74
}
75
76
static CIRGenCallee
77
forDirect(mlir::Operation *funcPtr,
78
const CIRGenCalleeInfo &abstractInfo = CIRGenCalleeInfo()) {
79
return CIRGenCallee(abstractInfo, funcPtr);
80
}
81
82
bool isBuiltin() const { return kindOrFunctionPtr == SpecialKind::Builtin; }
83
84
const clang::FunctionDecl *getBuiltinDecl() const {
85
assert(isBuiltin());
86
return builtinInfo.decl;
87
}
88
unsigned getBuiltinID() const {
89
assert(isBuiltin());
90
return builtinInfo.id;
91
}
92
93
static CIRGenCallee forBuiltin(unsigned builtinID,
94
const clang::FunctionDecl *builtinDecl) {
95
CIRGenCallee result(SpecialKind::Builtin);
96
result.builtinInfo.decl = builtinDecl;
97
result.builtinInfo.id = builtinID;
98
return result;
99
}
100
101
bool isOrdinary() const {
102
return uintptr_t(kindOrFunctionPtr) > uintptr_t(SpecialKind::Last);
103
}
104
105
/// If this is a delayed callee computation of some sort, prepare a concrete
106
/// callee
107
CIRGenCallee prepareConcreteCallee(CIRGenFunction &cgf) const;
108
109
CIRGenCalleeInfo getAbstractInfo() const {
110
assert(!cir::MissingFeatures::opCallVirtual());
111
assert(isOrdinary());
112
return abstractInfo;
113
}
114
115
mlir::Operation *getFunctionPointer() const {
116
assert(isOrdinary());
117
return reinterpret_cast<mlir::Operation *>(kindOrFunctionPtr);
118
}
119
};
120
121
/// Type for representing both the decl and type of parameters to a function.
122
/// The decl must be either a ParmVarDecl or ImplicitParamDecl.
123
class FunctionArgList : public llvm::SmallVector<const clang::VarDecl *, 16> {};
124
125
struct CallArg {
126
private:
127
union {
128
RValue rv;
129
LValue lv; // This argument is semantically a load from this l-value
130
};
131
bool hasLV;
132
133
/// A data-flow flag to make sure getRValue and/or copyInto are not
134
/// called twice for duplicated IR emission.
135
mutable bool isUsed;
136
137
public:
138
clang::QualType ty;
139
140
CallArg(RValue rv, clang::QualType ty)
141
: rv(rv), hasLV(false), isUsed(false), ty(ty) {}
142
143
CallArg(LValue lv, clang::QualType ty)
144
: lv(lv), hasLV(true), isUsed(false), ty(ty) {}
145
146
bool hasLValue() const { return hasLV; }
147
148
LValue getKnownLValue() const {
149
assert(hasLV && !isUsed);
150
return lv;
151
}
152
153
RValue getKnownRValue() const {
154
assert(!hasLV && !isUsed);
155
return rv;
156
}
157
158
bool isAggregate() const { return hasLV || rv.isAggregate(); }
159
};
160
161
class CallArgList : public llvm::SmallVector<CallArg, 8> {
162
public:
163
void add(RValue rvalue, clang::QualType type) { emplace_back(rvalue, type); }
164
165
void addUncopiedAggregate(LValue lvalue, clang::QualType type) {
166
emplace_back(lvalue, type);
167
}
168
169
/// Add all the arguments from another CallArgList to this one. After doing
170
/// this, the old CallArgList retains its list of arguments, but must not
171
/// be used to emit a call.
172
void addFrom(const CallArgList &other) {
173
insert(end(), other.begin(), other.end());
174
// Classic codegen has handling for these here. We may not need it here for
175
// CIR, but if not we should implement equivalent handling in lowering.
176
assert(!cir::MissingFeatures::writebacks());
177
assert(!cir::MissingFeatures::cleanupsToDeactivate());
178
assert(!cir::MissingFeatures::stackBase());
179
}
180
};
181
182
/// Contains the address where the return value of a function can be stored, and
183
/// whether the address is volatile or not.
184
class ReturnValueSlot {
185
Address addr = Address::invalid();
186
187
public:
188
ReturnValueSlot() = default;
189
ReturnValueSlot(Address addr) : addr(addr) {}
190
191
Address getValue() const { return addr; }
192
};
193
194
} // namespace clang::CIRGen
195
196
#endif // CLANG_LIB_CODEGEN_CIRGENCALL_H
197
198