diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenFunction.h')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenFunction.h | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 5a71126..e3b9b6a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -60,11 +60,44 @@ private: /// is where the next operations will be introduced. CIRGenBuilderTy &builder; + /// A jump destination is an abstract label, branching to which may + /// require a jump out through normal cleanups. + struct JumpDest { + JumpDest() = default; + JumpDest(mlir::Block *block, EHScopeStack::stable_iterator depth = {}, + unsigned index = 0) + : block(block) {} + + bool isValid() const { return block != nullptr; } + mlir::Block *getBlock() const { return block; } + EHScopeStack::stable_iterator getScopeDepth() const { return scopeDepth; } + unsigned getDestIndex() const { return index; } + + // This should be used cautiously. + void setScopeDepth(EHScopeStack::stable_iterator depth) { + scopeDepth = depth; + } + + private: + mlir::Block *block = nullptr; + EHScopeStack::stable_iterator scopeDepth; + unsigned index; + }; + public: /// The GlobalDecl for the current function being compiled or the global /// variable currently being initialized. clang::GlobalDecl curGD; + /// Unified return block. + /// In CIR this is a function because each scope might have + /// its associated return block. + JumpDest returnBlock(mlir::Block *retBlock) { + return getJumpDestInCurrentScope(retBlock); + } + + unsigned nextCleanupDestIndex = 1; + /// The compiler-generated variable that holds the return value. std::optional<mlir::Value> fnRetAlloca; @@ -574,6 +607,16 @@ public: } }; + /// The given basic block lies in the current EH scope, but may be a + /// target of a potentially scope-crossing jump; get a stable handle + /// to which we can perform this jump later. + /// CIRGen: this mostly tracks state for figuring out the proper scope + /// information, no actual branches are emitted. + JumpDest getJumpDestInCurrentScope(mlir::Block *target) { + return JumpDest(target, ehStack.getInnermostNormalCleanup(), + nextCleanupDestIndex++); + } + /// Perform the usual unary conversions on the specified expression and /// compare the result against zero, returning an Int1Ty value. mlir::Value evaluateExprAsBool(const clang::Expr *e); @@ -954,6 +997,9 @@ public: LexicalScope *parentScope = nullptr; + // Holds the actual value for ScopeKind::Try + cir::TryOp tryOp = nullptr; + // Only Regular is used at the moment. Support for other kinds will be // added as the relevant statements/expressions are upstreamed. enum Kind { @@ -1013,6 +1059,10 @@ public: void setAsGlobalInit() { scopeKind = Kind::GlobalInit; } void setAsSwitch() { scopeKind = Kind::Switch; } void setAsTernary() { scopeKind = Kind::Ternary; } + void setAsTry(cir::TryOp op) { + scopeKind = Kind::Try; + tryOp = op; + } // Lazy create cleanup block or return what's available. mlir::Block *getOrCreateCleanupBlock(mlir::OpBuilder &builder) { @@ -1022,6 +1072,11 @@ public: return cleanupBlock; } + cir::TryOp getTry() { + assert(isTry()); + return tryOp; + } + mlir::Block *getCleanupBlock(mlir::OpBuilder &builder) { return cleanupBlock; } @@ -1209,6 +1264,8 @@ public: LValue emitBinaryOperatorLValue(const BinaryOperator *e); + cir::BrOp emitBranchThroughCleanup(mlir::Location loc, JumpDest dest); + mlir::LogicalResult emitBreakStmt(const clang::BreakStmt &s); RValue emitBuiltinExpr(const clang::GlobalDecl &gd, unsigned builtinID, @@ -1348,6 +1405,13 @@ public: mlir::LogicalResult emitCXXTryStmt(const clang::CXXTryStmt &s); + mlir::LogicalResult emitCXXTryStmtUnderScope(const clang::CXXTryStmt &s); + + void enterCXXTryStmt(const CXXTryStmt &s, cir::TryOp tryOp, + bool isFnTryBlock = false); + + void exitCXXTryStmt(const CXXTryStmt &s, bool isFnTryBlock = false); + void emitCtorPrologue(const clang::CXXConstructorDecl *ctor, clang::CXXCtorType ctorType, FunctionArgList &args); @@ -1595,6 +1659,10 @@ public: bool buildingTopLevelCase); mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s); + mlir::Value emitTargetBuiltinExpr(unsigned builtinID, + const clang::CallExpr *e, + ReturnValueSlot &returnValue); + /// Given a value and its clang type, returns the value casted to its memory /// representation. /// Note: CIR defers most of the special casting to the final lowering passes @@ -1633,6 +1701,8 @@ public: mlir::LogicalResult emitWhileStmt(const clang::WhileStmt &s); + mlir::Value emitX86BuiltinExpr(unsigned builtinID, const CallExpr *e); + /// Given an assignment `*lhs = rhs`, emit a test that checks if \p rhs is /// nonnull, if 1\p LHS is marked _Nonnull. void emitNullabilityCheck(LValue lhs, mlir::Value rhs, |