Skip to content

Include‐What‐You‐Use Analyser

June Rhodes edited this page Aug 1, 2024 · 1 revision

Clang for Unreal Engine contains an experimental include-what-you-use analyser that detects unused #include directives in source and header files, and emits a warning diagnostic when they are found.

It currently only detects completely unused headers. It won't recommend forward declarations or narrowing headers for transitive includes like the include-what-you-use tool does, because it doesn't yet have knowledge about transitive includes that shouldn't be narrowed (such as cstdio not being narrowed to stdio.h).

It's also experimental because it might detect a header as unused, even though it is used. If you encounter this scenario, please open an issue with example code that reproduces it so it can be fixed.

Turning on the include-what-you-use analyser

To turn on the include-what-you-use analyser in a folder, set IWYUAnalysis to true in a .clang-rules file:

Namespace: # ...
IWYUAnalysis: true

IMPORTANT: The configuration format for turning on the include-what-you-use analyser is expected to change in future when we add additional configuration options for controlling narrowing of transitive dependencies. If you enable the include-what-you-use analyser, you should expect to have to update your .clang-rules files at some point in a newer version of Clang for Unreal Engine.

Silencing warnings

If you want to silence the IWYU warnings for certain headers, you can silence them like you would any other Clang diagnostic:

#if defined(__clang__)
#pragma clang diagnostic push
// @note: This is necessary so silencing "-Winclude-what-you-use" doesn't cause a warning under normal Clang.
#pragma clang diagnostic ignored "-Wunknown-warning-option"
#pragma clang diagnostic ignored "-Winclude-what-you-use"
#endif

#include "HeaderYouWantToSilenceWarningFor.h"

#if defined(__clang__)
#pragma clang diagnostic pop
#endif

You can bundle this up into usable macros to make it a bit easier to use and read:

#if defined(__clang__)
#define IWYU_ALLOW_UNUSED_HEADERS_BEGIN()                                                                 \
    _Pragma("clang diagnostic push")                                                                                   \
    _Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"")                                                   \
    _Pragma("clang diagnostic ignored \"-Winclude-what-you-use\"")
#define IWYU_ALLOW_UNUSED_HEADERS_END() \
    _Pragma("clang diagnostic pop")
#else
#define IWYU_ALLOW_UNUSED_HEADERS_BEGIN()
#define IWYU_ALLOW_UNUSED_HEADERS_END()
#endif

// Then:
IWYU_ALLOW_UNUSED_HEADERS_BEGIN()
#include "HeaderYouWantToSilenceWarningFor.h"
IWYU_ALLOW_UNUSED_HEADERS_END()