[clang] [CIR] Upstream initial function call support (PR #134673)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 7 08:43:53 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Sirui Mu (Lancern)
<details>
<summary>Changes</summary>
This PR upstreams initial support for making function calls in CIR. Function arguments and return values are not included to keep the patch small for review.
Related to #<!-- -->132487
---
Patch is 27.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/134673.diff
17 Files Affected:
- (modified) clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h (+13)
- (modified) clang/include/clang/CIR/Dialect/IR/CIROps.td (+37)
- (modified) clang/include/clang/CIR/Interfaces/CIROpInterfaces.td (+9)
- (modified) clang/include/clang/CIR/MissingFeatures.h (+24)
- (added) clang/lib/CIR/CodeGen/CIRGenCall.cpp (+95)
- (modified) clang/lib/CIR/CodeGen/CIRGenCall.h (+58)
- (modified) clang/lib/CIR/CodeGen/CIRGenExpr.cpp (+97)
- (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+13)
- (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+20)
- (added) clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h (+34)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+12-1)
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.h (+6)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.cpp (+30)
- (modified) clang/lib/CIR/CodeGen/CIRGenTypes.h (+11)
- (modified) clang/lib/CIR/CodeGen/CMakeLists.txt (+1)
- (modified) clang/lib/CIR/Dialect/IR/CIRDialect.cpp (+81)
- (added) clang/test/CIR/CodeGen/call.cpp (+9)
``````````diff
diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
index c1e93fe790c08..dda3ecf492506 100644
--- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
+++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
@@ -201,6 +201,19 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return create<cir::PtrStrideOp>(loc, base.getType(), base, stride);
}
+ //===--------------------------------------------------------------------===//
+ // Call operators
+ //===--------------------------------------------------------------------===//
+
+ cir::CallOp createCallOp(mlir::Location loc, mlir::SymbolRefAttr callee) {
+ auto op = create<cir::CallOp>(loc, callee);
+ return op;
+ }
+
+ cir::CallOp createCallOp(mlir::Location loc, cir::FuncOp callee) {
+ return createCallOp(loc, mlir::SymbolRefAttr::get(callee));
+ }
+
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td
index 609e60ca74b49..aa805ee4108da 100644
--- a/clang/include/clang/CIR/Dialect/IR/CIROps.td
+++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td
@@ -1242,6 +1242,43 @@ def FuncOp : CIR_Op<"func", [
let hasVerifier = 1;
}
+//===----------------------------------------------------------------------===//
+// CallOp
+//===----------------------------------------------------------------------===//
+
+class CIR_CallOp<string mnemonic, list<Trait> extra_traits = []>
+ : Op<CIR_Dialect, mnemonic,
+ !listconcat(extra_traits,
+ [DeclareOpInterfaceMethods<CIRCallOpInterface>,
+ DeclareOpInterfaceMethods<SymbolUserOpInterface>])> {
+ let hasCustomAssemblyFormat = 1;
+ let skipDefaultBuilders = 1;
+ let hasVerifier = 0;
+
+ dag commonArgs = (ins FlatSymbolRefAttr:$callee);
+}
+
+def CallOp : CIR_CallOp<"call", [NoRegionArguments]> {
+ let summary = "call a function";
+ let description = [{
+ The `cir.call` operation represents a direct call to a function that is
+ within the same symbol scope as the call. The callee is encoded as a symbol
+ reference attribute named `callee`.
+
+ Example:
+
+ ```mlir
+ %0 = cir.call @foo()
+ ```
+ }];
+
+ let arguments = commonArgs;
+
+ let builders = [OpBuilder<(ins "mlir::SymbolRefAttr":$callee), [{
+ $_state.addAttribute("callee", callee);
+ }]>];
+}
+
//===----------------------------------------------------------------------===//
// UnreachableOp
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
index 39ef402c59e43..c6c6356118ac6 100644
--- a/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
+++ b/clang/include/clang/CIR/Interfaces/CIROpInterfaces.td
@@ -15,8 +15,17 @@
include "mlir/IR/OpBase.td"
include "mlir/IR/SymbolInterfaces.td"
+include "mlir/Interfaces/CallInterfaces.td"
let cppNamespace = "::cir" in {
+ // The CIRCallOpInterface must be used instead of CallOpInterface when looking
+ // at arguments and other bits of CallOp. This creates a level of abstraction
+ // that's useful for handling indirect calls and other details.
+ def CIRCallOpInterface : OpInterface<"CIRCallOpInterface", []> {
+ // Currently we don't have any methods defined in CIRCallOpInterface. We'll
+ // add more methods as the upstreaming proceeds.
+ }
+
def CIRGlobalValueInterface
: OpInterface<"CIRGlobalValueInterface", [Symbol]> {
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 86fdaf1ddaf51..491fb31c4b7e2 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -72,6 +72,24 @@ struct MissingFeatures {
static bool opFuncLinkage() { return false; }
static bool opFuncVisibility() { return false; }
+ // CallOp handling
+ static bool opCallBuiltinFunc() { return false; }
+ static bool opCallPseudoDtor() { return false; }
+ static bool opCallArgs() { return false; }
+ static bool opCallReturn() { return false; }
+ static bool opCallArgEvaluationOrder() { return false; }
+ static bool opCallCallConv() { return false; }
+ static bool opCallSideEffect() { return false; }
+ static bool opCallChainCall() { return false; }
+ static bool opCallNoPrototypeFunc() { return false; }
+ static bool opCallMustTail() { return false; }
+ static bool opCallIndirect() { return false; }
+ static bool opCallVirtual() { return false; }
+ static bool opCallInAlloca() { return false; }
+ static bool opCallAttrs() { return false; }
+ static bool opCallSurroundingTry() { return false; }
+ static bool opCallASTAttr() { return false; }
+
// ScopeOp handling
static bool opScopeCleanupRegion() { return false; }
@@ -90,7 +108,10 @@ struct MissingFeatures {
static bool opTBAA() { return false; }
static bool opCmp() { return false; }
static bool objCLifetime() { return false; }
+ static bool objCBlocks() { return false; }
static bool emitNullabilityCheck() { return false; }
+ static bool emitLValueAlignmentAssumption() { return false; }
+ static bool emitLifetimeMarkers() { return false; }
static bool astVarDeclInterface() { return false; }
static bool stackSaveOp() { return false; }
static bool aggValueSlot() { return false; }
@@ -108,6 +129,8 @@ struct MissingFeatures {
static bool cgFPOptionsRAII() { return false; }
static bool metaDataNode() { return false; }
static bool fastMathFlags() { return false; }
+ static bool weakRefReference() { return false; }
+ static bool hip() { return false; }
// Missing types
static bool dataMemberType() { return false; }
@@ -127,6 +150,7 @@ struct MissingFeatures {
static bool complexImagOp() { return false; }
static bool complexRealOp() { return false; }
static bool ifOp() { return false; }
+ static bool invokeOp() { return false; }
static bool labelOp() { return false; }
static bool ptrDiffOp() { return false; }
static bool ptrStrideOp() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
new file mode 100644
index 0000000000000..1a936458782ea
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -0,0 +1,95 @@
+//===--- CIRGenCall.cpp - Encapsulate calling convention details ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// These classes wrap the information about a call or function definition used
+// to handle ABI compliancy.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenCall.h"
+#include "CIRGenFunction.h"
+#include "clang/CIR/MissingFeatures.h"
+
+using namespace clang;
+using namespace clang::CIRGen;
+
+CIRGenFunctionInfo *CIRGenFunctionInfo::create() {
+ // For now we just create an empty CIRGenFunctionInfo.
+ CIRGenFunctionInfo *fi = new CIRGenFunctionInfo();
+ return fi;
+}
+
+CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
+ assert(!cir::MissingFeatures::opCallVirtual());
+ return *this;
+}
+
+static const CIRGenFunctionInfo &arrangeFreeFunctionLikeCall(CIRGenTypes &cgt) {
+ assert(!cir::MissingFeatures::opCallArgs());
+ return cgt.arrangeCIRFunctionInfo();
+}
+
+const CIRGenFunctionInfo &CIRGenTypes::arrangeFreeFunctionCall() {
+ return arrangeFreeFunctionLikeCall(*this);
+}
+
+static cir::CIRCallOpInterface emitCallLikeOp(CIRGenFunction &cgf,
+ mlir::Location callLoc,
+ cir::FuncOp directFuncOp) {
+ CIRGenBuilderTy &builder = cgf.getBuilder();
+
+ assert(!cir::MissingFeatures::opCallSurroundingTry());
+ assert(!cir::MissingFeatures::invokeOp());
+
+ assert(builder.getInsertionBlock() && "expected valid basic block");
+ assert(!cir::MissingFeatures::opCallIndirect());
+
+ return builder.createCallOp(callLoc, directFuncOp);
+}
+
+RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
+ const CIRGenCallee &callee,
+ cir::CIRCallOpInterface *callOp,
+ mlir::Location loc) {
+ assert(!cir::MissingFeatures::opCallArgs());
+ assert(!cir::MissingFeatures::emitLifetimeMarkers());
+
+ const CIRGenCallee &concreteCallee = callee.prepareConcreteCallee(*this);
+ mlir::Operation *calleePtr = concreteCallee.getFunctionPointer();
+
+ assert(!cir::MissingFeatures::opCallInAlloca());
+
+ mlir::NamedAttrList attrs;
+ StringRef funcName;
+ if (auto calleeFuncOp = dyn_cast<cir::FuncOp>(calleePtr))
+ funcName = calleeFuncOp.getName();
+
+ assert(!cir::MissingFeatures::opCallCallConv());
+ assert(!cir::MissingFeatures::opCallSideEffect());
+ assert(!cir::MissingFeatures::opCallAttrs());
+
+ assert(!cir::MissingFeatures::invokeOp());
+
+ auto directFuncOp = dyn_cast<cir::FuncOp>(calleePtr);
+ assert(!cir::MissingFeatures::opCallIndirect());
+ assert(!cir::MissingFeatures::opCallAttrs());
+
+ cir::CIRCallOpInterface theCall = emitCallLikeOp(*this, loc, directFuncOp);
+
+ if (callOp)
+ *callOp = theCall;
+
+ assert(!cir::MissingFeatures::opCallMustTail());
+ assert(!cir::MissingFeatures::opCallReturn());
+
+ // For now we just return nothing because we don't have support for return
+ // values yet.
+ RValue ret = RValue::get(nullptr);
+
+ return ret;
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.h b/clang/lib/CIR/CodeGen/CIRGenCall.h
index 0996167feeef6..76fefdca9e45e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.h
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.h
@@ -14,15 +14,73 @@
#ifndef CLANG_LIB_CODEGEN_CIRGENCALL_H
#define CLANG_LIB_CODEGEN_CIRGENCALL_H
+#include "mlir/IR/Operation.h"
#include "clang/AST/GlobalDecl.h"
#include "llvm/ADT/SmallVector.h"
namespace clang::CIRGen {
+class CIRGenFunction;
+
+/// Abstract information about a function or function prototype.
+class CIRGenCalleeInfo {
+ clang::GlobalDecl calleeDecl;
+
+public:
+ explicit CIRGenCalleeInfo() : calleeDecl() {}
+ CIRGenCalleeInfo(clang::GlobalDecl calleeDecl) : calleeDecl(calleeDecl) {}
+};
+
+class CIRGenCallee {
+ enum class SpecialKind : uintptr_t {
+ Invalid,
+
+ Last = Invalid,
+ };
+
+ SpecialKind kindOrFunctionPtr;
+
+ union {
+ CIRGenCalleeInfo abstractInfo;
+ };
+
+public:
+ CIRGenCallee() : kindOrFunctionPtr(SpecialKind::Invalid) {}
+
+ CIRGenCallee(const CIRGenCalleeInfo &abstractInfo, mlir::Operation *funcPtr)
+ : kindOrFunctionPtr(SpecialKind(reinterpret_cast<uintptr_t>(funcPtr))),
+ abstractInfo(abstractInfo) {
+ assert(funcPtr && "configuring callee without function pointer");
+ }
+
+ static CIRGenCallee
+ forDirect(mlir::Operation *funcPtr,
+ const CIRGenCalleeInfo &abstractInfo = CIRGenCalleeInfo()) {
+ return CIRGenCallee(abstractInfo, funcPtr);
+ }
+
+ bool isOrdinary() const {
+ return uintptr_t(kindOrFunctionPtr) > uintptr_t(SpecialKind::Last);
+ }
+
+ /// If this is a delayed callee computation of some sort, prepare a concrete
+ /// callee
+ CIRGenCallee prepareConcreteCallee(CIRGenFunction &cgf) const;
+
+ mlir::Operation *getFunctionPointer() const {
+ assert(isOrdinary());
+ return reinterpret_cast<mlir::Operation *>(kindOrFunctionPtr);
+ }
+};
+
/// Type for representing both the decl and type of parameters to a function.
/// The decl must be either a ParmVarDecl or ImplicitParamDecl.
class FunctionArgList : public llvm::SmallVector<const clang::VarDecl *, 16> {};
+struct CallArg {};
+
+class CallArgList : public llvm::SmallVector<CallArg, 8> {};
+
} // namespace clang::CIRGen
#endif // CLANG_LIB_CODEGEN_CIRGENCALL_H
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index f01e03a89981d..1e5fb985b0b8c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/CharUnits.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/MissingFeatures.h"
@@ -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());
+
+ assert(!cir::MissingFeatures::opCallBuiltinFunc());
+ assert(!cir::MissingFeatures::opCallPseudoDtor());
+
+ return emitCall(e->getCallee()->getType(), callee, e);
+}
+
/// Emit code to compute the specified expression, ignoring the result.
void CIRGenFunction::emitIgnoredExpr(const Expr *e) {
if (e->isPRValue()) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 3863d21487531..ca6f35e0f7319 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -156,6 +156,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
}
mlir::Value VisitCastExpr(CastExpr *e);
+ mlir::Value VisitCallExpr(const CallExpr *e);
mlir::Value VisitExplicitCastExpr(ExplicitCastExpr *e) {
return VisitCastExpr(e);
@@ -1345,6 +1346,18 @@ mlir::Value ScalarExprEmitter::VisitCastExpr(CastExpr *ce) {
return {};
}
+mlir::Value ScalarExprEmitter::VisitCallExpr(const CallExpr *e) {
+ if (e->getCallReturnType(cgf.getContext())->isReferenceType()) {
+ cgf.getCIRGenModule().errorNYI(
+ e->getSourceRange(), "call to function with non-void return type");
+ return {};
+ }
+
+ auto v = cgf.emitCallExpr(e).getScalarVal();
+ assert(!cir::MissingFeatures::emitLValueAlignmentAssumption());
+ return v;
+}
+
mlir::Value CIRGenFunction::emitScalarConversion(mlir::Value src,
QualType srcTy, QualType dstTy,
SourceLocation loc) {
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 1bedbe28ae625..1a0ab51c759f5 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -403,6 +403,26 @@ class CIRGenFunction : public CIRGenTypeCache {
mlir::LogicalResult emitContinueStmt(const clang::ContinueStmt &s);
mlir::LogicalResult emitDoStmt(const clang::DoStmt &s);
+ /// An abstract representation of regular/ObjC call/message targets.
+ class AbstractCallee {
+ /// The function declaration of the callee.
+ const clang::Decl *calleeDecl;
+
+ public:
+ AbstractCallee() : calleeDecl(nullptr) {}
+ AbstractCallee(const clang::FunctionDecl *fd) : calleeDecl(fd) {}
+ };
+
+ RValue emitCall(const CIRGenFunctionInfo &funcInfo,
+ const CIRGenCallee &callee, cir::CIRCallOpInterface *callOp,
+ mlir::Location loc);
+ RValue emitCall(clang::QualType calleeTy, const CIRGenCallee &callee,
+ const clang::CallExpr *e);
+
+ CIRGenCallee emitCallee(const clang::Expr *e);
+
+ RValue emitCallExpr(const clang::CallExpr *e);
+
/// Emit an expression as an initializer for an object (variable, field, etc.)
/// at the given location. The expression is not necessarily the normal
/// initializer for the object, and the address is not necessarily
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
new file mode 100644
index 0000000000000..37191ee300eda
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenFunctionInfo.h
@@ -0,0 +1,34 @@
+//==-- CIRGenFunctionInfo.h - Representation of fn argument/return types ---==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines CIRGenFunctionInfo and associated types used in representing the
+// CIR source types and ABI-coerced types for function arguments and
+// return values.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H
+#define LLVM_CLANG_CIR_CIRGENFUNCTIONINFO_H
+
+#include "llvm/ADT/FoldingSet.h"
+
+namespace clang::CIRGen {
+
+class CIRGenFunctionInfo final : public llvm::FoldingSetNode {
+public:
+ static CIRGenFunctionInfo *create();
+
+ // NOLINTNEXTLINE(readability-identifier-naming)
+ static void Profile(llvm::FoldingSetNodeID &id) {
+ // We don't have anything to profile yet.
+ }
+};
+
+} // namespace clang::CIRGen
+
+#endif
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index d3b3b0632c2f0..a07a1e3d52e2c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/134673
More information about the cfe-commits
mailing list