summaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenCall.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenCall.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenCall.cpp52
1 files changed, 39 insertions, 13 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenCall.cpp b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
index 9c9c96604c16..938d1436a76e 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCall.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCall.cpp
@@ -77,17 +77,40 @@ void CIRGenFunction::emitAggregateStore(mlir::Value value, Address dest) {
builder.createStore(*currSrcLoc, value, dest);
}
+static void addAttributesFromFunctionProtoType(CIRGenBuilderTy &builder,
+ mlir::NamedAttrList &attrs,
+ const FunctionProtoType *fpt) {
+ if (!fpt)
+ return;
+
+ if (!isUnresolvedExceptionSpec(fpt->getExceptionSpecType()) &&
+ fpt->isNothrow())
+ attrs.set(cir::CIRDialect::getNoThrowAttrName(),
+ mlir::UnitAttr::get(builder.getContext()));
+}
+
/// Construct the CIR attribute list of a function or call.
void CIRGenModule::constructAttributeList(CIRGenCalleeInfo calleeInfo,
- cir::SideEffect &sideEffect) {
+ mlir::NamedAttrList &attrs) {
assert(!cir::MissingFeatures::opCallCallConv());
- sideEffect = cir::SideEffect::All;
+ auto sideEffect = cir::SideEffect::All;
- assert(!cir::MissingFeatures::opCallAttrs());
+ addAttributesFromFunctionProtoType(getBuilder(), attrs,
+ calleeInfo.getCalleeFunctionProtoType());
const Decl *targetDecl = calleeInfo.getCalleeDecl().getDecl();
if (targetDecl) {
+ if (targetDecl->hasAttr<NoThrowAttr>())
+ attrs.set(cir::CIRDialect::getNoThrowAttrName(),
+ mlir::UnitAttr::get(&getMLIRContext()));
+
+ if (const FunctionDecl *func = dyn_cast<FunctionDecl>(targetDecl)) {
+ addAttributesFromFunctionProtoType(
+ getBuilder(), attrs, func->getType()->getAs<FunctionProtoType>());
+ assert(!cir::MissingFeatures::opCallAttrs());
+ }
+
assert(!cir::MissingFeatures::opCallAttrs());
// 'const', 'pure' and 'noalias' attributed functions are also nounwind.
@@ -104,6 +127,9 @@ void CIRGenModule::constructAttributeList(CIRGenCalleeInfo calleeInfo,
}
assert(!cir::MissingFeatures::opCallAttrs());
+
+ attrs.set(cir::CIRDialect::getSideEffectAttrName(),
+ cir::SideEffectAttr::get(&getMLIRContext(), sideEffect));
}
/// Returns the canonical formal type of the given C++ method.
@@ -404,7 +430,7 @@ CIRGenTypes::arrangeFunctionDeclaration(const FunctionDecl *fd) {
funcTy.getAs<FunctionNoProtoType>()) {
assert(!cir::MissingFeatures::opCallCIRGenFuncInfoExtParamInfo());
assert(!cir::MissingFeatures::opCallFnInfoOpts());
- return arrangeCIRFunctionInfo(noProto->getReturnType(), std::nullopt,
+ return arrangeCIRFunctionInfo(noProto->getReturnType(), {},
RequiredArgs::All);
}
@@ -416,7 +442,7 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal,
cir::FuncOp directFuncOp,
const SmallVectorImpl<mlir::Value> &cirCallArgs,
- cir::SideEffect sideEffect) {
+ const mlir::NamedAttrList &attrs) {
CIRGenBuilderTy &builder = cgf.getBuilder();
assert(!cir::MissingFeatures::opCallSurroundingTry());
@@ -424,14 +450,17 @@ emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
assert(builder.getInsertionBlock() && "expected valid basic block");
+ cir::CallOp op;
if (indirectFuncTy) {
// TODO(cir): Set calling convention for indirect calls.
assert(!cir::MissingFeatures::opCallCallConv());
- return builder.createIndirectCallOp(
- callLoc, indirectFuncVal, indirectFuncTy, cirCallArgs, sideEffect);
+ op = builder.createIndirectCallOp(callLoc, indirectFuncVal, indirectFuncTy,
+ cirCallArgs, attrs);
+ } else {
+ op = builder.createCallOp(callLoc, directFuncOp, cirCallArgs, attrs);
}
- return builder.createCallOp(callLoc, directFuncOp, cirCallArgs, sideEffect);
+ return op;
}
const CIRGenFunctionInfo &
@@ -544,8 +573,7 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
assert(!cir::MissingFeatures::opCallCallConv());
assert(!cir::MissingFeatures::opCallAttrs());
- cir::SideEffect sideEffect;
- cgm.constructAttributeList(callee.getAbstractInfo(), sideEffect);
+ cgm.constructAttributeList(callee.getAbstractInfo(), attrs);
assert(!cir::MissingFeatures::invokeOp());
@@ -566,12 +594,10 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
indirectFuncVal = calleePtr->getResult(0);
}
- assert(!cir::MissingFeatures::opCallAttrs());
-
mlir::Location callLoc = loc;
cir::CIRCallOpInterface theCall =
emitCallLikeOp(*this, loc, indirectFuncTy, indirectFuncVal, directFuncOp,
- cirCallArgs, sideEffect);
+ cirCallArgs, attrs);
if (callOp)
*callOp = theCall;