[clang] [clang][Serialization] Outline LangOptions mismatch diagnostics (PR #202843)

David Zbarsky via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 9 20:51:05 PDT 2026


https://github.com/dzbarsky created https://github.com/llvm/llvm-project/pull/202843

Outline language-option mismatch diagnostic construction into two `noinline` helpers. Generated comparisons remain direct and ordered as before, so successful imports add no indirect calls and the serialized format is unchanged.

Linked `clang` and `clangd` shrink by 35,264 and 29,216 bytes respectively; `ASTReader.cpp.o` shrinks by 62,712 bytes with 1,347 fewer relocations, while linked fixups are unchanged.

PCH, PCM, and BMI outputs and mismatch diagnostics are byte-identical, focused module/PCH tests pass, and batched PCH and module imports show no significant performance change.

Work towards #202616

AI tool disclosure: Co-authored with OpenAI Codex.


>From 85ffcd83da47e9b234f0c55a0b01a2aff2acca0d Mon Sep 17 00:00:00 2001
From: David Zbarsky <dzbarsky at gmail.com>
Date: Tue, 9 Jun 2026 23:50:19 -0400
Subject: [PATCH] [clang][Serialization] Outline LangOptions mismatch
 diagnostics

Move language-option mismatch diagnostic construction into two noinline helpers. Generated comparisons remain direct and in their original order, so successful imports add no indirect calls and the serialized format is unchanged.

ASTReader.cpp.o shrinks by 62,712 bytes, including 36,284 bytes of __text, and has 1,347 fewer relocations. Controlled links shrink clang by 35,264 bytes and clangd by 29,216 bytes; stripped sizes fall by 16,752 and 16,664 bytes, and linked fixups are unchanged.

PCH, PCM, and BMI outputs are byte-identical and cross-import successfully. Mismatch diagnostics are byte-identical for boolean options, OpenMP, module features, Objective-C runtime, block command names, and AddressSanitizer. Focused module/PCH tests pass, and batched PCH and module imports show no significant performance change.
---
 clang/lib/Serialization/ASTReader.cpp | 43 +++++++++++++++++----------
 1 file changed, 28 insertions(+), 15 deletions(-)

diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index f8a6a38bb9b5c..80feea0a0c795 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -276,6 +276,19 @@ void ChainedASTReaderListener::readModuleFileExtension(
 
 ASTReaderListener::~ASTReaderListener() = default;
 
+static LLVM_ATTRIBUTE_NOINLINE void diagnoseLanguageOptionFlagMismatch(
+    DiagnosticsEngine &Diags, StringRef Description, bool SerializedValue,
+    bool CurrentValue, StringRef ModuleFilename) {
+  Diags.Report(diag::err_ast_file_langopt_mismatch)
+      << Description << SerializedValue << CurrentValue << ModuleFilename;
+}
+
+static LLVM_ATTRIBUTE_NOINLINE void diagnoseLanguageOptionValueMismatch(
+    DiagnosticsEngine &Diags, StringRef Description, StringRef ModuleFilename) {
+  Diags.Report(diag::err_ast_file_langopt_value_mismatch)
+      << Description << ModuleFilename;
+}
+
 /// Compare the given set of language options against an existing set of
 /// language options.
 ///
@@ -300,12 +313,12 @@ static bool checkLanguageOptions(const LangOptions &LangOpts,
       if (ExistingLangOpts.Name != LangOpts.Name) {                            \
         if (Diags) {                                                           \
           if (Bits == 1)                                                       \
-            Diags->Report(diag::err_ast_file_langopt_mismatch)                 \
-                << Description << LangOpts.Name << ExistingLangOpts.Name       \
-                << ModuleFilename;                                             \
+            diagnoseLanguageOptionFlagMismatch(                                \
+                *Diags, Description, LangOpts.Name, ExistingLangOpts.Name,     \
+                ModuleFilename);                                               \
           else                                                                 \
-            Diags->Report(diag::err_ast_file_langopt_value_mismatch)           \
-                << Description << ModuleFilename;                              \
+            diagnoseLanguageOptionValueMismatch(*Diags, Description,           \
+                                                ModuleFilename);               \
         }                                                                      \
         return true;                                                           \
       }                                                                        \
@@ -319,8 +332,8 @@ static bool checkLanguageOptions(const LangOptions &LangOpts,
          !AllowCompatibleDifferences)) {                                       \
       if (ExistingLangOpts.Name != LangOpts.Name) {                            \
         if (Diags)                                                             \
-          Diags->Report(diag::err_ast_file_langopt_value_mismatch)             \
-              << Description << ModuleFilename;                                \
+          diagnoseLanguageOptionValueMismatch(*Diags, Description,             \
+                                              ModuleFilename);                 \
         return true;                                                           \
       }                                                                        \
     }                                                                          \
@@ -333,8 +346,8 @@ static bool checkLanguageOptions(const LangOptions &LangOpts,
          !AllowCompatibleDifferences)) {                                       \
       if (ExistingLangOpts.get##Name() != LangOpts.get##Name()) {              \
         if (Diags)                                                             \
-          Diags->Report(diag::err_ast_file_langopt_value_mismatch)             \
-              << Description << ModuleFilename;                                \
+          diagnoseLanguageOptionValueMismatch(*Diags, Description,             \
+                                              ModuleFilename);                 \
         return true;                                                           \
       }                                                                        \
     }                                                                          \
@@ -344,23 +357,23 @@ static bool checkLanguageOptions(const LangOptions &LangOpts,
 
   if (ExistingLangOpts.ModuleFeatures != LangOpts.ModuleFeatures) {
     if (Diags)
-      Diags->Report(diag::err_ast_file_langopt_value_mismatch)
-          << "module features" << ModuleFilename;
+      diagnoseLanguageOptionValueMismatch(*Diags, "module features",
+                                          ModuleFilename);
     return true;
   }
 
   if (ExistingLangOpts.ObjCRuntime != LangOpts.ObjCRuntime) {
     if (Diags)
-      Diags->Report(diag::err_ast_file_langopt_value_mismatch)
-          << "target Objective-C runtime" << ModuleFilename;
+      diagnoseLanguageOptionValueMismatch(*Diags, "target Objective-C runtime",
+                                          ModuleFilename);
     return true;
   }
 
   if (ExistingLangOpts.CommentOpts.BlockCommandNames !=
       LangOpts.CommentOpts.BlockCommandNames) {
     if (Diags)
-      Diags->Report(diag::err_ast_file_langopt_value_mismatch)
-          << "block command names" << ModuleFilename;
+      diagnoseLanguageOptionValueMismatch(*Diags, "block command names",
+                                          ModuleFilename);
     return true;
   }
 



More information about the cfe-commits mailing list