You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Clang] Match MSVC handling of duplicate header search paths in Microsoft compatibility modes.
Clang has historically matched GCC's behavior for header search path order
and pruning of duplicate paths. That traditional behavior is to order user
search paths before system search paths, to ignore user search paths that
duplicate a (later) system search path, and to ignore search paths that
duplicate an earlier search path of the same user/system kind. This differs
from MSVC and can result in inconsistent header file resolution for `#include`
directives.
MSVC orders header search paths as follows:
1) Paths specified by the `/I` and `/external:I` options are processed in
the order that they appear. Paths specified by `/I` that duplicate a path
specified by `/external:I` are ignored regardless of the order of the
options. Paths specified by `/I` that duplicate a path from a prior `/I`
option are ignored. Paths specified by `/external:I` that duplicate a
path from a later `/external:I` option are ignored.
2) Paths specified by `/external:env` are processed in the order that they
appear. Paths that duplicate a path from a `/I` or `/external:I` option
are ignored regardless of the order of the options. Paths that duplicate a
path from a prior `/external:env` option or an earlier path from the same
`/external:env` option are ignored.
3) Paths specified by the `INCLUDE` environment variable are processed in
the order they appear. Paths that duplicate a path from a `/I`,
`/external:I`, or `/external:env` option are ignored. Paths that
duplicate an earlier path in the `INCLUDE` environment variable are
ignored.
4) Paths specified by the `EXTERNAL_INCLUDE` environment variable are
processed in the order they appear. Paths that duplicate a path from a
`/I`, `/external:I`, or `/external:env` option are ignored. Paths that
duplicate a path from the `INCLUDE` environment variable are ignored.
Paths that duplicate an earlier path in the `EXTERNAL_INCLUDE
environment variable are ignored.
Prior to this change, Clang handled the `/external:I` and `/external:env`
options and the paths present in the `INCLUDE` and `EXTERNAL_INCLUDE`
environment variables as though they were specified with the `-isystem` option.
The GCC behavior described above then lead to a command line such as
`/external:I dir1 /Idir2` having a header search order of `dir2` followed by
`dir1`; contrary to MSVC behavior.
This change adds support for the MSVC external path concept for both the `clang`
and `clang-cl` drivers with the following option syntax. These options match the
MSVC behavior described above for both drivers.
clang clang-cl
-------------------- -------------------
-iexternal <dir> /external:I <dir>
-iexternal-env=<ENV> /external:env:<ENV>
Paths specified by these options are still treated as system paths. That is,
whether warnings are issued in header files found via these paths remains
subject to use of the `-Wsystem-headers` and `-Wno-system-headers` options.
In the future, it would make sense to add a separate option that matches the
MSVC `/external:Wn` option to control such warnings.
The MSVC behavior described above implies that (system) paths present in the
`INCLUDE` and `EXTERNAL_INCLUDE` environment variables do not suppress matching
user paths specified via `/I`. This contrasts with GCC's behavior of suppressing
user paths that match a system path regardless of how each is specified. Since
the `clang-cl` driver maps paths from the `INCLUDE` and `EXTERNAL_INCLUDE`
environment variable to `-internal-isystem`, matching MSVC behavior requires
suppressing that aspect of the GCC behavior. With this change, system paths
will no longer suppress user paths when the `-fms-compatibility` option is
explicitly or implicitly enabled. This will affect header search path ordering
for options like `-isystem` when duplicate user paths are present. Should
motivation arise for preserving such suppression of user paths when compiling
with `-fms-compatibility` enabled, it would make sense to introduce a new
option for the `clang-cl` driver to map paths in these environment variabless
to that would match MSVC behavior without impacting other system path options.
0 commit comments