@@ -39,6 +39,27 @@ CIRGenFunctionInfo::create(CanQualType resultType,
3939 return fi;
4040}
4141
42+ cir::FuncType CIRGenTypes::getFunctionType (const CIRGenFunctionInfo &info) {
43+ [[maybe_unused]] bool inserted = functionsBeingProcessed.insert (&info).second ;
44+ assert (inserted && " Recursively being processed?" );
45+
46+ mlir::Type resultType = convertType (info.getReturnType ());
47+ SmallVector<mlir::Type, 8 > argTypes;
48+ argTypes.reserve (info.getNumRequiredArgs ());
49+
50+ // Add in all of the required arguments.
51+ for (const CIRGenFunctionInfoArgInfo &argInfo : info.requiredArguments ())
52+ argTypes.push_back (convertType (argInfo.type ));
53+
54+ [[maybe_unused]] bool erased = functionsBeingProcessed.erase (&info);
55+ assert (erased && " Not in set?" );
56+
57+ assert (!cir::MissingFeatures::opCallVariadic ());
58+ return cir::FuncType::get (argTypes,
59+ (resultType ? resultType : builder.getVoidTy ()),
60+ /* isVarArg=*/ false );
61+ }
62+
4263CIRGenCallee CIRGenCallee::prepareConcreteCallee (CIRGenFunction &cgf) const {
4364 assert (!cir::MissingFeatures::opCallVirtual ());
4465 return *this ;
@@ -75,6 +96,7 @@ CIRGenTypes::arrangeFreeFunctionCall(const CallArgList &args,
7596
7697static cir::CIRCallOpInterface
7798emitCallLikeOp (CIRGenFunction &cgf, mlir::Location callLoc,
99+ cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal,
78100 cir::FuncOp directFuncOp,
79101 const SmallVectorImpl<mlir::Value> &cirCallArgs) {
80102 CIRGenBuilderTy &builder = cgf.getBuilder ();
@@ -83,7 +105,13 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
83105 assert (!cir::MissingFeatures::invokeOp ());
84106
85107 assert (builder.getInsertionBlock () && " expected valid basic block" );
86- assert (!cir::MissingFeatures::opCallIndirect ());
108+
109+ if (indirectFuncTy) {
110+ // TODO(cir): Set calling convention for indirect calls.
111+ assert (!cir::MissingFeatures::opCallCallConv ());
112+ return builder.createIndirectCallOp (callLoc, indirectFuncVal,
113+ indirectFuncTy, cirCallArgs);
114+ }
87115
88116 return builder.createCallOp (callLoc, directFuncOp, cirCallArgs);
89117}
@@ -95,6 +123,7 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
95123 cir::CIRCallOpInterface *callOp,
96124 mlir::Location loc) {
97125 QualType retTy = funcInfo.getReturnType ();
126+ cir::FuncType cirFuncTy = getTypes ().getFunctionType (funcInfo);
98127
99128 SmallVector<mlir::Value, 16 > cirCallArgs (args.size ());
100129
@@ -145,12 +174,26 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
145174
146175 assert (!cir::MissingFeatures::invokeOp ());
147176
148- auto directFuncOp = dyn_cast<cir::FuncOp>(calleePtr);
149- assert (!cir::MissingFeatures::opCallIndirect ());
177+ cir::FuncType indirectFuncTy;
178+ mlir::Value indirectFuncVal;
179+ cir::FuncOp directFuncOp;
180+ if (auto fnOp = dyn_cast<cir::FuncOp>(calleePtr))
181+ directFuncOp = fnOp;
182+ else {
183+ [[maybe_unused]] auto resultTypes = calleePtr->getResultTypes ();
184+ [[maybe_unused]] auto funcPtrTy =
185+ mlir::dyn_cast<cir::PointerType>(resultTypes.front ());
186+ assert (funcPtrTy && mlir::isa<cir::FuncType>(funcPtrTy.getPointee ()) &&
187+ " expected pointer to function" );
188+
189+ indirectFuncTy = cirFuncTy;
190+ indirectFuncVal = calleePtr->getResult (0 );
191+ }
192+
150193 assert (!cir::MissingFeatures::opCallAttrs ());
151194
152- cir::CIRCallOpInterface theCall =
153- emitCallLikeOp ( *this , loc, directFuncOp, cirCallArgs);
195+ cir::CIRCallOpInterface theCall = emitCallLikeOp (
196+ *this , loc, indirectFuncTy, indirectFuncVal , directFuncOp, cirCallArgs);
154197
155198 if (callOp)
156199 *callOp = theCall;
@@ -250,7 +293,7 @@ void CIRGenFunction::emitCallArgs(
250293
251294 auto maybeEmitImplicitObjectSize = [&](size_t i, const Expr *arg,
252295 RValue emittedArg) {
253- if (callee.hasFunctionDecl () || i >= callee.getNumParams ())
296+ if (! callee.hasFunctionDecl () || i >= callee.getNumParams ())
254297 return ;
255298 auto *ps = callee.getParamDecl (i)->getAttr <PassObjectSizeAttr>();
256299 if (!ps)
0 commit comments