Skip to content
Open
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
10 changes: 5 additions & 5 deletions clang-tools-extra/clangd/ScanningProjectModules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

#include "ProjectModules.h"
#include "support/Logger.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
#include "clang/DependencyScanning/DependencyScanningService.h"
#include "clang/Tooling/DependencyScanningTool.h"

namespace clang::clangd {
namespace {
Expand All @@ -36,8 +36,8 @@ class ModuleDependencyScanner {
std::shared_ptr<const clang::tooling::CompilationDatabase> CDB,
const ThreadsafeFS &TFS)
: CDB(CDB), TFS(TFS),
Service(tooling::dependencies::ScanningMode::CanonicalPreprocessing,
tooling::dependencies::ScanningOutputFormat::P1689) {}
Service(dependencies::ScanningMode::CanonicalPreprocessing,
dependencies::ScanningOutputFormat::P1689) {}

/// The scanned modules dependency information for a specific source file.
struct ModuleDependencyInfo {
Expand Down Expand Up @@ -81,7 +81,7 @@ class ModuleDependencyScanner {
// Whether the scanner has scanned the project globally.
bool GlobalScanned = false;

clang::tooling::dependencies::DependencyScanningService Service;
clang::dependencies::DependencyScanningService Service;

// TODO: Add a scanning cache.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@
#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNER_H
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNER_H

#include "clang/DependencyScanning/DependencyScanningFilesystem.h"
#include "clang/DependencyScanning/ModuleDepCollector.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Serialization/ObjectFilePCHContainerReader.h"
#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"

namespace clang {
class DiagnosticConsumer;

namespace tooling {
namespace dependencies {
class DependencyScanningService;
class DependencyScanningWorker;
Expand Down Expand Up @@ -103,27 +102,10 @@ struct TextDiagnosticsPrinterWithOutput {
DiagPrinter(DiagnosticsOS, *DiagOpts) {}
};

std::pair<std::unique_ptr<driver::Driver>, std::unique_ptr<driver::Compilation>>
buildCompilation(ArrayRef<std::string> ArgStrs, DiagnosticsEngine &Diags,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
llvm::BumpPtrAllocator &Alloc);

std::unique_ptr<CompilerInvocation>
createCompilerInvocation(ArrayRef<std::string> CommandLine,
DiagnosticsEngine &Diags);

std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>>
initVFSForTUBufferScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
ArrayRef<std::string> CommandLine,
StringRef WorkingDirectory,
llvm::MemoryBufferRef TUBuffer);

std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>,
std::vector<std::string>>
initVFSForByNameScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
ArrayRef<std::string> CommandLine,
StringRef WorkingDirectory, StringRef ModuleName);

bool initializeScanCompilerInstance(
CompilerInstance &ScanInstance,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
Expand Down Expand Up @@ -158,22 +140,11 @@ class CompilerInstanceWithContext {
llvm::StringRef CWD;
std::vector<std::string> CommandLine;

// Context - file systems
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS;

// Context - Diagnostics engine.
std::unique_ptr<TextDiagnosticsPrinterWithOutput> DiagPrinterWithOS;
// DiagConsumer may points to DiagPrinterWithOS->DiagPrinter, or a custom
// DiagnosticConsumer passed in from initialize.
DiagnosticConsumer *DiagConsumer = nullptr;
std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts;

// Context - compiler invocation
// Compilation's command's arguments may be owned by Alloc when expanded from
// response files, so we need to keep Alloc alive in the context.
llvm::BumpPtrAllocator Alloc;
std::unique_ptr<clang::driver::Driver> Driver;
std::unique_ptr<clang::driver::Compilation> Compilation;
std::unique_ptr<CompilerInvocation> OriginalInvocation;

// Context - output options
Expand All @@ -195,18 +166,15 @@ class CompilerInstanceWithContext {
: Worker(Worker), CWD(CWD), CommandLine(CMD) {};

// The three methods below returns false when they fail, with the detail
// accumulated in DiagConsumer.
bool initialize(DiagnosticConsumer *DC);
// accumulated in \c DiagEngineWithDiagOpts's diagnostic consumer.
bool initialize(
std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer,
DependencyActionController &Controller);
bool finalize();

// The method below turns the return status from the above methods
// into an llvm::Error using a default DiagnosticConsumer.
llvm::Error handleReturnStatus(bool Success);
};
} // namespace dependencies
} // namespace tooling
} // namespace clang

#endif
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//===- DependencyScanningFilesystem.h - clang-scan-deps fs ===---*- C++ -*-===//
//===- DependencyScanningFilesystem.h - Optimized Scanning FS ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H

#include "clang/Basic/LLVM.h"
#include "clang/Lex/DependencyDirectivesScanner.h"
Expand All @@ -21,7 +21,6 @@
#include <variant>

namespace clang {
namespace tooling {
namespace dependencies {

using DependencyDirectivesTy =
Expand Down Expand Up @@ -521,7 +520,6 @@ class DependencyScanningWorkerFilesystem
};

} // end namespace dependencies
} // end namespace tooling
} // end namespace clang

#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGFILESYSTEM_H
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
//===- DependencyScanningService.h - clang-scan-deps service ===-*- C++ -*-===//
//===- DependencyScanningService.h - Scanning Service -----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H
#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H
#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H

#include "clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h"
#include "clang/Tooling/DependencyScanning/InProcessModuleCache.h"
#include "clang/DependencyScanning/DependencyScanningFilesystem.h"
#include "clang/DependencyScanning/InProcessModuleCache.h"
#include "llvm/ADT/BitmaskEnum.h"
#include "llvm/Support/Chrono.h"

namespace clang {
namespace tooling {
namespace dependencies {

/// The mode in which the dependency scanner will operate to find the
Expand Down Expand Up @@ -125,7 +124,6 @@ class DependencyScanningService {
};

} // end namespace dependencies
} // end namespace tooling
} // end namespace clang

#endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H
#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGSERVICE_H
166 changes: 166 additions & 0 deletions clang/include/clang/DependencyScanning/DependencyScanningUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
//===- DependencyScanningUtils.h - Common Scanning Utilities ----*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H
#define LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H

#include "clang/DependencyScanning/DependencyScannerImpl.h"
#include "clang/DependencyScanning/DependencyScanningWorker.h"
#include "clang/DependencyScanning/ModuleDepCollector.h"

namespace clang {
namespace dependencies {

/// Graph of modular dependencies.
using ModuleDepsGraph = std::vector<clang::dependencies::ModuleDeps>;

/// The full dependencies and module graph for a specific input.
struct TranslationUnitDeps {
/// The graph of direct and transitive modular dependencies.
ModuleDepsGraph ModuleGraph;

/// The identifier of the C++20 module this translation unit exports.
///
/// If the translation unit is not a module then \c ID.ModuleName is empty.
clang::dependencies::ModuleID ID;

/// A collection of absolute paths to files that this translation unit
/// directly depends on, not including transitive dependencies.
std::vector<std::string> FileDeps;

/// A collection of prebuilt modules this translation unit directly depends
/// on, not including transitive dependencies.
std::vector<clang::dependencies::PrebuiltModuleDep> PrebuiltModuleDeps;

/// A list of modules this translation unit directly depends on, not including
/// transitive dependencies.
///
/// This may include modules with a different context hash when it can be
/// determined that the differences are benign for this compilation.
std::vector<clang::dependencies::ModuleID> ClangModuleDeps;

/// A list of module names that are visible to this translation unit. This
/// includes both direct and transitive module dependencies.
std::vector<std::string> VisibleModules;

/// A list of the C++20 named modules this translation unit depends on.
std::vector<std::string> NamedModuleDeps;

/// The sequence of commands required to build the translation unit. Commands
/// should be executed in order.
///
/// FIXME: If we add support for multi-arch builds in clang-scan-deps, we
/// should make the dependencies between commands explicit to enable parallel
/// builds of each architecture.
std::vector<clang::dependencies::Command> Commands;

/// Deprecated driver command-line. This will be removed in a future version.
std::vector<std::string> DriverCommandLine;
};

class FullDependencyConsumer : public clang::dependencies::DependencyConsumer {
public:
FullDependencyConsumer(
const llvm::DenseSet<clang::dependencies::ModuleID> &AlreadySeen)
: AlreadySeen(AlreadySeen) {}

void handleBuildCommand(clang::dependencies::Command Cmd) override {
Commands.push_back(std::move(Cmd));
}

void handleDependencyOutputOpts(const DependencyOutputOptions &) override {}

void handleFileDependency(StringRef File) override {
Dependencies.push_back(std::string(File));
}

void handlePrebuiltModuleDependency(
clang::dependencies::PrebuiltModuleDep PMD) override {
PrebuiltModuleDeps.emplace_back(std::move(PMD));
}

void handleModuleDependency(clang::dependencies::ModuleDeps MD) override {
ClangModuleDeps[MD.ID] = std::move(MD);
}

void handleDirectModuleDependency(clang::dependencies::ModuleID ID) override {
DirectModuleDeps.push_back(ID);
}

void handleVisibleModule(std::string ModuleName) override {
VisibleModules.push_back(ModuleName);
}

void handleContextHash(std::string Hash) override {
ContextHash = std::move(Hash);
}

void handleProvidedAndRequiredStdCXXModules(
std::optional<clang::dependencies::P1689ModuleInfo> Provided,
std::vector<clang::dependencies::P1689ModuleInfo> Requires) override {
ModuleName = Provided ? Provided->ModuleName : "";
llvm::transform(Requires, std::back_inserter(NamedModuleDeps),
[](const auto &Module) { return Module.ModuleName; });
}

TranslationUnitDeps takeTranslationUnitDeps();

private:
std::vector<std::string> Dependencies;
std::vector<clang::dependencies::PrebuiltModuleDep> PrebuiltModuleDeps;
llvm::MapVector<clang::dependencies::ModuleID,
clang::dependencies::ModuleDeps>
ClangModuleDeps;
std::string ModuleName;
std::vector<std::string> NamedModuleDeps;
std::vector<clang::dependencies::ModuleID> DirectModuleDeps;
std::vector<std::string> VisibleModules;
std::vector<clang::dependencies::Command> Commands;
std::string ContextHash;
const llvm::DenseSet<clang::dependencies::ModuleID> &AlreadySeen;
};

/// A callback to lookup module outputs for "-fmodule-file=", "-o" etc.
using LookupModuleOutputCallback =
llvm::function_ref<std::string(const clang::dependencies::ModuleDeps &,
clang::dependencies::ModuleOutputKind)>;

/// A simple dependency action controller that uses a callback. If no callback
/// is provided, it is assumed that looking up module outputs is unreachable.
class CallbackActionController
: public clang::dependencies::DependencyActionController {
public:
virtual ~CallbackActionController();

static std::string
lookupUnreachableModuleOutput(const clang::dependencies::ModuleDeps &MD,
clang::dependencies::ModuleOutputKind Kind) {
llvm::report_fatal_error("unexpected call to lookupModuleOutput");
};

CallbackActionController(LookupModuleOutputCallback LMO)
: LookupModuleOutput(std::move(LMO)) {
if (!LookupModuleOutput) {
LookupModuleOutput = lookupUnreachableModuleOutput;
}
}

std::string
lookupModuleOutput(const clang::dependencies::ModuleDeps &MD,
clang::dependencies::ModuleOutputKind Kind) override {
return LookupModuleOutput(MD, Kind);
}

private:
LookupModuleOutputCallback LookupModuleOutput;
};

} // end namespace dependencies
} // end namespace clang

#endif // LLVM_CLANG_DEPENDENCYSCANNING_DEPENDENCYSCANNINGUTILS_H
Loading