aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CIR/CodeGen/CIRGenModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenModule.cpp')
-rw-r--r--clang/lib/CIR/CodeGen/CIRGenModule.cpp74
1 files changed, 68 insertions, 6 deletions
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index cbecdf9..c1d3265 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "CIRGenModule.h"
+#include "CIRGenFunction.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclBase.h"
@@ -102,19 +103,30 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) {
void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd,
mlir::Operation *op) {
auto const *funcDecl = cast<FunctionDecl>(gd.getDecl());
- if (clang::IdentifierInfo *identifier = funcDecl->getIdentifier()) {
- auto funcOp = builder.create<cir::FuncOp>(
- getLoc(funcDecl->getSourceRange()), identifier->getName());
- theModule.push_back(funcOp);
- } else {
+ if (funcDecl->getIdentifier() == nullptr) {
errorNYI(funcDecl->getSourceRange().getBegin(),
"function definition with a non-identifier for a name");
+ return;
+ }
+ cir::FuncType funcType =
+ cast<cir::FuncType>(convertType(funcDecl->getType()));
+
+ cir::FuncOp funcOp = dyn_cast_if_present<cir::FuncOp>(op);
+ if (!funcOp || funcOp.getFunctionType() != funcType) {
+ funcOp = getAddrOfFunction(gd, funcType, /*ForVTable=*/false,
+ /*DontDefer=*/true, ForDefinition);
+ }
+
+ CIRGenFunction cgf(*this, builder);
+ {
+ mlir::OpBuilder::InsertionGuard guard(builder);
+ cgf.generateCode(gd, funcOp, funcType);
}
}
void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
bool isTentative) {
- mlir::Type type = getTypes().convertType(vd->getType());
+ mlir::Type type = convertType(vd->getType());
if (clang::IdentifierInfo *identifier = vd->getIdentifier()) {
auto varOp = builder.create<cir::GlobalOp>(getLoc(vd->getSourceRange()),
identifier->getName(), type);
@@ -223,6 +235,56 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
}
}
+cir::FuncOp CIRGenModule::getAddrOfFunction(clang::GlobalDecl gd,
+ mlir::Type funcType, bool forVTable,
+ bool dontDefer,
+ ForDefinition_t isForDefinition) {
+ assert(!cast<FunctionDecl>(gd.getDecl())->isConsteval() &&
+ "consteval function should never be emitted");
+
+ if (!funcType) {
+ const auto *fd = cast<FunctionDecl>(gd.getDecl());
+ funcType = convertType(fd->getType());
+ }
+
+ cir::FuncOp func = getOrCreateCIRFunction(
+ cast<NamedDecl>(gd.getDecl())->getIdentifier()->getName(), funcType, gd,
+ forVTable, dontDefer, /*isThunk=*/false, isForDefinition);
+ return func;
+}
+
+cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
+ StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
+ bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
+ mlir::ArrayAttr extraAttrs) {
+ auto *funcDecl = llvm::cast_or_null<FunctionDecl>(gd.getDecl());
+ bool invalidLoc = !funcDecl ||
+ funcDecl->getSourceRange().getBegin().isInvalid() ||
+ funcDecl->getSourceRange().getEnd().isInvalid();
+ cir::FuncOp funcOp = createCIRFunction(
+ invalidLoc ? theModule->getLoc() : getLoc(funcDecl->getSourceRange()),
+ mangledName, mlir::cast<cir::FuncType>(funcType), funcDecl);
+ return funcOp;
+}
+
+cir::FuncOp
+CIRGenModule::createCIRFunction(mlir::Location loc, StringRef name,
+ cir::FuncType funcType,
+ const clang::FunctionDecl *funcDecl) {
+ cir::FuncOp func;
+ {
+ mlir::OpBuilder::InsertionGuard guard(builder);
+
+ func = builder.create<cir::FuncOp>(loc, name, funcType);
+ theModule.push_back(func);
+ }
+ return func;
+}
+
+mlir::Type CIRGenModule::convertType(QualType type) {
+ return genTypes.convertType(type);
+}
+
DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc,
llvm::StringRef feature) {
unsigned diagID = diags.getCustomDiagID(