feat: support macros#1192
Conversation
|
| Scope | Lines Δ% | Lines Δ | Lines + | Lines - | Files Δ | Files + | Files ~ | Files ↔ | Files - |
|---|---|---|---|---|---|---|---|---|---|
| 🥇 Golden Tests | 78% | 3800 | 3800 | - | 53 | 53 | - | - | - |
| 🛠️ Source | 22% | 1087 | 1062 | 25 | 35 | 6 | 29 | - | - |
| 🏗️ Build | <1% | 13 | 13 | - | 1 | - | 1 | - | - |
| Total | 100% | 4900 | 4875 | 25 | 89 | 59 | 30 | - | - |
Legend: Files + (added), Files ~ (modified), Files ↔ (renamed), Files - (removed)
🔝 Top Files
- test-files/golden-tests/symbols/macro/macros.xml (Golden Tests): 649 lines Δ (+649 / -0)
- test-files/golden-tests/symbols/macro/macros.html (Golden Tests): 531 lines Δ (+531 / -0)
- test-files/golden-tests/symbols/macro/macros.adoc (Golden Tests): 397 lines Δ (+397 / -0)
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1192 +/- ##
========================================
Coverage 82.12% 82.12%
========================================
Files 33 33
Lines 3149 3149
Branches 734 734
========================================
Hits 2586 2586
Misses 387 387
Partials 176 176
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
An automated preview of the documentation is available at https://1192.mrdocs.prtest2.cppalliance.org/index.html If more commits are pushed to the pull request, the docs will rebuild at the same URL. 2026-05-04 06:09:45 UTC |
c1ce891 to
a42ad72
Compare
|
Thanks for exploring this. This is a complex issue.
Interesting. I thought it would be easier to have a preprocessor step just for macros.
This seems extremely problematic because the counterexamples where it doesn't work would be kind of obvious. Clang doesn't even attach comments to anything if there's not close to a symbol, which is probably the case when there's a macro. My intuition is we can't really implement this feature unless clang wants to attach comments to macros or we implement our own parser (which we also intend to).
How do these compare to doxygen? Shouldn't we have some special options for macros? I'm not sure. I assume macros are somewhat special in terms of what's typically hidden or shown, but I haven't thought too much about it. I think @mizvekov would probably be more qualified to review this issue and PR. |
This adds support for preprocessing macros: `#define` directives are
captured via a `clang::PPCallbacks` subclass and exposed as
`MacroSymbol` instances at the corpus root (macros aren't in any C++
scope, so they sit alongside the global namespace rather than under it).
Doc-comment association: Clang doesn't link comments to macros, so we
look up a preceding doc-comment by source location. A comment is
attached only when the lines between it and the directive are blank.
Filters apply to macros, too:
- `extract-all`: when off, undocumented macros are dropped.
- `exclude-symbols`, `include-symbols`, `implementation-defined`,
`see-below`: matched against the macro name.
- File-pattern filters: matched against the directive's source location.
Schema additions: `<macro>` is a new top-level element in mrdocs.rnc,
sibling of `<namespace>`, with `<source>` carrying the verbatim
definition (modulo a minor normalization).
New output pages: multipage mode now produces `macros.{ext}` at the
output root, listing every macro with a link to its per-symbol page. The
global-namespace page gains a "See also: Macros" navigation hint at the
bottom (multipage-only) so the new page is discoverable.
Macro `@param` blocks are validated.
Golden tests also cover the three filter paths (`extract-all: false`,
`include-symbols`, `exclude-symbols`).
Closes issue cppalliance#1127.
a42ad72 to
32e9ccf
Compare
Hmm... I'm listening for
Why? The current condition for accepting a preceding comment is that it is separated from the macro definition by blank lines only (and it is a doc-comment). We could tighten that to "no lines at all between the comment and the macro definition"; or maybe we can accept at most one line that is blank.
I surveyed Doxygen's options. They are:
Would you like to add any of these to MrDocs? |
Oh... OK. That's good. I had only made the comment because your previous comment only said by "source location", which implied there could be content between the macro and the source location. But what you mentioned sounds great.
No. Great survey. Thanks. I think my original comment was more specific about filtering macros. But that’s great. If there are no specific options to filter macros by name, let's just go with what we have. Sounds great. One more question: if clang doesn't attach comments to macros like it does to the Decls, how do we find these comments? Do we look for comments attached to something else that should be attached to macros and then move them to the macros? I don't really understand it yet. |
|
Good question. Clang's |
This adds support for preprocessing macros:
#definedirectives are captured via aclang::PPCallbackssubclass and exposed asMacroSymbolinstances at the corpus root (macros aren't in any C++ scope, so they sit alongside the global namespace rather than under it).Doc-comment association: Clang doesn't link comments to macros, so we look up a preceding doc-comment by source location. A comment is attached only when the lines between it and the directive are blank.
Filters apply to macros, too:
extract-all: when off, undocumented macros are dropped.exclude-symbols,include-symbols,implementation-defined,see-below: matched against the macro name.Schema additions:
<macro>is a new top-level element in mrdocs.rnc, sibling of<namespace>, with<source>carrying the verbatim definition (modulo a minor normalization).New output pages: multipage mode now produces
macros.{ext}at the output root, listing every macro with a link to its per-symbol page. The global-namespace page gains a "See also: Macros" navigation hint at the bottom (multipage-only) so the new page is discoverable.Macro
@paramblocks are validated.Golden tests also cover the three filter paths (
extract-all: false,include-symbols,exclude-symbols).Closes issue #1127.
Adds first-class support for preprocessing macros.
#definedirectives are captured through aclang::PPCallbackssubclass (MacroCollector) and surfaced asMacroSymbolinstances at the corpus root — macros aren't in any C++ scope, so they sit alongside the global namespace rather than under it. Closes #1127.Several pieces fit together:
#definedirective are blank, matching how a contributor would intuitively expect it to bind.extract-all(when off, undocumented macros are dropped),exclude-symbols/include-symbols/implementation-defined/see-below(matched against the macro name), and file-pattern filters (matched against the directive's source location).<macro>becomes a new top-level element inmrdocs.rnc, sibling of<namespace>, with<source>carrying the verbatim definition (modulo a minor normalization).macros.{ext}at the output root, listing every macro with a link to its per-symbol page. The global-namespace page gains a "See also: Macros" navigation hint at the bottom (multipage-only) so the new page is discoverable.@paramvalidation: Macro@paramblocks are validated like for functions.Changes
src/lib/AST/MacroCollector.{cpp,hpp}(thePPCallbackssubclass) wired intoASTVisitor.{cpp,hpp}andASTAction.cpp. Newinclude/mrdocs/Metadata/Symbol/Macro.hppdefiningMacroSymbol;Metadata.hpp,Symbol/SymbolKind.hpp, andSymbol/SymbolNodes.incextended with the new symbol kind;include/mrdocs/Corpus.hppandsrc/lib/Corpus.cppexpose macros at the corpus root.Metadata/Finalizers/DocCommentFinalizer.cppcarries the doc-comment-by-source-location association and macro-@paramvalidation. Handlebars generators (Gen/hbs/Builder.cpp,HandlebarsGenerator.cpp,SinglePageVisitor.cpp) emit macro pages and the navigation hint on the global-namespace page; newshare/mrdocs/addons/generator/{adoc,html}/layouts/macros-index.*.hbsandshare/mrdocs/addons/generator/common/partials/symbol/signature/macro.hbsare the template-side pieces.test-files/golden-tests/symbols/macro/(macros,macros-edge-cases,macros-extraction-modes,macros-embedded,macros-multi-file) cover the happy path, edge cases, extraction modes, multi-file inputs, and macros embedded in other constructs. Three filter-coverage fixtures undertest-files/golden-tests/config/:extract-all/no-extract-all-macros,include-symbols/macros-allowlist,exclude-symbols/macros-excluded. One multipage fixture undertest-files/golden-tests/config/multipage/multipage-macrosproves the newmacros.{ext}page and per-symbol pages are generated.mrdocs.rncextended with the new<macro>element and its children.<macro>element — downstream tooling that consumes mrdocs output and assumes the previous set of top-level elements will need to add a clause for macros.Testing
test-files/golden-tests/symbols/macro/andtest-files/golden-tests/config/are the verification layer. Each runs the full pipeline (parse → preprocess capture → finalize → generate) against fixed.cppinputs and asserts the resulting.xml/.html/.adocoutput byte-for-byte. The fixtures cover the main flow, edge cases, extraction modes, multi-file inputs, embedded macros, multipage output, and each of the three filter paths individually.test-files/golden-tests/on every build, so the new trees stay covered automatically going forward.Documentation
No user-facing documentation is added in this PR. The schema (
mrdocs.rnc) is updated for the new<macro>element, but a how-to / reference page underdocs/modules/ROOT/pages/describing macro support — what gets captured, how the doc-comment association rule works, how the filters apply, and the new multipagemacrospage — is worth adding as a follow-up so the feature is discoverable for users browsing the documentation rather than the schema.