[clang] [CIR] Upstream initial function call support (PR #134673)
Bruno Cardoso Lopes via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 9 11:06:01 PDT 2025
================
@@ -304,6 +305,102 @@ RValue CIRGenFunction::emitAnyExpr(const Expr *e) {
llvm_unreachable("bad evaluation kind");
}
+static cir::FuncOp emitFunctionDeclPointer(CIRGenModule &cgm, GlobalDecl gd) {
+ assert(!cir::MissingFeatures::weakRefReference());
+ return cgm.getAddrOfFunction(gd);
+}
+
+static CIRGenCallee emitDirectCallee(CIRGenModule &cgm, GlobalDecl gd) {
+ assert(!cir::MissingFeatures::opCallBuiltinFunc());
+
+ cir::FuncOp callee = emitFunctionDeclPointer(cgm, gd);
+
+ assert(!cir::MissingFeatures::hip());
+
+ return CIRGenCallee::forDirect(callee, gd);
+}
+
+RValue CIRGenFunction::emitCall(clang::QualType calleeTy,
+ const CIRGenCallee &callee,
+ const clang::CallExpr *e) {
+ // Get the actual function type. The callee type will always be a pointer to
+ // function type or a block pointer type.
+ assert(calleeTy->isFunctionPointerType() &&
+ "Callee must have function pointer type!");
+
+ calleeTy = getContext().getCanonicalType(calleeTy);
+
+ if (getLangOpts().CPlusPlus)
+ assert(!cir::MissingFeatures::sanitizers());
+
+ assert(!cir::MissingFeatures::sanitizers());
+ assert(!cir::MissingFeatures::opCallArgs());
+
+ const CIRGenFunctionInfo &funcInfo = cgm.getTypes().arrangeFreeFunctionCall();
+
+ assert(!cir::MissingFeatures::opCallNoPrototypeFunc());
+ assert(!cir::MissingFeatures::opCallChainCall());
+ assert(!cir::MissingFeatures::hip());
+ assert(!cir::MissingFeatures::opCallMustTail());
+
+ cir::CIRCallOpInterface callOp;
+ RValue callResult =
+ emitCall(funcInfo, callee, &callOp, getLoc(e->getExprLoc()));
+
+ assert(!cir::MissingFeatures::generateDebugInfo());
+
+ return callResult;
+}
+
+CIRGenCallee CIRGenFunction::emitCallee(const clang::Expr *e) {
+ e = e->IgnoreParens();
+
+ // Look through function-to-pointer decay.
+ if (const auto *implicitCast = dyn_cast<ImplicitCastExpr>(e)) {
+ if (implicitCast->getCastKind() == CK_FunctionToPointerDecay ||
+ implicitCast->getCastKind() == CK_BuiltinFnToFnPtr) {
+ return emitCallee(implicitCast->getSubExpr());
+ }
+ // Resolve direct calls.
+ } else if (const auto *declRef = dyn_cast<DeclRefExpr>(e)) {
+ const auto *funcDecl = dyn_cast<FunctionDecl>(declRef->getDecl());
+ assert(
+ funcDecl &&
+ "DeclRef referring to FunctionDecl is the only thing supported so far");
+ return emitDirectCallee(cgm, funcDecl);
+ }
+
+ llvm_unreachable("Nothing else supported yet!");
+}
+
+RValue CIRGenFunction::emitCallExpr(const clang::CallExpr *e) {
+ assert(!cir::MissingFeatures::objCBlocks());
+
+ if (isa<CXXMemberCallExpr>(e)) {
+ cgm.errorNYI(e->getSourceRange(), "call to member function");
+ return RValue::get(nullptr);
+ }
+
+ if (isa<CUDAKernelCallExpr>(e)) {
+ cgm.errorNYI(e->getSourceRange(), "call to CUDA kernel");
+ return RValue::get(nullptr);
+ }
+
+ if (const auto *operatorCall = dyn_cast<CXXOperatorCallExpr>(e)) {
+ if (isa_and_nonnull<CXXMethodDecl>(operatorCall->getCalleeDecl())) {
+ cgm.errorNYI(e->getSourceRange(), "call to member operator");
+ return RValue::get(nullptr);
+ }
+ }
+
+ CIRGenCallee callee = emitCallee(e->getCallee());
+
----------------
bcardosolopes wrote:
> We don't like the assert(false) approach apparently.
Do you mean llvm_unrecheable? The way to go about them in upstream is errorNYI
https://github.com/llvm/llvm-project/pull/134673
More information about the cfe-commits
mailing list