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,14 @@ 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+ }
6474};
6575
6676// / Details of a given module used for dependency scanner cache queries.
@@ -409,29 +419,30 @@ class ModuleDependencies {
409419};
410420
411421using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
422+ using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1 >;
412423
413424// / A cache describing the set of module dependencies that has been queried
414- // / thus far.
415- class ModuleDependenciesCache {
416- using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1 >;
417-
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 {
418434 // / All cached module dependencies, in the order in which they were
419435 // / encountered.
420436 std::vector<ModuleDependencyID> AllModules;
421437
422- // / Dependencies for Textual Swift modules that have already been computed.
423- // / This maps a module's id (name, kind) to a vector of Dependency objects, which correspond
424- // / to instances of the same module that may have been found in different sets of search paths.
425- llvm::StringMap<ModuleDependenciesVector> SwiftTextualModuleDependencies;
426-
427- // / Dependencies for Binary Swift modules that have already been computed.
428- llvm::StringMap<ModuleDependenciesVector> SwiftBinaryModuleDependencies;
429-
430- // / Dependencies for Swift placeholder dependency modules that have already been computed.
431- llvm::StringMap<ModuleDependenciesVector> SwiftPlaceholderModuleDependencies;
432-
433- // / Dependencies for Clang modules that have already been computed.
434- llvm::StringMap<ModuleDependenciesVector> 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;
435446
436447 // / Additional information needed for Clang dependency scanning.
437448 ClangModuleDependenciesCacheImpl *clangImpl = nullptr ;
@@ -447,55 +458,148 @@ class ModuleDependenciesCache {
447458
448459 // / Retrieve the dependencies map that corresponds to the given dependency
449460 // / kind.
450- llvm::StringMap<ModuleDependenciesVector> &getDependenciesMap (
451- ModuleDependenciesKind kind);
452- const llvm::StringMap<ModuleDependenciesVector> &getDependenciesMap (
453- ModuleDependenciesKind kind) const ;
461+ llvm::StringMap<ModuleDependenciesVector> &
462+ getDependenciesMap ( ModuleDependenciesKind kind);
463+ const llvm::StringMap<ModuleDependenciesVector> &
464+ getDependenciesMap ( ModuleDependenciesKind kind) const ;
454465
455466public:
456- ModuleDependenciesCache () { }
467+ GlobalModuleDependenciesCache ();
468+ GlobalModuleDependenciesCache (const GlobalModuleDependenciesCache &) = delete ;
469+ GlobalModuleDependenciesCache &
470+ operator =(const GlobalModuleDependenciesCache &) = delete ;
457471
458- ModuleDependenciesCache (const ModuleDependenciesCache &) = delete ;
459- ModuleDependenciesCache &operator =(const ModuleDependenciesCache &) = delete ;
472+ virtual ~GlobalModuleDependenciesCache () { destroyClangImpl (); }
460473
461- ~ModuleDependenciesCache () {
462- destroyClangImpl ();
463- }
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 ;
464478
465479 // / Set the Clang-specific implementation data.
466- void setClangImpl (
467- ClangModuleDependenciesCacheImpl *clangImpl,
468- void (*clangImplDeleter)(ClangModuleDependenciesCacheImpl *)) {
480+ virtual void
481+ setClangImpl ( ClangModuleDependenciesCacheImpl *clangImpl,
482+ void (*clangImplDeleter)(ClangModuleDependenciesCacheImpl *)) {
469483 destroyClangImpl ();
470484
471485 this ->clangImpl = clangImpl;
472486 this ->clangImplDeleter = clangImplDeleter;
473487 }
474488
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+
475576 // / Retrieve the Clang-specific implementation data;
476577 ClangModuleDependenciesCacheImpl *getClangImpl () const {
477- return clangImpl ;
578+ return globalCache. getClangImpl () ;
478579 }
479580
480581 // / Whether we have cached dependency information for the given module.
481582 bool hasDependencies (StringRef moduleName,
482583 ModuleLookupSpecifics details) const ;
483584
484- // / Look for module dependencies for a module with the given name given current search paths.
585+ // / Look for module dependencies for a module with the given name given
586+ // / current search paths.
485587 // /
486588 // / \returns the cached result, or \c None if there is no cached entry.
487- Optional<ModuleDependencies> findDependencies (
488- StringRef moduleName,
489- ModuleLookupSpecifics details) const ;
589+ Optional<ModuleDependencies>
590+ findDependencies (StringRef moduleName, ModuleLookupSpecifics details) const ;
490591
491592 // / Look for module dependencies for a module with the given name.
492- // / This method has a deliberately-obtuse name to indicate that it is not to be used for general
493- // / queries.
593+ // / This method has a deliberately-obtuse name to indicate that it is not to
594+ // / be used for general queries.
494595 // /
495596 // / \returns the cached result, or \c None if there is no cached entry.
496- Optional<ModuleDependenciesVector> findAllDependenciesIrrespectiveOfSearchPaths (
497- StringRef moduleName,
498- Optional<ModuleDependenciesKind> kind) const ;
597+ Optional<ModuleDependenciesVector>
598+ findAllDependenciesIrrespectiveOfSearchPaths (
599+ StringRef moduleName, Optional<ModuleDependenciesKind> kind) const {
600+ return globalCache.findAllDependenciesIrrespectiveOfSearchPaths (moduleName,
601+ kind);
602+ }
499603
500604 // / Record dependencies for the given module.
501605 void recordDependencies (StringRef moduleName,
@@ -507,10 +611,10 @@ class ModuleDependenciesCache {
507611
508612 // / Reference the list of all module dependencies.
509613 const std::vector<ModuleDependencyID> &getAllModules () const {
510- return AllModules ;
614+ return globalCache. getAllModules () ;
511615 }
512616};
513617
514- }
618+ } // namespace swift
515619
516620#endif /* SWIFT_AST_MODULE_DEPENDENCIES_H */
0 commit comments