[clang] [clang][Dependency Scanning] Canonicalize Defines of a Compiler Invocation As Early As Possible (PR #159620)

Qiongsi Wu via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 18 11:11:06 PDT 2025


https://github.com/qiongsiwu created https://github.com/llvm/llvm-project/pull/159620

Before this patch, we only perform `-D` canonicalization on the deep copy of the `CompilerInvocation` instance, since the canonicalization should have no impact on scanning. 

However, in the presence of CAS, the content of the `builtin` macros are hashed and used as context hash. This patch moves the canonicalization to an earlier point so the canonicalized macros are used consistently for the command line argument for explicit PCM builds, and during scanning. 

Part of work for rdar://136303612. 

>From d13bc746e23c5f82a107913ed101851163dab2d5 Mon Sep 17 00:00:00 2001
From: Qiongsi Wu <qiongsi_wu at apple.com>
Date: Thu, 18 Sep 2025 11:04:37 -0700
Subject: [PATCH] Moving the code to canonicalize defines to the earliest
 possible point.

---
 .../DependencyScanningWorker.cpp               | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 0855e6dec6158..8c4a3684a10a7 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -393,8 +393,6 @@ class DependencyScanningAction {
                      DiagnosticConsumer *DiagConsumer) {
     // Make a deep copy of the original Clang invocation.
     CompilerInvocation OriginalInvocation(*Invocation);
-    if (any(Service.getOptimizeArgs() & ScanningOptimizations::Macros))
-      canonicalizeDefines(OriginalInvocation.getPreprocessorOpts());
 
     if (Scanned) {
       // Scanning runs once for the first -cc1 invocation in a chain of driver
@@ -708,7 +706,8 @@ static bool createAndRunToolInvocation(
     std::vector<std::string> CommandLine, DependencyScanningAction &Action,
     IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
     std::shared_ptr<clang::PCHContainerOperations> &PCHContainerOps,
-    DiagnosticsEngine &Diags, DependencyConsumer &Consumer) {
+    DiagnosticsEngine &Diags, DependencyConsumer &Consumer,
+    bool CanonicalizeDefs) {
 
   // Save executable path before providing CommandLine to ToolInvocation
   std::string Executable = CommandLine[0];
@@ -723,6 +722,9 @@ static bool createAndRunToolInvocation(
     return false;
   }
 
+  if (CanonicalizeDefs)
+    canonicalizeDefines(Invocation->getPreprocessorOpts());
+
   if (!Action.runInvocation(std::move(Invocation), std::move(FS),
                             PCHContainerOps, Diags.getClient()))
     return false;
@@ -744,14 +746,17 @@ bool DependencyScanningWorker::scanDependencies(
   sanitizeDiagOpts(*DiagOpts);
   auto Diags = CompilerInstance::createDiagnostics(*FS, *DiagOpts, &DC,
                                                    /*ShouldOwnClient=*/false);
+  bool canonicalizeDefs =
+      any(Service.getOptimizeArgs() & ScanningOptimizations::Macros);
 
   DependencyScanningAction Action(Service, WorkingDirectory, Consumer,
                                   Controller, DepFS, ModuleName);
 
   bool Success = false;
   if (CommandLine[1] == "-cc1") {
-    Success = createAndRunToolInvocation(CommandLine, Action, FS,
-                                         PCHContainerOps, *Diags, Consumer);
+    Success =
+        createAndRunToolInvocation(CommandLine, Action, FS, PCHContainerOps,
+                                   *Diags, Consumer, canonicalizeDefs);
   } else {
     Success = forEachDriverJob(
         CommandLine, *Diags, FS, [&](const driver::Command &Cmd) {
@@ -774,7 +779,8 @@ bool DependencyScanningWorker::scanDependencies(
           // are made by the driver do not go through the
           // dependency scanning filesystem.
           return createAndRunToolInvocation(std::move(Argv), Action, FS,
-                                            PCHContainerOps, *Diags, Consumer);
+                                            PCHContainerOps, *Diags, Consumer,
+                                            canonicalizeDefs);
         });
   }
 



More information about the cfe-commits mailing list