VSCode + IWYU

This extension integrates Include What You Use or short `IWYU` in VSCode.

“Include what you use means this: for every symbol (type, function, variable, or macro) that you use in foo.cc (or foo.cpp), either foo.cc or foo.h should include a .h file that exports the declaration of that symbol. (Similarly, for foo_test.cc, either foo_test.cc or foo.h should do the including.) Obviously symbols defined in foo.cc itself are excluded from this requirement.” [IWYU]

Features

1. The extension automatically detects unused includes and provides diagnostic squiggles which come with a quickfix that invokes IWYU.

2. Manually optimize the include files for the current C/C++ file by pressing cmd-shit-P + I + W + Y + U, then select “Include What You Use (current file). The extension will then lookup the current editor’s file in the compile_commands.json file. If found it will then run the include-what-you-use tool. If that is successful it will then call the fix_includes.py script to apply the changes.

3. The extension also allows to fix all target files by pressing cmd-shit-P + I + W + Y + U, then select “Include What You Use (all targets). In this mode the extension will iterate over all workspace target files listed in the compile_commands.joson file. For each file it will run include-what-you-use and fix_includes.py.

4. The extension will check headers for presence and correctness of include guards. Include guards will only be searched for in files matching `iwyu.diagnostics.include_guard_files`. In those files the guards are derived from the `iwyu.diagnostics.include_guard` setting. The value `${file}` will be replaced with the filename as is and `${FILE}` will be replaced with the filename in all upper case. All other chars are used as is. So the value `${FILE}_` adds a ‘_’ to the relative filename in all upper case.

Background

During C++ development includes are added all the time. And sometimes when code changes unused includes are not removed. These includes require unnecessary dependencies and result in slower compile time and larger code and binary sizes.

The extension assumes C++ development using clang toolchain and a compile_commands.json database that covers all C++ files. When building with bazel this can be autogenerated using

hedronvision/bazel-compile-commands-extractor.

The compile_commands.json file allows include-what-you-use to correctly build and analyze all source files with a detailed report on used, required and unnecessary include files.

Debug

The extension can be easily debugged using the IWYU Output window. The amount of detail it shows can be controlled using the Developer: Set Log Level command.

Configuration

  • iwyu.compile_commands
    The location of the ‘compile_commands.json’ file. This defaults to “${workspaceFolder}/compile_commands.json” where “${workspaceFolder}” will be replaced with he workspace folder.
  • iwyu.diagnostics
    A boolean value that enables (true) or disables (false) the diagnostics features.
  • “iwyu.filter_iwyu_output”
    A regular expression filter for iwyu output. This will be used as {here} in ‘#include.*({here})’. For instance in order to not add system includes under ‘__fwd/*.’, set this to ‘<__fwd/’. This does not result in removing such headers, it merely prevents adding them, so it won’t produce diagnostics for such includes.
  • “iwyu.fix_includes.py”
    Path to the `fix_includes.py` executable.
  • “iwyu.diagnostics.full_line_squiggles”
    A boolean setting that controls whether to underline the whole line with squiggles or only the actual include part.
  • “iwyu.diagnostics.include_guard_files”
    Regular expression for files that should be checked for include guards (defaults to “[.](h|hh|hpp|hxx)$”).
  • “iwyu.diagnostics.include_guard”
    If this is non empty, then include guards are checked. The relative filename is denoted as ‘${file}’ (as-is) or ‘${FILE}’ (uppercase) , so in order to require all caps include guards that end in a ‘_’, this must be set to ‘${FILE}_’ (e.g. ‘path/foo.h’ then becomes ‘PATH_FOO_H_’).
  • “iwyu.diagnostics.iwyu_interval”
    Minimum interval time in seconds between iwyu calls.
  • “iwyu.diagnostics.only_re”
    Only compute diagnostics for files that match this regular expression.
  • “iwyu.diagnostics.scan_min”
    Scan at least this many lines, if no include is found, then stop (min 10). The scanner does not count lines that start with `#` and `//`.
  • “iwyu.diagnostics.scan_more”
    After finding an include, scan at least this many more lines (min 1).
  • “iwyu.include-what-you-use”
    Path to the `include-what-you-use` executable.
  • “iwyu.iwyu.additional_params”
    Additional parameters you wish to pass to iwyu (must be prefixed with `-Xiwyu` in order to affect iwyu, otherwise will affect the compiler.
  • “iwyu.iwyu.keep”
    A glob that tells iwyu to always keep these includes.
  • “iwyu.iwyu.mapping_file”
    Mapping file to use if any.
  • “iwyu.iwyu.max_line_length”
    Maximum line length for includes.Note that this only affects comments and alignment thereof, the maximum line length can still be exceeded with long file names.
  • “iwyu.iwyu.no_default_mappings”
    Do not add iwyu’s default mappings.
  • “iwyu.iwyu.no_fwd_decls”
    Do not use forward declarations.
  • “iwyu.iwyu.transitive_includes_only”
    Do not suggest that a file add foo.h unless foo.h is already visible in the file’s transitive includes.
  • “iwyu.fix.comments”
    Put comments after the #include lines.
  • “iwyu.fix.dry_run”
    Do not actually edit any files; just print diffs on the log OUTPUT.
  • “iwyu.fix.ignore_re”
    Skip editing any file whose name matches this regular expression.
  • “iwyu.fix.only_re”
    Skip editing any file whose name does NOT match this regular expression.
  • “iwyu.fix.reorder”
    Re-order lines relative to other similar lines (e.g. headers relative to other headers).
  • “iwyu.fix.safe_headers”
    Do not remove unused #includes/fwd-declares from header files; just add new ones.
  • “iwyu.fix.update_comments”
    Replace *why* comments with the ones provided by IWYU.

Include guards

The extension can scan for include guards including #pragma once. If no include guard is found, or a part is missing or the actual guard does not match the expected guard, then diagnostics will be provided and fixes offered.

Include guards will only be searched for in files matching `iwyu.diagnostics.include_guard_files`. In those files the guards are derived from the `iwyu.diagnostics.include_guard` setting. This defaults to “” and must be configured otherwise for the feature to be active. The value `${file}` will be replaced with the filename as is and `${FILE}` will be replaced with the filename in all upper case. All other chars are used as is. So the setting value `${FILE}_` adds a ‘_’ to the relative filename in all upper case. Note that double underscores are reserved in C++ and should not be used as header guards. Therefore splitting the filename in path and directory and joining with a double underscore is not supported.

Quickfixes

iwyu.unused_header

The quickfix will run include-what-you-use and fix_includes.py on the current file and apply all changes.

iwyu.include_guard_bad_ifndef

The quickfix identified the first “#ifndef” but found no or an incorrect guard value. The guard value will be replaced. All whitespace and possible terminating comments will be kept (“//” styple only).

iwyu.include_guard_bad_define

The quickfix identified a bad #define line after the #ifndef line. The line will be fixed.

iwyu.include_guard_bad_endif

The quickfix identified a bad #endif (the last endif of the file). The line will be fixed.

iwyu.include_guard_missing_ifndef

The quickfix could not find a #ifndef include guard. The include guard will be inserted at the beginning of the file and a matching #define will be added.

iwyu.include_guard_missing_endif

The quickfix could not find the terminating #endif header guard. That missing include guard will be added at the end of the file.