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,20 @@ 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
+ }
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;
64
80
};
65
81
66
82
// / Base class for the variant storage of ModuleDependencies.
@@ -275,8 +291,8 @@ class ModuleDependencies {
275
291
276
292
// / Describe the module dependencies for a Swift module that can be
277
293
// / 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,
280
296
ArrayRef<std::string> compiledCandidates,
281
297
ArrayRef<StringRef> buildCommands,
282
298
ArrayRef<StringRef> extraPCMArgs,
@@ -386,6 +402,9 @@ class ModuleDependencies {
386
402
// / Add a bridging header to a Swift module's dependencies.
387
403
void addBridgingHeader (StringRef bridgingHeader);
388
404
405
+ // / Add source files
406
+ void addSourceFile (StringRef sourceFile);
407
+
389
408
// / Add source files that the bridging header depends on.
390
409
void addBridgingSourceFile (StringRef bridgingSourceFile);
391
410
@@ -400,25 +419,30 @@ class ModuleDependencies {
400
419
};
401
420
402
421
using ModuleDependencyID = std::pair<std::string, ModuleDependenciesKind>;
422
+ using ModuleDependenciesVector = llvm::SmallVector<ModuleDependencies, 1 >;
403
423
404
424
// / 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 {
407
434
// / All cached module dependencies, in the order in which they were
408
435
// / encountered.
409
436
std::vector<ModuleDependencyID> AllModules;
410
437
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;
422
446
423
447
// / Additional information needed for Clang dependency scanning.
424
448
ClangModuleDependenciesCacheImpl *clangImpl = nullptr ;
@@ -434,46 +458,148 @@ class ModuleDependenciesCache {
434
458
435
459
// / Retrieve the dependencies map that corresponds to the given dependency
436
460
// / 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 ;
441
465
442
466
public:
443
- ModuleDependenciesCache () { }
467
+ GlobalModuleDependenciesCache ();
468
+ GlobalModuleDependenciesCache (const GlobalModuleDependenciesCache &) = delete ;
469
+ GlobalModuleDependenciesCache &
470
+ operator =(const GlobalModuleDependenciesCache &) = delete ;
444
471
445
- ModuleDependenciesCache (const ModuleDependenciesCache &) = delete ;
446
- ModuleDependenciesCache &operator =(const ModuleDependenciesCache &) = delete ;
472
+ virtual ~GlobalModuleDependenciesCache () { destroyClangImpl (); }
447
473
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 ;
451
478
452
479
// / 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 *)) {
456
483
destroyClangImpl ();
457
484
458
485
this ->clangImpl = clangImpl;
459
486
this ->clangImplDeleter = clangImplDeleter;
460
487
}
461
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
+
462
576
// / Retrieve the Clang-specific implementation data;
463
577
ClangModuleDependenciesCacheImpl *getClangImpl () const {
464
- return clangImpl ;
578
+ return globalCache. getClangImpl () ;
465
579
}
466
580
467
581
// / Whether we have cached dependency information for the given module.
468
582
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 ;
470
591
471
592
// / 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.
472
595
// /
473
596
// / \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
+ }
477
603
478
604
// / Record dependencies for the given module.
479
605
void recordDependencies (StringRef moduleName,
@@ -485,10 +611,10 @@ class ModuleDependenciesCache {
485
611
486
612
// / Reference the list of all module dependencies.
487
613
const std::vector<ModuleDependencyID> &getAllModules () const {
488
- return AllModules ;
614
+ return globalCache. getAllModules () ;
489
615
}
490
616
};
491
617
492
- }
618
+ } // namespace swift
493
619
494
620
#endif /* SWIFT_AST_MODULE_DEPENDENCIES_H */
0 commit comments