Home / Alt manpages / clang-include-fixer-20(1)

  • clang-include-fixer-20(1)
  • User command
  • linux

Add Missing C++ Headers Safely with clang-include-fixer-20

The compiler says std::vector is undeclared, and you cannot remember which header to add, so let clang-include-fixer-20 find it. This guide covers finding a header for an unresolved C++ symbol, applying the include to a source file, and checking the result without giving the tool more authority than it needs. Allow 15 to 30 minutes for a project that already has its databases; building an index for a large project takes longer.

It uses Ubuntu LLVM 20.1.8, installed by the clang-tools-20 package. The installed manual describes three database formats, source-file and standard-input modes, direct symbol queries, and JSON output.

Warning

This tool cannot reliably find a header from a filename alone. For normal use it needs project compilation information and a symbol index.

1. Check the installed tool

Run these as your ordinary user. They do not edit source files or need elevated privileges:

$ command -v clang-include-fixer-20
/usr/bin/clang-include-fixer-20
$ clang-include-fixer-20 --version
Ubuntu LLVM version 20.1.8
  Optimized build.
$ clang-include-fixer-20 --help

The local command accepts a source path after its options. Keep the -20 suffix in scripts when you want this exact major version rather than whichever unversioned LLVM tool comes first in PATH.

Checkpoint

--version prints 20.1.8 and --help lists --db, -p, --query-symbol, --stdin, --output-headers and --insert-header.

2. Put the two project databases in place

Normal source-file fixing needs two things:

  • A compilation database, usually compile_commands.json.
  • A symbol database, commonly produced by the companion find-all-symbols tooling. It maps an identifier to a header.

The LLVM documentation recommends placing or linking both where the source tree can find them. First inspect what your project already has:

$ find /path/to/project -maxdepth 3 \( -name compile_commands.json -o -name find_all_symbols_db.yaml \) -print

Replace /path/to/project with the real project directory. Do not create an empty database as a shortcut. A missing or unrelated one gives you missing results, misleading matches, or a diagnostic instead of a useful include.

If your build directory is elsewhere, the installed program has -p <string> for the build path. Pass the directory containing the compilation database:

$ clang-include-fixer-20 -p /path/to/build /path/to/project/src/example.cc

The command may change the source file, so start from a reviewable state. A clean Git worktree is a good baseline:

$ git -C /path/to/project status --short
$ git -C /path/to/project diff -- /path/to/project/src/example.cc

Checkpoint

You can name the compilation database, the symbol index and the exact source file that will be processed. If any of those is unclear, stop and fix the project setup before trying edits.

3. Run a normal include-fix pass

Start with the source file that contains the unresolved symbol, and use the database format that matches your index. For the YAML index documented by LLVM, the explicit form is:

$ clang-include-fixer-20 --db=yaml -p /path/to/build /path/to/project/src/example.cc

The tool analyses the file using its compilation options, looks up a missing identifier and can insert a header. It may also add namespace qualifiers when needed to resolve the symbol.

Tip

The upstream documentation says one include is inserted per pass. Review each change before repeating, rather than assuming one run fixes every diagnostic.

Warning

This is an editing command, not a read-only report. Use a project copy or a disposable branch while you learn what it does, and never run it with sudo: root ownership can leave your source or generated files hard to edit later.

Inspect the diff straight away:

$ git -C /path/to/project diff -- src/example.cc
$ git -C /path/to/project diff --check

Look for an include that really declares the symbol, sensible include ordering, and qualifiers that preserve the intended API. Then build, or run the project's normal compile command. The fixer's exit status does not prove the program now builds.

4. Query a symbol without a source file

For a quick database lookup, use --query-symbol. Give the spelling as the database knows it, with a namespace where appropriate:

$ clang-include-fixer-20 --db=yaml -p /path/to/build --query-symbol='std::vector'

This suits an editor with the symbol under the cursor, or a check that an index holds a candidate. It does not replace compiling the target file: it validates none of the file's macros, language standard, include paths or overload context.

For machine-readable symbol and header information, use --output-headers. The manual shows JSON containing FilePath, QuerySymbolInfos and HeaderInfos. Capture the output in a temporary file if another program will consume it:

$ clang-include-fixer-20 --db=yaml -p /path/to/build --output-headers /path/to/project/src/example.cc > /tmp/include-fixer-headers.json
$ head -n 12 /tmp/include-fixer-headers.json

Tip

Do not treat every returned header as safe. A symbol can have more than one relevant header, and the right choice depends on the project's public interface and include policy.

5. Handle unsaved editor content

--stdin tells the tool to overlay the source file's content with standard input while keeping that file's compilation options. It is meant for editor integration. The source path still matters because it anchors the compilation command and database lookup.

$ cat /path/to/project/src/example.cc | clang-include-fixer-20 --db=yaml -p /path/to/build --stdin /path/to/project/src/example.cc

Do not assume this pipeline writes an edited file back to disk. Standard-input workflows and the structured --insert-header option let an integration exchange data with the editor, so capture and inspect the output according to that integration's protocol. For a durable change, save the buffer separately, review the diff and run the normal source-file pass.

--insert-header=<string> accepts the YAML or JSON request format shown by the local manual and writes its result to standard output. It is an editor protocol, not a handy replacement for the normal command.

Warning

Let the editor generate the payload. Hand-editing offsets and ranges is an easy way to insert a header in the wrong place.

6. Recover from a bad suggestion

If the diff is wrong, undo it before another pass. With Git, revert only the file you inspected:

$ git -C /path/to/project restore --source=HEAD -- src/example.cc
$ git -C /path/to/project status --short

Warning

That restore discards uncommitted changes in the named file. If it holds work you need, copy or commit that work first, then remove the unwanted include by hand. Keep generated or unrelated changes out of the restore command.

Common failures have distinct causes:

  • No compilation database: the tool cannot reproduce the file's compiler options.
  • No symbol database: it has nothing reliable to map to a header.
  • Still unresolved: the cause may be spelling, namespace, macro or language standard rather than a missing include.

Try --extra-arg-before=<string> or --extra-arg=<string> only when you know the missing compiler option. Arbitrary flags make the analysis less representative of the real build.

Use -q when terminal output is distracting, not when you need to diagnose a failure. Use --minimize-paths only after checking that the shortened include paths match the project's include conventions. The manual does not promise that either option yields a correct include for every build system.

Done means

  • Right tool. clang-include-fixer-20 --version identified the installed LLVM 20.1.8 binary.
  • Right inputs. The source file was analysed with the correct compilation database and symbol-index format.
  • Reviewed change. The proposed include and any namespace change were checked in a diff.
  • It builds. The project build or a targeted test passed after the edit.
  • Recoverable. Any bad change was undone through a reviewed Git restore or manual edit.