Skip to content

Commit e6cffd1

Browse files
committed
[clang][cas] Move caching ActionControllers into separate files
Move the IncludeTreeActionController and CASFSActionController into their own files. (cherry picked from commit a199e29)
1 parent 3a3a7c9 commit e6cffd1

File tree

8 files changed

+751
-608
lines changed

8 files changed

+751
-608
lines changed

clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -265,30 +265,6 @@ class CallbackActionController : public DependencyActionController {
265265
LookupModuleOutputCallback LookupModuleOutput;
266266
};
267267

268-
class CASFSActionController : public CallbackActionController {
269-
public:
270-
CASFSActionController(LookupModuleOutputCallback LookupModuleOutput,
271-
llvm::cas::CachingOnDiskFileSystem &CacheFS,
272-
DepscanPrefixMapping PrefixMapping);
273-
274-
llvm::Error initialize(CompilerInstance &ScanInstance,
275-
CompilerInvocation &NewInvocation) override;
276-
llvm::Error finalize(CompilerInstance &ScanInstance,
277-
CompilerInvocation &NewInvocation) override;
278-
llvm::Error
279-
initializeModuleBuild(CompilerInstance &ModuleScanInstance) override;
280-
llvm::Error
281-
finalizeModuleBuild(CompilerInstance &ModuleScanInstance) override;
282-
llvm::Error finalizeModuleInvocation(CompilerInvocation &CI,
283-
const ModuleDeps &MD) override;
284-
285-
private:
286-
llvm::cas::CachingOnDiskFileSystem &CacheFS;
287-
DepscanPrefixMapping PrefixMapping;
288-
std::optional<llvm::TreePathPrefixMapper> Mapper;
289-
CASOptions CASOpts;
290-
};
291-
292268
} // end namespace dependencies
293269
} // end namespace tooling
294270
} // end namespace clang

clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class DependencyConsumer {
5959
virtual void handleContextHash(std::string Hash) = 0;
6060

6161
virtual void handleCASFileSystemRootID(std::string ID) {}
62+
63+
virtual void handleIncludeTreeID(std::string ID) {}
6264
};
6365

