@@ -241,8 +241,10 @@ bool fine_grained_dependencies::withReferenceDependencies(
241
241
const DependencyTracker &depTracker, StringRef outputPath,
242
242
bool alsoEmitDotFile,
243
243
llvm::function_ref<bool (SourceFileDepGraph &&)> cont) {
244
- if (MSF.dyn_cast <ModuleDecl *>()) {
245
- llvm_unreachable (" Cannot construct dependency graph for modules!" );
244
+ if (auto *MD = MSF.dyn_cast <ModuleDecl *>()) {
245
+ SourceFileDepGraph g =
246
+ ModuleDepGraphFactory (MD, alsoEmitDotFile).construct ();
247
+ return cont (std::move (g));
246
248
} else {
247
249
auto *SF = MSF.get <SourceFile *>();
248
250
SourceFileDepGraph g = FrontendSourceFileDepGraphFactory (
@@ -592,6 +594,9 @@ class UsedDeclEnumerator {
592
594
}
593
595
594
596
void enumerateExternalUses () {
597
+ for (StringRef s : depTracker.getIncrementalDependencies ())
598
+ enumerateUse<NodeKind::incrementalExternalDepend>(" " , s);
599
+
595
600
for (StringRef s : depTracker.getDependencies ())
596
601
enumerateUse<NodeKind::externalDepend>(" " , s);
597
602
}
@@ -632,3 +637,75 @@ FrontendSourceFileDepGraphFactory::getFingerprintIfAny(const Decl *d) {
632
637
}
633
638
return None;
634
639
}
640
+
641
+ // ==============================================================================
642
+ // MARK: ModuleDepGraphFactory
643
+ // ==============================================================================
644
+
645
+ ModuleDepGraphFactory::ModuleDepGraphFactory (ModuleDecl *Mod, bool emitDot)
646
+ : AbstractSourceFileDepGraphFactory(
647
+ /* include private*/ true , Mod->getASTContext ().hadError(),
648
+ Mod->getNameStr(), "0xBADBEEF", emitDot, Mod->getASTContext().Diags),
649
+ Mod(Mod) {}
650
+
651
+ void ModuleDepGraphFactory::addAllDefinedDecls () {
652
+ // TODO: express the multiple provides and depends streams with variadic
653
+ // templates
654
+
655
+ // Many kinds of Decls become top-level depends.
656
+
657
+ SmallVector<Decl *, 32 > TopLevelDecls;
658
+ Mod->getTopLevelDecls (TopLevelDecls);
659
+ DeclFinder declFinder (TopLevelDecls, includePrivateDeps,
660
+ [this ](VisibleDeclConsumer &consumer) {
661
+ return Mod->lookupClassMembers ({}, consumer);
662
+ });
663
+
664
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(
665
+ declFinder.precedenceGroups );
666
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(
667
+ declFinder.memberOperatorDecls );
668
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(declFinder.operators );
669
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(declFinder.topNominals );
670
+ addAllDefinedDeclsOfAGivenType<NodeKind::topLevel>(declFinder.topValues );
671
+ addAllDefinedDeclsOfAGivenType<NodeKind::nominal>(declFinder.allNominals );
672
+ addAllDefinedDeclsOfAGivenType<NodeKind::potentialMember>(
673
+ declFinder.potentialMemberHolders );
674
+ addAllDefinedDeclsOfAGivenType<NodeKind::member>(
675
+ declFinder.valuesInExtensions );
676
+ addAllDefinedDeclsOfAGivenType<NodeKind::dynamicLookup>(
677
+ declFinder.classMembers );
678
+ }
679
+
680
+ // / Given an array of Decls or pairs of them in \p declsOrPairs
681
+ // / create node pairs for context and name
682
+ template <NodeKind kind, typename ContentsT>
683
+ void ModuleDepGraphFactory::addAllDefinedDeclsOfAGivenType (
684
+ std::vector<ContentsT> &contentsVec) {
685
+ for (const auto &declOrPair : contentsVec) {
686
+ Optional<std::string> fp = getFingerprintIfAny (declOrPair);
687
+ addADefinedDecl (
688
+ DependencyKey::createForProvidedEntityInterface<kind>(declOrPair),
689
+ fp ? StringRef (fp.getValue ()) : Optional<StringRef>());
690
+ }
691
+ }
692
+
693
+ // ==============================================================================
694
+ // MARK: ModuleDepGraphFactory - adding individual defined Decls
695
+ // ==============================================================================
696
+
697
+ // / At present, only \c NominalTypeDecls have (body) fingerprints
698
+ Optional<std::string> ModuleDepGraphFactory::getFingerprintIfAny (
699
+ std::pair<const NominalTypeDecl *, const ValueDecl *>) {
700
+ return None;
701
+ }
702
+ Optional<std::string>
703
+ ModuleDepGraphFactory::getFingerprintIfAny (const Decl *d) {
704
+ if (const auto *idc = dyn_cast<IterableDeclContext>(d)) {
705
+ auto result = idc->getBodyFingerprint ();
706
+ assert ((!result || !result->empty ()) &&
707
+ " Fingerprint should never be empty" );
708
+ return result;
709
+ }
710
+ return None;
711
+ }
0 commit comments