Skip to content

Commit 1351d6d

Browse files
authored
Merge pull request #6481 from benlangmuir/include-tree-libclang-stable
[clang][cas] Cherry-pick include-tree support for full dependencies and libclang
2 parents c2dbd48 + 477a00f commit 1351d6d

21 files changed

+1293
-850
lines changed

clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ enum class ScanningOutputFormat {
5151

5252
/// This emits the CAS ID of the include tree.
5353
IncludeTree,
54+
55+
/// This emits the full dependency graph but with include tree.
56+
FullIncludeTree,
5457
};
5558

5659
/// The dependency scanning service contains shared configuration and state that
@@ -59,6 +62,7 @@ class DependencyScanningService {
5962
public:
6063
DependencyScanningService(
6164
ScanningMode Mode, ScanningOutputFormat Format, CASOptions CASOpts,
65+
std::shared_ptr<llvm::cas::ObjectStore> CAS,
6266
std::shared_ptr<llvm::cas::ActionCache> Cache,
6367
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> SharedFS,
6468
bool OptimizeArgs = false, bool EagerLoadModules = false);
@@ -78,19 +82,19 @@ class DependencyScanningService {
7882
}
7983

8084
const CASOptions &getCASOpts() const { return CASOpts; }
81-
llvm::cas::ActionCache &getCache() const {
82-
assert(Cache && "Cache is not initialized");
83-
return *Cache;
84-
}
85+
86+
std::shared_ptr<llvm::cas::ObjectStore> getCAS() const { return CAS; }
87+
std::shared_ptr<llvm::cas::ActionCache> getCache() const { return Cache; }
8588

8689
llvm::cas::CachingOnDiskFileSystem &getSharedFS() { return *SharedFS; }
8790

88-
bool useCASScanning() const { return (bool)SharedFS; }
91+
bool useCASFS() const { return (bool)SharedFS; }
8992

9093
private:
9194
const ScanningMode Mode;
9295
const ScanningOutputFormat Format;
9396
CASOptions CASOpts;
97+
std::shared_ptr<llvm::cas::ObjectStore> CAS;
9498
std::shared_ptr<llvm::cas::ActionCache> Cache;
9599
/// Whether to optimize the modules' command-line arguments.
96100
const bool OptimizeArgs;

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

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ struct TranslationUnitDeps {
6969
std::vector<ModuleID> ClangModuleDeps;
7070

7171
/// The CASID for input file dependency tree.
72-
llvm::Optional<llvm::cas::CASID> CASFileSystemRootID;
72+
llvm::Optional<std::string> CASFileSystemRootID;
7373

7474
/// The sequence of commands required to build the translation unit. Commands
7575
/// should be executed in order.
@@ -180,29 +180,24 @@ class DependencyScanningTool {
180180
return Worker.getOrCreateFileManager();
181181
}
182182

183+
static std::unique_ptr<DependencyActionController>
184+
createActionController(DependencyScanningWorker &Worker,
185+
LookupModuleOutputCallback LookupModuleOutput,
186+
DepscanPrefixMapping PrefixMapping);
187+
188+
private:
189+
std::unique_ptr<DependencyActionController>
190+
createActionController(LookupModuleOutputCallback LookupModuleOutput,
191+
DepscanPrefixMapping PrefixMapping);
192+
183193
private:
184194
DependencyScanningWorker Worker;
185195
};
186196

187197
class FullDependencyConsumer : public DependencyConsumer {
188198
public:
189-
FullDependencyConsumer(const llvm::StringSet<> &AlreadySeen,
190-
LookupModuleOutputCallback LookupModuleOutput,
191-
CachingOnDiskFileSystemPtr CacheFS = nullptr,
192-
DepscanPrefixMapping PrefixMapping = {})
193-
: CacheFS(std::move(CacheFS)), PrefixMapping(std::move(PrefixMapping)),
194-
AlreadySeen(AlreadySeen), LookupModuleOutput(LookupModuleOutput) {}
195-
196-
llvm::Error initialize(CompilerInstance &ScanInstance,
197-
CompilerInvocation &NewInvocation) override;
198-
llvm::Error finalize(CompilerInstance &ScanInstance,
199-
CompilerInvocation &NewInvocation) override;
200-
llvm::Error
201-
initializeModuleBuild(CompilerInstance &ModuleScanInstance) override;
202-
llvm::Error
203-
finalizeModuleBuild(CompilerInstance &ModuleScanInstance) override;
204-
llvm::Error finalizeModuleInvocation(CompilerInvocation &CI,
205-
const ModuleDeps &MD) override;
199+
FullDependencyConsumer(const llvm::StringSet<> &AlreadySeen)
200+
: AlreadySeen(AlreadySeen) {}
206201

207202
void handleBuildCommand(Command Cmd) override {
208203
Commands.push_back(std::move(Cmd));
@@ -226,17 +221,8 @@ class FullDependencyConsumer : public DependencyConsumer {
226221
ContextHash = std::move(Hash);
227222
}
228223

229-
void handleCASFileSystemRootID(cas::CASID ID) override {
230-
CASFileSystemRootID = ID;
231-
}
232-
233-
Optional<cas::CASID> getCASFileSystemRootID() const {
234-
return CASFileSystemRootID;
235-
}
236-
237-
std::string lookupModuleOutput(const ModuleID &ID,
238-
ModuleOutputKind Kind) override {
239-
return LookupModuleOutput(ID, Kind);
224+
void handleCASFileSystemRootID(std::string ID) override {
225+
CASFileSystemRootID = std::move(ID);
240226
}
241227

242228
TranslationUnitDeps takeTranslationUnitDeps();
@@ -249,13 +235,33 @@ class FullDependencyConsumer : public DependencyConsumer {
249235
ClangModuleDeps;
250236
std::vector<Command> Commands;
251237
std::string ContextHash;
252-
CachingOnDiskFileSystemPtr CacheFS;
253-
DepscanPrefixMapping PrefixMapping;
254-
std::optional<llvm::TreePathPrefixMapper> Mapper;
255-
CASOptions CASOpts;
256-
Optional<cas::CASID> CASFileSystemRootID;
238+
Optional<std::string> CASFileSystemRootID;
257239
std::vector<std::string> OutputPaths;
258240
const llvm::StringSet<> &AlreadySeen;
241+
};
242+
243+
/// A simple dependency action controller that uses a callback. If no callback
244+
/// is provided, it is assumed that looking up module outputs is unreachable.
245+
class CallbackActionController : public DependencyActionController {
246+
public:
247+
virtual ~CallbackActionController();
248+
249+
CallbackActionController(LookupModuleOutputCallback LMO)
250+
: LookupModuleOutput(std::move(LMO)) {
251+
if (!LookupModuleOutput) {
252+
LookupModuleOutput = [](const ModuleID &,
253+
ModuleOutputKind) -> std::string {
254+
llvm::report_fatal_error("unexpected call to lookupModuleOutput");
255+
};
256+
}
257+
}
258+
259+
std::string lookupModuleOutput(const ModuleID &ID,
260+
ModuleOutputKind Kind) override {
261+
return LookupModuleOutput(ID, Kind);
262+
}
263+
264+
private:
259265
LookupModuleOutputCallback LookupModuleOutput;
260266
};
261267

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

Lines changed: 42 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,33 @@ class DependencyConsumer {
4545
public:
4646
virtual ~DependencyConsumer() {}
4747

48+
virtual void handleBuildCommand(Command Cmd) {}
49+
50+
virtual void
51+
handleDependencyOutputOpts(const DependencyOutputOptions &Opts) = 0;
52+
53+
virtual void handleFileDependency(StringRef Filename) = 0;
54+
55+
virtual void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) = 0;
56+
57+
virtual void handleModuleDependency(ModuleDeps MD) = 0;
58+
59+
virtual void handleContextHash(std::string Hash) = 0;
60+
61+
virtual void handleCASFileSystemRootID(std::string ID) {}
62+
63+
virtual void handleIncludeTreeID(std::string ID) {}
64+
};
65+
66+
/// Dependency scanner callbacks that are used during scanning to influence the
67+
/// behaviour of the scan - for example, to customize the scanned invocations.
68+
class DependencyActionController {
69+
public:
70+
virtual ~DependencyActionController();
71+
72+
virtual std::string lookupModuleOutput(const ModuleID &ID,
73+
ModuleOutputKind Kind) = 0;
74+
4875
virtual llvm::Error initialize(CompilerInstance &ScanInstance,
4976
CompilerInvocation &NewInvocation) {
5077
return llvm::Error::success();
@@ -70,65 +97,18 @@ class DependencyConsumer {
7097
return llvm::Error::success();
7198
}
7299

73-
virtual void handleBuildCommand(Command Cmd) = 0;
74-
75-
virtual void
76-
handleDependencyOutputOpts(const DependencyOutputOptions &Opts) = 0;
77-
78-
virtual void handleFileDependency(StringRef Filename) = 0;
79-
80-
virtual void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) = 0;
81-
82-
virtual void handleModuleDependency(ModuleDeps MD) = 0;
83-
84-
virtual void handleContextHash(std::string Hash) = 0;
85-
86-
virtual void handleCASFileSystemRootID(cas::CASID ID) = 0;
87-
88-
virtual std::string lookupModuleOutput(const ModuleID &ID,
89-
ModuleOutputKind Kind) = 0;
90-
};
91-
92-
// FIXME: This may need to merge with \p DependencyConsumer in order to support
93-
// clang modules for the include-tree.
94-
class PPIncludeActionsConsumer : public DependencyConsumer {
95-
public:
96-
virtual void enteredInclude(Preprocessor &PP, FileID FID) = 0;
100+
virtual void enteredInclude(Preprocessor &PP, FileID FID) {}
97101

98102
virtual void exitedInclude(Preprocessor &PP, FileID IncludedBy,
99-
FileID Include, SourceLocation ExitLoc) = 0;
103+
FileID Include, SourceLocation ExitLoc) {}
100104

101-
virtual void handleHasIncludeCheck(Preprocessor &PP, bool Result) = 0;
105+
virtual void handleHasIncludeCheck(Preprocessor &PP, bool Result) {}
102106

103107
/// FIXME: This is temporary until we eliminate the split between consumers in
104108
/// \p DependencyScanningTool and collectors in \p DependencyScanningWorker
105109
/// and have them both in the same file. see FIXME in \p
106110
/// DependencyScanningAction::runInvocation.
107-
virtual const DepscanPrefixMapping &getPrefixMapping() = 0;
108-
109-
protected:
110-
void handleBuildCommand(Command) override {}
111-
void handleDependencyOutputOpts(const DependencyOutputOptions &Opts) override {
112-
llvm::report_fatal_error("unexpected callback for include-tree");
113-
}
114-
void handleFileDependency(StringRef Filename) override {
115-
llvm::report_fatal_error("unexpected callback for include-tree");
116-
}
117-
void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override {
118-
llvm::report_fatal_error("unexpected callback for include-tree");
119-
}
120-
void handleModuleDependency(ModuleDeps MD) override {
121-
llvm::report_fatal_error("unexpected callback for include-tree");
122-
}
123-
void handleContextHash(std::string Hash) override {
124-
llvm::report_fatal_error("unexpected callback for include-tree");
125-
}
126-
void handleCASFileSystemRootID(cas::CASID ID) override {
127-
llvm::report_fatal_error("unexpected callback for include-tree");
128-
}
129-
std::string lookupModuleOutput(const ModuleID &, ModuleOutputKind) override {
130-
llvm::report_fatal_error("unexpected callback for include-tree");
131-
}
111+
virtual const DepscanPrefixMapping *getPrefixMapping() { return nullptr; }
132112
};
133113

134114
/// An individual dependency scanning worker that is able to run on its own
@@ -152,16 +132,15 @@ class DependencyScanningWorker {
152132
bool computeDependencies(StringRef WorkingDirectory,
153133
const std::vector<std::string> &CommandLine,
154134
DependencyConsumer &DepConsumer,
135+
DependencyActionController &Controller,
155136
DiagnosticConsumer &DiagConsumer,
156137
llvm::Optional<StringRef> ModuleName = None);
157138
/// \returns A \c StringError with the diagnostic output if clang errors
158139
/// occurred, success otherwise.
159-
llvm::Error computeDependencies(StringRef WorkingDirectory,
160-
const std::vector<std::string> &CommandLine,
161-
DependencyConsumer &Consumer,
162-
llvm::Optional<StringRef> ModuleName = None);
163-
164-
ScanningOutputFormat getFormat() const { return Format; }
140+
llvm::Error computeDependencies(
141+
StringRef WorkingDirectory, const std::vector<std::string> &CommandLine,
142+
DependencyConsumer &Consumer, DependencyActionController &Controller,
143+
llvm::Optional<StringRef> ModuleName = None);
165144

166145
/// Scan from a compiler invocation.
167146
/// If \p DiagGenerationAsCompilation is true it will generate error
@@ -171,15 +150,14 @@ class DependencyScanningWorker {
171150
void computeDependenciesFromCompilerInvocation(
172151
std::shared_ptr<CompilerInvocation> Invocation,
173152
StringRef WorkingDirectory, DependencyConsumer &Consumer,
174-
DiagnosticConsumer &DiagsConsumer, raw_ostream *VerboseOS,
175-
bool DiagGenerationAsCompilation);
153+
DependencyActionController &Controller, DiagnosticConsumer &DiagsConsumer,
154+
raw_ostream *VerboseOS, bool DiagGenerationAsCompilation);
176155

177156
ScanningOutputFormat getScanningFormat() const { return Format; }
178157

179-
llvm::vfs::FileSystem &getRealFS() { return *BaseFS; }
180158
CachingOnDiskFileSystemPtr getCASFS() { return CacheFS; }
181-
bool useCAS() const { return UseCAS; }
182159
const CASOptions &getCASOpts() const { return CASOpts; }
160+
std::shared_ptr<cas::ObjectStore> getCAS() const { return CAS; }
183161

184162
/// If \p DependencyScanningService enabled sharing of \p FileManager this
185163
/// will return the same instance, otherwise it will create a new one for
@@ -201,16 +179,15 @@ class DependencyScanningWorker {
201179
ScanningOutputFormat Format;
202180
/// Whether to optimize the modules' command-line arguments.
203181
bool OptimizeArgs;
182+
/// Whether to set up command-lines to load PCM files eagerly.
183+
bool EagerLoadModules;
204184

205185
/// The caching file system.
206186
CachingOnDiskFileSystemPtr CacheFS;
207187
/// The CAS Dependency Filesytem. This is not set at the sametime as DepFS;
208188
llvm::IntrusiveRefCntPtr<DependencyScanningCASFilesystem> DepCASFS;
209189
CASOptions CASOpts;
210-
bool UseCAS;
211-
212-
/// Whether to set up command-lines to load PCM files eagerly.
213-
bool EagerLoadModules;
190+
std::shared_ptr<cas::ObjectStore> CAS;
214191
};
215192

216193
} // end namespace dependencies

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ namespace clang {
2828
namespace tooling {
2929
namespace dependencies {
3030

31+
class DependencyActionController;
3132
class DependencyConsumer;
3233

3334
/// Modular dependency that has already been built prior to the dependency scan.
@@ -192,6 +193,7 @@ class ModuleDepCollector final : public DependencyCollector {
192193
public:
193194
ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
194195
CompilerInstance &ScanInstance, DependencyConsumer &C,
196+
DependencyActionController &Controller,
195197
CompilerInvocation OriginalCI, bool OptimizeArgs,
196198
bool EagerLoadModules);
197199

@@ -209,6 +211,8 @@ class ModuleDepCollector final : public DependencyCollector {
209211
CompilerInstance &ScanInstance;
210212
/// The consumer of collected dependency information.
211213
DependencyConsumer &Consumer;
214+
/// Callbacks for computing dependency information.
215+
DependencyActionController &Controller;
212216
/// Path to the main source file.
213217
std::string MainFile;
214218
/// Hash identifying the compilation conditions of the current TU.

0 commit comments

Comments
 (0)