6466
/// Dependency scanner callbacks that are used during scanning to influence the
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
//===- CASFSActionController.cpp ------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "CachingActions.h"
10+
#include "clang/Frontend/CompilerInstance.h"
11+
#include "clang/Lex/Preprocessor.h"
12+
#include "llvm/CAS/CachingOnDiskFileSystem.h"
13+
#include "llvm/CAS/ObjectStore.h"
14+
#include "llvm/Support/PrefixMapper.h"
15+
16+
using namespace clang;
17+
using namespace tooling;
18+
using namespace dependencies;
19+
using llvm::Error;
20+
21+
namespace {
22+
class CASFSActionController : public CallbackActionController {
23+
public:
24+
CASFSActionController(LookupModuleOutputCallback LookupModuleOutput,
25+
llvm::cas::CachingOnDiskFileSystem &CacheFS,
26+
DepscanPrefixMapping PrefixMapping);
27+
28+
llvm::Error initialize(CompilerInstance &ScanInstance,
29+
CompilerInvocation &NewInvocation) override;
30+
llvm::Error finalize(CompilerInstance &ScanInstance,
31+
CompilerInvocation &NewInvocation) override;
32+
llvm::Error
33+
initializeModuleBuild(CompilerInstance &ModuleScanInstance) override;
34+
llvm::Error
35+
finalizeModuleBuild(CompilerInstance &ModuleScanInstance) override;
36+
llvm::Error finalizeModuleInvocation(CompilerInvocation &CI,
37+
const ModuleDeps &MD) override;
38+
39+
private:
40+
llvm::cas::CachingOnDiskFileSystem &CacheFS;
41+
DepscanPrefixMapping PrefixMapping;
42+
std::optional<llvm::TreePathPrefixMapper> Mapper;
43+
CASOptions CASOpts;
44+
};
45+
} // anonymous namespace
46+
47+
CASFSActionController::CASFSActionController(
48+
LookupModuleOutputCallback LookupModuleOutput,
49+
llvm::cas::CachingOnDiskFileSystem &CacheFS,
50+
DepscanPrefixMapping PrefixMapping)
51+
: CallbackActionController(std::move(LookupModuleOutput)), CacheFS(CacheFS),
52+
PrefixMapping(std::move(PrefixMapping)) {}
53+
54+
Error CASFSActionController::initialize(CompilerInstance &ScanInstance,
55+
CompilerInvocation &NewInvocation) {
56+
// Setup prefix mapping.
57+
Mapper.emplace(&CacheFS);
58+
if (Error E = PrefixMapping.configurePrefixMapper(NewInvocation, *Mapper))
59+
return E;
60+
61+
const PreprocessorOptions &PPOpts = ScanInstance.getPreprocessorOpts();
62+
if (!PPOpts.Includes.empty() || !PPOpts.ImplicitPCHInclude.empty())
63+
addReversePrefixMappingFileSystem(*Mapper, ScanInstance);
64+
65+
CacheFS.trackNewAccesses();
66+
if (auto CWD =
67+
ScanInstance.getVirtualFileSystem().getCurrentWorkingDirectory())
68+
CacheFS.setCurrentWorkingDirectory(*CWD);
69+
// Track paths that are accessed by the scanner before we reach here.
70+
for (const auto &File : ScanInstance.getHeaderSearchOpts().VFSOverlayFiles)
71+
(void)CacheFS.status(File);
72+
// Enable caching in the resulting commands.
73+
ScanInstance.getFrontendOpts().CacheCompileJob = true;
74+
CASOpts = ScanInstance.getCASOpts();
75+
return Error::success();
76+
}
77+
78+
/// Ensure that all files reachable from imported modules/pch are tracked.
79+
/// These could be loaded lazily during compilation.
80+
static void trackASTFileInputs(CompilerInstance &CI,
81+
llvm::cas::CachingOnDiskFileSystem &CacheFS) {
82+
auto Reader = CI.getASTReader();
83+
if (!Reader)
84+
return;
85+
86+
for (serialization::ModuleFile &MF : Reader->getModuleManager()) {
87+
Reader->visitInputFiles(
88+
MF, /*IncludeSystem=*/true, /*Complain=*/false,
89+
[](const serialization::InputFile &IF, bool isSystem) {
90+
// Visiting input files triggers the file system lookup.
91+
});
92+
}
93+
}
94+
95+
/// Ensure files that are not accessed during the scan (or accessed before the
96+
/// tracking scope) are tracked.
97+
static void trackFilesCommon(CompilerInstance &CI,
98+
llvm::cas::CachingOnDiskFileSystem &CacheFS) {
99+
trackASTFileInputs(CI, CacheFS);
100+
101+
// Exclude the module cache from tracking. The implicit build pcms should
102+
// not be needed after scanning.
103+
if (!CI.getHeaderSearchOpts().ModuleCachePath.empty())
104+
(void)CacheFS.excludeFromTracking(CI.getHeaderSearchOpts().ModuleCachePath);
105+
106+
// Normally this would be looked up while creating the VFS, but implicit
107+
// modules share their VFS and it happens too early for the TU scan.
108+
for (const auto &File : CI.getHeaderSearchOpts().VFSOverlayFiles)
109+
(void)CacheFS.status(File);
110+
111+
StringRef Sysroot = CI.getHeaderSearchOpts().Sysroot;
112+
if (!Sysroot.empty()) {
113+
// Include 'SDKSettings.json', if it exists, to accomodate availability
114+
// checks during the compilation.
115+
llvm::SmallString<256> FilePath = Sysroot;
116+
llvm::sys::path::append(FilePath, "SDKSettings.json");
117+
(void)CacheFS.status(FilePath);
118+
}
119+
}
120+
121+
Error CASFSActionController::finalize(CompilerInstance &ScanInstance,
122+
CompilerInvocation &NewInvocation) {
123+
// Handle profile mappings.
124+
(void)CacheFS.status(NewInvocation.getCodeGenOpts().ProfileInstrumentUsePath);
125+
(void)CacheFS.status(NewInvocation.getCodeGenOpts().SampleProfileFile);
126+
(void)CacheFS.status(NewInvocation.getCodeGenOpts().ProfileRemappingFile);
127+
128+
trackFilesCommon(ScanInstance, CacheFS);
129+
130+
auto CASFileSystemRootID = CacheFS.createTreeFromNewAccesses(
131+
[&](const llvm::vfs::CachedDirectoryEntry &Entry,
132+
SmallVectorImpl<char> &Storage) {
133+
return Mapper->mapDirEntry(Entry, Storage);
134+
});
135+
if (!CASFileSystemRootID)
136+
return CASFileSystemRootID.takeError();
137+
138+
configureInvocationForCaching(NewInvocation, CASOpts,
139+
CASFileSystemRootID->getID().toString(),
140+
CacheFS.getCurrentWorkingDirectory().get(),
141+
/*ProduceIncludeTree=*/false);
142+
143+
if (Mapper)
144+
DepscanPrefixMapping::remapInvocationPaths(NewInvocation, *Mapper);
145+
146+
return Error::success();
147+
}
148+
149+
Error CASFSActionController::initializeModuleBuild(
150+
CompilerInstance &ModuleScanInstance) {
151+
152+
CacheFS.trackNewAccesses();
153+
// If the working directory is not otherwise accessed by the module build,
154+
// we still need it due to -fcas-fs-working-directory being set.
155+
if (auto CWD = CacheFS.getCurrentWorkingDirectory())
156+
(void)CacheFS.status(*CWD);
157+
158+
return Error::success();
159+
}
160+
161+
Error CASFSActionController::finalizeModuleBuild(
162+
CompilerInstance &ModuleScanInstance) {
163+
trackFilesCommon(ModuleScanInstance, CacheFS);
164+
165+
Optional<cas::CASID> RootID;
166+
auto E = CacheFS
167+
.createTreeFromNewAccesses(
168+
[&](const llvm::vfs::CachedDirectoryEntry &Entry,
169+
SmallVectorImpl<char> &Storage) {
170+
return Mapper->mapDirEntry(Entry, Storage);
171+
})
172+
.moveInto(RootID);
173+
if (E)
174+
return E;
175+
176+
Module *M = ModuleScanInstance.getPreprocessor().getCurrentModule();
177+
assert(M && "finalizing without a module");
178+
179+
M->setCASFileSystemRootID(RootID->toString());
180+
return Error::success();
181+
}
182+
183+
Error CASFSActionController::finalizeModuleInvocation(CompilerInvocation &CI,
184+
const ModuleDeps &MD) {
185+
if (auto ID = MD.CASFileSystemRootID) {
186+
configureInvocationForCaching(CI, CASOpts, ID->toString(),
187+
CacheFS.getCurrentWorkingDirectory().get(),
188+
/*ProduceIncludeTree=*/false);
189+
}
190+
191+
if (Mapper)
192+
DepscanPrefixMapping::remapInvocationPaths(CI, *Mapper);
193+
194+
return llvm::Error::success();
195+
}
196+
197+
std::unique_ptr<DependencyActionController>
198+
dependencies::createCASFSActionController(
199+
LookupModuleOutputCallback LookupModuleOutput,
200+
llvm::cas::CachingOnDiskFileSystem &CacheFS,
201+
DepscanPrefixMapping PrefixMapping) {
202+
return std::make_unique<CASFSActionController>(LookupModuleOutput, CacheFS,
203+
std::move(PrefixMapping));
204+
}

