13
13
14
14
#include " CIRGenCall.h"
15
15
#include " CIRGenFunction.h"
16
+ #include " CIRGenFunctionInfo.h"
16
17
#include " clang/CIR/MissingFeatures.h"
17
18
18
19
using namespace clang ;
19
20
using namespace clang ::CIRGen;
20
21
21
22
CIRGenFunctionInfo *
22
23
CIRGenFunctionInfo::create (CanQualType resultType,
23
- llvm::ArrayRef<CanQualType> argTypes) {
24
+ llvm::ArrayRef<CanQualType> argTypes,
25
+ RequiredArgs required) {
24
26
// The first slot allocated for ArgInfo is for the return value.
25
27
void *buffer = operator new (totalSizeToAlloc<ArgInfo>(argTypes.size () + 1 ));
26
28
29
+ assert (!cir::MissingFeatures::opCallCIRGenFuncInfoParamInfo ());
30
+
27
31
CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo ();
28
- fi->numArgs = argTypes.size ();
29
32
30
- assert (!cir::MissingFeatures::opCallCIRGenFuncInfoParamInfo ());
33
+ fi->required = required;
34
+ fi->numArgs = argTypes.size ();
31
35
32
36
ArgInfo *argsBuffer = fi->getArgsBuffer ();
33
37
(argsBuffer++)->type = resultType;
34
38
for (CanQualType ty : argTypes)
35
39
(argsBuffer++)->type = ty;
36
-
37
40
assert (!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo ());
38
41
39
42
return fi;
@@ -45,7 +48,7 @@ namespace {
45
48
// / CIRGenFunctionInfo should be passed to actual CIR function.
46
49
class ClangToCIRArgMapping {
47
50
static constexpr unsigned invalidIndex = ~0U ;
48
- unsigned totalNumCIRArgs;
51
+ unsigned totalNumCIRArgs = 0 ;
49
52
50
53
// / Arguments of CIR function corresponding to single Clang argument.
51
54
struct CIRArgs {
@@ -61,14 +64,20 @@ class ClangToCIRArgMapping {
61
64
62
65
public:
63
66
ClangToCIRArgMapping (const ASTContext &astContext,
64
- const CIRGenFunctionInfo &funcInfo)
65
- : totalNumCIRArgs(0 ), argInfo(funcInfo.arg_size()) {
67
+ const CIRGenFunctionInfo &funcInfo,
68
+ bool onlyRequiredArgs)
69
+ : argInfo(onlyRequiredArgs ? funcInfo.getNumRequiredArgs()
70
+ : funcInfo.argInfoSize()) {
66
71
unsigned cirArgNo = 0 ;
67
72
68
73
assert (!cir::MissingFeatures::opCallABIIndirectArg ());
69
74
70
75
unsigned argNo = 0 ;
71
- for (const CIRGenFunctionInfoArgInfo &i : funcInfo.arguments ()) {
76
+ llvm::ArrayRef<CIRGenFunctionInfoArgInfo> argInfos (
77
+ funcInfo.argInfoBegin (), onlyRequiredArgs
78
+ ? funcInfo.getNumRequiredArgs ()
79
+ : funcInfo.argInfoSize ());
80
+ for (const CIRGenFunctionInfoArgInfo &i : argInfos) {
72
81
// Collect data about CIR arguments corresponding to Clang argument ArgNo.
73
82
CIRArgs &cirArgs = argInfo[argNo];
74
83
@@ -119,6 +128,63 @@ class ClangToCIRArgMapping {
119
128
120
129
} // namespace
121
130
131
+ cir::FuncType CIRGenTypes::getFunctionType (const CIRGenFunctionInfo &fi) {
132
+ bool inserted = functionsBeingProcessed.insert (&fi).second ;
133
+ (void )inserted;
134
+ assert (inserted && " Recursively being processed?" );
135
+
136
+ mlir::Type resultType;
137
+ const cir::ABIArgInfo &retInfo = fi.getReturnInfo ();
138
+
139
+ switch (retInfo.getKind ()) {
140
+ case cir::ABIArgInfo::Ignore:
141
+ // TODO(CIR): This should probably be the None type from the builtin
142
+ // dialect.
143
+ resultType = nullptr ;
144
+ break ;
145
+ case cir::ABIArgInfo::Direct:
146
+ resultType = retInfo.getCoerceToType ();
147
+ break ;
148
+ }
149
+
150
+ ClangToCIRArgMapping cirFunctionArgs (getASTContext (), fi, true );
151
+ SmallVector<mlir::Type, 8 > argTypes (cirFunctionArgs.totalCIRArgs ());
152
+
153
+ unsigned argNo = 0 ;
154
+ llvm::ArrayRef<CIRGenFunctionInfoArgInfo> argInfos (fi.argInfoBegin (),
155
+ fi.getNumRequiredArgs ());
156
+ for (const auto &argInfo : argInfos) {
157
+ const auto &abiArgInfo = argInfo.info ;
158
+
159
+ unsigned firstCIRArg, numCIRArgs;
160
+ std::tie (firstCIRArg, numCIRArgs) = cirFunctionArgs.getCIRArgs (argNo);
161
+
162
+ switch (abiArgInfo.getKind ()) {
163
+ case cir::ABIArgInfo::Direct: {
164
+ mlir::Type argType = abiArgInfo.getCoerceToType ();
165
+ // TODO: handle the test against llvm::RecordType from codegen
166
+ assert (numCIRArgs == 1 );
167
+ argTypes[firstCIRArg] = argType;
168
+ break ;
169
+ }
170
+ default :
171
+ cgm.errorNYI (" getFunctionType: unhandled argument kind" );
172
+ }
173
+
174
+ ++argNo;
175
+ }
176
+ assert (argNo == fi.argInfoSize () &&
177
+ " Mismatch between function info and args" );
178
+
179
+ bool erased = functionsBeingProcessed.erase (&fi);
180
+ (void )erased;
181
+ assert (erased && " Not in set?" );
182
+
183
+ return cir::FuncType::get (argTypes,
184
+ (resultType ? resultType : builder.getVoidTy ()),
185
+ fi.isVariadic ());
186
+ }
187
+
122
188
CIRGenCallee CIRGenCallee::prepareConcreteCallee (CIRGenFunction &cgf) const {
123
189
assert (!cir::MissingFeatures::opCallVirtual ());
124
190
return *this ;
@@ -128,6 +194,9 @@ static const CIRGenFunctionInfo &
128
194
arrangeFreeFunctionLikeCall (CIRGenTypes &cgt, CIRGenModule &cgm,
129
195
const CallArgList &args,
130
196
const FunctionType *fnType) {
197
+
198
+ RequiredArgs required = RequiredArgs::All;
199
+
131
200
if (const auto *proto = dyn_cast<FunctionProtoType>(fnType)) {
132
201
if (proto->isVariadic ())
133
202
cgm.errorNYI (" call to variadic function" );
@@ -144,7 +213,7 @@ arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
144
213
CanQualType retType = fnType->getReturnType ()
145
214
->getCanonicalTypeUnqualified ()
146
215
.getUnqualifiedType ();
147
- return cgt.arrangeCIRFunctionInfo (retType, argTypes);
216
+ return cgt.arrangeCIRFunctionInfo (retType, argTypes, required );
148
217
}
149
218
150
219
const CIRGenFunctionInfo &
@@ -168,6 +237,23 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
168
237
return builder.createCallOp (callLoc, directFuncOp, cirCallArgs);
169
238
}
170
239
240
+ const CIRGenFunctionInfo &
241
+ CIRGenTypes::arrangeFreeFunctionType (CanQual<FunctionProtoType> fpt) {
242
+ SmallVector<CanQualType, 8 > argTypes;
243
+ for (unsigned i = 0 , e = fpt->getNumParams (); i != e; ++i)
244
+ argTypes.push_back (fpt->getParamType (i));
245
+ RequiredArgs required = RequiredArgs::forPrototypePlus (fpt);
246
+
247
+ CanQualType resultType = fpt->getReturnType ().getUnqualifiedType ();
248
+ return arrangeCIRFunctionInfo (resultType, argTypes, required);
249
+ }
250
+
251
+ const CIRGenFunctionInfo &
252
+ CIRGenTypes::arrangeFreeFunctionType (CanQual<FunctionNoProtoType> fnpt) {
253
+ CanQualType resultType = fnpt->getReturnType ().getUnqualifiedType ();
254
+ return arrangeCIRFunctionInfo (resultType, {}, RequiredArgs (0 ));
255
+ }
256
+
171
257
RValue CIRGenFunction::emitCall (const CIRGenFunctionInfo &funcInfo,
172
258
const CIRGenCallee &callee,
173
259
ReturnValueSlot returnValue,
@@ -177,16 +263,16 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
177
263
QualType retTy = funcInfo.getReturnType ();
178
264
const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo ();
179
265
180
- ClangToCIRArgMapping cirFuncArgs (cgm.getASTContext (), funcInfo);
266
+ ClangToCIRArgMapping cirFuncArgs (cgm.getASTContext (), funcInfo, false );
181
267
SmallVector<mlir::Value, 16 > cirCallArgs (cirFuncArgs.totalCIRArgs ());
182
268
183
269
assert (!cir::MissingFeatures::emitLifetimeMarkers ());
184
270
185
271
// Translate all of the arguments as necessary to match the CIR lowering.
186
- assert (funcInfo.arg_size () == args.size () &&
272
+ assert (funcInfo.argInfoSize () == args.size () &&
187
273
" Mismatch between function signature & arguments." );
188
274
unsigned argNo = 0 ;
189
- for (const auto &[arg, argInfo] : llvm::zip (args, funcInfo.arguments ())) {
275
+ for (const auto &[arg, argInfo] : llvm::zip (args, funcInfo.argInfos ())) {
190
276
// Insert a padding argument to ensure proper alignment.
191
277
assert (!cir::MissingFeatures::opCallPaddingArgs ());
192
278
0 commit comments