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
6 changes: 6 additions & 0 deletions clang/include/clang/Frontend/CompilerInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,12 @@ class CompilerInstance : public ModuleLoader {
DependencyCollectors.push_back(std::move(Listener));
}

void clearDependencyCollectors() { DependencyCollectors.clear(); }

std::vector<std::shared_ptr<DependencyCollector>> &getDependencyCollectors() {
return DependencyCollectors;
}

void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);

ModuleCache &getModuleCache() const { return *ModCache; }
Expand Down
9 changes: 0 additions & 9 deletions clang/include/clang/Frontend/FrontendActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,15 +320,6 @@ class PrintPreprocessedAction : public PreprocessorFrontendAction {
bool hasPCHSupport() const override { return true; }
};

class GetDependenciesByModuleNameAction : public PreprocessOnlyAction {
StringRef ModuleName;
void ExecuteAction() override;

public:
GetDependenciesByModuleNameAction(StringRef ModuleName)
: ModuleName(ModuleName) {}
};

//===----------------------------------------------------------------------===//
// HLSL Specific Actions
//===----------------------------------------------------------------------===//
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1327,6 +1327,7 @@ class Preprocessor {
std::move(Callbacks));
Callbacks = std::move(C);
}
void removePPCallbacks() { Callbacks.reset(); }
/// \}

/// Get the number of tokens processed so far.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,44 @@ class DependencyScanningTool {
LookupModuleOutputCallback LookupModuleOutput,
std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt);

