2525#include " llvm/ADT/StringSet.h"
2626#include < string>
2727#include < vector>
28+ #include < unordered_map>
2829
2930namespace swift {
3031
@@ -35,7 +36,8 @@ class Identifier;
3536
3637// / Which kind of module dependencies we are looking for.
3738enum class ModuleDependenciesKind : int8_t {
38- SwiftTextual,
39+ FirstKind,
40+ SwiftTextual = FirstKind,
3941 SwiftBinary,
4042 // Placeholder dependencies are a kind of dependencies used only by the
4143 // dependency scanner. They are swift modules that the scanner will not be
@@ -61,6 +63,20 @@ enum class ModuleDependenciesKind : int8_t {
6163 // of all targets, individually, have been computed.
6264 SwiftPlaceholder,
6365 Clang,
66+ LastKind = Clang + 1
67+ };
68+
69+ struct ModuleDependenciesKindHash {
70+ std::size_t operator ()(ModuleDependenciesKind k) const {
71+ using UnderlyingType = std::underlying_type<ModuleDependenciesKind>::type;
72+ return std::hash<UnderlyingType>{}(static_cast <UnderlyingType>(k));
73+ }
74+ };
75+
76+ // / Details of a given module used for dependency scanner cache queries.
77+ struct ModuleLookupSpecifics {
78+ Optional<ModuleDependenciesKind> kind;
79+ llvm::StringSet<> currentSearchPaths;
6480};
6581
6682// / Base class for the variant storage of ModuleDependencies.
@@ -275,8 +291,8 @@ class ModuleDependencies {
275291
276292 // / Describe the module dependencies for a Swift module that can be
277293 // / built from a Swift interface file (\c .swiftinterface).
278- static ModuleDependencies forSwiftInterface (
279- const std::string &swiftInterfaceFile,
294+ static ModuleDependencies forSwiftTextualModule (
295+ const Optional< std::string> &swiftInterfaceFile,
280296 ArrayRef<std::string> compiledCandidates,
281297 ArrayRef<StringRef> buildCommands,
282298 ArrayRef<StringRef> extraPCMArgs,
@@ -386,6 +402,9 @@ class ModuleDependencies {
386402 // / Add a bridging header to a Swift module's dependencies.
387403 void addBridgingHeader (StringRef bridgingHeader);
388404
405+ // / Add source files
406+ void addSourceFile (StringRef sourceFile);
407+
389408 // / Add source files that the bridging header depends on.
390409 void addBridgingSourceFile (StringRef bridgingSourceFile);
391410
@@ -400,25 +419,30 @@ class ModuleDependencies {
400419};
401420
402421using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
422+ using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1 >;
403423
404424// / A cache describing the set of module dependencies that has been queried
405- // / thus far.
406- class ModuleDependenciesCache {
425+ // / thus far. This cache records/stores the actual Dependency values and can be
426+ // / preserved across different scanning actions (e.g. in
427+ // / `DependencyScanningTool`). It is not to be queried directly, but is rather
428+ // / meant to be wrapped in an instance of `ModuleDependenciesCache`, responsible
429+ // / for recording new dependencies and answering cache queries in a given scan.
430+ // / Queries to this cache must be disambiguated with a set of search paths to
431+ // / ensure that the returned cached dependency was one that can be found in the
432+ // / current scanning action's filesystem view.
433+ class GlobalModuleDependenciesCache {
407434 // / All cached module dependencies, in the order in which they were
408435 // / encountered.
409436 std::vector<ModuleDependencyID> AllModules;
410437
411- // / Dependencies for Textual Swift modules that have already been computed.
412- llvm::StringMap<ModuleDependencies> SwiftTextualModuleDependencies;
413-
414- // / Dependencies for Binary Swift modules that have already been computed.
415- llvm::StringMap<ModuleDependencies> SwiftBinaryModuleDependencies;
416-
417- // / Dependencies for Swift placeholder dependency modules that have already been computed.
418- llvm::StringMap<ModuleDependencies> SwiftPlaceholderModuleDependencies;
419-
420- // / Dependencies for Clang modules that have already been computed.
421- llvm::StringMap<ModuleDependencies> ClangModuleDependencies;
438+ // / Dependencies for modules that have already been computed.
439+ // / This maps a dependency kind to a map of a module's name to a vector of Dependency objects,
440+ // / which correspond to instances of the same module that may have been found
441+ // / in different sets of search paths.
442+ std::unordered_map<ModuleDependenciesKind,
443+ llvm::StringMap<ModuleDependenciesVector>,
444+ ModuleDependenciesKindHash>
445+ ModuleDependenciesKindMap;
422446
423447 // / Additional information needed for Clang dependency scanning.
424448 ClangModuleDependenciesCacheImpl *clangImpl = nullptr ;
@@ -434,46 +458,148 @@ class ModuleDependenciesCache {
434458
435459 // / Retrieve the dependencies map that corresponds to the given dependency
436460 // / kind.
437- llvm::StringMap<ModuleDependencies > &getDependenciesMap (
438- ModuleDependenciesKind kind);
439- const llvm::StringMap<ModuleDependencies > &getDependenciesMap (
440- ModuleDependenciesKind kind) const ;
461+ llvm::StringMap<ModuleDependenciesVector > &
462+ getDependenciesMap ( ModuleDependenciesKind kind);
463+ const llvm::StringMap<ModuleDependenciesVector > &
464+ getDependenciesMap ( ModuleDependenciesKind kind) const ;
441465
442466public:
443- ModuleDependenciesCache () { }
467+ GlobalModuleDependenciesCache ();
468+ GlobalModuleDependenciesCache (const GlobalModuleDependenciesCache &) = delete ;
469+ GlobalModuleDependenciesCache &
470+ operator =(const GlobalModuleDependenciesCache &) = delete ;
444471
445- ModuleDependenciesCache (const ModuleDependenciesCache &) = delete ;
446- ModuleDependenciesCache &operator =(const ModuleDependenciesCache &) = delete ;
472+ virtual ~GlobalModuleDependenciesCache () { destroyClangImpl (); }
447473
448- ~ModuleDependenciesCache () {
449- destroyClangImpl ();
450- }
474+ private:
475+ // / Enforce clients not being allowed to query this cache directly, it must be
476+ // / wrapped in an instance of `ModuleDependenciesCache`.
477+ friend class ModuleDependenciesCache ;
451478
452479 // / Set the Clang-specific implementation data.
453- void setClangImpl (
454- ClangModuleDependenciesCacheImpl *clangImpl,
455- void (*clangImplDeleter)(ClangModuleDependenciesCacheImpl *)) {
480+ virtual void
481+ setClangImpl ( ClangModuleDependenciesCacheImpl *clangImpl,
482+ void (*clangImplDeleter)(ClangModuleDependenciesCacheImpl *)) {
456483 destroyClangImpl ();
457484
458485 this ->clangImpl = clangImpl;
459486 this ->clangImplDeleter = clangImplDeleter;
460487 }
461488
489+ // / Retrieve the Clang-specific implementation data;
490+ ClangModuleDependenciesCacheImpl *getClangImpl () const { return clangImpl; }
491+
492+ // / Whether we have cached dependency information for the given module.
493+ bool hasDependencies (StringRef moduleName,
494+ ModuleLookupSpecifics details) const ;
495+
496+ // / Look for module dependencies for a module with the given name given
497+ // / current search paths.
498+ // /
499+ // / \returns the cached result, or \c None if there is no cached entry.
500+ Optional<ModuleDependencies>
501+ findDependencies (StringRef moduleName, ModuleLookupSpecifics details) const ;
502+
503+ public:
504+ // / Look for module dependencies for a module with the given name.
505+ // / This method has a deliberately-obtuse name to indicate that it is not to
506+ // / be used for general queries.
507+ // /
508+ // / \returns the cached result, or \c None if there is no cached entry.
509+ Optional<ModuleDependenciesVector>
510+ findAllDependenciesIrrespectiveOfSearchPaths (
511+ StringRef moduleName, Optional<ModuleDependenciesKind> kind) const ;
512+
513+ // / Record dependencies for the given module.
514+ const ModuleDependencies *recordDependencies (StringRef moduleName,
515+ ModuleDependencies dependencies);
516+
517+ // / Update stored dependencies for the given module.
518+ const ModuleDependencies *updateDependencies (ModuleDependencyID moduleID,
519+ ModuleDependencies dependencies);
520+
521+ // / Reference the list of all module dependencies.
522+ const std::vector<ModuleDependencyID> &getAllModules () const {
523+ return AllModules;
524+ }
525+ };
526+
527+ // / This "local" dependencies cache persists only for the duration of a given
528+ // / scanning action, and wraps an instance of a `GlobalModuleDependenciesCache`
529+ // / which may carry cached scanning information from prior scanning actions.
530+ // / This cache maintains a store of references to all dependencies found within
531+ // / the current scanning action (with their values stored in the global Cache),
532+ // / since these do not require clients to disambiguate them with search paths.
533+ class ModuleDependenciesCache {
534+ private:
535+ GlobalModuleDependenciesCache &globalCache;
536+
537+ // / References to data in `globalCache` for dependencies accimulated during
538+ // / the current scanning action.
539+ std::unordered_map<ModuleDependenciesKind,
540+ llvm::StringMap<const ModuleDependencies *>,
541+ ModuleDependenciesKindHash>
542+ ModuleDependenciesKindMap;
543+
544+ // / Retrieve the dependencies map that corresponds to the given dependency
545+ // / kind.
546+ llvm::StringMap<const ModuleDependencies *> &
547+ getDependencyReferencesMap (ModuleDependenciesKind kind);
548+ const llvm::StringMap<const ModuleDependencies *> &
549+ getDependencyReferencesMap (ModuleDependenciesKind kind) const ;
550+
551+ // / Local cache results lookup, only for modules which were discovered during
552+ // / the current scanner invocation.
553+ bool hasDependencies (StringRef moduleName,
554+ Optional<ModuleDependenciesKind> kind) const ;
555+
556+ // / Local cache results lookup, only for modules which were discovered during
557+ // / the current scanner invocation.
558+ Optional<const ModuleDependencies *>
559+ findDependencies (StringRef moduleName,
560+ Optional<ModuleDependenciesKind> kind) const ;
561+
562+ public:
563+ ModuleDependenciesCache (GlobalModuleDependenciesCache &globalCache);
564+ ModuleDependenciesCache (const ModuleDependenciesCache &) = delete ;
565+ ModuleDependenciesCache &operator =(const ModuleDependenciesCache &) = delete ;
566+ virtual ~ModuleDependenciesCache () {}
567+
568+ public:
569+ // / Set the Clang-specific implementation data.
570+ void
571+ setClangImpl (ClangModuleDependenciesCacheImpl *clangImpl,
572+ void (*clangImplDeleter)(ClangModuleDependenciesCacheImpl *)) {
573+ globalCache.setClangImpl (clangImpl, clangImplDeleter);
574+ }
575+
462576 // / Retrieve the Clang-specific implementation data;
463577 ClangModuleDependenciesCacheImpl *getClangImpl () const {
464- return clangImpl ;
578+ return globalCache. getClangImpl () ;
465579 }
466580
467581 // / Whether we have cached dependency information for the given module.
468582 bool hasDependencies (StringRef moduleName,
469- Optional<ModuleDependenciesKind> kind) const ;
583+ ModuleLookupSpecifics details) const ;
584+
585+ // / Look for module dependencies for a module with the given name given
586+ // / current search paths.
587+ // /
588+ // / \returns the cached result, or \c None if there is no cached entry.
589+ Optional<ModuleDependencies>
590+ findDependencies (StringRef moduleName, ModuleLookupSpecifics details) const ;
470591
471592 // / Look for module dependencies for a module with the given name.
593+ // / This method has a deliberately-obtuse name to indicate that it is not to
594+ // / be used for general queries.
472595 // /
473596 // / \returns the cached result, or \c None if there is no cached entry.
474- Optional<ModuleDependencies> findDependencies (
475- StringRef moduleName,
476- Optional<ModuleDependenciesKind> kind) const ;
597+ Optional<ModuleDependenciesVector>
598+ findAllDependenciesIrrespectiveOfSearchPaths (
599+ StringRef moduleName, Optional<ModuleDependenciesKind> kind) const {
600+ return globalCache.findAllDependenciesIrrespectiveOfSearchPaths (moduleName,
601+ kind);
602+ }
477603
478604 // / Record dependencies for the given module.
479605 void recordDependencies (StringRef moduleName,
@@ -485,10 +611,10 @@ class ModuleDependenciesCache {
485611
486612 // / Reference the list of all module dependencies.
487613 const std::vector<ModuleDependencyID> &getAllModules () const {
488- return AllModules ;
614+ return globalCache. getAllModules () ;
489615 }
490616};
491617
492- }
618+ } // namespace swift
493619
494620#endif /* SWIFT_AST_MODULE_DEPENDENCIES_H */
0 commit comments