https://github.com/ziqingluo-90 updated 
https://github.com/llvm/llvm-project/pull/218823

>From 5a4214a4261cf583217655faa28fb613136d2d6f Mon Sep 17 00:00:00 2001
From: Ziqing Luo <[email protected]>
Date: Tue, 18 Aug 2026 16:07:53 -0700
Subject: [PATCH 1/2] [SSAF][SourceTransform] Add '--ssaf-link-unit-id=' for
 specifying link unit identifiers

The source-transformation pass takes WPA results as input, where
entities are named under link-unit and compilation-unit namespaces.
To associate ASTNodes with entities, the source-transformation pass
needs to know both link-unit and compilation-unit IDs. Such information
is provided by the caller.

rdar://185818153
---
 .../user-docs/SourceEditGeneration.md              | 11 ++++++++---
 .../include/clang/Basic/DiagnosticFrontendKinds.td |  3 ++-
 clang/include/clang/Frontend/SSAFOptions.h         |  4 ++++
 clang/include/clang/Options/Options.td             |  9 +++++++++
 clang/lib/Driver/ToolChains/Clang.cpp              |  1 +
 .../SourceTransformationFrontendAction.cpp         |  6 ++++++
 clang/test/Analysis/Scalable/help.cpp              |  2 ++
 .../Scalable/source-edit-generation/cli-errors.cpp | 14 ++++++++------
 .../source-edit-generation/coexistence.cpp         |  1 +
 .../source-edit-generation/downgradable-errors.cpp |  3 ++-
 .../Scalable/source-edit-generation/happy-path.cpp |  1 +
 .../source-edit-generation/write-failure.cpp       |  2 ++
 12 files changed, 46 insertions(+), 11 deletions(-)

diff --git 
a/clang/docs/ScalableStaticAnalysis/user-docs/SourceEditGeneration.md 
b/clang/docs/ScalableStaticAnalysis/user-docs/SourceEditGeneration.md
index ad7d93d02fcf9..9a3ed2f10fd4e 100644
--- a/clang/docs/ScalableStaticAnalysis/user-docs/SourceEditGeneration.md
+++ b/clang/docs/ScalableStaticAnalysis/user-docs/SourceEditGeneration.md
@@ -12,11 +12,12 @@ and emits two per-translation-unit artifacts:
 
 ## Driver options
 
-Four options control the pipeline; they are all both `--ssaf-…` driver
+Five options control the pipeline; they are all both `--ssaf-…` driver
 options and `cc1` options. The compilation-unit identifier is shared
 with the summary extraction step. A given compilation unit needs to
 receive the same identifier for both summary extraction and source
-edit generation.
+edit generation. The link-unit identifier must match the namespace
+name the compilation unit's `WPASuite` result was linked into.
 
 ```{eval-rst}
 .. list-table::
@@ -38,6 +39,9 @@ edit generation.
    * - ``--ssaf-compilation-unit-id=<id>``
      - Stable identifier for this translation unit (also required by
        the summary extraction).
+   * - ``--ssaf-link-unit-id=<id>``
+     - Stable identifier of the link unit this translation unit was
+       linked into.
 ```
 
 When `--ssaf-source-transformation=` is non-empty the framework wraps
@@ -54,7 +58,8 @@ $ clang -c foo.cpp \
     --ssaf-global-scope-analysis-result=wpa.json \
     --ssaf-src-edit-file=foo.yaml \
     --ssaf-transformation-report-file=foo.sarif \
