[clang] [CIR] Route MLIR diagnostics through clang::DiagnosticsEngine (PR #199297)
Konstantinos Parasyris via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 23 11:53:31 PDT 2026
https://github.com/koparasy updated https://github.com/llvm/llvm-project/pull/199297
>From 9e44a5d9e20cd27ca3e98ac72d7a62930d848a78 Mon Sep 17 00:00:00 2001
From: y <konstantinos.parasyris at intel.com>
Date: Fri, 22 May 2026 16:09:18 -0700
Subject: [PATCH 1/4] [CIR] Route MLIR diagnostics through
clang::DiagnosticsEngine
Install a scoped MLIR diagnostic handler on the CIRGenerator's
MLIRContext that translates mlir::Diagnostic severity and location to
clang diag IDs and SourceLocation, so CIR pass / verifier / lowering
errors surface in clang's standard format and respect -W/-R flags.
Disable MLIR multithreading on that context (DiagnosticsEngine is not
thread-safe). Gate the generic CIR-to-CIR fallback errors on
hasErrorOccurred() to avoid double-printing alongside specific routed
diagnostics.
LLVM-side opt/codegen diagnostics are out of scope and
will be addressed by sharing BackendConsumer in a follow-up.
---
.../clang/Basic/DiagnosticFrontendKinds.td | 7 +
clang/include/clang/Basic/DiagnosticGroups.td | 4 +
clang/lib/CIR/CodeGen/CIRGenerator.cpp | 5 +
.../FrontendAction/CIRDiagnosticHandler.cpp | 94 +++++++
.../CIR/FrontendAction/CIRDiagnosticHandler.h | 54 ++++
clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 20 +-
clang/lib/CIR/FrontendAction/CMakeLists.txt | 1 +
.../CIR/Diagnostics/mlir-error-routing.cu | 20 ++
.../CIR/CIRDiagnosticHandlerTest.cpp | 247 ++++++++++++++++++
clang/unittests/CIR/CMakeLists.txt | 3 +
10 files changed, 452 insertions(+), 3 deletions(-)
create mode 100644 clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
create mode 100644 clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.h
create mode 100644 clang/test/CIR/Diagnostics/mlir-error-routing.cu
create mode 100644 clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index b585f0d3fa9a9..3b7d9a1d56c1b 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -519,4 +519,11 @@ def err_cir_to_cir_transform_failed : Error<
def err_cir_verification_failed_pre_passes : Error<
"CIR module verification error before running CIR-to-CIR passes">,
DefaultFatal;
+
+// Diagnostics relayed from MLIR-side passes/verifier through the
+// clang::DiagnosticsEngine. The full message text comes from MLIR.
+def err_cir_mlir_diagnostic : Error<"%0">;
+def warn_cir_mlir_diagnostic : Warning<"%0">, InGroup<ClangIR>;
+def remark_cir_mlir_diagnostic : Remark<"%0">, InGroup<RemarkClangIR>;
+def note_cir_mlir_diagnostic : Note<"%0">;
}
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 8031f99419bdc..92fcda5ec6d6a 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1728,6 +1728,10 @@ def OpenMP : DiagGroup<"openmp", [
def SourceUsesOpenACC : DiagGroup<"source-uses-openacc">;
def OpenACC : DiagGroup<"openacc", [SourceUsesOpenACC]>;
+// ClangIR (CIR) warnings emitted by MLIR-side passes routed through clang.
+def ClangIR : DiagGroup<"clangir">;
+def RemarkClangIR : DiagGroup<"remark-clangir">;
+
// Backend warnings.
def BackendInlineAsm : DiagGroup<"inline-asm">;
def BackendSourceMgr : DiagGroup<"source-mgr">;
diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
index 31d40c21ef6e1..3b4700d2ed38b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
@@ -52,6 +52,11 @@ void CIRGenerator::Initialize(ASTContext &astContext) {
this->astContext = &astContext;
mlirContext = std::make_unique<mlir::MLIRContext>();
+ // Disable MLIR multithreading: clang::DiagnosticsEngine is not thread-safe,
+ // and the per-context handler installed by CIRGenAction reports diagnostics
+ // straight through it. CIR's pass pipeline is short enough that we don't
+ // miss meaningful parallelism here.
+ mlirContext->disableMultithreading();
mlirContext->loadDialect<mlir::DLTIDialect>();
mlirContext->loadDialect<cir::CIRDialect>();
mlirContext->getOrLoadDialect<mlir::acc::OpenACCDialect>();
diff --git a/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
new file mode 100644
index 0000000000000..7c42f69661788
--- /dev/null
+++ b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
@@ -0,0 +1,94 @@
+//===--- CIRDiagnosticHandler.cpp - Route MLIR diags to clang ---------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRDiagnosticHandler.h"
+
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/Location.h"
+#include "mlir/IR/MLIRContext.h"
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+
+namespace cir {
+
+CIRDiagnosticHandler::CIRDiagnosticHandler(
+ mlir::MLIRContext *ctx, clang::DiagnosticsEngine &diags,
+ clang::SourceManager &srcMgr, clang::FileManager &fileMgr)
+ : mlir::ScopedDiagnosticHandler(ctx), Diags(diags), SrcMgr(srcMgr),
+ FileMgr(fileMgr) {
+ setHandler([this](mlir::Diagnostic &D) { return handle(D); });
+}
+
+clang::SourceLocation
+CIRDiagnosticHandler::translateLoc(mlir::Location loc) {
+ // Walk common location wrappers to reach a usable file/line/column triple.
+ // Anything we can't translate becomes an invalid SourceLocation, which the
+ // diagnostics engine renders without a source line.
+ if (auto file = mlir::dyn_cast<mlir::FileLineColLoc>(loc)) {
+ // SourceManager::translateFileLineCol requires 1-based line/column.
+ // Module-level locations carry (0, 0); fall through unattached.
+ if (file.getLine() == 0 || file.getColumn() == 0)
+ return clang::SourceLocation();
+ auto fileRef = FileMgr.getOptionalFileRef(file.getFilename().getValue());
+ if (!fileRef)
+ return clang::SourceLocation();
+ return SrcMgr.translateFileLineCol(&fileRef->getFileEntry(),
+ file.getLine(), file.getColumn());
+ }
+ if (auto fused = mlir::dyn_cast<mlir::FusedLoc>(loc)) {
+ for (mlir::Location child : fused.getLocations()) {
+ clang::SourceLocation translated = translateLoc(child);
+ if (translated.isValid())
+ return translated;
+ }
+ return clang::SourceLocation();
+ }
+ if (auto callsite = mlir::dyn_cast<mlir::CallSiteLoc>(loc))
+ return translateLoc(callsite.getCallee());
+ if (auto named = mlir::dyn_cast<mlir::NameLoc>(loc))
+ return translateLoc(named.getChildLoc());
+ // OpaqueLoc / UnknownLoc and anything else fall through unattached.
+ return clang::SourceLocation();
+}
+
+void CIRDiagnosticHandler::emit(mlir::Diagnostic &diag, bool isNote) {
+ unsigned diagID;
+ if (isNote) {
+ diagID = clang::diag::note_cir_mlir_diagnostic;
+ } else {
+ switch (diag.getSeverity()) {
+ case mlir::DiagnosticSeverity::Error:
+ diagID = clang::diag::err_cir_mlir_diagnostic;
+ break;
+ case mlir::DiagnosticSeverity::Warning:
+ diagID = clang::diag::warn_cir_mlir_diagnostic;
+ break;
+ case mlir::DiagnosticSeverity::Remark:
+ diagID = clang::diag::remark_cir_mlir_diagnostic;
+ break;
+ case mlir::DiagnosticSeverity::Note:
+ diagID = clang::diag::note_cir_mlir_diagnostic;
+ break;
+ }
+ }
+ Diags.Report(translateLoc(diag.getLocation()), diagID) << diag.str();
+}
+
+mlir::LogicalResult CIRDiagnosticHandler::handle(mlir::Diagnostic &diag) {
+ emit(diag, /*isNote=*/false);
+ for (mlir::Diagnostic ¬e : diag.getNotes())
+ emit(note, /*isNote=*/true);
+ return mlir::success();
+}
+
+} // namespace cir
diff --git a/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.h b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.h
new file mode 100644
index 0000000000000..6a2e99125b62d
--- /dev/null
+++ b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.h
@@ -0,0 +1,54 @@
+//===--- CIRDiagnosticHandler.h - Route MLIR diags to clang ----*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_LIB_CIR_FRONTENDACTION_CIRDIAGNOSTICHANDLER_H
+#define CLANG_LIB_CIR_FRONTENDACTION_CIRDIAGNOSTICHANDLER_H
+
+#include "mlir/IR/Diagnostics.h"
+
+namespace clang {
+class DiagnosticsEngine;
+class FileManager;
+class SourceLocation;
+class SourceManager;
+} // namespace clang
+
+namespace mlir {
+class Location;
+class MLIRContext;
+} // namespace mlir
+
+namespace cir {
+
+/// Routes MLIR-side diagnostics emitted during CIR passes, the verifier, and
+/// CIR-to-LLVM lowering through the surrounding clang::DiagnosticsEngine.
+///
+/// MLIR locations carrying file/line/column info are translated to a
+/// clang::SourceLocation via the active SourceManager + FileManager so errors
+/// surface in the user's preferred format. Locations that cannot be translated
+/// fall back to an invalid clang::SourceLocation.
+class CIRDiagnosticHandler : public mlir::ScopedDiagnosticHandler {
+public:
+ CIRDiagnosticHandler(mlir::MLIRContext *ctx,
+ clang::DiagnosticsEngine &diags,
+ clang::SourceManager &srcMgr,
+ clang::FileManager &fileMgr);
+
+private:
+ mlir::LogicalResult handle(mlir::Diagnostic &diag);
+ void emit(mlir::Diagnostic &diag, bool isNote);
+ clang::SourceLocation translateLoc(mlir::Location loc);
+
+ clang::DiagnosticsEngine &Diags;
+ clang::SourceManager &SrcMgr;
+ clang::FileManager &FileMgr;
+};
+
+} // namespace cir
+
+#endif // CLANG_LIB_CIR_FRONTENDACTION_CIRDIAGNOSTICHANDLER_H
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index fccd270a95ccd..d43db7a5e7e27 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "clang/CIR/FrontendAction/CIRGenAction.h"
+#include "CIRDiagnosticHandler.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OwningOpRef.h"
#include "clang/Basic/DiagnosticFrontend.h"
@@ -82,6 +83,8 @@ class CIRGenConsumer : public clang::ASTConsumer {
llvm::LLVMContext &LLVMCtx;
SmallVectorImpl<::clang::LinkModule> &LinkModules;
+ std::optional<CIRDiagnosticHandler> MLIRDiagHandler;
+
public:
CIRGenConsumer(CIRGenAction::OutputType Action, CompilerInstance &CI,
CodeGenOptions &CGO, std::unique_ptr<raw_pwrite_stream> OS,
@@ -98,6 +101,11 @@ class CIRGenConsumer : public clang::ASTConsumer {
assert(!Context && "initialized multiple times");
Context = &Ctx;
Gen->Initialize(Ctx);
+ // Install the MLIR diagnostic handler now that CIRGenerator owns its
+ // MLIRContext. Lifetime is tied to this consumer, which spans CIRGen,
+ // CIR-to-CIR passes, and CIR-to-LLVM lowering.
+ MLIRDiagHandler.emplace(&Gen->getMLIRContext(), CI.getDiagnostics(),
+ CI.getSourceManager(), CI.getFileManager());
}
bool HandleTopLevelDecl(DeclGroupRef D) override {
@@ -123,8 +131,11 @@ class CIRGenConsumer : public clang::ASTConsumer {
if (!FEOptions.ClangIRDisableCIRVerifier) {
if (!Gen->verifyModule()) {
- CI.getDiagnostics().Report(
- diag::err_cir_verification_failed_pre_passes);
+ // Verifier output already routed through ClangIRDiagnosticHandler.
+ // Only emit the generic fatal if nothing more specific was reported.
+ if (!CI.getDiagnostics().hasErrorOccurred())
+ CI.getDiagnostics().Report(
+ diag::err_cir_verification_failed_pre_passes);
llvm::report_fatal_error(
"CIR codegen: module verification error before running CIR passes");
return;
@@ -140,7 +151,10 @@ class CIRGenConsumer : public clang::ASTConsumer {
MlirModule, MlirCtx, C, !FEOptions.ClangIRDisableCIRVerifier,
FEOptions.ClangIREnableIdiomRecognizer, CGO.OptimizationLevel > 0)
.failed()) {
- CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
+ // Pass-side errors already routed through ClangIRDiagnosticHandler.
+ // Skip the generic catch-all if a specific diagnostic was emitted.
+ if (!CI.getDiagnostics().hasErrorOccurred())
+ CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
return;
}
}
diff --git a/clang/lib/CIR/FrontendAction/CMakeLists.txt b/clang/lib/CIR/FrontendAction/CMakeLists.txt
index b2d2fc1621693..9577a907c9334 100644
--- a/clang/lib/CIR/FrontendAction/CMakeLists.txt
+++ b/clang/lib/CIR/FrontendAction/CMakeLists.txt
@@ -9,6 +9,7 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
add_clang_library(clangCIRFrontendAction
CIRGenAction.cpp
+ CIRDiagnosticHandler.cpp
DEPENDS
MLIRCIROpsIncGen
diff --git a/clang/test/CIR/Diagnostics/mlir-error-routing.cu b/clang/test/CIR/Diagnostics/mlir-error-routing.cu
new file mode 100644
index 0000000000000..25759ace8b5bd
--- /dev/null
+++ b/clang/test/CIR/Diagnostics/mlir-error-routing.cu
@@ -0,0 +1,20 @@
+// RUN: not %clang_cc1 -triple x86_64-linux-gnu -fclangir -emit-llvm -x cuda \
+// RUN: -target-sdk-version=12.3 -fcuda-include-gpubinary %t.missing.bin \
+// RUN: %s -o %t.ll 2>&1 | FileCheck %s
+
+// LoweringPrepare emits an MLIR-side error via mlir::Operation::emitError when
+// the requested CUDA gpubinary cannot be opened. With CIRDiagnosticHandler
+// installed, that diagnostic surfaces through clang's DiagnosticsEngine in
+// clang's standard format (`error: ...`) rather than MLIR's
+// `loc("file":N:M): error: ...` default-handler format.
+
+// CHECK: error: cannot open GPU binary file: {{.*}}.missing.bin
+// CHECK-NOT: loc({{.*}}): error: cannot open GPU binary file
+
+// The generic CIR-to-CIR transform fatal error must NOT be reported on top of
+// the specific MLIR-relayed error. CIRGenAction gates the fallback diag on
+// clang::DiagnosticsEngine::hasErrorOccurred() so users see one root cause,
+// not two.
+// CHECK-NOT: error: CIR-to-CIR transformation failed
+
+__attribute__((global)) void kernel() {}
diff --git a/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp b/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
new file mode 100644
index 0000000000000..d5917bc1cdf32
--- /dev/null
+++ b/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
@@ -0,0 +1,247 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Unit tests for cir::CIRDiagnosticHandler.
+//
+// The handler routes MLIR-side diagnostics emitted during CIR passes, the
+// verifier, and CIR-to-LLVM lowering through clang::DiagnosticsEngine. These
+// tests exercise severity mapping, location translation, note attachment, and
+// edge cases (missing files, fused/callsite/name locations, 0-line/0-col)
+// without depending on a particular pass-side trigger.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../../lib/CIR/FrontendAction/CIRDiagnosticHandler.h"
+
+#include "mlir/IR/Builders.h"
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/Location.h"
+#include "mlir/IR/MLIRContext.h"
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+// Don't pull `using namespace clang;` or `using namespace mlir;` here:
+// `clang::Diagnostic` and `mlir::Diagnostic` would clash.
+
+namespace {
+
+struct CapturedDiag {
+ clang::DiagnosticsEngine::Level Level;
+ unsigned ID;
+ std::string Message;
+ bool HasLoc;
+ unsigned Line = 0;
+ unsigned Column = 0;
+};
+
+class CapturingConsumer : public clang::DiagnosticConsumer {
+public:
+ std::vector<CapturedDiag> Diags;
+
+ void HandleDiagnostic(clang::DiagnosticsEngine::Level Level,
+ const clang::Diagnostic &Info) override {
+ clang::DiagnosticConsumer::HandleDiagnostic(Level, Info);
+ CapturedDiag CD;
+ CD.Level = Level;
+ CD.ID = Info.getID();
+ llvm::SmallString<128> Buf;
+ Info.FormatDiagnostic(Buf);
+ CD.Message = std::string(Buf);
+ clang::SourceLocation Loc = Info.getLocation();
+ CD.HasLoc = Loc.isValid();
+ if (CD.HasLoc && Info.hasSourceManager()) {
+ clang::PresumedLoc PL = Info.getSourceManager().getPresumedLoc(Loc);
+ if (PL.isValid()) {
+ CD.Line = PL.getLine();
+ CD.Column = PL.getColumn();
+ }
+ }
+ Diags.push_back(std::move(CD));
+ }
+};
+
+class CIRDiagnosticHandlerTest : public ::testing::Test {
+protected:
+ CIRDiagnosticHandlerTest()
+ : Consumer(new CapturingConsumer),
+ FileMgr(FileMgrOpts),
+ Diags(clang::DiagnosticIDs::create(), DiagOpts, Consumer.get(),
+ /*ShouldOwnClient=*/false),
+ SrcMgr(Diags, FileMgr) {
+ // Register a virtual file so FileManager::getOptionalFileRef succeeds and
+ // SourceManager has a buffer for line/col translation.
+ constexpr llvm::StringLiteral Body =
+ "line 1\nline 2\nline 3\nline 4\nline 5\n";
+ auto Buf = llvm::MemoryBuffer::getMemBufferCopy(Body, srcName());
+ clang::FileEntryRef File =
+ FileMgr.getVirtualFileRef(srcName(), Buf->getBufferSize(), 0);
+ SrcMgr.overrideFileContents(File, std::move(Buf));
+ clang::FileID FID = SrcMgr.getOrCreateFileID(File, clang::SrcMgr::C_User);
+ SrcMgr.setMainFileID(FID);
+ }
+
+ static llvm::StringRef srcName() { return "/virtual/file.c"; }
+
+ mlir::Location fileLoc(unsigned Line, unsigned Col,
+ llvm::StringRef Path = srcName()) {
+ return mlir::FileLineColLoc::get(&MLIRCtx, Path, Line, Col);
+ }
+
+ std::unique_ptr<CapturingConsumer> Consumer;
+ clang::FileSystemOptions FileMgrOpts;
+ clang::FileManager FileMgr;
+ clang::DiagnosticOptions DiagOpts;
+ clang::DiagnosticsEngine Diags;
+ clang::SourceManager SrcMgr;
+ mlir::MLIRContext MLIRCtx{mlir::MLIRContext::Threading::DISABLED};
+};
+
+TEST_F(CIRDiagnosticHandlerTest, ErrorRoutedWithSeverityAndLocation) {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::emitError(fileLoc(2, 3)) << "boom";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ const CapturedDiag &D = Consumer->Diags.front();
+ EXPECT_EQ(D.Level, clang::DiagnosticsEngine::Error);
+ EXPECT_EQ(D.ID,
+ static_cast<unsigned>(clang::diag::err_cir_mlir_diagnostic));
+ EXPECT_EQ(D.Message, "boom");
+ EXPECT_TRUE(D.HasLoc);
+ EXPECT_EQ(D.Line, 2u);
+ EXPECT_EQ(D.Column, 3u);
+}
+
+TEST_F(CIRDiagnosticHandlerTest, WarningRoutesToWarningId) {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::emitWarning(fileLoc(1, 1)) << "soft";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ EXPECT_EQ(Consumer->Diags[0].Level, clang::DiagnosticsEngine::Warning);
+ EXPECT_EQ(Consumer->Diags[0].ID,
+ static_cast<unsigned>(clang::diag::warn_cir_mlir_diagnostic));
+}
+
+TEST_F(CIRDiagnosticHandlerTest, RemarkRoutesToRemarkId) {
+ // Remarks are off by default. Promote -Rclangir so the consumer sees them.
+ bool unknownGroup = Diags.setSeverityForGroup(
+ clang::diag::Flavor::Remark, "remark-clangir",
+ clang::diag::Severity::Remark);
+ ASSERT_FALSE(unknownGroup) << "remark-clangir group not registered";
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::emitRemark(fileLoc(1, 1)) << "fyi";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ EXPECT_EQ(Consumer->Diags[0].Level, clang::DiagnosticsEngine::Remark);
+ EXPECT_EQ(Consumer->Diags[0].ID,
+ static_cast<unsigned>(clang::diag::remark_cir_mlir_diagnostic));
+}
+
+TEST_F(CIRDiagnosticHandlerTest, NotesAttachAfterPrimary) {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ {
+ mlir::InFlightDiagnostic d = mlir::emitError(fileLoc(3, 4)) << "primary";
+ d.attachNote(fileLoc(4, 5)) << "extra info";
+ } // InFlightDiagnostic dtor reports.
+
+ ASSERT_EQ(Consumer->Diags.size(), 2u);
+ EXPECT_EQ(Consumer->Diags[0].Level, clang::DiagnosticsEngine::Error);
+ EXPECT_EQ(Consumer->Diags[0].ID,
+ static_cast<unsigned>(clang::diag::err_cir_mlir_diagnostic));
+ EXPECT_EQ(Consumer->Diags[1].Level, clang::DiagnosticsEngine::Note);
+ EXPECT_EQ(Consumer->Diags[1].ID,
+ static_cast<unsigned>(clang::diag::note_cir_mlir_diagnostic));
+ EXPECT_EQ(Consumer->Diags[1].Message, "extra info");
+ EXPECT_EQ(Consumer->Diags[1].Line, 4u);
+ EXPECT_EQ(Consumer->Diags[1].Column, 5u);
+}
+
+TEST_F(CIRDiagnosticHandlerTest, ZeroLineColumnFallsBackToInvalidLoc) {
+ // Module-level locations use line 0 / column 0; SourceManager would assert.
+ // The handler must guard and emit without a source location.
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::emitError(fileLoc(0, 0)) << "module-level";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ EXPECT_FALSE(Consumer->Diags[0].HasLoc);
+ EXPECT_EQ(Consumer->Diags[0].Message, "module-level");
+}
+
+TEST_F(CIRDiagnosticHandlerTest, FileNotInManagerFallsBack) {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::emitError(fileLoc(1, 1, "/not/registered.c")) << "stray";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ EXPECT_FALSE(Consumer->Diags[0].HasLoc);
+ EXPECT_EQ(Consumer->Diags[0].Message, "stray");
+}
+
+TEST_F(CIRDiagnosticHandlerTest, FusedLocResolvesToFirstTranslatableChild) {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::Location unknown = mlir::UnknownLoc::get(&MLIRCtx);
+ mlir::Location good = fileLoc(2, 1);
+ mlir::Location fused = mlir::FusedLoc::get({unknown, good}, {}, &MLIRCtx);
+ mlir::emitError(fused) << "fused";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ EXPECT_TRUE(Consumer->Diags[0].HasLoc);
+ EXPECT_EQ(Consumer->Diags[0].Line, 2u);
+}
+
+TEST_F(CIRDiagnosticHandlerTest, CallSiteLocFollowsCallee) {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::Location callee = fileLoc(3, 2);
+ mlir::Location caller = fileLoc(5, 1);
+ mlir::Location cs = mlir::CallSiteLoc::get(callee, caller);
+ mlir::emitError(cs) << "cs";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ EXPECT_EQ(Consumer->Diags[0].Line, 3u);
+ EXPECT_EQ(Consumer->Diags[0].Column, 2u);
+}
+
+TEST_F(CIRDiagnosticHandlerTest, NameLocFollowsChild) {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::Location child = fileLoc(4, 1);
+ mlir::Location named =
+ mlir::NameLoc::get(mlir::StringAttr::get(&MLIRCtx, "tag"), child);
+ mlir::emitError(named) << "named";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ EXPECT_EQ(Consumer->Diags[0].Line, 4u);
+}
+
+TEST_F(CIRDiagnosticHandlerTest, UnknownLocEmitsUnattached) {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::emitError(mlir::UnknownLoc::get(&MLIRCtx)) << "lost";
+
+ ASSERT_EQ(Consumer->Diags.size(), 1u);
+ EXPECT_FALSE(Consumer->Diags[0].HasLoc);
+}
+
+TEST_F(CIRDiagnosticHandlerTest, ScopedLifetimeUnregistersOnDestruction) {
+ // After the handler scope ends, MLIR's default handler takes over.
+ // Verify the consumer no longer receives diagnostics through our path.
+ {
+ cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
+ mlir::emitError(fileLoc(1, 1)) << "in-scope";
+ }
+ size_t scopedCount = Consumer->Diags.size();
+ mlir::emitError(fileLoc(1, 1)) << "out-of-scope";
+ // Default handler prints to stderr but does not call our consumer.
+ EXPECT_EQ(Consumer->Diags.size(), scopedCount);
+}
+
+} // namespace
diff --git a/clang/unittests/CIR/CMakeLists.txt b/clang/unittests/CIR/CMakeLists.txt
index 81ef87878d33e..6b43389389228 100644
--- a/clang/unittests/CIR/CMakeLists.txt
+++ b/clang/unittests/CIR/CMakeLists.txt
@@ -4,6 +4,7 @@ include_directories(SYSTEM ${MLIR_INCLUDE_DIR})
include_directories(${MLIR_TABLEGEN_OUTPUT_DIR})
add_distinct_clang_unittest(CIRUnitTests
+ CIRDiagnosticHandlerTest.cpp
ControlFlowTest.cpp
PointerLikeTest.cpp
RecordTypeMetadataTest.cpp
@@ -12,6 +13,8 @@ add_distinct_clang_unittest(CIRUnitTests
Core
LINK_LIBS
+ clangBasic
+ clangCIRFrontendAction
MLIRCIR
CIROpenACCSupport
MLIRIR
>From 55974ed2f2565e115a75ee6be86e403bf77d2fed Mon Sep 17 00:00:00 2001
From: y <konstantinos.parasyris at intel.com>
Date: Fri, 22 May 2026 16:31:30 -0700
Subject: [PATCH 2/4] Format
---
.../CIR/FrontendAction/CIRDiagnosticHandler.cpp | 14 +++++++-------
.../lib/CIR/FrontendAction/CIRDiagnosticHandler.h | 3 +--
clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp | 12 +++++-------
3 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
index 7c42f69661788..5f0045a7c40cf 100644
--- a/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
@@ -21,16 +21,16 @@
namespace cir {
-CIRDiagnosticHandler::CIRDiagnosticHandler(
- mlir::MLIRContext *ctx, clang::DiagnosticsEngine &diags,
- clang::SourceManager &srcMgr, clang::FileManager &fileMgr)
+CIRDiagnosticHandler::CIRDiagnosticHandler(mlir::MLIRContext *ctx,
+ clang::DiagnosticsEngine &diags,
+ clang::SourceManager &srcMgr,
+ clang::FileManager &fileMgr)
: mlir::ScopedDiagnosticHandler(ctx), Diags(diags), SrcMgr(srcMgr),
FileMgr(fileMgr) {
setHandler([this](mlir::Diagnostic &D) { return handle(D); });
}
-clang::SourceLocation
-CIRDiagnosticHandler::translateLoc(mlir::Location loc) {
+clang::SourceLocation CIRDiagnosticHandler::translateLoc(mlir::Location loc) {
// Walk common location wrappers to reach a usable file/line/column triple.
// Anything we can't translate becomes an invalid SourceLocation, which the
// diagnostics engine renders without a source line.
@@ -42,8 +42,8 @@ CIRDiagnosticHandler::translateLoc(mlir::Location loc) {
auto fileRef = FileMgr.getOptionalFileRef(file.getFilename().getValue());
if (!fileRef)
return clang::SourceLocation();
- return SrcMgr.translateFileLineCol(&fileRef->getFileEntry(),
- file.getLine(), file.getColumn());
+ return SrcMgr.translateFileLineCol(&fileRef->getFileEntry(), file.getLine(),
+ file.getColumn());
}
if (auto fused = mlir::dyn_cast<mlir::FusedLoc>(loc)) {
for (mlir::Location child : fused.getLocations()) {
diff --git a/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.h b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.h
index 6a2e99125b62d..a5610aaff632f 100644
--- a/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.h
+++ b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.h
@@ -34,8 +34,7 @@ namespace cir {
/// fall back to an invalid clang::SourceLocation.
class CIRDiagnosticHandler : public mlir::ScopedDiagnosticHandler {
public:
- CIRDiagnosticHandler(mlir::MLIRContext *ctx,
- clang::DiagnosticsEngine &diags,
+ CIRDiagnosticHandler(mlir::MLIRContext *ctx, clang::DiagnosticsEngine &diags,
clang::SourceManager &srcMgr,
clang::FileManager &fileMgr);
diff --git a/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp b/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
index d5917bc1cdf32..a3e26da6d57ba 100644
--- a/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
+++ b/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
@@ -76,8 +76,7 @@ class CapturingConsumer : public clang::DiagnosticConsumer {
class CIRDiagnosticHandlerTest : public ::testing::Test {
protected:
CIRDiagnosticHandlerTest()
- : Consumer(new CapturingConsumer),
- FileMgr(FileMgrOpts),
+ : Consumer(new CapturingConsumer), FileMgr(FileMgrOpts),
Diags(clang::DiagnosticIDs::create(), DiagOpts, Consumer.get(),
/*ShouldOwnClient=*/false),
SrcMgr(Diags, FileMgr) {
@@ -116,8 +115,7 @@ TEST_F(CIRDiagnosticHandlerTest, ErrorRoutedWithSeverityAndLocation) {
ASSERT_EQ(Consumer->Diags.size(), 1u);
const CapturedDiag &D = Consumer->Diags.front();
EXPECT_EQ(D.Level, clang::DiagnosticsEngine::Error);
- EXPECT_EQ(D.ID,
- static_cast<unsigned>(clang::diag::err_cir_mlir_diagnostic));
+ EXPECT_EQ(D.ID, static_cast<unsigned>(clang::diag::err_cir_mlir_diagnostic));
EXPECT_EQ(D.Message, "boom");
EXPECT_TRUE(D.HasLoc);
EXPECT_EQ(D.Line, 2u);
@@ -136,9 +134,9 @@ TEST_F(CIRDiagnosticHandlerTest, WarningRoutesToWarningId) {
TEST_F(CIRDiagnosticHandlerTest, RemarkRoutesToRemarkId) {
// Remarks are off by default. Promote -Rclangir so the consumer sees them.
- bool unknownGroup = Diags.setSeverityForGroup(
- clang::diag::Flavor::Remark, "remark-clangir",
- clang::diag::Severity::Remark);
+ bool unknownGroup =
+ Diags.setSeverityForGroup(clang::diag::Flavor::Remark, "remark-clangir",
+ clang::diag::Severity::Remark);
ASSERT_FALSE(unknownGroup) << "remark-clangir group not registered";
cir::CIRDiagnosticHandler Handler(&MLIRCtx, Diags, SrcMgr, FileMgr);
mlir::emitRemark(fileLoc(1, 1)) << "fyi";
>From e2a7689a16f0715f4e426ebc27259abe2abd1c68 Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <konstantinos.parasyris at intel.com>
Date: Thu, 23 Jul 2026 10:17:24 -0700
Subject: [PATCH 3/4] Drop disableMultithreading
---
clang/lib/CIR/CodeGen/CIRGenerator.cpp | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
index 3b4700d2ed38b..01f6a5bd5be76 100644
--- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp
@@ -52,11 +52,15 @@ void CIRGenerator::Initialize(ASTContext &astContext) {
this->astContext = &astContext;
mlirContext = std::make_unique<mlir::MLIRContext>();
- // Disable MLIR multithreading: clang::DiagnosticsEngine is not thread-safe,
- // and the per-context handler installed by CIRGenAction reports diagnostics
- // straight through it. CIR's pass pipeline is short enough that we don't
- // miss meaningful parallelism here.
- mlirContext->disableMultithreading();
+ // MLIR multithreading stays enabled. clang::DiagnosticsEngine is not
+ // thread-safe, but the CIRDiagnosticHandler installed by CIRGenAction is
+ // never invoked concurrently: when passes run in parallel, the MLIR pass
+ // manager installs an mlir::ParallelDiagnosticHandler (see
+ // mlir/IR/Threading.h) that buffers per-thread diagnostics and re-emits them,
+ // deterministically ordered, on a single thread when it is destroyed. Those
+ // re-emitted diagnostics only then reach the (lower priority)
+ // CIRDiagnosticHandler, serially, so the DiagnosticsEngine is only ever
+ // touched from one thread.
mlirContext->loadDialect<mlir::DLTIDialect>();
mlirContext->loadDialect<cir::CIRDialect>();
mlirContext->getOrLoadDialect<mlir::acc::OpenACCDialect>();
>From eabf2732d369ed54cbf0e49440433c8289917b42 Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <konstantinos.parasyris at intel.com>
Date: Thu, 23 Jul 2026 11:49:44 -0700
Subject: [PATCH 4/4] [CIR] Move codegen diagnostics to
DiagnosticCodeGenKinds.td
---
.../clang/Basic/AllDiagnosticKinds.inc | 1 +
clang/include/clang/Basic/AllDiagnostics.h | 1 +
clang/include/clang/Basic/CMakeLists.txt | 1 +
clang/include/clang/Basic/Diagnostic.td | 1 +
clang/include/clang/Basic/DiagnosticCodeGen.h | 15 ++++++++
.../clang/Basic/DiagnosticCodeGenKinds.td | 34 +++++++++++++++++++
.../clang/Basic/DiagnosticFrontendKinds.td | 14 --------
clang/include/clang/Basic/DiagnosticIDs.h | 4 ++-
clang/lib/Basic/DiagnosticIDs.cpp | 5 ++-
.../FrontendAction/CIRDiagnosticHandler.cpp | 2 +-
clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 2 +-
.../CIR/CIRDiagnosticHandlerTest.cpp | 2 +-
12 files changed, 63 insertions(+), 19 deletions(-)
create mode 100644 clang/include/clang/Basic/DiagnosticCodeGen.h
create mode 100644 clang/include/clang/Basic/DiagnosticCodeGenKinds.td
diff --git a/clang/include/clang/Basic/AllDiagnosticKinds.inc b/clang/include/clang/Basic/AllDiagnosticKinds.inc
index 2d08bb0525970..1b50675a34858 100644
--- a/clang/include/clang/Basic/AllDiagnosticKinds.inc
+++ b/clang/include/clang/Basic/AllDiagnosticKinds.inc
@@ -20,6 +20,7 @@
#include "clang/Basic/DiagnosticCommonKinds.inc"
#include "clang/Basic/DiagnosticDriverKinds.inc"
#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#include "clang/Basic/DiagnosticCodeGenKinds.inc"
#include "clang/Basic/DiagnosticSerializationKinds.inc"
#include "clang/Basic/DiagnosticLexKinds.inc"
#include "clang/Basic/DiagnosticParseKinds.inc"
diff --git a/clang/include/clang/Basic/AllDiagnostics.h b/clang/include/clang/Basic/AllDiagnostics.h
index 78e5428ddbfff..aaedfcf7f7354 100644
--- a/clang/include/clang/Basic/AllDiagnostics.h
+++ b/clang/include/clang/Basic/AllDiagnostics.h
@@ -16,6 +16,7 @@
#include "clang/Basic/DiagnosticAST.h"
#include "clang/Basic/DiagnosticAnalysis.h"
+#include "clang/Basic/DiagnosticCodeGen.h"
#include "clang/Basic/DiagnosticComment.h"
#include "clang/Basic/DiagnosticCrossTU.h"
#include "clang/Basic/DiagnosticDriver.h"
diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt
index 20172622ca424..19df0008dd3e3 100644
--- a/clang/include/clang/Basic/CMakeLists.txt
+++ b/clang/include/clang/Basic/CMakeLists.txt
@@ -22,6 +22,7 @@ endmacro(clang_diag_gen)
clang_diag_gen(Analysis)
clang_diag_gen(AST)
+clang_diag_gen(CodeGen)
clang_diag_gen(Comment)
clang_diag_gen(Common)
clang_diag_gen(CrossTU)
diff --git a/clang/include/clang/Basic/Diagnostic.td b/clang/include/clang/Basic/Diagnostic.td
index d56fb22b2f539..cfe8e16624a3d 100644
--- a/clang/include/clang/Basic/Diagnostic.td
+++ b/clang/include/clang/Basic/Diagnostic.td
@@ -247,6 +247,7 @@ multiclass CXX26Compat<string message, bit ext_warn = true> : CXXCompat<message,
// Definitions for Diagnostics.
include "DiagnosticASTKinds.td"
+include "DiagnosticCodeGenKinds.td"
include "DiagnosticCommentKinds.td"
include "DiagnosticCommonKinds.td"
include "DiagnosticCrossTUKinds.td"
diff --git a/clang/include/clang/Basic/DiagnosticCodeGen.h b/clang/include/clang/Basic/DiagnosticCodeGen.h
new file mode 100644
index 0000000000000..eb3b50ed18a57
--- /dev/null
+++ b/clang/include/clang/Basic/DiagnosticCodeGen.h
@@ -0,0 +1,15 @@
+//===--- DiagnosticCodeGen.h - Diagnostics for codegen ----------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_DIAGNOSTICCODEGEN_H
+#define LLVM_CLANG_BASIC_DIAGNOSTICCODEGEN_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/DiagnosticCodeGenInterface.inc"
+
+#endif // LLVM_CLANG_BASIC_DIAGNOSTICCODEGEN_H
diff --git a/clang/include/clang/Basic/DiagnosticCodeGenKinds.td b/clang/include/clang/Basic/DiagnosticCodeGenKinds.td
new file mode 100644
index 0000000000000..f135cc5df3057
--- /dev/null
+++ b/clang/include/clang/Basic/DiagnosticCodeGenKinds.td
@@ -0,0 +1,34 @@
+//==--- DiagnosticCodeGenKinds.td - codegen diagnostics -------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Diagnostics emitted while lowering the AST to code. This component is shared
+// between the LLVM IR code generator (clang/lib/CodeGen) and the ClangIR (CIR)
+// pipeline (clang/lib/CIR). Existing LLVM IR codegen diagnostics still live in
+// DiagnosticFrontendKinds.td and can migrate here incrementally.
+//
+//===----------------------------------------------------------------------===//
+
+let Component = "CodeGen" in {
+
+// ClangIR (CIR) diagnostics.
+
+def err_cir_to_cir_transform_failed : Error<
+ "CIR-to-CIR transformation failed">, DefaultFatal;
+
+def err_cir_verification_failed_pre_passes : Error<
+ "CIR module verification error before running CIR-to-CIR passes">,
+ DefaultFatal;
+
+// Diagnostics relayed from MLIR-side passes/verifier through the
+// clang::DiagnosticsEngine. The full message text comes from MLIR.
+def err_cir_mlir_diagnostic : Error<"%0">;
+def warn_cir_mlir_diagnostic : Warning<"%0">, InGroup<ClangIR>;
+def remark_cir_mlir_diagnostic : Remark<"%0">, InGroup<RemarkClangIR>;
+def note_cir_mlir_diagnostic : Note<"%0">;
+
+}
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 3b7d9a1d56c1b..e1a392f42b837 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -512,18 +512,4 @@ def err_member_ptr_requires_complete_type
: Error<"member pointer representation requires a complete class type for "
"%0 to perform this expression">;
-// ClangIR frontend errors
-def err_cir_to_cir_transform_failed : Error<
- "CIR-to-CIR transformation failed">, DefaultFatal;
-
-def err_cir_verification_failed_pre_passes : Error<
- "CIR module verification error before running CIR-to-CIR passes">,
- DefaultFatal;
-
-// Diagnostics relayed from MLIR-side passes/verifier through the
-// clang::DiagnosticsEngine. The full message text comes from MLIR.
-def err_cir_mlir_diagnostic : Error<"%0">;
-def warn_cir_mlir_diagnostic : Warning<"%0">, InGroup<ClangIR>;
-def remark_cir_mlir_diagnostic : Remark<"%0">, InGroup<RemarkClangIR>;
-def note_cir_mlir_diagnostic : Note<"%0">;
}
diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h
index 47f63933e1e2f..52e2a28b0d4d5 100644
--- a/clang/include/clang/Basic/DiagnosticIDs.h
+++ b/clang/include/clang/Basic/DiagnosticIDs.h
@@ -37,6 +37,7 @@ enum {
DIAG_SIZE_COMMON = 300,
DIAG_SIZE_DRIVER = 400,
DIAG_SIZE_FRONTEND = 200,
+ DIAG_SIZE_CODEGEN = 100,
DIAG_SIZE_SERIALIZATION = 120,
DIAG_SIZE_LEX = 500,
DIAG_SIZE_PARSE = 800,
@@ -55,7 +56,8 @@ enum {
DIAG_START_COMMON = 0,
DIAG_START_DRIVER = DIAG_START_COMMON + static_cast<int>(DIAG_SIZE_COMMON),
DIAG_START_FRONTEND = DIAG_START_DRIVER + static_cast<int>(DIAG_SIZE_DRIVER),
- DIAG_START_SERIALIZATION = DIAG_START_FRONTEND + static_cast<int>(DIAG_SIZE_FRONTEND),
+ DIAG_START_CODEGEN = DIAG_START_FRONTEND + static_cast<int>(DIAG_SIZE_FRONTEND),
+ DIAG_START_SERIALIZATION = DIAG_START_CODEGEN + static_cast<int>(DIAG_SIZE_CODEGEN),
DIAG_START_LEX = DIAG_START_SERIALIZATION + static_cast<int>(DIAG_SIZE_SERIALIZATION),
DIAG_START_PARSE = DIAG_START_LEX + static_cast<int>(DIAG_SIZE_LEX),
DIAG_START_AST = DIAG_START_PARSE + static_cast<int>(DIAG_SIZE_PARSE),
diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp
index d9c5e4082c1a7..a59f59d030fd0 100644
--- a/clang/lib/Basic/DiagnosticIDs.cpp
+++ b/clang/lib/Basic/DiagnosticIDs.cpp
@@ -173,6 +173,7 @@ struct StaticDiagInfoRec {
VALIDATE_DIAG_SIZE(COMMON)
VALIDATE_DIAG_SIZE(DRIVER)
VALIDATE_DIAG_SIZE(FRONTEND)
+VALIDATE_DIAG_SIZE(CODEGEN)
VALIDATE_DIAG_SIZE(SERIALIZATION)
VALIDATE_DIAG_SIZE(LEX)
VALIDATE_DIAG_SIZE(PARSE)
@@ -207,6 +208,7 @@ const StaticDiagInfoRec StaticDiagInfo[] = {
#include "clang/Basic/DiagnosticCommonKinds.inc"
#include "clang/Basic/DiagnosticDriverKinds.inc"
#include "clang/Basic/DiagnosticFrontendKinds.inc"
+#include "clang/Basic/DiagnosticCodeGenKinds.inc"
#include "clang/Basic/DiagnosticSerializationKinds.inc"
#include "clang/Basic/DiagnosticLexKinds.inc"
#include "clang/Basic/DiagnosticParseKinds.inc"
@@ -251,7 +253,8 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
}
CATEGORY(DRIVER, COMMON)
CATEGORY(FRONTEND, DRIVER)
-CATEGORY(SERIALIZATION, FRONTEND)
+CATEGORY(CODEGEN, FRONTEND)
+CATEGORY(SERIALIZATION, CODEGEN)
CATEGORY(LEX, SERIALIZATION)
CATEGORY(PARSE, LEX)
CATEGORY(AST, PARSE)
diff --git a/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
index 5f0045a7c40cf..f4aa41c837b3c 100644
--- a/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRDiagnosticHandler.cpp
@@ -14,7 +14,7 @@
#include "mlir/IR/MLIRContext.h"
#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/DiagnosticCodeGen.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index d43db7a5e7e27..6e330a6182cbf 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -10,7 +10,7 @@
#include "CIRDiagnosticHandler.h"
#include "mlir/IR/MLIRContext.h"
#include "mlir/IR/OwningOpRef.h"
-#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/DiagnosticCodeGen.h"
#include "clang/CIR/CIRGenerator.h"
#include "clang/CIR/CIRToCIRPasses.h"
#include "clang/CIR/LowerToLLVM.h"
diff --git a/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp b/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
index a3e26da6d57ba..bf3cdc36dc0a7 100644
--- a/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
+++ b/clang/unittests/CIR/CIRDiagnosticHandlerTest.cpp
@@ -24,7 +24,7 @@
#include "mlir/IR/MLIRContext.h"
#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/Basic/DiagnosticCodeGen.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "clang/Basic/FileManager.h"
More information about the cfe-commits
mailing list