1313
1414#include " CIRGenCall.h"
1515#include " CIRGenFunction.h"
16+ #include " CIRGenFunctionInfo.h"
1617#include " clang/CIR/MissingFeatures.h"
1718
1819using namespace clang ;
1920using namespace clang ::CIRGen;
2021
2122CIRGenFunctionInfo *
2223CIRGenFunctionInfo::create (CanQualType resultType,
23- llvm::ArrayRef<CanQualType> argTypes) {
24+ llvm::ArrayRef<CanQualType> argTypes,
25+ RequiredArgs required) {
2426 // The first slot allocated for ArgInfo is for the return value.
2527 void *buffer = operator new (totalSizeToAlloc<ArgInfo>(argTypes.size () + 1 ));
2628
29+ assert (!cir::MissingFeatures::opCallCIRGenFuncInfoParamInfo ());
30+
2731 CIRGenFunctionInfo *fi = new (buffer) CIRGenFunctionInfo ();
28- fi->numArgs = argTypes.size ();
2932
30- assert (!cir::MissingFeatures::opCallCIRGenFuncInfoParamInfo ());
33+ fi->required = required;
34+ fi->numArgs = argTypes.size ();
3135
3236 ArgInfo *argsBuffer = fi->getArgsBuffer ();
3337 (argsBuffer++)->type = resultType;
3438 for (CanQualType ty : argTypes)
3539 (argsBuffer++)->type = ty;
36-
3740 assert (!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo ());
3841
3942 return fi;
@@ -45,7 +48,7 @@ namespace {
4548// / CIRGenFunctionInfo should be passed to actual CIR function.
4649class ClangToCIRArgMapping {
4750 static constexpr unsigned invalidIndex = ~0U ;
48- unsigned totalNumCIRArgs;
51+ unsigned totalNumCIRArgs = 0 ;
4952
5053 // / Arguments of CIR function corresponding to single Clang argument.
5154 struct CIRArgs {
@@ -61,14 +64,20 @@ class ClangToCIRArgMapping {
6164
6265public:
6366 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()) {
6671 unsigned cirArgNo = 0 ;
6772
6873 assert (!cir::MissingFeatures::opCallABIIndirectArg ());
6974
7075 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) {
7281 // Collect data about CIR arguments corresponding to Clang argument ArgNo.
7382 CIRArgs &cirArgs = argInfo[argNo];
7483
@@ -119,6 +128,63 @@ class ClangToCIRArgMapping {
119128
120129} // namespace
121130
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+
122188CIRGenCallee CIRGenCallee::prepareConcreteCallee (CIRGenFunction &cgf) const {
123189 assert (!cir::MissingFeatures::opCallVirtual ());
124190 return *this ;
@@ -128,6 +194,9 @@ static const CIRGenFunctionInfo &
128194arrangeFreeFunctionLikeCall (CIRGenTypes &cgt, CIRGenModule &cgm,
129195 const CallArgList &args,
130196 const FunctionType *fnType) {
197+
198+ RequiredArgs required = RequiredArgs::All;
199+
131200 if (const auto *proto = dyn_cast<FunctionProtoType>(fnType)) {
132201 if (proto->isVariadic ())
133202 cgm.errorNYI (" call to variadic function" );
@@ -144,7 +213,7 @@ arrangeFreeFunctionLikeCall(CIRGenTypes &cgt, CIRGenModule &cgm,
144213 CanQualType retType = fnType->getReturnType ()
145214 ->getCanonicalTypeUnqualified ()
146215 .getUnqualifiedType ();
147- return cgt.arrangeCIRFunctionInfo (retType, argTypes);
216+ return cgt.arrangeCIRFunctionInfo (retType, argTypes, required );
148217}
149218
150219const CIRGenFunctionInfo &
@@ -168,6 +237,23 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
168237 return builder.createCallOp (callLoc, directFuncOp, cirCallArgs);
169238}
170239
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+
171257RValue CIRGenFunction::emitCall (const CIRGenFunctionInfo &funcInfo,
172258 const CIRGenCallee &callee,
173259 ReturnValueSlot returnValue,
@@ -177,16 +263,16 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
177263 QualType retTy = funcInfo.getReturnType ();
178264 const cir::ABIArgInfo &retInfo = funcInfo.getReturnInfo ();
179265
180- ClangToCIRArgMapping cirFuncArgs (cgm.getASTContext (), funcInfo);
266+ ClangToCIRArgMapping cirFuncArgs (cgm.getASTContext (), funcInfo, false );
181267 SmallVector<mlir::Value, 16 > cirCallArgs (cirFuncArgs.totalCIRArgs ());
182268
183269 assert (!cir::MissingFeatures::emitLifetimeMarkers ());
184270
185271 // 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 () &&
187273 " Mismatch between function signature & arguments." );
188274 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 ())) {
190276 // Insert a padding argument to ensure proper alignment.
191277 assert (!cir::MissingFeatures::opCallPaddingArgs ());
192278
0 commit comments