diff options
Diffstat (limited to 'clang/lib/CIR/CodeGen/CIRGenModule.cpp')
-rw-r--r-- | clang/lib/CIR/CodeGen/CIRGenModule.cpp | 74 |
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( |