364 Commits

Author SHA1 Message Date
Jan Svoboda
f94afdd0b7
[clang][modules] Unify "context hash" and "specific module cache path" (#176215)
This PR unifies the terminology for:
* "context hash" - previously ambiguously referred to as "module hash"
or as overly specific "module context hash"
* "specific module cache path" - previously referred to as just "module
cache path" - hard to distinguish from the command-line-provided module
cache path without the context hash

NFCI
2026-01-15 12:02:31 -08:00
Jinjie Huang
689b3cc7c7
[clang] Support header shadowing diagnostics in Clang header search (#162491)
When including a header file, multiple files with the same name may
exist across different search paths, like:
   |-- main.cpp
  |-- **header.h**
  |-- include
  |  └── **header.h**
The compiler usually picks the first match it finds (typically following
MSVC rules for current/include-chain paths first, then regular -I
paths), which may not be the user’s intended header.
This silent behavior can lead to subtle runtime API mismatches or
increase the cost of resolving errors such as “error: use of undeclared
identifier”, especially in large projects.

Therefore, this patch tries to provide a diagnostic message without
changing the current header selection. It does this by performing an
additional search for duplicate filenames across all search paths (both
MSVC rules and standard paths). This informs the user about a potential
"header shadowing" issue and clarifies which header path was actually
used.

Since header searching is much cheaper than file loading, the added
overhead should be within an acceptable range -- assuming the diagnostic
message is valuable.
2025-12-03 14:08:20 +08:00
Jan Svoboda
3056727a1a
[clang][lex] Use FileManager to make prebuilt module paths absolute (#165347)
This PR switches from using `llvm::sys::fs::make_absolute()` to
`FileManager::makeAbsolutePath()` so that `FileSystemOptions` (i.e. the
`-working-directory` option) and the `VFS`'s CWD have a say in how the
prebuilt module paths are resolved. This matches how the rest of the
compiler treats input files.
2025-10-30 10:25:53 -07:00
Jan Svoboda
1ab6c0d60c
[clang] Make explicitly-built modules independent of the CWD (#164840)
PR https://github.com/llvm/llvm-project/pull/150123 changed how we
normalize the modules cache path. Unfortunately, empty path would get
normalized to the current working directory. This means that even
explicitly-built PCMs that don't rely on the CWD now embed it, leading
to surprising behavior. This PR fixes that by normalizing an empty
modules cache path to an empty string.
2025-10-23 10:09:50 -07:00
Jan Svoboda
f122484b99
[llvm][support] Move make_absolute from sys::fs to sys::path (#161459)
The `llvm::sys::fs::make_absolute(const Twine &, SmallVectorImpl<char>
&)` functions doesn't perform any FS access - it only modifies the
second parameter via path/string operations. This function should live
in the `llvm::sys::path` namespace for consistency and for making it
easier to spot function calls that perform IO.
2025-10-01 14:35:17 -07:00
Jan Svoboda
1aefabe554
[clang] Use the VFS to check the system framework marker (#160946)
This PR uses the VFS/`FileManager` to check the system framework marker
instead of going straight to the real file system. This matches the
behavior of other input files of the compiler.
2025-09-26 14:53:29 -07:00
Jan Svoboda
55bef46146 Reland "[clang] Delay normalization of -fmodules-cache-path (#150123)"
This reverts commit 613caa909c78f707e88960723c6a98364656a926, essentially
reapplying 4a4bddec3571d78c8073fa45b57bbabc8796d13d after moving
`normalizeModuleCachePath` from clangFrontend to clangLex.

This PR is part of an effort to remove file system usage from the
command line parsing code. The reason for that is that it's impossible
to do file system access correctly without a configured VFS, and the VFS
can only be configured after the command line is parsed. I don't want to
intertwine command line parsing and VFS configuration, so I decided to
perform the file system access after the command line is parsed and the
VFS is configured - ideally right before the file system entity is used
for the first time.

This patch delays normalization of the module cache path until
`CompilerInstance` is asked for the cache path in the current
compilation context.
2025-09-10 15:56:04 -07:00
Michael Spencer
32fb8c5f5f
[clang][modules] Lazily load by name lookups in module maps (#132853)
Instead of eagerly populating the `clang::ModuleMap` when looking up a
module by name, this patch changes `HeaderSearch` to only load the
modules that are actually used.

This introduces `ModuleMap::findOrLoadModule` which will load modules
from parsed but not loaded module maps. This cannot be used anywhere
that the module loading code calls into as it can create infinite
recursion.

This currently just reparses module maps when looking up a module by
header. This is fine as redeclarations are allowed from the same file,
but future patches will also make looking up a module by header lazy.

This patch changes the shadow.m test to use explicitly built modules and
`#import`. This test and the shadow feature are very brittle and do not
work in general. The test relied on pcm files being left behind by prior
failing clang invocations that were then reused by the last invocation.
If you clean the cache then the last invocation will always fail. This
is because the input module map and the `-fmodule-map-file=` module map
are parsed in the same module scope, and `-fmodule-map-file=` is
forwarded to implicit module builds. That means you are guaranteed to
hit a module redeclaration error if the TU actually imports the module
it is trying to shadow.

This patch changes when we load A2's module map to after the `A` module
has been loaded, which sets the `IsFromModuleFile` bit on `A`. This
means that A2's `A` is skipped entirely instead of creating a shadow
module, and we get textual inclusion. It is possible to construct a case
where this would happen before this patch too.

An upcoming patch in this series will rework shadowing to work in the
general case, but that's only possible once header -> module lookup is
lazy too.
2025-05-06 16:40:01 -07:00
Kazu Hirata
3d97d71e66
[Lex] Use llvm::make_second_range (NFC) (#135902) 2025-04-16 00:33:29 -07:00
Michael Spencer
57f2e76e30
[clang] Consistently use "load" to refer to populating clang::ModuleMap (#132970)
Now that we have ModuleMapFile.cpp which parses module maps, it's
confusing what ModuleMap::parseModuleMapFile actually does. HeaderSearch
already called this loading a module map, so consistently use that term
in ModuleMap too.

An upcoming patch will allow just parsing a module map without loading
the modules from it.
2025-03-25 12:32:58 -07:00
Jan Svoboda
7a370748c0
[clang][lex] Store non-owning options ref in HeaderSearch (#132780)
This makes it so that `CompilerInvocation` can be the only entity that
manages ownership of `HeaderSearchOptions`, making it possible to
implement copy-on-write semantics.
2025-03-25 12:14:06 -07:00
Jan Svoboda
72e596f359
[clang] Make HeaderSearchOptions references const (#130825)
This PR makes the `HeaderSearchOptions` object referenced by
`HeaderSearch` constant. Depends on #130823.
2025-03-21 14:39:50 -07:00
Hiroshi Yamauchi
f58fde5857
Exclude RedirectingFileSystem with null OverlayFileDir in VFSUsage (#128267)
This is to avoid assertion failures like the following when
RedirectingFileSystem's are created and used outside
createVFSFromOverlayFiles.

```
Assertion failed: VFSUsage.size() == getHeaderSearchOpts().VFSOverlayFiles.size() && "A different number of RedirectingFileSystem's were present than " "-ivfsoverlay options passed to Clang!", file S:\SourceCache\llvm-project\clang\lib\Lex\HeaderSearch.cpp, line 162
```
2025-02-24 22:52:15 -08:00
Kazu Hirata
7642759498
[Lex] Remove unused includes (NFC) (#116460)
Identified with misc-include-cleaner.
2024-11-16 12:14:06 -08:00
Jan Svoboda
e494e2694a
[clang][lex] Remove HeaderFileInfo::Framework (#114460)
This PR removes the `HeaderFileInfo::Framework` member and reduces the
size of this data type from 32B to 16B. This should improve Clang's
memory usage in situations where it keeps track of lots of header files.
NFCI. Depends on #114459.
2024-10-31 16:33:28 -07:00
Jan Svoboda
19b4f17d4c
[clang][lex] Remove -index-header-map (#114459)
This PR removes the `-index-header-map` functionality from Clang. AFAIK
this was only used internally at Apple and is now dead code. The main
motivation behind this change is to enable the removal of
`HeaderFileInfo::Framework` member and reducing the size of that data
structure.

rdar://84036149
2024-10-31 16:04:35 -07:00
Jan Svoboda
590b1e3154
[clang][modules] Only serialize info for locally-included headers (#113718)
I noticed that some PCM files contain `HeaderFileInfo` for headers only
included in a dependent PCM file, which is wasteful.

This patch changes the logic to only write headers that are included
locally. This makes the PCM files smaller and saves some superfluous
deserialization of `HeaderFileInfo` triggered by
`Preprocessor::alreadyIncluded()`.
2024-10-25 15:00:07 -07:00
Jan Svoboda
b1aea98cfa
[clang] Make deprecations of some FileManager APIs formal (#110014)
Some `FileManager` APIs still return `{File,Directory}Entry` instead of
the preferred `{File,Directory}EntryRef`. These are documented to be
deprecated, but don't have the attribute that warns on their usage. This
PR marks them as such with `LLVM_DEPRECATED()` and replaces their usage
with the recommended counterparts. NFCI.
2024-09-25 10:36:44 -07:00
Jan Svoboda
17dc43d623
[clang] Stop adjusting the module cache path (#102540)
This patch stops adjustments of the module cache path beyond what is
done in `ParseHeaderSearchArgs` (making it absolute and removing dots).
This enables more efficient implementation of the caching VFS in
https://github.com/llvm/llvm-project/pull/88800.
2024-08-13 08:39:11 -07:00
Volodymyr Sapsai
cbd5ba20d1
[Modules] Don't search for modulemaps in the immediate sub-directories of search paths for recent Apple SDKs. (#100005)
Such searches can be costly and non-intuitive. We've seen complaints
from developers that they don't expect clang to find modules on their
own and not in search paths that developers provide. Keeping the search
of modulemaps in subdirectories for code completion as it provides
better user experience.

If you are defining module "UsefulCode" in
"include/UnrelatedName/module.modulemap", it is recommended to rename
the directory "UnrelatedName" to "UsefulCode". If you cannot do so, you
can add to "include/module.modulemap" a line like `extern module
UsefulCode "UnrelatedName/module.modulemap"`, so clang can find module
"UsefulCode" without checking each subdirectory in "include/".

rdar://106677321

---------

Co-authored-by: Jan Svoboda <jan@svoboda.ai>
2024-07-23 13:59:44 -07:00
Fangrui Song
12c0281f8c [Lex] Replace hash_combine with a stable hash 2024-06-20 23:26:15 -07:00
Chuanqi Xu
da2ad44119 [HeaderSearch] Introduce LazyIdentifierInfoPtr for Controlling Macro in HeaderFileInfo
This patch is helpful to reduce 32 bits for HeaderFileInfo by combining
a uint32_t and pointer into a tagged pointer.

This is reviewed as part of
https://github.com/llvm/llvm-project/pull/92085 and required to be split
as a separate commit
2024-06-20 13:13:47 +08:00
Ian Anderson
29b0d57554
[clang][modules] HeaderSearch::MarkFileModuleHeader sets textual headers' HeaderFileInfo non-external when it shouldn't (#89005)
HeaderSearch::MarkFileModuleHeader is no longer properly checking for
no-changes, and so sets the HeaderFileInfo for every `textual header` to
non-external.
2024-06-15 07:41:58 -07:00
kadir çetinkaya
8e0ba08448
[clang][HeaderSearch] Fix handling of relative file-paths in suggestPathToFileForDiagnostics (#95121)
Normalize header-to-be-spelled using WorkingDir, similar to search paths
themselves.

Addresses https://github.com/llvm/llvm-project/issues/81215.
2024-06-14 16:07:42 +02:00
Jan Svoboda
d609029d6c
[clang][modules] Allow module maps with textual headers to be non-affecting (#89441)
When writing out a PCM, we skip serializing headers' `HeaderFileInfo`
struct whenever this condition evaluates to `true`:

```c++
!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader)
```

However, when Clang parses a module map file, each textual header gets a
`HFI` with `isModuleHeader=false`, `isTextualModuleHeader=true` and
`isCompilingModuleHeader=false`. This means the condition evaluates to
`false` even if the header was never included and the module map did not
affect the compilation. Each PCM file that happened to parse such module
map then contains a copy of the `HeaderFileInfo` struct for all textual
headers, and considers the containing module map affecting.

This patch makes it so that we skip headers that have not been included,
essentially removing the virality of textual headers when it comes to
PCM serialization.
2024-04-24 09:05:56 -07:00
Jan Svoboda
84df7a09f8
[clang][modules] Do not resolve HeaderFileInfo externally in ASTWriter (#87848)
Clang uses the `HeaderFileInfo` struct to track bits of information on
header files, which gets used throughout the compiler. We also use this
to compute the set of affecting module maps in `ASTWriter` and in the
end serialize the information into the `HEADER_SEARCH_TABLE` record of a
PCM file, allowing clients to learn about headers from the module. In
doing so, Clang asks for existing `HeaderFileInfo` for all known
`FileEntries`. Note that this asks the loaded PCM files for the
information they have on each header file in question. This seems
unnecessary: we only want to serialize information on header files that
either belong to the current module or that got included textually.
Loaded PCM files can't provide us with any useful information.

For explicit modules with lazy loading (using `-fmodule-map-file=<path>`
with `-fmodule-file=<name>=<path>`) the compiler knows about header
files listed in the module map files on the command-line. This can be a
large number.

Asking for existing `HeaderFileInfo` can trigger deserialization of
`HEADER_SEARCH_TABLE` from loaded PCM files. Keys of the on-disk hash
table consist of the header file size and modification time. However,
with explicit modules Clang zeroes out the modification time. Moreover,
if you import lots of modules, some of their header files end up having
identical sizes. This means lots of hash collisions that can only be
resolved by running the serialized filename through `FileManager` and
comparing equality of the `FileEntry`. This ends up being super
expensive, essentially re-stating lots of the transitively loaded SDK
header files.

This patch cleans up the API for getting `HeaderFileInfo` and makes sure
`ASTWriter` uses the version that doesn't ask loaded PCM files for more
information. This removes the excessive stat traffic coming from
`ASTWriter` hopefully without changing observable behavior.
2024-04-11 14:44:55 -07:00
Bill Wendling
fca51911d4
[NFC][Clang] Improve const correctness for IdentifierInfo (#79365)
The IdentifierInfo isn't typically modified. Use 'const' wherever
possible.
2024-04-11 00:33:40 +00:00
Ian Anderson
0cd0aa0296
[clang][modules] Headers meant to be included multiple times can be completely invisible in clang module builds (#83660)
Once a file has been `#import`'ed, it gets stamped as if it was `#pragma
once` and will not be re-entered, even on #include. This means that any
errant #import of a file designed to be included multiple times, such as
<assert.h>, will incorrectly mark it as include-once and break the
multiple include functionality. Normally this isn't a big problem, e.g.
<assert.h> can't have its NDEBUG mode changed after the first #import,
but it is still mostly functional. However, when clang modules are
involved, this can cause the header to be hidden entirely.

Objective-C code most often uses #import for everything, because it's
required for most Objective-C headers to prevent double inclusion and
redeclaration errors. (It's rare for Objective-C headers to use macro
guards or `#pragma once`.) The problem arises when a submodule includes
a multiple-include header. The "already included" state is global across
all modules (which is necessary so that non-modular headers don't get
compiled into multiple translation units and cause redeclaration
errors). If another module or the main file #import's the same header,
it becomes invisible from then on. If the original submodule is not
imported, the include of the header will effectively do nothing and the
header will be invisible. The only way to actually get the header's
declarations is to somehow figure out which submodule consumed the
header, and import that instead. That's basically impossible since it
depends on exactly which modules were built in which order.

#import is a poor indicator of whether a header is actually
include-once, as the #import is external to the header it applies to,
and requires that all inclusions correctly and consistently use #import
vs #include. When modules are enabled, consider a header marked
`textual` in its module as a stronger indicator of multiple-include than
#import's indication of include-once. This will allow headers like
<assert.h> to always be included when modules are enabled, even if
#import is erroneously used somewhere.
2024-04-05 10:13:42 -07:00
Michael Spencer
7847e44594
[clang][DependencyScanner] Remove unused -ivfsoverlay files (#73734)
`-ivfsoverlay` files are unused when building most modules. Enable
removing them by,
* adding a way to visit the filesystem tree with extensible RTTI to
  access each `RedirectingFileSystem`.
* Adding tracking to `RedirectingFileSystem` to record when it
  actually redirects a file access.
* Storing this information in each PCM.

Usage tracking is only enabled when iterating over the source manager
and affecting modulemaps. Here each path is stated to cause an access.
During scanning these stats all hit the cache.
2024-01-30 15:39:18 -08:00
gulfemsavrun
549bee8a55
Revert "[Modules] [HeaderSearch] Don't reenter headers if it is pragm… (#79396)
…a once  (#76119)"

This reverts commit f0c387038854d61a632520a4073d1b6ebf4997ed because it
causes an lldb test to fail on a missing import on Mac.

https://logs.chromium.org/logs/fuchsia/buildbucket/cr-buildbucket/8758053465398947297/+/u/lldb/test/stdout
2024-01-24 17:58:25 -08:00
Chuanqi Xu
f0c3870388
[Modules] [HeaderSearch] Don't reenter headers if it is pragma once (#76119)
Close https://github.com/llvm/llvm-project/issues/73023

The direct issue of https://github.com/llvm/llvm-project/issues/73023 is
that we entered a header which is marked as pragma once since the
compiler think it is OK if there is controlling macro.

It doesn't make sense. I feel like it should be sufficient to skip it
after we see the '#pragma once'.

From the context, it looks like the workaround is primarily for
ObjectiveC. So we might need reviewers from OC.
2024-01-24 10:22:35 +08:00
Kazu Hirata
395f9ce30e Use StringRef::{starts,ends}_with (NFC)
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
2023-12-16 10:14:44 -08:00
Michael Spencer
a171d248ca
[clang][modules] Deprecate module.map in favor of module.modulemap (#75142)
This patch deprecates `module.map` in favor of `module.modulemap`, which
has been the preferred form since 2014. The eventual goal is to remove
support for `module.map` to reduce the number of stats Clang needs to do
while searching for module map files.

This patch touches a lot of files, but the majority of them are just
renaming tests or references to the file in comments or documentation.

The relevant files are:
* lib/Lex/HeaderSearch.cpp
* include/clang/Basic/DiagnosticGroups.td
* include/clang/Basic/DiagnosticLexKinds.td
2023-12-14 14:03:57 -08:00
Kazu Hirata
f3dcc2351c
[clang] Use StringRef::{starts,ends}_with (NFC) (#75149)
This patch replaces uses of StringRef::{starts,ends}with with
StringRef::{starts,ends}_with for consistency with
std::{string,string_view}::{starts,ends}_with in C++20.

I'm planning to deprecate and eventually remove
StringRef::{starts,ends}with.
2023-12-13 08:54:13 -08:00
Aaron Ballman
3293c088c2 Remove dead code; NFC
This code was added 17 years ago but never enabled or tested. GCC warns
that -I- is deprecated for them, and Clang gives an error when passed
-I-, so we may as well remove this code rather than hook it up to the
driver and maintain it.
2023-12-07 08:26:33 -05:00
Jan Svoboda
1afb313b26
[clang][modules] Use file name as requested (#68957)
This prevents redefinition errors due to having multiple paths for the
same module map. (rdar://24116019)

Originally implemented and tested downstream by @bcardosolopes, I just
made use of `FileEntryRef::getNameAsRequested()`.
2023-10-20 09:23:19 -07:00
Jan Svoboda
b0abc9dd44 [clang] NFCI: Use FileEntryRef in ASTReader::GetHeaderFileInfo()
This is the `ASTReader` counterpart to PR #67383.
2023-09-29 09:07:13 -07:00
Jan Svoboda
12866a2b87 [clang][modules] Use FileEntryRef in ModuleMap (2/2) 2023-09-28 12:59:26 -07:00
Jan Svoboda
12cb98fe04 [clang][modules] Use FileEntryRef in ModuleMap (1/2) 2023-09-28 12:59:26 -07:00
Jan Svoboda
89bacc0bb9 [clang] NFCI: Use FileEntryRef in CreateHeaderMap() 2023-09-09 21:51:04 -07:00
Jan Svoboda
e483a6e174 [clang] NFCI: Use FileEntryRef in LookupSubframeworkHeader() 2023-09-09 21:50:38 -07:00
Jan Svoboda
6966c06bed [clang] NFCI: Use FileEntryRef in suggestPathToFileForDiagnostics() 2023-09-09 20:29:04 -07:00
Jan Svoboda
c23d65b90f [clang] NFCI: Use FileEntryRef in ModuleMapParser 2023-09-09 09:12:35 -07:00
Jan Svoboda
ef996175a7 [clang] NFCI: Use FileEntryRef in diagnoseFrameworkInclude() 2023-09-09 09:12:35 -07:00
Jan Svoboda
358d9dbf4f [clang] NFCI: Use FileEntryRef in checkMSVCHeaderSearch() 2023-09-08 21:28:05 -07:00
Jan Svoboda
5523fefb01 [clang][lex] Use preferred path separator in includer-relative lookup
There is a long-standing FIXME in `HeaderSearch.cpp` to use the path separator preferred by the platform instead of forward slash. There was an attempt to fix that (1cf6c28a) which got reverted (cf385dc8). I couldn't find an explanation, but my guess is that some tests assuming forward slash started failing.

This commit fixes tests with that assumption.

This is intended to be NFC, but there are two exceptions to that:
* Some diagnostic messages might now contain backslash instead of forward slash.
* Arguments to the "-remap-file" option that use forward slash might stop kicking in. Separators between potential includer path and header name need to be replaced by backslash in that case.
2023-09-08 16:38:08 -07:00
Volodymyr Sapsai
52c62d46a0
Reland "[modules] Fix error about the same module being defined in different .pcm files when using VFS overlays."
Fixing Windows buildbot by not using "BuildTemporaries/module.modulemap"
because it is interpreted as defining a module in "BuildTemporaries" directory.

Fix errors like
> module 'MultiPath' is defined in both 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-1352QHUF8RNMU.pcm' and 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-20HNSLLIUDDV1.pcm'

To avoid building extra identical modules `-ivfsoverlay` option is not a
part of the hash like "/3JR48BPRU7BCG/". And it is build system's
responsibility to provide `-ivfsoverlay` options that don't cause
observable differences.  We also need to make sure the hash like
"-1352QHUF8RNMU" is not affected by `-ivfsoverlay`. As this hash is
defined by the module map path, use the path prior to any VFS
remappings.

rdar://111921464

Differential Revision: https://reviews.llvm.org/D156749
2023-08-16 18:27:17 -07:00
Volodymyr Sapsai
fe9c332408
Revert "Reland "[modules] Fix error about the same module being defined in different .pcm files when using VFS overlays.""
This reverts commit b070be82bb8fb4414a8a6eb4fbfc77921d89fa4b.
2023-08-10 15:14:26 -07:00
Volodymyr Sapsai
b070be82bb
Reland "[modules] Fix error about the same module being defined in different .pcm files when using VFS overlays."
Fixing Windows buildbot by using the same separators for `-F` and `-I`
paths both in VFS overlay and on command line.

Fix errors like
> module 'MultiPath' is defined in both 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-1352QHUF8RNMU.pcm' and 'path/to/modules.cache/3JR48BPRU7BCG/MultiPath-20HNSLLIUDDV1.pcm'

To avoid building extra identical modules `-ivfsoverlay` option is not a
part of the hash like "/3JR48BPRU7BCG/". And it is build system's
responsibility to provide `-ivfsoverlay` options that don't cause
observable differences.  We also need to make sure the hash like
"-1352QHUF8RNMU" is not affected by `-ivfsoverlay`. As this hash is
defined by the module map path, use the path prior to any VFS
remappings.

rdar://111921464

Differential Revision: https://reviews.llvm.org/D156749
2023-08-10 14:52:49 -07:00
Volodymyr Sapsai
91b10f6974
Revert "[modules] Fix error about the same module being defined in different .pcm files when using VFS overlays."
This reverts commit 97dfaf4cd27814bdf9aa9d2eafc21fdb4f76c56d.

llvm-clang-x86_64-sie-win buildbot is failing with the added test.
2023-08-10 11:27:08 -07:00