Skip to content

Commit 26319ba

Browse files
authored
Merge pull request #5234 from apple/jan_svoboda/cherry-pick
[clang][deps] Cherry-pick recent changes
2 parents 338153f + b1c74a0 commit 26319ba

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1029
-756
lines changed

clang/include/clang-c/Dependencies.h

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -200,42 +200,6 @@ CINDEX_LINKAGE void clang_experimental_DependencyScannerWorker_dispose_v0(
200200
typedef void CXModuleDiscoveredCallback(void *Context,
201201
CXModuleDependencySet *MDS);
202202

203-
/**
204-
* Returns the list of file dependencies for a particular compiler invocation.
205-
*
206-
* \param argc the number of compiler invocation arguments (including argv[0]).
207-
* \param argv the compiler driver invocation arguments (including argv[0]).
208-
* \param WorkingDirectory the directory in which the invocation runs.
209-
* \param MDC a callback that is called whenever a new module is discovered.
210-
* This may receive the same module on different workers. This should
211-
* be NULL if
212-
* \c clang_experimental_DependencyScannerService_create_v0 was
213-
* called with \c CXDependencyMode_Flat. This callback will be called
214-
* on the same thread that called this function.
215-
* \param Context the context that will be passed to \c MDC each time it is
216-
* called.
217-
* \param [out] error the error string to pass back to client (if any).
218-
*
219-
* \returns A pointer to a CXFileDependencies on success, NULL otherwise. The
220-
* CXFileDependencies must be freed by calling
221-
* \c clang_experimental_FileDependencies_dispose.
222-
*/
223-
CINDEX_LINKAGE CXFileDependencies *
224-
clang_experimental_DependencyScannerWorker_getFileDependencies_v2(
225-
CXDependencyScannerWorker Worker, int argc, const char *const *argv,
226-
const char *WorkingDirectory, CXModuleDiscoveredCallback *MDC,
227-
void *Context, CXString *error);
228-
229-
/**
230-
* Same as \c clang_experimental_DependencyScannerWorker_getFileDependencies_v2,
231-
* but get the dependencies by module name alone.
232-
*/
233-
CINDEX_LINKAGE CXFileDependencies *
234-
clang_experimental_DependencyScannerWorker_getDependenciesByModuleName_v0(
235-
CXDependencyScannerWorker Worker, int argc, const char *const *argv,
236-
const char *ModuleName, const char *WorkingDirectory,
237-
CXModuleDiscoveredCallback *MDC, void *Context, CXString *error);
238-
239203
/**
240204
* A callback that is called to determine the paths of output files for each
241205
* module dependency. The ModuleFile (pcm) path mapping is mandatory.

clang/include/clang/Basic/Module.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,10 @@ class Module {
352352
/// module depends.
353353
llvm::SmallSetVector<Module *, 2> Imports;
354354

355+
/// The set of top-level modules that affected the compilation of this module,
356+
/// but were not imported.
357+
llvm::SmallSetVector<Module *, 2> AffectingModules;
358+
355359
/// Describes an exported module.
356360
///
357361
/// The pointer is the module being re-exported, while the bit will be true

clang/include/clang/Frontend/CompilerInvocation.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ class CompilerInvocation : public CompilerInvocationRefBase,
243243
std::string getModuleHash(DiagnosticsEngine &Diags) const;
244244

245245
using StringAllocator = llvm::function_ref<const char *(const llvm::Twine &)>;
246-
/// Generate a cc1-compatible command line arguments from this instance.
246+
/// Generate cc1-compatible command line arguments from this instance.
247247
///
248248
/// \param [out] Args - The generated arguments. Note that the caller is
249249
/// responsible for inserting the path to the clang executable and "-cc1" if
@@ -254,6 +254,20 @@ class CompilerInvocation : public CompilerInvocationRefBase,
254254
void generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args,
255255
StringAllocator SA) const;
256256

257+
/// Generate cc1-compatible command line arguments from this instance,
258+
/// wrapping the result as a std::vector<std::string>.
259+
///
260+
/// This is a (less-efficient) wrapper over generateCC1CommandLine().
261+
std::vector<std::string> getCC1CommandLine() const;
262+
263+
/// Reset all of the options that are not considered when building a
264+
/// module.
265+
void resetNonModularOptions();
266+
267+
/// Disable implicit modules and canonicalize options that are only used by
268+
/// implicit modules.
269+
void clearImplicitModuleBuildOptions();
270+
257271
/// Parse command line options that map to \p CASOptions.
258272
static bool ParseCASArgs(CASOptions &Opts, const llvm::opt::ArgList &Args,
259273
DiagnosticsEngine &Diags);

clang/include/clang/Lex/ModuleLoader.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class ModuleLoadResult {
5151
ModuleLoadResult() = default;
5252
ModuleLoadResult(Module *M) : Storage(M, Normal) {}
5353
ModuleLoadResult(LoadResultKind Kind) : Storage(nullptr, Kind) {}
54+
ModuleLoadResult(Module *M, LoadResultKind Kind) : Storage(M, Kind) {}
55+
56+
operator bool() const {
57+
return Storage.getInt() == Normal && Storage.getPointer();
58+
}
5459

5560
operator Module *() const { return Storage.getPointer(); }
5661

clang/include/clang/Lex/Preprocessor.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,10 @@ class Preprocessor {
798798
/// The files that have been included.
799799
IncludedFilesSet IncludedFiles;
800800

801+
/// The set of top-level modules that affected preprocessing, but were not
802+
/// imported.
803+
llvm::SmallSetVector<Module *, 2> AffectingModules;
804+
801805
/// The set of known macros exported from modules.
802806
llvm::FoldingSet<ModuleMacro> ModuleMacros;
803807

@@ -1274,6 +1278,22 @@ class Preprocessor {
12741278

12751279
/// \}
12761280

1281+
/// Mark the given module as affecting the current module or translation unit.
1282+
void markModuleAsAffecting(Module *M) {
1283+
if (!BuildingSubmoduleStack.empty()) {
1284+
if (M != BuildingSubmoduleStack.back().M)
1285+
BuildingSubmoduleStack.back().M->AffectingModules.insert(M);
1286+
} else {
1287+
AffectingModules.insert(M);
1288+
}
1289+
}
1290+
1291+
/// Get the set of top-level modules that affected preprocessing, but were not
1292+
/// imported.
1293+
const llvm::SmallSetVector<Module *, 2> &getAffectingModules() const {
1294+
return AffectingModules;
1295+
}
1296+
12771297
/// Mark the file as included.
12781298
/// Returns true if this is the first time the file was included.
12791299
bool markIncluded(const FileEntry *File) {

clang/include/clang/Serialization/ASTBitCodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,9 @@ enum SubmoduleRecordTypes {
835835
/// Specifies the name of the module that will eventually
836836
/// re-export the entities in this module.
837837
SUBMODULE_EXPORT_AS = 17,
838+
839+
/// Specifies affecting modules that were not imported.
840+
SUBMODULE_AFFECTING_MODULES = 18,
838841
};
839842

840843
/// Record types used within a comments block.

clang/include/clang/Serialization/ASTReader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ class ASTReader
696696
Module *Mod;
697697

698698
/// The kind of module reference.
699-
enum { Import, Export, Conflict } Kind;
699+
enum { Import, Export, Conflict, Affecting } Kind;
700700

701701
/// The local ID of the module that is being exported.
702702
unsigned ID;

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,26 +61,27 @@ class DependencyScanningService {
6161
ScanningMode Mode, ScanningOutputFormat Format, CASOptions CASOpts,
6262
std::shared_ptr<llvm::cas::ActionCache> Cache,
6363
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> SharedFS,
64-
bool ReuseFileManager = true, bool OptimizeArgs = false);
65-
66-
~DependencyScanningService();
64+
bool ReuseFileManager = true, bool OptimizeArgs = false,
65+
bool EagerLoadModules = false);
6766

6867
ScanningMode getMode() const { return Mode; }
6968

7069
ScanningOutputFormat getFormat() const { return Format; }
7170

72-
const CASOptions &getCASOpts() const { return CASOpts; }
73-
7471
bool canReuseFileManager() const { return ReuseFileManager; }
7572

7673
bool canOptimizeArgs() const { return OptimizeArgs; }
7774

75+
bool shouldEagerLoadModules() const { return EagerLoadModules; }
76+
7877
DependencyScanningFilesystemSharedCache &getSharedCache() {
7978
assert(!SharedFS && "Expected not to have a CASFS");
8079
assert(SharedCache && "Expected a shared cache");
8180
return *SharedCache;
8281
}
8382

83+
const CASOptions &getCASOpts() const { return CASOpts; }
84+
8485
llvm::cas::ActionCache &getCache() const {
8586
assert(Cache && "Cache is not initialized");
8687
return *Cache;
@@ -98,6 +99,8 @@ class DependencyScanningService {
9899
const bool ReuseFileManager;
99100
/// Whether to optimize the modules' command-line arguments.
100101
const bool OptimizeArgs;
102+
/// Whether to set up command-lines to load PCM files eagerly.
103+
const bool EagerLoadModules;
101104
/// Shared CachingOnDiskFileSystem. Set to nullptr to not use CAS dependency
102105
/// scanning.
103106
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> SharedFS;

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

Lines changed: 60 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@
1313
#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h"
1414
#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
1515
#include "clang/Tooling/JSONCompilationDatabase.h"
16+
#include "llvm/ADT/MapVector.h"
1617
#include "llvm/ADT/StringSet.h"
18+
#include "llvm/ADT/StringMap.h"
1719
#include "llvm/CAS/CASID.h"
1820
#include <string>
21+
#include <vector>
1922

2023
namespace llvm {
2124
namespace cas {
@@ -30,6 +33,10 @@ class IncludeTreeRoot;
3033
namespace tooling {
3134
namespace dependencies {
3235

36+
/// A callback to lookup module outputs for "-fmodule-file=", "-o" etc.
37+
using LookupModuleOutputCallback =
38+
llvm::function_ref<std::string(const ModuleID &, ModuleOutputKind)>;
39+
3340
/// The full dependencies and module graph for a specific input.
3441
struct FullDependencies {
3542
/// The identifier of the C++20 module this translation unit exports.
@@ -52,23 +59,11 @@ struct FullDependencies {
5259
/// determined that the differences are benign for this compilation.
5360
std::vector<ModuleID> ClangModuleDeps;
5461

55-
/// The original command line of the TU (excluding the compiler executable).
56-
std::vector<std::string> OriginalCommandLine;
62+
/// The command line of the TU (excluding the compiler executable).
63+
std::vector<std::string> CommandLine;
5764

5865
/// The CASID for input file dependency tree.
5966
llvm::Optional<llvm::cas::CASID> CASFileSystemRootID;
60-
61-
/// Get the full command line.
62-
///
63-
/// \param LookupOutput This function is called to fill in
64-
/// "-fmodule-file=", "-o" and other output
65-
/// arguments for dependencies.
66-
std::vector<std::string> getCommandLine(
67-
llvm::function_ref<std::string(const ModuleID &, ModuleOutputKind)>
68-
LookupOutput) const;
69-
70-
/// Get the full command line, excluding -fmodule-file=" arguments.
71-
std::vector<std::string> getCommandLineWithoutModulePaths() const;
7267
};
7368

7469
struct FullDependenciesResult {
@@ -134,12 +129,16 @@ class DependencyScanningTool {
134129
/// function for a single \c DependencyScanningTool in a
135130
/// single build. Use a different one for different tools,
136131
/// and clear it between builds.
132+
/// \param LookupModuleOutput This function is called to fill in
133+
/// "-fmodule-file=", "-o" and other output
134+
/// arguments for dependencies.
137135
///
138136
/// \returns a \c StringError with the diagnostic output if clang errors
139137
/// occurred, \c FullDependencies otherwise.
140138
llvm::Expected<FullDependenciesResult>
141139
getFullDependencies(const std::vector<std::string> &CommandLine,
142140
StringRef CWD, const llvm::StringSet<> &AlreadySeen,
141+
LookupModuleOutputCallback LookupModuleOutput,
143142
llvm::Optional<StringRef> ModuleName = None);
144143

145144
ScanningOutputFormat getScanningFormat() const {
@@ -163,6 +162,53 @@ class DependencyScanningTool {
163162
DependencyScanningWorker Worker;
164163
};
165164

165+
class FullDependencyConsumer : public DependencyConsumer {
166+
public:
167+
FullDependencyConsumer(const llvm::StringSet<> &AlreadySeen,
168+
LookupModuleOutputCallback LookupModuleOutput,
169+
bool EagerLoadModules)
170+
: AlreadySeen(AlreadySeen), LookupModuleOutput(LookupModuleOutput),
171+
EagerLoadModules(EagerLoadModules) {}
172+
173+
void handleDependencyOutputOpts(const DependencyOutputOptions &) override {}
174+
175+
void handleFileDependency(StringRef File) override {
176+
Dependencies.push_back(std::string(File));
177+
}
178+
179+
void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override {
180+
PrebuiltModuleDeps.emplace_back(std::move(PMD));
181+
}
182+
183+
void handleModuleDependency(ModuleDeps MD) override {
184+
ClangModuleDeps[MD.ID.ContextHash + MD.ID.ModuleName] = std::move(MD);
185+
}
186+
187+
void handleContextHash(std::string Hash) override {
188+
ContextHash = std::move(Hash);
189+
}
190+
191+
std::string lookupModuleOutput(const ModuleID &ID,
192+
ModuleOutputKind Kind) override {
193+
return LookupModuleOutput(ID, Kind);
194+
}
195+
196+
FullDependenciesResult getFullDependencies(
197+
const std::vector<std::string> &OriginalCommandLine,
198+
Optional<cas::CASID> CASFileSystemRootID = None) const;
199+
200+
private:
201+
std::vector<std::string> Dependencies;
202+
std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
203+
llvm::MapVector<std::string, ModuleDeps, llvm::StringMap<unsigned>>
204+
ClangModuleDeps;
205+
std::string ContextHash;
206+
std::vector<std::string> OutputPaths;
207+
const llvm::StringSet<> &AlreadySeen;
208+
LookupModuleOutputCallback LookupModuleOutput;
209+
bool EagerLoadModules;
210+
};
211+
166212
} // end namespace dependencies
167213
} // end namespace tooling
168214
} // end namespace clang

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ class DependencyConsumer {
4545
virtual void handleModuleDependency(ModuleDeps MD) = 0;
4646

4747
virtual void handleContextHash(std::string Hash) = 0;
48+
49+
virtual std::string lookupModuleOutput(const ModuleID &ID,
50+
ModuleOutputKind Kind) = 0;
4851
};
4952

5053
// FIXME: This may need to merge with \p DependencyConsumer in order to support
@@ -74,6 +77,9 @@ class PPIncludeActionsConsumer : public DependencyConsumer {
7477
void handleContextHash(std::string Hash) override {
7578
llvm::report_fatal_error("unexpected callback for include-tree");
7679
}
80+
std::string lookupModuleOutput(const ModuleID &, ModuleOutputKind) override {
81+
llvm::report_fatal_error("unexpected callback for include-tree");
82+
}
7783
};
7884

7985
/// An individual dependency scanning worker that is able to run on its own
@@ -99,6 +105,8 @@ class DependencyScanningWorker {
99105
DependencyConsumer &Consumer,
100106
llvm::Optional<StringRef> ModuleName = None);
101107

108+
bool shouldEagerLoadModules() const { return EagerLoadModules; }
109+
102110
ScanningOutputFormat getFormat() const { return Format; }
103111

104112
/// Scan from a compiler invocation.
@@ -131,21 +139,23 @@ class DependencyScanningWorker {
131139
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS;
132140
/// The in-memory filesystem laid on top the physical filesystem in `RealFS`.
133141
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFS;
134-
/// The caching file system.
135-
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS;
136142
/// The file system that is used by each worker when scanning for
137143
/// dependencies. This filesystem persists across multiple compiler
138144
/// invocations.
139145
llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
140-
/// The CAS Dependency Filesytem. This is not set at the sametime as DepFS;
141-
llvm::IntrusiveRefCntPtr<DependencyScanningCASFilesystem> DepCASFS;
142146
/// The file manager that is reused across multiple invocations by this
143147
/// worker. If null, the file manager will not be reused.
144148
llvm::IntrusiveRefCntPtr<FileManager> Files;
145149
ScanningOutputFormat Format;
146150
/// Whether to optimize the modules' command-line arguments.
147151
bool OptimizeArgs;
152+
/// Whether to set up command-lines to load PCM files eagerly.
153+
bool EagerLoadModules;
148154

155+
/// The caching file system.
156+
llvm::IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> CacheFS;
157+
/// The CAS Dependency Filesytem. This is not set at the sametime as DepFS;
158+
llvm::IntrusiveRefCntPtr<DependencyScanningCASFilesystem> DepCASFS;
149159
CASOptions CASOpts;
150160
bool UseCAS;
151161
};

0 commit comments

Comments
 (0)