Repository navigation
🐛 sphinx-codelinks: read a compile-database entry's -- as the compiler does - #2510
Merged
Merged
Conversation
Two shared extraction cases for the libclang engine: an entry that ends its options with `--` before its input (only the active arms' markers are extracted), and an entry whose `--` is the value of -Xlinker (the -DFEATURE after it is still read as an option). Both fail against the current code: the first extracts the markers of every arm, the second loads no translation unit and extracts nothing.
… only there filter_args leaves an options-ending `--` out with every argument after it (they are inputs), so the arguments the libclang engine adds are no longer read as inputs and the parse keeps its preprocessing record. A `--` that is an option's value ends nothing. libclang, though, takes the first `--` of its arguments for the end of the options whatever precedes it, so none is passed on: a pass-through option (-Xlinker, -Xclang, -mllvm, -Xarch_<arch>, -Xopenmp-target=<triple>, ...) whose value is `--` is left out with it, and a -I/-include/-isystem/-iquote/-idirafter/-isysroot/-x whose value is `--` is joined to it (-I--), which the driver reads the same. Any other pass-through value is kept verbatim with its option. filter_args asks builtin_headers.passes_next_argument, the predicate the -resource-dir placement uses, so there is one list of pass-through options; -mllvm joins it. env_version 7: records extracted with such an entry change.
The driver reads the value of -Xarch_host (and of -Xarch_<arch> for the architecture a Mach-O target compiles) as one of its own options, so filter_args routes it through the rules a bare option goes through: a value that would be left out (-MD, -MMD, -c, -o out.o, -MF dep.d, the input) is left out with its -Xarch_*. Passed on, -Xarch_host -MD made the parse write a dependency file into the working directory. The filter_args docstring and the docs now say exactly which options' `--` value ends nothing, and why leaving a pass-through option out with its `--` loses nothing: a real compile rejects a `--` handed to the compiler or the driver, and the other tools have no say in preprocessing. Two tests run the joined -I-- and the inputs after an entry's `--` through libclang.
…entry; -x -- promises nothing
Documentation build overview
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #2510 +/- ##
=======================================
Coverage 95.10% 95.11%
=======================================
Files 161 161
Lines 31392 31415 +23
=======================================
+ Hits 29856 29880 +24
+ Misses 1536 1535 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
packages/sphinx-codelinks: the libclang engine now reads acompile_commands.jsonentry whose arguments contain--correctly.An options-ending
--(clang-cl ... -c -- src/a.cpp, as CMake writes it for clang-cl) is left out together with every argument after it (compile_db.filter_args), because those arguments are inputs.A
--that is an option's value ends nothing, and the options after it are still read. That covers-Xlinker --,-mllvm --,-Xopenmp-target=<triple> --,-I --and similar.No
--is ever passed on to libclang. libclang reads the first literal--in its arguments as the end of the options, whatever comes before it: it inserts-fsyntax-onlyahead of that--before the driver runs. So:--is left out together with that value;-I,-include,-isystem,-iquote,-idirafteror-isysrootwith a--value is joined into one argument (-I--), which the driver reads the same way.Leaving out a pass-through pair loses nothing a working entry has. Real clang rejects a
--handed to the compiler or the driver:-Xclang --and-Xpreprocessor --give "unknown argument: '--'";-Xarch_host --gives "invalid Xarch argument".The other pass-through options hand the
--to a tool or stage that plays no part in preprocessing (the linker, the assembler, LLVM's backend). Nothing is promised for any other option whose value is--(-x --,-D --).The value of
-Xarch_<arch>is one of the driver's own options, so it goes through the same rules as a bare option.-Xarch_host -MD,-c,-o out.o, the input and so on are left out together with their-Xarch_*. Passed on,-Xarch_host -MDwould make the parse write a dependency file. The values of the other pass-through options are kept verbatim with them.One list of pass-through options.
filter_argsasksbuiltin_headers.passes_next_argument, the predicate the-resource-dirplacement already used.-mllvmis added to that list.env_versionis now 7, so an environment holding records extracted the old way is read again once.Why
When the
--was passed on, the arguments libclang appends after the entry's own were read as input files. Those include the request for the detailed preprocessing record. As a result, the parse had no record and no skipped ranges, so the markers of every#ifarm were extracted. An entry with-Xlinker --could not be loaded at all, and all of its file's markers were dropped.Tests
tests/data/extraction/preproc_compile_db.yaml, committed first and failing on the previous code:options_terminator_in_entry_libclang: only the active arms' markers are extracted;double_dash_value_of_pass_through_option_libclang(-Xlinker -- -DFEATURE): the#ifdef FEATUREmarker is extracted and the#ifndefone is not.tests/test_preproc_compile_db.pycovers:--as the last argument, and two--;--and by another value;-I--family and-o --;-Xopenmp-target=<triple> --against-Xopenmp-target <triple> --;commandform;-Xarch_<arch>value read as a bare option.-I --and-- case.cpp other.cppis parsed with the header the joined-I--finds;-Xarch_host -MDwrites no.dfile.tests/test_builtin_headers.py:-mllvmhands its argument on, checked against the driver.tests/test_preproc_includer.py: an environment atenv_version6 is read again.Checklist
uv run poe test-<package>) and they pass.docs/changelog.rsthas an entry under Unreleased.uv run poe lintanduv run poe typecheckpass.