Skip to content

Migrate IPR non-mutating headers to C++20 modules (includes and supersedes #322)#323

Merged
GabrielDosReis merged 5 commits intoGabrielDosReis:mainfrom
gdr-at-ms:modules/cxx-ipr-traversal-io
Mar 17, 2026
Merged

Migrate IPR non-mutating headers to C++20 modules (includes and supersedes #322)#323
GabrielDosReis merged 5 commits intoGabrielDosReis:mainfrom
gdr-at-ms:modules/cxx-ipr-traversal-io

Conversation

@gdr-at-ms
Copy link
Copy Markdown
Contributor

Summary

Migrate the IPR interface, traversal, and io headers to C++20 named modules. This PR includes and supersedes #322 (Migrate IPR interface to C++20 module cxx.ipr), building on that work to also modularize <ipr/traversal> and <ipr/io>. Together, this completes the modularization of all non-mutating IPR components.

Modules introduced

  • cxx.ipr (from PR Migrate IPR interface to C++20 module cxx.ipr #322) — the semantic node hierarchy, Visitor, Lexicon. Three partitions: :vocabulary, :syntax, and the primary interface.
  • cxx.ipr.traversal — structural comparison (structurally_same, denote_builtin_type), visitor adapters (Constant_visitor<F>, No_op, Missing_overrider), and util::view<T>.
  • cxx.ipr.io — the XPR pretty-printer: Printer, xpr_decl/xpr_stmt/xpr_type/xpr_expr, and their operator<< overloads.

Key architectural decisions

  • physically_same and as<> in cxx.ipr:vocabulary. Both are vocabulary-level predicates depending only on Node&. This eliminates duplicates, removes the need for <ipr/impl> to import cxx.ipr.traversal, and avoids a GCC-rejected import cycle.

  • util::std_insertable defined solely in cxx.ipr.io. Removed from <ipr/utility-impl> — single source of truth.

  • Module interfaces import only cxx.ipr. Implementation-only dependencies are in the .cxx files (minimize interface dependencies).

  • Separate modules, not partitions for traversal and io — optional subsystems with distinct rates of change.

Testing

Compiler Stdlib Result
MSVC 19.50 (VS 18 Preview)
GCC 15.2 libstdc++
Clang 21.1 libstdc++
Clang 21.1 libc++

Documentation

  • reports/implementing-cxx-ipr-traversal-io.md — eight lessons learned during this migration
  • reports/implementing-cxx-ipr-module.md — lessons from the cxx.ipr migration (PR Migrate IPR interface to C++20 module cxx.ipr #322)
  • reports/modularizing-traversal-and-io.md — architecture plan
  • reports/modularizing-ipr-interface.md — original architecture plan for cxx.ipr

@gdr-at-ms gdr-at-ms force-pushed the modules/cxx-ipr-traversal-io branch 2 times, most recently from 41bd17c to dfe7945 Compare March 17, 2026 07:05
Replace <ipr/interface> and its transitive header dependencies with a
named C++20 module expressed as three partitions:

  cxx.ipr:vocabulary  - structural templates, enums, locations
  cxx.ipr:syntax      - tokens, attributes, declarators, constraints
  cxx.ipr             - semantic node hierarchy, Visitor, Lexicon

New files:
  src/cxx-ipr-vocabulary.ixx  - :vocabulary partition
  src/cxx-ipr-syntax.ixx      - :syntax partition
  src/cxx-ipr.ixx             - primary module interface
  src/cxx-ipr.cxx             - module implementation unit
  include/ipr/std-preamble    - TEMPORARY standard header preamble
  include/ipr/utility-impl    - impl-only utility types (rb_tree, etc.)

Removed headers: interface, synopsis, ancillary, location, attribute,
cxx-form, utility, and src/interface.cxx.

Tested on MSVC 19.50, GCC 15.2, Clang 21.1 (libstdc++ and libc++).
Preserve the original form and content of comments that were
inadvertently dropped or reformatted when migrating headers to
C++20 module partitions:

- cxx-ipr-syntax.ixx: restore '// -- ' prefix on the design
  rationale comment block (matching the original <ipr/cxx-form>)
- cxx-ipr-vocabulary.ixx: restore box-style section dividers,
  add missing directive forward declarations section, add
  'distinguished node' section, restore multi-line inline
  comments on Phantom, Demotion, and Label
- cxx-ipr.cxx: add Visitor sub-hierarchy forwarding rationale
  and section headers (Types, Expressions, Directives,
  Statements, Declarations) from the original traversal.cxx
- utility-impl: restore rb_tree algorithm comments (rotation
  operations, chain/container insert documentation, string
  pool description)
Introduce two new named modules:
  - cxx.ipr.traversal: structural comparison, visitor utilities
  - cxx.ipr.io: the XPR pretty-printer

Move physically_same and as<> from the traversal module to
cxx.ipr's :vocabulary partition, where they belong: both are
vocabulary-level predicates depending only on Node&.

New files:
  - src/cxx-ipr-traversal.ixx (module interface)
  - src/cxx-ipr-traversal.cxx (module implementation unit)
  - src/cxx-ipr-io.ixx (module interface)
  - src/cxx-ipr-io.cxx (module implementation unit)

Deleted files:
  - include/ipr/traversal (replaced by cxx.ipr.traversal)
  - include/ipr/io (replaced by cxx.ipr.io)
  - src/traversal.cxx (renamed to cxx-ipr-traversal.cxx)
  - src/io.cxx (renamed to cxx-ipr-io.cxx)

Key changes:
  - Export physically_same and as<> from cxx.ipr:vocabulary.
    This eliminates the as<> duplicate that was in cxx-ipr.cxx,
    and removes the need for <ipr/impl> to import cxx.ipr.traversal.
  - Define util::std_insertable solely in cxx.ipr.io (removed
    from <ipr/utility-impl> where it was the only consumer).
  - Both module interfaces import only cxx.ipr; implementation-
    only dependencies (cxx.ipr.traversal in cxx-ipr-io.cxx,
    <typeinfo> in cxx-ipr-traversal.cxx) are in the .cxx files.
  - Update CMakeLists.txt: new module file sets, renamed sources,
    removed deleted headers from PRIVATE list.
  - Update consumer TUs: only files that use traversal-specific
    symbols (Constant_visitor, util::view, etc.) import
    cxx.ipr.traversal; others get physically_same from cxx.ipr.

Tested on:
  - MSVC 19.50 (VS 18 Preview): pass
  - GCC 15.2: pass
  - Clang 21.1 (libstdc++): pass
  - Clang 21.1 (libc++): pass
@gdr-at-ms gdr-at-ms force-pushed the modules/cxx-ipr-traversal-io branch from dfe7945 to e584ff7 Compare March 17, 2026 10:59
@GabrielDosReis GabrielDosReis merged commit 3ada312 into GabrielDosReis:main Mar 17, 2026
12 checks passed
@@ -0,0 +1,45 @@
// -*- C++ -*-
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this not import std?

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.

3 participants