Skip to content

Support C++ Modules in code analysis#45

Open
gdr-at-ms wants to merge 1 commit intomicrosoft:mainfrom
gdr-at-ms:support-cxx-modules
Open

Support C++ Modules in code analysis#45
gdr-at-ms wants to merge 1 commit intomicrosoft:mainfrom
gdr-at-ms:support-cxx-modules

Conversation

@gdr-at-ms
Copy link
Copy Markdown
Member

Summary

Add support for analyzing CMake projects that use C++ Modules (named modules, module partitions, and module implementation units).

Problem

The action fails on projects with C++ Modules because it passes each source file to cl.exe /analyze:only independently, without awareness of module dependencies. This causes errors because:

  • Module interface units require -interface and -ifcOutput flags
  • Sources that import modules need -reference flags to resolve imports
  • Module interfaces must be analyzed before their consumers

See #44 for the original report.

Fix

The fix leverages two artifacts that CMake already generates during its dependency scan phase:

  1. P1689R5 dependency files (.ddi) — contain provides and requires entries for each source, enabling construction of a module dependency graph.

  2. Module map files (.modmap) — contain the exact -interface, -ifcOutput, and -reference flags needed for each source's compilation.

Changes to index.js:

  • CompileCommand: new ddiFile and modmapFile fields to track CMake-generated artifacts alongside each source.
  • loadCompileCommands: locate .ddi and .modmap files for each source in the CMake build directory.
  • resolveModuleDependencies (new function): read .ddi files to build a module dependency graph, add implicit partition-to-primary dependencies, and topologically sort sources so providers are analyzed before consumers.
  • createAnalysisCommands: iterate in topological order and pass each source's @<modmap> response file to cl.exe so it receives the correct module flags.

Key design decisions:

  • CMake does the heavy lifting. The action doesn't parse module semantics — it reads CMake's .ddi for ordering and passes CMake's .modmap verbatim. If CMake changes its module support, the action follows automatically.
  • Zero overhead for non-module projects. If no .ddi files exist or none contain module providers, the new code paths are not taken and the original ordering is preserved.
  • Partition workaround. CMake's dependency scanner may not capture the implicit dependency between a primary module interface and its partitions. The action infers this from the naming convention (X depends on X:<part>).

Testing

Tested locally against the IPR project (branch modules/cxx-ipr-traversal-io) which has 7 C++ Module interface units, 4 module implementation units, and 4 non-module source files. All sources that exist on the branch pass analysis (10 passed, 1 pre-existing input.cxx failure unrelated to modules).

Fixes #44

Add support for analyzing projects that use C++ Modules (named modules,
module partitions, and module implementation units) built with CMake.

Previously, the action passed each source file to cl.exe /analyze:only
independently, without awareness of module dependencies.  This caused
failures on projects using C++ Modules because:
  - Module interface units require -interface and -ifcOutput flags
  - Sources that import modules need -reference flags to resolve imports
  - Module interfaces must be analyzed before their consumers

The fix leverages two artifacts that CMake already generates during its
dependency scan phase:

  1. P1689R5 dependency files (.ddi) — contain 'provides' and 'requires'
     entries for each source, enabling construction of a dependency graph.

  2. Module map files (.modmap) — contain the exact -interface, -ifcOutput,
     and -reference flags needed for each source's compilation.

Changes:
  - CompileCommand: new ddiFile and modmapFile fields to track the paths
    of these CMake-generated artifacts alongside each source.
  - loadCompileCommands: locate .ddi and .modmap files for each source
    in the CMake build directory.
  - resolveModuleDependencies (new): read .ddi files to build a module
    dependency graph, add implicit partition-to-primary dependencies
    (workaround for a possible CMake scanner gap), and topologically
    sort sources so providers are analyzed before consumers.
  - createAnalysisCommands: iterate in topological order and pass each
    source's @<modmap> response file to cl.exe so it receives the correct
    module flags.

For projects without C++ Modules, the behavior is unchanged: no .ddi or
.modmap files exist, so the new code paths are not taken.

Fixes microsoft#44
@gdr-at-ms gdr-at-ms force-pushed the support-cxx-modules branch from 898b9b0 to 360ae8f Compare March 17, 2026 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Action fails on projects using C++20 module interface units (.ixx files)

1 participant