clang/lib/Tooling/DependencyScanning/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@ set(LLVM_LINK_COMPONENTS
77
)
88

99
add_clang_library(clangDependencyScanning
10+
CASFSActionController.cpp
1011
DependencyScanningCASFilesystem.cpp
1112
DependencyScanningFilesystem.cpp
1213
DependencyScanningService.cpp
1314
DependencyScanningWorker.cpp
1415
DependencyScanningTool.cpp
16+
IncludeTreeActionController.cpp
1517
ModuleDepCollector.cpp
1618
ScanAndUpdateArgs.cpp
1719

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//===- CachingActions.h -----------------------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_CACHINGACTIONS_H
10+
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_CACHINGACTIONS_H
11+
12+
#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
13+
#include "clang/Tooling/DependencyScanning/ScanAndUpdateArgs.h"
14+
15+
namespace llvm::cas {
16+
class CachingOnDiskFileSystem;
17+
}
18+
19+
namespace clang::tooling::dependencies {
20+
21+
std::unique_ptr<DependencyActionController>
22+
createIncludeTreeActionController(cas::ObjectStore &DB,
23+
DepscanPrefixMapping PrefixMapping);
24+
25+
std::unique_ptr<DependencyActionController>
26+
createCASFSActionController(LookupModuleOutputCallback LookupModuleOutput,
27+
llvm::cas::CachingOnDiskFileSystem &CacheFS,
28+
DepscanPrefixMapping PrefixMapping);
29+
30+
/// The PCH recorded file paths with canonical paths, create a VFS that
31+
/// allows remapping back to the non-canonical source paths so that they are
32+
/// found during dep-scanning.
33+
void addReversePrefixMappingFileSystem(const llvm::PrefixMapper &PrefixMapper,
34+
CompilerInstance &ScanInstance);
35+
36+
} // namespace clang::tooling::dependencies
37+
#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_CACHINGACTIONS_H

0 commit comments

Comments
 (0)