================ @@ -0,0 +1,128 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// +// Emit Stmt nodes as CIR code. +// +//===----------------------------------------------------------------------===// + +#include "CIRGenBuilder.h" +#include "CIRGenFunction.h" + +#include "mlir/IR/Builders.h" +#include "clang/AST/ExprCXX.h" +#include "clang/AST/Stmt.h" + +using namespace clang; +using namespace clang::CIRGen; +using namespace cir; + +void CIRGenFunction::emitCompoundStmtWithoutScope(const CompoundStmt &s) { + for (auto *curStmt : s.body()) { + if (emitStmt(curStmt, /*useCurrentScope=*/false).failed()) + getCIRGenModule().errorNYI(curStmt->getSourceRange(), "statement"); + } +} + +void CIRGenFunction::emitCompoundStmt(const CompoundStmt &s) { + mlir::Location scopeLoc = getLoc(s.getSourceRange()); + auto scope = builder.create<cir::ScopeOp>( + scopeLoc, [&](mlir::OpBuilder &b, mlir::Type &type, mlir::Location loc) { + emitCompoundStmtWithoutScope(s); + }); + + // This code to insert a cir.yield at the end of the scope is temporary until + // CIRGenFunction::LexicalScope::cleanup() is upstreamed. + if (!scope.getRegion().empty()) { + mlir::Block &lastBlock = scope.getRegion().back(); + if (lastBlock.empty() || !lastBlock.mightHaveTerminator() || + !lastBlock.getTerminator()->hasTrait<mlir::OpTrait::IsTerminator>()) { + builder.setInsertionPointToEnd(&lastBlock); + builder.create<cir::YieldOp>(getLoc(s.getEndLoc())); + } + } +} + +// Build CIR for a statement. useCurrentScope should be true if no new scopes +// need to be created when finding a compound statement. +mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s, + bool useCurrentScope, + ArrayRef<const Attr *> attr) { + if (mlir::succeeded(emitSimpleStmt(s, useCurrentScope))) + return mlir::success(); + + // Only a subset of simple statements are supported at the moment. When more + // kinds of statements are supported, a + // switch (s->getStmtClass()) { + // will be added here. + return mlir::failure(); +} + +mlir::LogicalResult CIRGenFunction::emitSimpleStmt(const Stmt *s, + bool useCurrentScope) { + switch (s->getStmtClass()) { + default: + // Only compound and return statements are supported right now. + return mlir::failure(); + case Stmt::CompoundStmtClass: + if (useCurrentScope) + emitCompoundStmtWithoutScope(cast<CompoundStmt>(*s)); + else + emitCompoundStmt(cast<CompoundStmt>(*s)); + break; + case Stmt::ReturnStmtClass: + return emitReturnStmt(cast<ReturnStmt>(*s)); ---------------- andykaylor wrote:
Why do some `emitXXX()` statements return `LogicalResult` while others are void? https://github.com/llvm/llvm-project/pull/127674 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits