Skip to content

Support C++ Modules in code analysis - #45

Open
Gabriel Dos Reis (gdr-at-ms) wants to merge 1 commit into
microsoft:mainfrom
gdr-at-ms:support-cxx-modules
Open

Support C++ Modules in code analysis#45
Gabriel Dos Reis (gdr-at-ms) wants to merge 1 commit into
microsoft: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.
Fixesmicrosoft#44
Sign up for freeto 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

@gdr-at-ms