Skip to content

Commit 1948276

Browse files
committed
Inital commit of CompilerInstanceWithContext, all tests passing.
1 parent bed17c0 commit 1948276

File tree

12 files changed

+463
-8
lines changed

12 files changed

+463
-8
lines changed

clang/include/clang/Frontend/CompilerInstance.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,12 @@ class CompilerInstance : public ModuleLoader {
946946
DependencyCollectors.push_back(std::move(Listener));
947947
}
948948

949+
void clearDependencyCollectors() { DependencyCollectors.clear(); }
950+
951+
std::vector<std::shared_ptr<DependencyCollector>> &getDependencyCollectors() {
952+
return DependencyCollectors;
953+
}
954+
949955
void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
950956

951957
ModuleCache &getModuleCache() const { return *ModCache; }

clang/include/clang/Frontend/Utils.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class DiagnosticsEngine;
4040
class ExternalSemaSource;
4141
class FrontendOptions;
4242
class PCHContainerReader;
43+
class PPCallbacks;
4344
class Preprocessor;
4445
class PreprocessorOptions;
4546
class PreprocessorOutputOptions;
@@ -87,6 +88,9 @@ class DependencyCollector {
8788
bool IsSystem, bool IsModuleFile,
8889
bool IsMissing);
8990

91+
/// @return the PPCallback this collector added to the Preprocessor.
92+
virtual PPCallbacks *getPPCallbacks() { return nullptr; };
93+
9094
protected:
9195
/// Return true if the filename was added to the list of dependencies, false
9296
/// otherwise.

clang/include/clang/Lex/Preprocessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,6 +1327,7 @@ class Preprocessor {
13271327
std::move(Callbacks));
13281328
Callbacks = std::move(C);
13291329
}
1330+
void removePPCallbacks() { Callbacks.reset(); }
13301331
/// \}
13311332

13321333
/// Get the number of tokens processed so far.

clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.h renamed to clang/include/clang/Tooling/DependencyScanning/DependencyScannerImpl.h

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===- DependencyScanner.h - Performs module dependency scanning *- C++ -*-===//
1+
//===- DependencyScannerImpl.h - Implements dependency scanning *- C++ -*--===//
22
//
33
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
44
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,6 +10,7 @@
1010
#define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNER_H
1111

1212
#include "clang/Driver/Compilation.h"
13+
#include "clang/Driver/Driver.h"
1314
#include "clang/Frontend/CompilerInstance.h"
1415
#include "clang/Frontend/CompilerInvocation.h"
1516
#include "clang/Frontend/TextDiagnosticPrinter.h"
@@ -23,6 +24,8 @@ class DiagnosticConsumer;
2324
namespace tooling {
2425
namespace dependencies {
2526
class DependencyScanningService;
27+
class DependencyScanningWorker;
28+
2629
class DependencyConsumer;
2730
class DependencyActionController;
2831
class DependencyScanningWorkerFilesystem;
@@ -149,6 +152,59 @@ std::shared_ptr<ModuleDepCollector> initializeScanInstanceDependencyCollector(
149152
DependencyActionController &Controller,
150153
PrebuiltModulesAttrsMap PrebuiltModulesASTMap,
151154
llvm::SmallVector<StringRef> &StableDirs);
155+
156+
class CompilerInstanceWithContext {
157+
// Context
158+
DependencyScanningWorker &Worker;
159+
llvm::StringRef CWD;
160+
std::vector<std::string> CommandLine;
161+
static const uint64_t MAX_NUM_NAMES = (1 << 12);
162+
static const std::string FakeFileBuffer;
163+
164+
// Context - file systems
165+
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS;
166+
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFS;
167+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> InMemoryOverlay;
168+
169+
// Context - Diagnostics engine, file manager and source mamanger.
170+
std::string DiagnosticOutput;
171+
llvm::raw_string_ostream DiagnosticsOS;
172+
std::unique_ptr<TextDiagnosticPrinter> DiagPrinter;
173+
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
174+
std::unique_ptr<FileManager> FileMgr;
175+
std::unique_ptr<SourceManager> SrcMgr;
176+
177+
// Context - compiler invocation
178+
std::unique_ptr<clang::driver::Driver> Driver;
179+
std::unique_ptr<clang::driver::Compilation> Compilation;
180+
std::unique_ptr<CompilerInvocation> Invocation;
181+
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFSFromCompilerInvocation;
182+
183+
// Context - output options
184+
std::unique_ptr<DependencyOutputOptions> OutputOpts;
185+
186+
// Context - stable directory handling
187+
llvm::SmallVector<StringRef> StableDirs;
188+
PrebuiltModulesAttrsMap PrebuiltModuleVFSMap;
189+
190+
// Compiler Instance
191+
std::unique_ptr<CompilerInstance> CIPtr;
192+
193+
// // Source location offset.
194+
int32_t SrcLocOffset = 0;
195+
196+
public:
197+
CompilerInstanceWithContext(DependencyScanningWorker &Worker, StringRef CWD,
198+
const std::vector<std::string> &CMD)
199+
: Worker(Worker), CWD(CWD), CommandLine(CMD),
200+
DiagnosticsOS(DiagnosticOutput) {};
201+
202+
llvm::Error initialize();
203+
llvm::Error computeDependencies(StringRef ModuleName,
204+
DependencyConsumer &Consumer,
205+
DependencyActionController &Controller);
206+
llvm::Error finalize();
207+
};
152208
} // namespace dependencies
153209
} // namespace tooling
154210
} // namespace clang

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,44 @@ class DependencyScanningTool {
159159
StringRef CWD, const llvm::DenseSet<ModuleID> &AlreadySeen,
160160
LookupModuleOutputCallback LookupModuleOutput);
161161

