[clang] [CIR] Call code gen; create empty cir.func op (PR #113483)

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 31 12:09:34 PDT 2024


================
@@ -24,9 +27,140 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &context,
                            clang::ASTContext &astctx,
                            const clang::CodeGenOptions &cgo,
                            DiagnosticsEngine &diags)
-    : astCtx(astctx), langOpts(astctx.getLangOpts()),
-      theModule{mlir::ModuleOp::create(mlir::UnknownLoc())},
-      target(astCtx.getTargetInfo()) {}
+    : builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()),
+      theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))},
+      diags(diags), target(astCtx.getTargetInfo()) {}
+
+mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) {
+  assert(cLoc.isValid() && "expected valid source location");
+  const SourceManager &sm = astCtx.getSourceManager();
+  PresumedLoc pLoc = sm.getPresumedLoc(cLoc);
+  StringRef filename = pLoc.getFilename();
+  return mlir::FileLineColLoc::get(builder.getStringAttr(filename),
+                                   pLoc.getLine(), pLoc.getColumn());
+}
+
+mlir::Location CIRGenModule::getLoc(SourceRange cRange) {
+  assert(cRange.isValid() && "expected a valid source range");
+  mlir::Location begin = getLoc(cRange.getBegin());
+  mlir::Location end = getLoc(cRange.getEnd());
+  SmallVector<mlir::Location, 2> locs = {begin, end};
+  mlir::Attribute metadata;
+  return mlir::FusedLoc::get(locs, metadata, builder.getContext());
+}
+
+void CIRGenModule::buildGlobal(clang::GlobalDecl gd) {
+  const auto *global = cast<ValueDecl>(gd.getDecl());
+
+  if (const auto *fd = dyn_cast<FunctionDecl>(global)) {
+    // Update deferred annotations with the latest declaration if the function
+    // was already used or defined.
+    if (fd->hasAttr<AnnotateAttr>()) {
+      errorNYI(fd->getSourceRange(), "defferedAnnotations");
+    }
+    if (!fd->doesThisDeclarationHaveABody()) {
+      if (!fd->doesDeclarationForceExternallyVisibleDefinition())
+        return;
+
+      errorNYI(fd->getSourceRange(),
+               "function declaration that forces code gen");
+      return;
+    }
+  } else {
+    errorNYI(global->getSourceRange(), "global variable declaration");
+  }
+
+  // TODO(CIR): Defer emitting some global definitions until later
+  buildGlobalDefinition(gd);
+}
+
+void CIRGenModule::buildGlobalFunctionDefinition(clang::GlobalDecl gd,
+                                                 mlir::Operation *op) {
+  auto const *funcDecl = cast<FunctionDecl>(gd.getDecl());
+  auto funcOp = builder.create<mlir::cir::FuncOp>(
+      getLoc(funcDecl->getSourceRange()), funcDecl->getIdentifier()->getName());
+  theModule.push_back(funcOp);
+}
+
+void CIRGenModule::buildGlobalDefinition(clang::GlobalDecl gd,
+                                         mlir::Operation *op) {
+  const auto *decl = cast<ValueDecl>(gd.getDecl());
+  if (const auto *fd = dyn_cast<FunctionDecl>(decl)) {
+    // TODO(CIR): Skip generation of CIR for functions with available_externally
+    // linkage at -O0.
+
+    if (const auto *method = dyn_cast<CXXMethodDecl>(decl)) {
+      // Make sure to emit the definition(s) before we emit the thunks. This is
+      // necessary for the generation of certain thunks.
+      (void)method;
+      errorNYI(method->getSourceRange(), "member function");
+      return;
+    }
+
+    if (fd->isMultiVersion())
+      errorNYI(fd->getSourceRange(), "multiversion functions");
+    buildGlobalFunctionDefinition(gd, op);
+    return;
+  }
+
+  llvm_unreachable("Invalid argument to CIRGenModule::buildGlobalDefinition");
+}
 
 // Emit code for a single top level declaration.
-void CIRGenModule::buildTopLevelDecl(Decl *decl) {}
+void CIRGenModule::buildTopLevelDecl(Decl *decl) {
+
+  // Ignore dependent declarations.
+  if (decl->isTemplated())
+    return;
+
+  switch (decl->getKind()) {
+  default:
+    errorNYI(decl->getBeginLoc(), "declaration of kind",
+             decl->getDeclKindName());
+    break;
+
+  case Decl::Function: {
+    auto *fd = cast<FunctionDecl>(decl);
+    // Consteval functions shouldn't be emitted.
+    if (!fd->isConsteval())
+      buildGlobal(fd);
+    break;
+  }
+  }
+}
+
+DiagnosticBuilder CIRGenModule::errorNYI(llvm::StringRef feature) {
+  unsigned diagID = diags.getCustomDiagID(DiagnosticsEngine::Error,
+                                          "ClangIR code gen NYI: %0");
----------------
erichkeane wrote:

```suggestion
                                          "ClangIR code gen Not Yet Implemented: %0");
```

Same for the rest here, I'd prefer we are better about this for user/early adopter readability.

https://github.com/llvm/llvm-project/pull/113483


More information about the cfe-commits mailing list