-    --ssaf-compilation-unit-id=cu-foo
+    --ssaf-compilation-unit-id=cu-foo \
+    --ssaf-link-unit-id=lu-foo
 $ clang-apply-replacements --remove-change-desc-files <dir-with-yaml>
 ```
 
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td 
b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index be321ca83da12..a10f10502a702 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -446,7 +446,8 @@ def warn_ssaf_source_transformation_unknown_name :
 def warn_ssaf_source_transformation_requires :
   Warning<"option '--ssaf-source-transformation=' requires "
           
"'%select{--ssaf-global-scope-analysis-result=|--ssaf-src-edit-file=|"
-          "--ssaf-transformation-report-file=|--ssaf-compilation-unit-id=}0' "
+          "--ssaf-transformation-report-file=|--ssaf-compilation-unit-id=|"
+          "--ssaf-link-unit-id=}0' "
           "to be set">,
   InGroup<ScalableStaticAnalysis>, DefaultError;
 
diff --git a/clang/include/clang/Frontend/SSAFOptions.h 
b/clang/include/clang/Frontend/SSAFOptions.h
index 189bf3b383c46..81bf686442c97 100644
--- a/clang/include/clang/Frontend/SSAFOptions.h
+++ b/clang/include/clang/Frontend/SSAFOptions.h
@@ -42,6 +42,10 @@ class SSAFOptions {
   /// Controlled by: --ssaf-global-scope-analysis-result
   std::string GlobalScopeAnalysisResult;
 
+  /// Stable identifier used as the name of the `LinkUnit` `BuildNamespace` of
+  /// every produced link unit. Controlled by: --ssaf-link-unit-id
+  std::string LinkUnitId;
+
   /// Path of the source-edit output file produced by the source
   /// transformation.
   /// Controlled by: --ssaf-src-edit-file
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index eb5a009b5628c..c5758ec7b557c 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -1021,6 +1021,15 @@ def _ssaf_global_scope_analysis_result :
     "consumed by the source transformation. The extension selects which file "
     "format to use.">,
   MarshallingInfoString<SSAFOpts<"GlobalScopeAnalysisResult">>;
+def _ssaf_link_unit_id :
+  Joined<["--"], "ssaf-link-unit-id=">,
+  MetaVarName<"<id>">,
+  Group<SSAF_Group>,
+  Visibility<[ClangOption, CC1Option]>,
+  HelpText<
+    "Stable identifier used as the LinkUnit namespace name of every "
+    "produced SSAF link unit.">,
+  MarshallingInfoString<SSAFOpts<"LinkUnitId">>;
 def _ssaf_src_edit_file :
   Joined<["--"], "ssaf-src-edit-file=">,
   MetaVarName<"<path>">,
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index b081265412752..fb94d114e0458 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8137,6 +8137,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
   Args.AddLastArg(CmdArgs, options::OPT__ssaf_no_extract_from_system_headers);
   Args.AddLastArg(CmdArgs, options::OPT__ssaf_source_transformation);
   Args.AddLastArg(CmdArgs, options::OPT__ssaf_global_scope_analysis_result);
+  Args.AddLastArg(CmdArgs, options::OPT__ssaf_link_unit_id);
   Args.AddLastArg(CmdArgs, options::OPT__ssaf_src_edit_file);
   Args.AddLastArg(CmdArgs, options::OPT__ssaf_transformation_report_file);
 
diff --git 
a/clang/lib/ScalableStaticAnalysis/Frontend/SourceTransformationFrontendAction.cpp
 
b/clang/lib/ScalableStaticAnalysis/Frontend/SourceTransformationFrontendAction.cpp
index 6ae7518e0ed56..4983d5e241e0f 100644
--- 
a/clang/lib/ScalableStaticAnalysis/Frontend/SourceTransformationFrontendAction.cpp
+++ 
b/clang/lib/ScalableStaticAnalysis/Frontend/SourceTransformationFrontendAction.cpp
@@ -98,6 +98,7 @@ enum SourceTransformationCompanion {
   STCompanion_EditFile,          // --ssaf-src-edit-file=
   STCompanion_ReportFile,        // --ssaf-transformation-report-file=
   STCompanion_CompilationUnitId, // --ssaf-compilation-unit-id=
+  STCompanion_LinkUnitId,        // --ssaf-link-unit-id=
 };
 
 /// Options that depend on `--ssaf-source-transformation=` being set. Values
@@ -136,6 +137,11 @@ static bool reportOrphanOptionMisuse(DiagnosticsEngine 
&Diags,
           << STCompanion_CompilationUnitId;
       Reported = true;
     }
+    if (Opts.LinkUnitId.empty()) {
+      Diags.Report(diag::warn_ssaf_source_transformation_requires)
+          << STCompanion_LinkUnitId;
+      Reported = true;
+    }
   } else {
     if (!Opts.SrcEditFile.empty()) {
       
Diags.Report(diag::warn_ssaf_option_ignored_without_source_transformation)
diff --git a/clang/test/Analysis/Scalable/help.cpp 
b/clang/test/Analysis/Scalable/help.cpp
index 3aee63d7ceaf5..c4220ff527bc5 100644
--- a/clang/test/Analysis/Scalable/help.cpp
+++ b/clang/test/Analysis/Scalable/help.cpp
@@ -11,6 +11,8 @@
 // HELP-NEXT:    Path to the WPASuite file containing the whole-program 
analysis result consumed by the source transformation. The extension selects 
which file format to use.
 // HELP-NEXT:  --ssaf-include-local-entities
 // HELP-NEXT:    Include block-scope (function-local) declarations in 
extracted SSAF summaries. By default they are omitted.
+// HELP-NEXT:  --ssaf-link-unit-id=<id>
+// HELP-NEXT:    Stable identifier used as the LinkUnit namespace name of 
every produced SSAF link unit.
 // HELP-NEXT:  --ssaf-list-extractors  Display the list of available SSAF 
summary extractors
 // HELP-NEXT:  --ssaf-list-formats     Display the list of available SSAF 
serialization formats
 // HELP-NEXT:  --ssaf-no-extract-from-system-headers
diff --git a/clang/test/Analysis/Scalable/source-edit-generation/cli-errors.cpp 
b/clang/test/Analysis/Scalable/source-edit-generation/cli-errors.cpp
index bc1ea22039525..3212ae10cc8de 100644
--- a/clang/test/Analysis/Scalable/source-edit-generation/cli-errors.cpp
+++ b/clang/test/Analysis/Scalable/source-edit-generation/cli-errors.cpp
@@ -1,16 +1,17 @@
 // CLI errors for the source-edit-generation pipeline. Every misuse of the
-// four `--ssaf-{source-transformation,global-scope-analysis-result,
-// src-edit-file,transformation-report-file}=` options emits a default-error
-// diagnostic under `-Wscalable-static-analysis-framework`. The runner
-// produces no edit/report files and the rest of the compile pipeline is
-// untouched.
+// six `--ssaf-{source-transformation,global-scope-analysis-result,
+// src-edit-file,transformation-report-file,compilation-unit-id,
+// link-unit-id}=` options emits a default-error diagnostic under
+// `-Wscalable-static-analysis-framework`. The runner produces no edit/report
+// files and the rest of the compile pipeline is untouched.
 
 // DEFINE: %{filecheck} = FileCheck %s --match-full-lines --check-prefix
 // DEFINE: %{base} = --ssaf-source-transformation=does-not-exist \
 // DEFINE:   --ssaf-global-scope-analysis-result=%S/Inputs/empty-suite.json \
 // DEFINE:   --ssaf-src-edit-file=%t/edits.yaml \
 // DEFINE:   --ssaf-transformation-report-file=%t/report.sarif \
-// DEFINE:   --ssaf-compilation-unit-id=cu
+// DEFINE:   --ssaf-compilation-unit-id=cu \
+// DEFINE:   --ssaf-link-unit-id=lu
 
 // 
=============================================================================
 // 1. Unknown transformation name.
@@ -33,6 +34,7 @@
 // ORPHAN-COMPANIONS-DAG: error: option '--ssaf-source-transformation=' 
requires '--ssaf-src-edit-file=' to be set 
[-Wscalable-static-analysis-framework]
 // ORPHAN-COMPANIONS-DAG: error: option '--ssaf-source-transformation=' 
requires '--ssaf-transformation-report-file=' to be set 
[-Wscalable-static-analysis-framework]
 // ORPHAN-COMPANIONS-DAG: error: option '--ssaf-source-transformation=' 
requires '--ssaf-compilation-unit-id=' to be set 
[-Wscalable-static-analysis-framework]
+// ORPHAN-COMPANIONS-DAG: error: option '--ssaf-source-transformation=' 
requires '--ssaf-link-unit-id=' to be set [-Wscalable-static-analysis-framework]
 
 // 
=============================================================================
 // 3. Reverse orphans: edit/report file set without transformation option.
diff --git 
a/clang/test/Analysis/Scalable/source-edit-generation/coexistence.cpp 
b/clang/test/Analysis/Scalable/source-edit-generation/coexistence.cpp
index 410022caaa3a9..b392fe0d2e808 100644
--- a/clang/test/Analysis/Scalable/source-edit-generation/coexistence.cpp
+++ b/clang/test/Analysis/Scalable/source-edit-generation/coexistence.cpp
@@ -17,6 +17,7 @@
 // RUN:   --ssaf-src-edit-file=%t/edits.yaml \
 // RUN:   --ssaf-transformation-report-file=%t/report.sarif \
 // RUN:   --ssaf-compilation-unit-id=cu \
+// RUN:   --ssaf-link-unit-id=lu \
 // RUN:   -emit-obj -o %t/test.o %s
 
 // All four artifacts must be present.
diff --git 
a/clang/test/Analysis/Scalable/source-edit-generation/downgradable-errors.cpp 
b/clang/test/Analysis/Scalable/source-edit-generation/downgradable-errors.cpp
index b2c79bc91cd51..008ef47f828dc 100644
--- 
a/clang/test/Analysis/Scalable/source-edit-generation/downgradable-errors.cpp
+++ 
b/clang/test/Analysis/Scalable/source-edit-generation/downgradable-errors.cpp
@@ -9,7 +9,8 @@
 // DEFINE:   --ssaf-global-scope-analysis-result=%S/Inputs/empty-suite.json \
 // DEFINE:   --ssaf-src-edit-file=%t/edits.yaml \
 // DEFINE:   --ssaf-transformation-report-file=%t/report.sarif \
-// DEFINE:   --ssaf-compilation-unit-id=cu
+// DEFINE:   --ssaf-compilation-unit-id=cu \
+// DEFINE:   --ssaf-link-unit-id=lu
 
 // 
=============================================================================
 // 1. -Wno-error=scalable-static-analysis-framework downgrades to a warning.
diff --git a/clang/test/Analysis/Scalable/source-edit-generation/happy-path.cpp 
b/clang/test/Analysis/Scalable/source-edit-generation/happy-path.cpp
index a0e6ab0de7a88..ce79ae5f004fb 100644
--- a/clang/test/Analysis/Scalable/source-edit-generation/happy-path.cpp
+++ b/clang/test/Analysis/Scalable/source-edit-generation/happy-path.cpp
@@ -17,6 +17,7 @@
 // RUN:   --ssaf-src-edit-file=%t/edits.yaml \
 // RUN:   --ssaf-transformation-report-file=%t/report.sarif \
 // RUN:   --ssaf-compilation-unit-id=cu \
+// RUN:   --ssaf-link-unit-id=lu \
 // RUN:   -emit-obj -o %t/test.o %s
 
 // RUN: FileCheck --check-prefix=EDITS --input-file=%t/edits.yaml %s
diff --git 
a/clang/test/Analysis/Scalable/source-edit-generation/write-failure.cpp 
b/clang/test/Analysis/Scalable/source-edit-generation/write-failure.cpp
index 4c077702b1014..3f372d191ffd6 100644
--- a/clang/test/Analysis/Scalable/source-edit-generation/write-failure.cpp
+++ b/clang/test/Analysis/Scalable/source-edit-generation/write-failure.cpp
@@ -20,6 +20,7 @@
 // RUN:   --ssaf-src-edit-file=%t/missing-dir/edits.yaml \
 // RUN:   --ssaf-transformation-report-file=%t/report.sarif \
 // RUN:   --ssaf-compilation-unit-id=cu \
+// RUN:   --ssaf-link-unit-id=lu \
 // RUN:   -emit-obj -o %t/test.o %s 2>&1 | FileCheck --check-prefix=EDIT-FAIL 
%s
 // EDIT-FAIL: warning: failed to write source edits to 
'{{.*}}/missing-dir/edits.yaml'{{.*}}[-Wscalable-static-analysis-framework]
 // RUN: test -e %t/test.o
@@ -36,6 +37,7 @@
 // RUN:   --ssaf-src-edit-file=%t/edits.yaml \
 // RUN:   --ssaf-transformation-report-file=%t/missing-dir/report.sarif \
 // RUN:   --ssaf-compilation-unit-id=cu \
+// RUN:   --ssaf-link-unit-id=lu \
 // RUN:   -emit-obj -o %t/test.o %s 2>&1 | FileCheck 
--check-prefix=REPORT-FAIL %s
 // REPORT-FAIL: warning: failed to write transformation report to 
'{{.*}}/missing-dir/report.sarif'{{.*}}[-Wscalable-static-analysis-framework]
 // RUN: test -e %t/test.o

>From d9c2d04775a6819ce4faa0b3f9b67df85eec5965 Mon Sep 17 00:00:00 2001
From: Ziqing Luo <[email protected]>
Date: Sat, 29 Aug 2026 20:19:38 -0700
Subject: [PATCH 2/2] address comments

---
 .../user-docs/SourceEditGeneration.md         |  4 ++--
 clang/include/clang/Frontend/SSAFOptions.h    |  4 ++--
 clang/include/clang/Options/Options.td        |  4 ++--
 clang/test/Analysis/Scalable/help.cpp         |  2 +-
 .../source-edit-generation/cli-errors.cpp     | 23 +++++++++++++++++++
 5 files changed, 30 insertions(+), 7 deletions(-)

diff --git 
a/clang/docs/ScalableStaticAnalysis/user-docs/SourceEditGeneration.md 
b/clang/docs/ScalableStaticAnalysis/user-docs/SourceEditGeneration.md
index 9a3ed2f10fd4e..af7fc7f56aa8c 100644
--- a/clang/docs/ScalableStaticAnalysis/user-docs/SourceEditGeneration.md
+++ b/clang/docs/ScalableStaticAnalysis/user-docs/SourceEditGeneration.md
@@ -16,8 +16,8 @@ Five options control the pipeline; they are all both 
`--ssaf-…` driver
 options and `cc1` options. The compilation-unit identifier is shared
 with the summary extraction step. A given compilation unit needs to
 receive the same identifier for both summary extraction and source
-edit generation. The link-unit identifier must match the namespace
-name the compilation unit's `WPASuite` result was linked into.
+edit generation. The link-unit identifier must match the identifier
+of the link unit that this compilation unit was linked into.
 
 ```{eval-rst}
 .. list-table::
diff --git a/clang/include/clang/Frontend/SSAFOptions.h 
b/clang/include/clang/Frontend/SSAFOptions.h
index 81bf686442c97..cfdc019395d2a 100644
--- a/clang/include/clang/Frontend/SSAFOptions.h
+++ b/clang/include/clang/Frontend/SSAFOptions.h
@@ -42,8 +42,8 @@ class SSAFOptions {
   /// Controlled by: --ssaf-global-scope-analysis-result
   std::string GlobalScopeAnalysisResult;
 
-  /// Stable identifier used as the name of the `LinkUnit` `BuildNamespace` of
-  /// every produced link unit. Controlled by: --ssaf-link-unit-id
+  /// Stable identifier of the link unit that this compilation unit was
+  /// linked into. Controlled by: --ssaf-link-unit-id
   std::string LinkUnitId;
 
   /// Path of the source-edit output file produced by the source
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index c5758ec7b557c..1b0ace3b90390 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -1027,8 +1027,8 @@ def _ssaf_link_unit_id :
   Group<SSAF_Group>,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<
-    "Stable identifier used as the LinkUnit namespace name of every "
-    "produced SSAF link unit.">,
+    "Stable identifier of the link unit that this compilation unit was "
+    "linked into.">,
   MarshallingInfoString<SSAFOpts<"LinkUnitId">>;
 def _ssaf_src_edit_file :
   Joined<["--"], "ssaf-src-edit-file=">,
diff --git a/clang/test/Analysis/Scalable/help.cpp 
b/clang/test/Analysis/Scalable/help.cpp
index c4220ff527bc5..73041823d27cd 100644
--- a/clang/test/Analysis/Scalable/help.cpp
+++ b/clang/test/Analysis/Scalable/help.cpp
@@ -12,7 +12,7 @@
 // HELP-NEXT:  --ssaf-include-local-entities
 // HELP-NEXT:    Include block-scope (function-local) declarations in 
extracted SSAF summaries. By default they are omitted.
 // HELP-NEXT:  --ssaf-link-unit-id=<id>
-// HELP-NEXT:    Stable identifier used as the LinkUnit namespace name of 
every produced SSAF link unit.
+// HELP-NEXT:    Stable identifier of the link unit that this compilation unit 
was linked into.
 // HELP-NEXT:  --ssaf-list-extractors  Display the list of available SSAF 
summary extractors
 // HELP-NEXT:  --ssaf-list-formats     Display the list of available SSAF 
serialization formats
 // HELP-NEXT:  --ssaf-no-extract-from-system-headers
diff --git a/clang/test/Analysis/Scalable/source-edit-generation/cli-errors.cpp 
b/clang/test/Analysis/Scalable/source-edit-generation/cli-errors.cpp
index 3212ae10cc8de..2c746222363ae 100644
--- a/clang/test/Analysis/Scalable/source-edit-generation/cli-errors.cpp
+++ b/clang/test/Analysis/Scalable/source-edit-generation/cli-errors.cpp
@@ -12,6 +12,11 @@
 // DEFINE:   --ssaf-transformation-report-file=%t/report.sarif \
 // DEFINE:   --ssaf-compilation-unit-id=cu \
 // DEFINE:   --ssaf-link-unit-id=lu
+// DEFINE: %{base-no-link-unit-id} = 
--ssaf-source-transformation=does-not-exist \
+// DEFINE:   --ssaf-global-scope-analysis-result=%S/Inputs/empty-suite.json \
+// DEFINE:   --ssaf-src-edit-file=%t/edits.yaml \
+// DEFINE:   --ssaf-transformation-report-file=%t/report.sarif \
+// DEFINE:   --ssaf-compilation-unit-id=cu
 
 // 
=============================================================================
 // 1. Unknown transformation name.
@@ -50,4 +55,22 @@
 // ORPHAN-REPORT: error: option '--ssaf-transformation-report-file=' is 
ignored without '--ssaf-source-transformation=' 
[-Wscalable-static-analysis-framework]
 // RUN: not test -e %t/r.sarif
 
+// 
=============================================================================
+// 4. Missing or empty --ssaf-link-unit-id= alone (all other companions set).
+// 
=============================================================================
+
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: not %clang     -c %s -o %t/test.o %{base-no-link-unit-id} 2>&1 | 
%{filecheck}=MISSING-LINK-UNIT-ID
+// RUN: not %clang_cc1    %s              %{base-no-link-unit-id} 2>&1 | 
%{filecheck}=MISSING-LINK-UNIT-ID
+// RUN: not test -e %t/edits.yaml
+// RUN: not test -e %t/report.sarif
+
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: not %clang     -c %s -o %t/test.o %{base-no-link-unit-id} 
--ssaf-link-unit-id= 2>&1 | %{filecheck}=MISSING-LINK-UNIT-ID
+// RUN: not %clang_cc1    %s              %{base-no-link-unit-id} 
--ssaf-link-unit-id= 2>&1 | %{filecheck}=MISSING-LINK-UNIT-ID
+// RUN: not test -e %t/edits.yaml
+// RUN: not test -e %t/report.sarif
+
+// MISSING-LINK-UNIT-ID: error: option '--ssaf-source-transformation=' 
requires '--ssaf-link-unit-id=' to be set [-Wscalable-static-analysis-framework]
+
 void foo() {}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to