Skip to content

fix: document only a file's own declarations, parsed with all its preprocessor options - #9

Draft
ubmarco wants to merge 2 commits into
cuinixam:mainfrom
useblocks:fix/docs-main-file-only
Draft

ubmarco wants to merge 2 commits into
cuinixam:mainfrom
useblocks:fix/docs-main-file-only

Conversation

@ubmarco

@ubmarco ubmarco commented Oct 1, 2026

Copy link
Copy Markdown

Two fixes for clanguru docs, found while generating the source listings of SPLED with spl-core. Both made a listing show code that is not the file's, or not the configuration the file is built in.

1. Document only the declarations of the source file itself

generate_doc_structure documented every function definition and class of the translation unit, including those of the headers the file includes. For a GoogleTest file this lists libstdc++'s __gthread_* functions from gthr-default.h and gtest's RUN_ALL_TESTS, with those headers' line numbers, under the title of the test file.

On a machine where libclang finds the system headers, test_doc_structure_for_gtest_files already fails on main for this reason (the expected file has no __gthread_* functions).

  • The parser is unchanged: the mock generator needs the headers' declarations.
  • The documentation now takes only declarations located in the source file.
  • RUN_ALL_TESTS is gone from tests/data/test_gtest.cc.md: it comes from gtest.h, not from the test file.

2. Keep every preprocessor option of the compile command

Only -I and -D were taken from the compilation database. This one is the more serious of the two:

  • What was dropped: a directory passed as -isystem, and the options -iquote, -idirafter, -include, -imacros and -U.
  • Effect: libclang parsed the file without those headers, so every #ifdef on a macro they define took the wrong branch.
  • Real case: SPLED's feature header reaches the test sources through -isystem. Its listings showed the "no feature defined" branch, which put a test specification of another product variant into the variant's report.

-std=, -W* and -O* are still not passed, as before.

Tests

  • test_doc_structure_lists_only_the_declarations_of_the_source_file: a source including a local header that defines a function and a class.
  • test_doc_structure_follows_the_branches_of_a_system_include: a macro from an -isystem header selects the branch.
  • A parametrized case of test_get_includes_and_defines with the added options.

Both new tests fail without their fix. pypeline run passes locally: pre-commit, 139 passed / 4 skipped, and the docs build. The docs build's 7 autodoc import warnings are the same as without these changes.

`clanguru docs` documented every function definition and class of the
translation unit, including those of the headers it includes. For a
GoogleTest file this lists libstdc++'s `__gthread_*` functions from
gthr-default.h and gtest's `RUN_ALL_TESTS`, with those headers' line
numbers, under the title of the test file. Wherever libclang finds the
system headers, test_doc_structure_for_gtest_files failed on main for the
same reason.

The parser keeps every declaration, because the mock generator needs the
headers' ones; the documentation now takes only those located in the
source file.
Only -I and -D were taken from the compilation database. A directory
passed as -isystem (CMake does so for SYSTEM includes, and for the
generated configuration headers of some build systems) was dropped, as
were -iquote, -idirafter, -include, -imacros and -U. libclang then parsed
the file without those headers, and every `#ifdef` on a macro they define
took the wrong branch: the documentation showed the code of a
configuration the file is not built in.

@cuinixam cuinixam left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

👍

def _filter_includes_and_defines(options: list[str]) -> list[str]:
"""Keep only -I and -D flags (including their values when passed as separate arguments)."""
#: Options that decide what the preprocessor sees: include paths, macros and forced includes.
PREPROCESSOR_OPTIONS = ("-I", "-D", "-U", "-isystem", "-iquote", "-idirafter", "-include", "-imacros")

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

There might still be options which are ignored but the gap is smaller than before.

@cuinixam

cuinixam commented Oct 9, 2026

Copy link
Copy Markdown
Owner

@ubmarco is there anything else you want to change in this PR? Otherwise I will remove the draft flag and merge it.

This branch had an error being deployed

1 failed deployment
release — 07b8843b Deployed Oct 5, 2026 by ubmarco via release #73
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.

2 participants