aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
diff options
context:
space:
mode:
authorMichael Spencer <bigcheesegs@gmail.com>2024-02-23 17:48:58 -0800
committerGitHub <noreply@github.com>2024-02-23 17:48:58 -0800
commitde3b2c293b8bf336f8e1380148cf16b54a794c0c (patch)
treec49440f3eaa0f72825f89369c99afefa0af61f97 /clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
parentd42de86eb37b08b3007a67650b3ca73b9ae174b1 (diff)
downloadllvm-de3b2c293b8bf336f8e1380148cf16b54a794c0c.zip
llvm-de3b2c293b8bf336f8e1380148cf16b54a794c0c.tar.gz
llvm-de3b2c293b8bf336f8e1380148cf16b54a794c0c.tar.bz2
[clang][ScanDeps] Allow PCHs to have different VFS overlays (#82294)
It turns out it's not that uncommon for real code to pass a different set of VFSs while building a PCH than while using the PCH. This can cause problems as seen in `test/ClangScanDeps/optimize-vfs-pch.m`. If you scan `compile-commands-tu-no-vfs-error.json` without -Werror and run the resulting commands, Clang will emit a fatal error while trying to emit a note saying that it can't find a remapped header. This also adds textual tracking of VFSs for prebuilt modules that are part of an included PCH, as the same issue can occur in a module we are building if we drop VFSs. This has to be textual because we have no guarantee the PCH had the same list of VFSs as the current TU. This uses the `PrebuiltModuleListener` to collect `VFSOverlayFiles` instead of trying to extract it out of a `serialization::ModuleFile` each time it's needed. There's not a great way to just store a pointer to the list of strings in the serialized AST.
Diffstat (limited to 'clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp')
-rw-r--r--clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp34
1 files changed, 26 insertions, 8 deletions
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index 5a9e563..eb5c50c 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -29,10 +29,11 @@ const std::vector<std::string> &ModuleDeps::getBuildArguments() {
return std::get<std::vector<std::string>>(BuildInfo);
}
-static void optimizeHeaderSearchOpts(HeaderSearchOptions &Opts,
- ASTReader &Reader,
- const serialization::ModuleFile &MF,
- ScanningOptimizations OptimizeArgs) {
+static void
+optimizeHeaderSearchOpts(HeaderSearchOptions &Opts, ASTReader &Reader,
+ const serialization::ModuleFile &MF,
+ const PrebuiltModuleVFSMapT &PrebuiltModuleVFSMap,
+ ScanningOptimizations OptimizeArgs) {
if (any(OptimizeArgs & ScanningOptimizations::HeaderSearch)) {
// Only preserve search paths that were used during the dependency scan.
std::vector<HeaderSearchOptions::Entry> Entries;
@@ -65,11 +66,25 @@ static void optimizeHeaderSearchOpts(HeaderSearchOptions &Opts,
llvm::DenseSet<const serialization::ModuleFile *> Visited;
std::function<void(const serialization::ModuleFile *)> VisitMF =
[&](const serialization::ModuleFile *MF) {
- VFSUsage |= MF->VFSUsage;
Visited.insert(MF);
- for (const serialization::ModuleFile *Import : MF->Imports)
- if (!Visited.contains(Import))
- VisitMF(Import);
+ if (MF->Kind == serialization::MK_ImplicitModule) {
+ VFSUsage |= MF->VFSUsage;
+ // We only need to recurse into implicit modules. Other module types
+ // will have the correct set of VFSs for anything they depend on.
+ for (const serialization::ModuleFile *Import : MF->Imports)
+ if (!Visited.contains(Import))
+ VisitMF(Import);
+ } else {
+ // This is not an implicitly built module, so it may have different
+ // VFS options. Fall back to a string comparison instead.
+ auto VFSMap = PrebuiltModuleVFSMap.find(MF->FileName);
+ if (VFSMap == PrebuiltModuleVFSMap.end())
+ return;
+ for (std::size_t I = 0, E = VFSOverlayFiles.size(); I != E; ++I) {
+ if (VFSMap->second.contains(VFSOverlayFiles[I]))
+ VFSUsage[I] = true;
+ }
+ }
};
VisitMF(&MF);
@@ -596,6 +611,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
ScanningOptimizations::VFS)))
optimizeHeaderSearchOpts(BuildInvocation.getMutHeaderSearchOpts(),
*MDC.ScanInstance.getASTReader(), *MF,
+ MDC.PrebuiltModuleVFSMap,
MDC.OptimizeArgs);
if (any(MDC.OptimizeArgs & ScanningOptimizations::SystemWarnings))
optimizeDiagnosticOpts(
@@ -697,9 +713,11 @@ ModuleDepCollector::ModuleDepCollector(
std::unique_ptr<DependencyOutputOptions> Opts,
CompilerInstance &ScanInstance, DependencyConsumer &C,
DependencyActionController &Controller, CompilerInvocation OriginalCI,
+ PrebuiltModuleVFSMapT PrebuiltModuleVFSMap,
ScanningOptimizations OptimizeArgs, bool EagerLoadModules,
bool IsStdModuleP1689Format)
: ScanInstance(ScanInstance), Consumer(C), Controller(Controller),
+ PrebuiltModuleVFSMap(std::move(PrebuiltModuleVFSMap)),
Opts(std::move(Opts)),
CommonInvocation(
makeCommonInvocationForModuleBuild(std::move(OriginalCI))),