/// Given a compilation context specified via the Clang driver command-line,
/// gather modular dependencies of module with the given name, and return the
/// information needed for explicit build.
llvm::Expected<TranslationUnitDeps> getModuleDependencies(
StringRef ModuleName, const std::vector<std::string> &CommandLine,
StringRef CWD, const llvm::DenseSet<ModuleID> &AlreadySeen,
/// The following three methods provide a new interface to perform
/// by name dependency scan. The new interface's intention is to improve
/// dependency scanning performance when a sequence of name is looked up
/// with the same current working directory and the command line.

/// @brief Initializing the context and the compiler instance.
/// This method must be called before calling
/// computeDependenciesByNameWithContext.
/// @param CWD The current working directory used during the scan.
/// @param CommandLine The commandline used for the scan.
/// @return Error if the initializaiton fails.
llvm::Error initializeCompilerInstanceWithContext(
StringRef CWD, const std::vector<std::string> &CommandLine);

/// @brief Computes the dependeny for the module named ModuleName.
/// @param ModuleName The name of the module for which this method computes
///. dependencies.
/// @param AlreadySeen This stores modules which have previously been
/// reported. Use the same instance for all calls to this
/// function for a single \c DependencyScanningTool in a
/// single build. Note that this parameter is not part of
/// the context because it can be shared across different
/// worker threads and each worker thread may update it.
/// @param LookupModuleOutput This function is called to fill in
/// "-fmodule-file=", "-o" and other output
/// arguments for dependencies.
/// @return An instance of \c TranslationUnitDeps if the scan is successful.
/// Otherwise it returns an error.
llvm::Expected<TranslationUnitDeps> computeDependenciesByNameWithContext(
StringRef ModuleName, const llvm::DenseSet<ModuleID> &AlreadySeen,
LookupModuleOutputCallback LookupModuleOutput);

/// @brief This method finializes the compiler instance. It finalizes the
/// diagnostics and deletes the compiler instance. Call this method
/// once all names for a same commandline are scanned.
/// @return Error if an error occured during finalization.
llvm::Error finalizeCompilerInstanceWithContext();

llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ namespace tooling {
namespace dependencies {

class DependencyScanningWorkerFilesystem;
class CompilerInstanceWithContext;

/// A command-line tool invocation that is part of building a TU.
///
Expand Down Expand Up @@ -89,6 +90,8 @@ class DependencyScanningWorker {
DependencyScanningWorker(DependencyScanningService &Service,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);

~DependencyScanningWorker();

/// Run the dependency scanning tool for a given clang driver command-line,
/// and report the discovered dependencies to the provided consumer. If
/// TUBuffer is not nullopt, it is used as TU input for the dependency
Expand All @@ -103,18 +106,6 @@ class DependencyScanningWorker {
DiagnosticConsumer &DiagConsumer,
std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt);

/// Run the dependency scanning tool for a given clang driver command-line
/// for a specific module.
///
/// \returns false if clang errors occurred (with diagnostics reported to
/// \c DiagConsumer), true otherwise.
bool computeDependencies(StringRef WorkingDirectory,
const std::vector<std::string> &CommandLine,
DependencyConsumer &DepConsumer,
DependencyActionController &Controller,
DiagnosticConsumer &DiagConsumer,
StringRef ModuleName);

/// Run the dependency scanning tool for a given clang driver command-line
/// for a specific translation unit via file system or memory buffer.
///
Expand All @@ -125,16 +116,33 @@ class DependencyScanningWorker {
DependencyConsumer &Consumer, DependencyActionController &Controller,
std::optional<llvm::MemoryBufferRef> TUBuffer = std::nullopt);

/// Run the dependency scanning tool for a given clang driver command-line
/// for a specific module.
///
/// \returns A \c StringError with the diagnostic output if clang errors
/// occurred, success otherwise.
llvm::Error computeDependencies(StringRef WorkingDirectory,
const std::vector<std::string> &CommandLine,
DependencyConsumer &Consumer,
DependencyActionController &Controller,
StringRef ModuleName);
/// The three method below implements a new interface for by name
/// dependency scanning. They together enable the dependency scanning worker
/// to more effectively perform scanning for a sequence of modules
/// by name when the CWD and CommandLine do not change across the queries.

/// @brief Initializing the context and the compiler instance.
/// @param CWD The current working directory used during the scan.
/// @param CommandLine The commandline used for the scan.
/// @return Error if the initializaiton fails.
llvm::Error initializeCompilerInstanceWithContext(
StringRef CWD, const std::vector<std::string> &CommandLine);

/// @brief Performaces dependency scanning for the module whose name is
/// specified.
/// @param ModuleName The name of the module whose dependency will be
/// scanned.
/// @param Consumer The dependency consumer that stores the results.
/// @param Controller The controller for the dependency scanning action.
/// @return Error if the scanner incurs errors.
llvm::Error
computeDependenciesByNameWithContext(StringRef ModuleName,
DependencyConsumer &Consumer,
DependencyActionController &Controller);

/// @brief Finalizes the diagnostics engine and deletes the compiler instance.
/// @return Error if errors occur during finalization.
llvm::Error finalizeCompilerInstanceWithContext();

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

Expand All @@ -151,14 +159,16 @@ class DependencyScanningWorker {
/// (passed in the constructor).
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;

friend CompilerInstanceWithContext;
std::unique_ptr<CompilerInstanceWithContext> CIWithContext;

/// Private helper functions.
bool scanDependencies(StringRef WorkingDirectory,
const std::vector<std::string> &CommandLine,
DependencyConsumer &Consumer,
DependencyActionController &Controller,
DiagnosticConsumer &DC,
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
std::optional<StringRef> ModuleName);
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
};

} // end namespace dependencies
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ class ModuleDepCollector final : public DependencyCollector {
void attachToPreprocessor(Preprocessor &PP) override;
void attachToASTReader(ASTReader &R) override;

PPCallbacks *getPPCallbacks() { return CollectorPPPtr; }

/// Apply any changes implied by the discovered dependencies to the given
/// invocation, (e.g. disable implicit modules, add explicit module paths).
void applyDiscoveredDependencies(CompilerInvocation &CI);
Expand Down Expand Up @@ -339,6 +341,10 @@ class ModuleDepCollector final : public DependencyCollector {
std::optional<P1689ModuleInfo> ProvidedStdCXXModule;
std::vector<P1689ModuleInfo> RequiredStdCXXModules;

/// A pointer to the preprocessor callback so we can invoke it directly
/// if needed.
ModuleDepCollectorPP *CollectorPPPtr = nullptr;

/// Checks whether the module is known as being prebuilt.
bool isPrebuiltModule(const Module *M);

Expand Down
14 changes: 0 additions & 14 deletions clang/lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1233,20 +1233,6 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() {
llvm::outs());
}

void GetDependenciesByModuleNameAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
Preprocessor &PP = CI.getPreprocessor();
SourceManager &SM = PP.getSourceManager();
FileID MainFileID = SM.getMainFileID();
SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);
SmallVector<IdentifierLoc, 2> Path;
IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName);
Path.emplace_back(FileStart, ModuleID);
auto ModResult = CI.loadModule(FileStart, Path, Module::Hidden, false);
PPCallbacks *CB = PP.getPPCallbacks();
CB->moduleImport(SourceLocation(), Path, ModResult);
}

//===----------------------------------------------------------------------===//
// HLSL Specific Actions
//===----------------------------------------------------------------------===//
Expand Down
Loading