Skip to content

[clang][deps] Propagate the entire service #128959

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ struct P1689Rule {
class DependencyScanningTool {
public:
/// Construct a dependency scanning tool.
///
/// @param Service The parent service. Must outlive the tool.
/// @param FS The filesystem for the tool to use. Defaults to the physical FS.
DependencyScanningTool(DependencyScanningService &Service,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
llvm::vfs::createPhysicalFileSystem());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ class DependencyActionController {
/// using the regular processing run.
class DependencyScanningWorker {
public:
/// Construct a dependency scanning worker.
///
/// @param Service The parent service. Must outlive the worker.
/// @param FS The filesystem for the worker to use.
DependencyScanningWorker(DependencyScanningService &Service,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);

Expand Down Expand Up @@ -130,11 +134,11 @@ class DependencyScanningWorker {
DependencyActionController &Controller,
StringRef ModuleName);

bool shouldEagerLoadModules() const { return EagerLoadModules; }

llvm::vfs::FileSystem &getVFS() const { return *BaseFS; }

private:
/// The parent dependency scanning service.
DependencyScanningService &Service;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
/// The file system to be used during the scan.
/// This is either \c FS passed in the constructor (when performing canonical
Expand All @@ -144,11 +148,6 @@ class DependencyScanningWorker {
/// dependency-directives-extracting) filesystem overlaid on top of \c FS
/// (passed in the constructor).
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
ScanningOutputFormat Format;
/// Whether to optimize the modules' command-line arguments.
ScanningOptimizations OptimizeArgs;
/// Whether to set up command-lines to load PCM files eagerly.
bool EagerLoadModules;

/// Private helper functions.
bool scanDependencies(StringRef WorkingDirectory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,12 @@ class ModuleDepCollectorPP final : public PPCallbacks {
/// \c ModuleDepCollectorPP to the preprocessor.
class ModuleDepCollector final : public DependencyCollector {
public:
ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
ModuleDepCollector(DependencyScanningService &Service,
std::unique_ptr<DependencyOutputOptions> Opts,
CompilerInstance &ScanInstance, DependencyConsumer &C,
DependencyActionController &Controller,
CompilerInvocation OriginalCI,
PrebuiltModuleVFSMapT PrebuiltModuleVFSMap,
ScanningOptimizations OptimizeArgs, bool EagerLoadModules,
bool IsStdModuleP1689Format);
PrebuiltModuleVFSMapT PrebuiltModuleVFSMap);

void attachToPreprocessor(Preprocessor &PP) override;
void attachToASTReader(ASTReader &R) override;
Expand All @@ -243,6 +242,8 @@ class ModuleDepCollector final : public DependencyCollector {
private:
friend ModuleDepCollectorPP;

/// The parent dependency scanning service.
DependencyScanningService &Service;
/// The compiler instance for scanning the current translation unit.
CompilerInstance &ScanInstance;
/// The consumer of collected dependency information.
Expand Down Expand Up @@ -274,13 +275,6 @@ class ModuleDepCollector final : public DependencyCollector {
/// a discovered modular dependency. Note that this still needs to be adjusted
/// for each individual module.
CowCompilerInvocation CommonInvocation;
/// Whether to optimize the modules' command-line arguments.
ScanningOptimizations OptimizeArgs;
/// Whether to set up command-lines to load PCM files eagerly.
bool EagerLoadModules;
/// If we're generating dependency output in P1689 format
/// for standard C++ modules.
bool IsStdModuleP1689Format;

std::optional<P1689ModuleInfo> ProvidedStdCXXModule;
std::vector<P1689ModuleInfo> RequiredStdCXXModules;
Expand Down
39 changes: 15 additions & 24 deletions clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,15 +284,12 @@ static void canonicalizeDefines(PreprocessorOptions &PPOpts) {
class DependencyScanningAction : public tooling::ToolAction {
public:
DependencyScanningAction(
StringRef WorkingDirectory, DependencyConsumer &Consumer,
DependencyActionController &Controller,
DependencyScanningService &Service, StringRef WorkingDirectory,
DependencyConsumer &Consumer, DependencyActionController &Controller,
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS,
ScanningOutputFormat Format, ScanningOptimizations OptimizeArgs,
bool EagerLoadModules, bool DisableFree,
std::optional<StringRef> ModuleName = std::nullopt)
: WorkingDirectory(WorkingDirectory), Consumer(Consumer),
Controller(Controller), DepFS(std::move(DepFS)), Format(Format),
OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules),
bool DisableFree, std::optional<StringRef> ModuleName = std::nullopt)
: Service(Service), WorkingDirectory(WorkingDirectory),
Consumer(Consumer), Controller(Controller), DepFS(std::move(DepFS)),
DisableFree(DisableFree), ModuleName(ModuleName) {}

bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
Expand All @@ -303,7 +300,7 @@ class DependencyScanningAction : public tooling::ToolAction {
CompilerInvocation OriginalInvocation(*Invocation);
// Restore the value of DisableFree, which may be modified by Tooling.
OriginalInvocation.getFrontendOpts().DisableFree = DisableFree;
if (any(OptimizeArgs & ScanningOptimizations::Macros))
if (any(Service.getOptimizeArgs() & ScanningOptimizations::Macros))
canonicalizeDefines(OriginalInvocation.getPreprocessorOpts());

if (Scanned) {
Expand Down Expand Up @@ -340,7 +337,7 @@ class DependencyScanningAction : public tooling::ToolAction {
ScanInstance.getFrontendOpts().ModulesShareFileManager = true;
ScanInstance.getHeaderSearchOpts().ModuleFormat = "raw";
ScanInstance.getHeaderSearchOpts().ModulesIncludeVFSUsage =
any(OptimizeArgs & ScanningOptimizations::VFS);
any(Service.getOptimizeArgs() & ScanningOptimizations::VFS);

// Support for virtual file system overlays.
auto FS = createVFSFromCompilerInvocation(
Expand Down Expand Up @@ -400,7 +397,7 @@ class DependencyScanningAction : public tooling::ToolAction {
ScanInstance.getFrontendOpts().Inputs)};
Opts->IncludeSystemHeaders = true;

switch (Format) {
switch (Service.getFormat()) {
case ScanningOutputFormat::Make:
ScanInstance.addDependencyCollector(
std::make_shared<DependencyConsumerForwarder>(
Expand All @@ -409,9 +406,8 @@ class DependencyScanningAction : public tooling::ToolAction {
case ScanningOutputFormat::P1689:
case ScanningOutputFormat::Full:
MDC = std::make_shared<ModuleDepCollector>(
std::move(Opts), ScanInstance, Consumer, Controller,
OriginalInvocation, std::move(PrebuiltModuleVFSMap), OptimizeArgs,
EagerLoadModules, Format == ScanningOutputFormat::P1689);
Service, std::move(Opts), ScanInstance, Consumer, Controller,
OriginalInvocation, std::move(PrebuiltModuleVFSMap));
ScanInstance.addDependencyCollector(MDC);
break;
}
Expand All @@ -433,7 +429,7 @@ class DependencyScanningAction : public tooling::ToolAction {

std::unique_ptr<FrontendAction> Action;

if (Format == ScanningOutputFormat::P1689)
if (Service.getFormat() == ScanningOutputFormat::P1689)
Action = std::make_unique<PreprocessOnlyAction>();
else if (ModuleName)
Action = std::make_unique<GetDependenciesByModuleNameAction>(*ModuleName);
Expand Down Expand Up @@ -476,14 +472,11 @@ class DependencyScanningAction : public tooling::ToolAction {
LastCC1Arguments = CI.getCC1CommandLine();
}

private:
DependencyScanningService &Service;
StringRef WorkingDirectory;
DependencyConsumer &Consumer;
DependencyActionController &Controller;
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
ScanningOutputFormat Format;
ScanningOptimizations OptimizeArgs;
bool EagerLoadModules;
bool DisableFree;
std::optional<StringRef> ModuleName;
std::optional<CompilerInstance> ScanInstanceStorage;
Expand All @@ -498,8 +491,7 @@ class DependencyScanningAction : public tooling::ToolAction {
DependencyScanningWorker::DependencyScanningWorker(
DependencyScanningService &Service,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
: Format(Service.getFormat()), OptimizeArgs(Service.getOptimizeArgs()),
EagerLoadModules(Service.shouldEagerLoadModules()) {
: Service(Service) {
PCHContainerOps = std::make_shared<PCHContainerOperations>();
// We need to read object files from PCH built outside the scanner.
PCHContainerOps->registerReader(
Expand Down Expand Up @@ -655,9 +647,8 @@ bool DependencyScanningWorker::scanDependencies(
// in-process; preserve the original value, which is
// always true for a driver invocation.
bool DisableFree = true;
DependencyScanningAction Action(WorkingDirectory, Consumer, Controller, DepFS,
Format, OptimizeArgs, EagerLoadModules,
DisableFree, ModuleName);
DependencyScanningAction Action(Service, WorkingDirectory, Consumer,
Controller, DepFS, DisableFree, ModuleName);

bool Success = false;
if (CommandLine[1] == "-cc1") {
Expand Down
45 changes: 23 additions & 22 deletions clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ ModuleDepCollector::getInvocationAdjustedForModuleBuildWithoutOutputs(
// TODO: Verify this works fine when modulemap for module A is eagerly
// loaded from A.pcm, and module map passed on the command line contains
// definition of a submodule: "explicit module A.Private { ... }".
if (EagerLoadModules && DepModuleMapFiles.contains(*ModuleMapEntry))
if (Service.shouldEagerLoadModules() &&
DepModuleMapFiles.contains(*ModuleMapEntry))
continue;

// Don't report module map file of the current module unless it also
Expand Down Expand Up @@ -345,7 +346,7 @@ llvm::DenseSet<const FileEntry *> ModuleDepCollector::collectModuleMapFiles(

void ModuleDepCollector::addModuleMapFiles(
CompilerInvocation &CI, ArrayRef<ModuleID> ClangModuleDeps) const {
if (EagerLoadModules)
if (Service.shouldEagerLoadModules())
return; // Only pcm is needed for eager load.

for (const ModuleID &MID : ClangModuleDeps) {
Expand All @@ -360,7 +361,7 @@ void ModuleDepCollector::addModuleFiles(
for (const ModuleID &MID : ClangModuleDeps) {
std::string PCMPath =
Controller.lookupModuleOutput(MID, ModuleOutputKind::ModuleFile);
if (EagerLoadModules)
if (Service.shouldEagerLoadModules())
CI.getFrontendOpts().ModuleFiles.push_back(std::move(PCMPath));
else
CI.getHeaderSearchOpts().PrebuiltModuleFiles.insert(
Expand All @@ -373,7 +374,7 @@ void ModuleDepCollector::addModuleFiles(
for (const ModuleID &MID : ClangModuleDeps) {
std::string PCMPath =
Controller.lookupModuleOutput(MID, ModuleOutputKind::ModuleFile);
if (EagerLoadModules)
if (Service.shouldEagerLoadModules())
CI.getMutFrontendOpts().ModuleFiles.push_back(std::move(PCMPath));
else
CI.getMutHeaderSearchOpts().PrebuiltModuleFiles.insert(
Expand Down Expand Up @@ -551,8 +552,8 @@ static std::string getModuleContextHash(const ModuleDeps &MD,
void ModuleDepCollector::associateWithContextHash(
const CowCompilerInvocation &CI, bool IgnoreCWD, ModuleDeps &Deps) {
Deps.ID.ContextHash =
getModuleContextHash(Deps, CI, EagerLoadModules, IgnoreCWD,
ScanInstance.getVirtualFileSystem());
getModuleContextHash(Deps, CI, Service.shouldEagerLoadModules(),
IgnoreCWD, ScanInstance.getVirtualFileSystem());
bool Inserted = ModuleDepsByID.insert({Deps.ID, &Deps}).second;
(void)Inserted;
assert(Inserted && "duplicate module mapping");
Expand Down Expand Up @@ -656,7 +657,7 @@ void ModuleDepCollectorPP::EndOfMainFile() {

MDC.Consumer.handleDependencyOutputOpts(*MDC.Opts);

if (MDC.IsStdModuleP1689Format)
if (MDC.Service.getFormat() == ScanningOutputFormat::P1689)
MDC.Consumer.handleProvidedAndRequiredStdCXXModules(
MDC.ProvidedStdCXXModule, MDC.RequiredStdCXXModules);

Expand Down Expand Up @@ -753,21 +754,23 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
CowCompilerInvocation CI =
MDC.getInvocationAdjustedForModuleBuildWithoutOutputs(
MD, [&](CowCompilerInvocation &BuildInvocation) {
if (any(MDC.OptimizeArgs & (ScanningOptimizations::HeaderSearch |
ScanningOptimizations::VFS)))
if (any(MDC.Service.getOptimizeArgs() &
(ScanningOptimizations::HeaderSearch |
ScanningOptimizations::VFS)))
optimizeHeaderSearchOpts(BuildInvocation.getMutHeaderSearchOpts(),
*MDC.ScanInstance.getASTReader(), *MF,
MDC.PrebuiltModuleVFSMap,
MDC.OptimizeArgs);
MDC.Service.getOptimizeArgs());

if (any(MDC.OptimizeArgs & ScanningOptimizations::SystemWarnings))
if (any(MDC.Service.getOptimizeArgs() &
ScanningOptimizations::SystemWarnings))
optimizeDiagnosticOpts(
BuildInvocation.getMutDiagnosticOpts(),
BuildInvocation.getFrontendOpts().IsSystemModule);

IgnoreCWD =
any(MDC.OptimizeArgs & ScanningOptimizations::IgnoreCWD) &&
isSafeToIgnoreCWD(BuildInvocation);
IgnoreCWD = any(MDC.Service.getOptimizeArgs() &
ScanningOptimizations::IgnoreCWD) &&
isSafeToIgnoreCWD(BuildInvocation);
if (IgnoreCWD) {
llvm::ErrorOr<std::string> CWD =
MDC.ScanInstance.getVirtualFileSystem()
Expand Down Expand Up @@ -870,19 +873,17 @@ void ModuleDepCollectorPP::addAffectingClangModule(
}

ModuleDepCollector::ModuleDepCollector(
DependencyScanningService &Service,
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),
PrebuiltModuleVFSMapT PrebuiltModuleVFSMap)
: Service(Service), ScanInstance(ScanInstance), Consumer(C),
Controller(Controller),
PrebuiltModuleVFSMap(std::move(PrebuiltModuleVFSMap)),
Opts(std::move(Opts)),
CommonInvocation(
makeCommonInvocationForModuleBuild(std::move(OriginalCI))),
OptimizeArgs(OptimizeArgs), EagerLoadModules(EagerLoadModules),
IsStdModuleP1689Format(IsStdModuleP1689Format) {}
makeCommonInvocationForModuleBuild(std::move(OriginalCI))) {}

void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) {
PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(*this));
Expand Down Expand Up @@ -914,7 +915,7 @@ static StringRef makeAbsoluteAndPreferred(CompilerInstance &CI, StringRef Path,
}

void ModuleDepCollector::addFileDep(StringRef Path) {
if (IsStdModuleP1689Format) {
if (Service.getFormat() == ScanningOutputFormat::P1689) {
// Within P1689 format, we don't want all the paths to be absolute path
// since it may violate the traditional make style dependencies info.
FileDeps.emplace_back(Path);
Expand Down
Loading