When running IWYU, process source files before headers

Suppose the following:

`foo.cpp` refers to the symbol `Bar`, declared in `bar.h`.
`foo.h` includes `bar.h`.
`foo.cpp` includes `foo.h`, but not `bar.h`.
`foo.h` does not refer to any symbols declared in `bar.h`.

If we process `foo.h` first, `#include "bar.h"` will be removed, causing IWYU to
fail with an error when it tries to process `foo.cpp`, but if we process them in
the other order, `foo.cpp` will get that include before it gets removed from
`foo.h`.  This change sorts the files to be processed, putting all cpp files
first, then all header files, minimizing that problem.

We could do even better by saving the results from `include-what-you-use` for
every file, then going back and calling `fix_includes.py` on each of them, but I
don't think it's worth it.

Signed-off-by: Michael Richters <gedankenexperimenter@gmail.com>
pull/1162/head
Michael Richters 3 years ago
parent 21d78160f4
commit a7e6f3f072
No known key found for this signature in database
GPG Key ID: 1288FD13E4EEF0C0

@ -3,4 +3,6 @@
: "${KALEIDOSCOPE_DIR:=$(pwd)}" : "${KALEIDOSCOPE_DIR:=$(pwd)}"
cd "${KALEIDOSCOPE_DIR}" || exit 1 cd "${KALEIDOSCOPE_DIR}" || exit 1
git ls-files -m | grep -E '\.(h|cpp)$' | xargs "${KALEIDOSCOPE_DIR}"/bin/iwyu.py # Process sources first, then headers to minimize errors from removed includes
git ls-files -m | grep -E '\.(cpp|ino)$' | xargs "${KALEIDOSCOPE_DIR}"/bin/iwyu.py
git ls-files -m | grep -E '\.h$' | xargs "${KALEIDOSCOPE_DIR}"/bin/iwyu.py

@ -296,12 +296,24 @@ def main():
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
regex = re.compile(opts.regex) regex = re.compile(opts.regex)
# Process source files first, then header files, because a source file might have been
# relying on a header included by its associated header, but which that header does not
# need on its own. In this case, if we process the header first, IWYU won't be able to
# parse the source file, and we'll get an error, but if we do them in the other order,
# it'll be fine.
source_files = []
header_files = []
for target_file in (_ for t in targets for _ in build_target_list(t, regex)):
if target_file.endswith('.cpp') or target_file.endswith('.ino'):
source_files.append(target_file)
else:
header_files.append(target_file)
exit_code = 0 exit_code = 0
for src in (_ for t in targets for _ in build_target_list(t, regex)): for target_file in source_files + header_files:
if src in ignores: if target_file in ignores:
logging.info("Skipping ignored file: %s", os.path.relpath(src)) logging.info("Skipping ignored file: %s", os.path.relpath(target_file))
continue continue
if not run_iwyu(os.path.relpath(src), iwyu_cmd, fix_includes_cmd): if not run_iwyu(os.path.relpath(target_file), iwyu_cmd, fix_includes_cmd):
exit_code = 1 exit_code = 1
return exit_code return exit_code

Loading…
Cancel
Save