Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 0 additions & 19 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,25 +389,6 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return createCallOp(loc, callee, cir::VoidType(), operands, attrs);
}

cir::CallOp createTryCallOp(
mlir::Location loc, mlir::SymbolRefAttr callee = mlir::SymbolRefAttr(),
mlir::Type returnType = cir::VoidType(),
mlir::ValueRange operands = mlir::ValueRange(),
[[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) {
assert(!cir::MissingFeatures::opCallCallConv());
assert(!cir::MissingFeatures::opCallSideEffect());
return createCallOp(loc, callee, returnType, operands);
}

cir::CallOp createTryCallOp(
mlir::Location loc, cir::FuncOp callee, mlir::ValueRange operands,
[[maybe_unused]] cir::SideEffect sideEffect = cir::SideEffect::All) {
assert(!cir::MissingFeatures::opCallCallConv());
assert(!cir::MissingFeatures::opCallSideEffect());
return createTryCallOp(loc, mlir::SymbolRefAttr::get(callee),
callee.getFunctionType().getReturnType(), operands);
}

//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct MissingFeatures {
static bool opFuncNoReturn() { return false; }
static bool setFunctionAttributes() { return false; }
static bool setLLVMFunctionFEnvAttributes() { return false; }
static bool setFunctionPersonality() { return false; }

// CallOp handling
static bool opCallAggregateArgs() { return false; }
Expand Down Expand Up @@ -339,7 +340,6 @@ struct MissingFeatures {
static bool awaitOp() { return false; }
static bool callOp() { return false; }
static bool ifOp() { return false; }
static bool invokeOp() { return false; }
static bool labelOp() { return false; }
static bool ptrDiffOp() { return false; }
static bool llvmLoweringPtrDiffConsidersPointee() { return false; }
Expand Down
49 changes: 44 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,12 +465,47 @@ static cir::CIRCallOpInterface
emitCallLikeOp(CIRGenFunction &cgf, mlir::Location callLoc,
cir::FuncType indirectFuncTy, mlir::Value indirectFuncVal,
cir::FuncOp directFuncOp,
const SmallVectorImpl<mlir::Value> &cirCallArgs,
const SmallVectorImpl<mlir::Value> &cirCallArgs, bool isInvoke,
const mlir::NamedAttrList &attrs) {
CIRGenBuilderTy &builder = cgf.getBuilder();

assert(!cir::MissingFeatures::opCallSurroundingTry());
assert(!cir::MissingFeatures::invokeOp());

if (isInvoke) {
// This call may throw and requires catch and/or cleanup handling.
// If this call does not appear within the `try` region of an existing
// TryOp, we must create a synthetic TryOp to contain the call. This
// happens when a call that may throw appears within a cleanup
// scope.

// In OG, we build the landing pad for this scope. In CIR, we emit a
// synthetic cir.try because this didn't come from code generating from a
// try/catch in C++.
assert(cgf.curLexScope && "expected scope");
cir::TryOp tryOp = cgf.curLexScope->getClosestTryParent();
if (!tryOp) {
cgf.cgm.errorNYI(
"emitCallLikeOp: call does not have an associated cir.try");
return {};
}

if (tryOp.getSynthetic()) {
cgf.cgm.errorNYI("emitCallLikeOp: tryOp synthetic");
return {};
}

cir::CallOp callOpWithExceptions;
if (indirectFuncTy) {
cgf.cgm.errorNYI("emitCallLikeOp: indirect function type");
return {};
}

callOpWithExceptions =
builder.createCallOp(callLoc, directFuncOp, cirCallArgs);

cgf.populateCatchHandlersIfRequired(tryOp);
return callOpWithExceptions;
}

assert(builder.getInsertionBlock() && "expected valid basic block");

Expand Down Expand Up @@ -601,8 +636,6 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
assert(!cir::MissingFeatures::opCallAttrs());
cgm.constructAttributeList(callee.getAbstractInfo(), attrs);

assert(!cir::MissingFeatures::invokeOp());

cir::FuncType indirectFuncTy;
mlir::Value indirectFuncVal;
cir::FuncOp directFuncOp;
Expand All @@ -628,10 +661,16 @@ RValue CIRGenFunction::emitCall(const CIRGenFunctionInfo &funcInfo,
indirectFuncVal = calleePtr->getResult(0);
}

// TODO(cir): currentFunctionUsesSEHTry
// TODO(cir): check for MSVCXXPersonality
// TODO(cir): Create NoThrowAttr
bool cannotThrow = attrs.getNamed("nothrow").has_value();
bool isInvoke = !cannotThrow && isCatchOrCleanupRequired();

mlir::Location callLoc = loc;
cir::CIRCallOpInterface theCall =
emitCallLikeOp(*this, loc, indirectFuncTy, indirectFuncVal, directFuncOp,
cirCallArgs, attrs);
cirCallArgs, isInvoke, attrs);

if (callOp)
*callOp = theCall;
Expand Down
10 changes: 9 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenCleanup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,17 @@ void EHScopeStack::popCleanup() {
}
}

bool EHScopeStack::requiresCatchOrCleanup() const {
for (stable_iterator si = getInnermostEHScope(); si != stable_end();) {
// TODO(cir): Skip lifetime markers.
assert(!cir::MissingFeatures::emitLifetimeMarkers());
return true;
}
return false;
}

EHCatchScope *EHScopeStack::pushCatch(unsigned numHandlers) {
char *buffer = allocate(EHCatchScope::getSizeForNumHandlers(numHandlers));
assert(!cir::MissingFeatures::innermostEHScope());
EHCatchScope *scope =
new (buffer) EHCatchScope(numHandlers, innermostEHScope);
innermostEHScope = stable_begin();
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenCleanup.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class EHScope {
};
enum { NumCommonBits = 3 };

bool scopeMayThrow;

protected:
class CatchBitFields {
friend class EHCatchScope;
Expand Down Expand Up @@ -92,10 +94,11 @@ class EHScope {
// Traditional LLVM codegen also checks for `!block->use_empty()`, but
// in CIRGen the block content is not important, just used as a way to
// signal `hasEHBranches`.
assert(!cir::MissingFeatures::ehstackBranches());
return false;
return scopeMayThrow;
}

void setMayThrow(bool mayThrow) { scopeMayThrow = mayThrow; }

EHScopeStack::stable_iterator getEnclosingEHScope() const {
return enclosingEHScope;
}
Expand Down
Loading