25
25
#include " llvm/ADT/StringSet.h"
26
26
#include < string>
27
27
#include < vector>
28
+ #include < unordered_map>
28
29
29
30
namespace swift {
30
31
@@ -35,7 +36,8 @@ class Identifier;
35
36
36
37
// / Which kind of module dependencies we are looking for.
37
38
enum class ModuleDependenciesKind : int8_t {
38
- SwiftTextual,
39
+ FirstKind,
40
+ SwiftTextual = FirstKind,
39
41
SwiftBinary,
40
42
// Placeholder dependencies are a kind of dependencies used only by the
41
43
// dependency scanner. They are swift modules that the scanner will not be
@@ -61,6 +63,14 @@ enum class ModuleDependenciesKind : int8_t {
61
63
// of all targets, individually, have been computed.
62
64
SwiftPlaceholder,
63
65
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
+ }
64
74
};
65
75
66
76
// / Details of a given module used for dependency scanner cache queries.
@@ -409,29 +419,30 @@ class ModuleDependencies {
409
419
};
410
420
411
421
using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
422
+ using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1 >;
412
423
413
424
// / 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 {
418
434
// / All cached module dependencies, in the order in which they were
419
435
// / encountered.
420
436
std::vector<ModuleDependencyID> AllModules;
421
437
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;
435
446
436
447
// / Additional information needed for Clang dependency scanning.
437
448
ClangModuleDependenciesCacheImpl *clangImpl = nullptr ;
@@ -447,55 +458,148 @@ class ModuleDependenciesCache {
447
458
448
459
// / Retrieve the dependencies map that corresponds to the given dependency
449
460
// / 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 ;
454
465
455
466
public:
456
- ModuleDependenciesCache () { }
467
+ GlobalModuleDependenciesCache ();
468
+ GlobalModuleDependenciesCache (const GlobalModuleDependenciesCache &) = delete ;
469
+ GlobalModuleDependenciesCache &
470
+ operator =(const GlobalModuleDependenciesCache &) = delete ;
457
471
458
- ModuleDependenciesCache (const ModuleDependenciesCache &) = delete ;
459
- ModuleDependenciesCache &operator =(const ModuleDependenciesCache &) = delete ;
472
+ virtual ~GlobalModuleDependenciesCache () { destroyClangImpl (); }
460
473
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 ;
464
478
465
479
// / 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 *)) {
469
483
destroyClangImpl ();
470
484
471
485
this ->clangImpl = clangImpl;
472
486
this ->clangImplDeleter = clangImplDeleter;
473
487
}
474
488
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
+
475
576
// / Retrieve the Clang-specific implementation data;
476
577
ClangModuleDependenciesCacheImpl *getClangImpl () const {
477
- return clangImpl ;
578
+ return globalCache. getClangImpl () ;
478
579
}
479
580
480
581
// / Whether we have cached dependency information for the given module.
481
582
bool hasDependencies (StringRef moduleName,
482
583
ModuleLookupSpecifics details) const ;
483
584
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.
485
587
// /
486
588
// / \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 ;
490
591
491
592
// / 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.
494
595
// /
495
596
// / \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
+ }
499
603
500
604
// / Record dependencies for the given module.
501
605
void recordDependencies (StringRef moduleName,
@@ -507,10 +611,10 @@ class ModuleDependenciesCache {
507
611
508
612
// / Reference the list of all module dependencies.
509
613
const std::vector<ModuleDependencyID> &getAllModules () const {
510
- return AllModules ;
614
+ return globalCache. getAllModules () ;
511
615
}
512
616
};
513
617
514
- }
618
+ } // namespace swift
515
619
516
620
#endif /* SWIFT_AST_MODULE_DEPENDENCIES_H */
0 commit comments