162+
/// The following three methods provide a new interface to perform
163+
/// by name dependency scan. The new interface's intention is to improve
164+
/// dependency scanning performance when a sequence of name is looked up
165+
/// with the same current working directory and the command line.
166+
167+
/// @brief Initializing the context and the compiler instance.
168+
/// This method must be called before calling
169+
/// computeDependenciesByNameWithContext.
170+
/// @param CWD The current working directory used during the scan.
171+
/// @param CommandLine The commandline used for the scan.
172+
/// @return Error if the initializaiton fails.
173+
llvm::Error initializeCompilerInstacneWithContext(
174+
StringRef CWD, const std::vector<std::string> &CommandLine);
175+
176+
/// @brief Computes the dependeny for the module named ModuleName.
177+
/// @param ModuleName The name of the module for which this method computes
178+
///. dependencies.
179+
/// @param AlreadySeen This stores modules which have previously been
180+
/// reported. Use the same instance for all calls to this
181+
/// function for a single \c DependencyScanningTool in a
182+
/// single build. Note that this parameter is not part of
183+
/// the context because it can be shared across different
184+
/// worker threads and each worker thread may update it.
185+
/// @param LookupModuleOutput This function is called to fill in
186+
/// "-fmodule-file=", "-o" and other output
187+
/// arguments for dependencies.
188+
/// @return An instance of \c TranslationUnitDeps if the scan is successful.
189+
/// Otherwise it returns an error.
190+
llvm::Expected<TranslationUnitDeps> computeDependenciesByNameWithContext(
191+
StringRef ModuleName, const llvm::DenseSet<ModuleID> &AlreadySeen,
192+
LookupModuleOutputCallback LookupModuleOutput);
193+
194+
/// @brief This method finializes the compiler instance. It finalizes the
195+
/// diagnostics and deletes the compiler instance. Call this method
196+
/// once all names for a same commandline are scanned.
197+
/// @return Error if an error occured during finalization.
198+
llvm::Error finalizeCompilerInstanceWithContext();
199+
162200
llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }
163201

164202
private:

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/Basic/FileManager.h"
1414
#include "clang/Basic/LLVM.h"
1515
#include "clang/Frontend/PCHContainerOperations.h"
16+
#include "clang/Tooling/DependencyScanning/DependencyScannerImpl.h"
1617
#include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
1718
#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
1819
#include "llvm/Support/Error.h"
@@ -136,6 +137,34 @@ class DependencyScanningWorker {
136137
DependencyActionController &Controller,
137138
StringRef ModuleName);
138139

140+
/// The three method below implements a new interface for by name
141+
/// dependency scanning. They together enable the dependency scanning worker
142+
/// to more effectively perform scanning for a sequence of modules
143+
/// by name when the CWD and CommandLine do not change across the queries.
144+
145+
/// @brief Initializing the context and the compiler instance.
146+
/// @param CWD The current working directory used during the scan.
147+
/// @param CommandLine The commandline used for the scan.
148+
/// @return Error if the initializaiton fails.
149+
llvm::Error initializeCompierInstanceWithContext(
150+
StringRef CWD, const std::vector<std::string> &CommandLine);
151+
152+
/// @brief Performaces dependency scanning for the module whose name is
153+
/// specified.
154+
/// @param ModuleName The name of the module whose dependency will be
155+
/// scanned.
156+
/// @param Consumer The dependency consumer that stores the results.
157+
/// @param Controller The controller for the dependency scanning action.
158+
/// @return Error if the scanner incurs errors.
159+
llvm::Error
160+
computeDependenciesByNameWithContext(StringRef ModuleName,
161+
DependencyConsumer &Consumer,
162+
DependencyActionController &Controller);
163+
164+
/// @brief Finalizes the diagnostics engine and deletes the compiler instance.
165+
/// @return Error if errors occur during finalization.
166+
llvm::Error finalizeCompilerInstanceWithContext();
167+
139168
llvm::vfs::FileSystem &getVFS() const { return *BaseFS; }
140169

141170
private:
@@ -151,6 +180,9 @@ class DependencyScanningWorker {
151180
/// (passed in the constructor).
152181
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
153182

183+
friend class CompilerInstanceWithContext;
184+
std::unique_ptr<CompilerInstanceWithContext> CIWithContext;
185+
154186
/// Private helper functions.
155187
bool scanDependencies(StringRef WorkingDirectory,
156188
const std::vector<std::string> &CommandLine,

clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ class ModuleDepCollector final : public DependencyCollector {
288288
void attachToPreprocessor(Preprocessor &PP) override;
289289
void attachToASTReader(ASTReader &R) override;
290290

291+
PPCallbacks *getPPCallbacks() override { return CollectorPPPtr; }
292+
291293
/// Apply any changes implied by the discovered dependencies to the given
292294
/// invocation, (e.g. disable implicit modules, add explicit module paths).
293295
void applyDiscoveredDependencies(CompilerInvocation &CI);
@@ -339,6 +341,10 @@ class ModuleDepCollector final : public DependencyCollector {
339341
std::optional<P1689ModuleInfo> ProvidedStdCXXModule;
340342
std::vector<P1689ModuleInfo> RequiredStdCXXModules;
341343

344+
/// A pointer to the preprocessor callback so we can invoke it directly
345+
/// if needed.
346+
ModuleDepCollectorPP *CollectorPPPtr = nullptr;
347+
342348
/// Checks whether the module is known as being prebuilt.
343349
bool isPrebuiltModule(const Module *M);
344350

0 commit comments

Comments
 (0)