Skip to content

Commit 85d70b5

Browse files
author
David Ungar
committed
Move use enumeration to ReferencedNameTracker
1 parent fa3d4c5 commit 85d70b5

File tree

4 files changed

+208
-137
lines changed

4 files changed

+208
-137
lines changed

include/swift/AST/ReferencedNameTracker.h

Lines changed: 47 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,33 @@
1414
#define SWIFT_REFERENCEDNAMETRACKER_H
1515

1616
#include "swift/AST/Identifier.h"
17+
#include "swift/Basic/ReferenceDependencyKeys.h"
1718
#include "llvm/ADT/DenseMap.h"
1819

20+
#include <unordered_set>
21+
1922
namespace swift {
2023

2124
class NominalTypeDecl;
25+
class DependencyTracker;
2226

2327
class ReferencedNameTracker {
24-
#define TRACKED_SET(KIND, NAME) \
25-
private: \
26-
llvm::DenseMap<KIND, bool> NAME##s; \
27-
public: \
28-
void add##NAME(KIND new##NAME, bool isCascadingUse) { \
29-
NAME##s[new##NAME] |= isCascadingUse; \
30-
} \
31-
const decltype(NAME##s) &get##NAME##s() const { \
32-
return NAME##s; \
33-
}
28+
public:
29+
using EnumerateUsedDecl = function_ref<void(
30+
fine_grained_dependencies::NodeKind kind, StringRef context,
31+
StringRef name, bool isCascadingUse)>;
32+
33+
private:
34+
#define TRACKED_SET(KIND, NAME) \
35+
private: \
36+
llvm::DenseMap<KIND, bool> NAME##s; \
37+
\
38+
public: \
39+
void add##NAME(KIND new##NAME, bool isCascadingUse) { \
40+
NAME##s[new##NAME] |= isCascadingUse; \
41+
} \
42+
/* make private once ReferenceDependencies.cpp is gone */ \
43+
const decltype(NAME##s) &get##NAME##s() const { return NAME##s; }
3444

3545
TRACKED_SET(DeclBaseName, TopLevelName)
3646
TRACKED_SET(DeclBaseName, DynamicLookupName)
@@ -39,6 +49,33 @@ public: \
3949
TRACKED_SET(MemberPair, UsedMember)
4050

4151
#undef TRACKED_SET
52+
public:
53+
// Pushing the DependencyTracker through unifies external dependency
54+
// enumeration.
55+
void enumerateAllUses(bool includeIntrafileDeps,
56+
const DependencyTracker &depTracker,
57+
EnumerateUsedDecl enumerateUsedDecl) const;
58+
59+
private:
60+
template <fine_grained_dependencies::NodeKind kind>
61+
void enumerateSimpleUses(llvm::DenseMap<DeclBaseName, bool> cascadesByName,
62+
EnumerateUsedDecl enumerateUsedDecl) const;
63+
64+
void enumerateExternalUses(const DependencyTracker &,
65+
EnumerateUsedDecl enumerateUsedDecl) const;
66+
67+
void enumerateCompoundUses(bool includeIntrafileDeps,
68+
EnumerateUsedDecl enumerateUsedDecl) const;
69+
70+
std::unordered_set<std::string>
71+
computeHoldersOfCascadingMembers(bool includeIntrafileDeps) const;
72+
73+
void enumerateNominalUses(
74+
bool includeIntrafileDeps,
75+
const std::unordered_set<std::string> &&holdersOfCascadingMembers,
76+
EnumerateUsedDecl enumerateUsedDecl) const;
77+
78+
void enumerateMemberUses(EnumerateUsedDecl enumerateUsedDecl) const;
4279
};
4380

4481
} // end namespace swift

lib/AST/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ add_swift_host_library(swiftAST STATIC
6666
PrettyStackTrace.cpp
6767
ProtocolConformance.cpp
6868
RawComment.cpp
69+
ReferencedNameTracker.cpp
6970
RequirementEnvironment.cpp
7071
SyntaxASTMap.cpp
7172
SILLayout.cpp

lib/AST/FrontendSourceFileDepGraphFactory.cpp

Lines changed: 17 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -554,134 +554,24 @@ void FrontendSourceFileDepGraphFactory::addAllDefinedDeclsOfAGivenType(
554554
// MARK: FrontendSourceFileDepGraphFactory - adding collections of used Decls
555555
//==============================================================================
556556

557-
namespace {
558-
/// Extracts uses out of a SourceFile
559-
class UsedDeclEnumerator {
560-
SourceFile *SF;
561-
const DependencyTracker &depTracker;
562-
StringRef swiftDeps;
563-
564-
/// Cache these for efficiency
565-
const DependencyKey sourceFileInterface;
566-
const DependencyKey sourceFileImplementation;
567-
568-
const bool includeIntrafileDeps;
569-
570-
function_ref<void(const DependencyKey &, const DependencyKey &)> createDefUse;
571-
572-
public:
573-
UsedDeclEnumerator(
574-
SourceFile *SF, const DependencyTracker &depTracker, StringRef swiftDeps,
575-
bool includeIntrafileDeps,
576-
function_ref<void(const DependencyKey &, const DependencyKey &)>
577-
createDefUse)
578-
: SF(SF), depTracker(depTracker), swiftDeps(swiftDeps),
579-
sourceFileInterface(DependencyKey::createKeyForWholeSourceFile(
580-
DeclAspect::interface, swiftDeps)),
581-
sourceFileImplementation(DependencyKey::createKeyForWholeSourceFile(
582-
DeclAspect::implementation, swiftDeps)),
583-
includeIntrafileDeps(includeIntrafileDeps), createDefUse(createDefUse) {
584-
}
585-
586-
public:
587-
void enumerateAllUses() {
588-
enumerateSimpleUses<NodeKind::topLevel>(
589-
SF->getReferencedNameTracker()->getTopLevelNames());
590-
enumerateSimpleUses<NodeKind::dynamicLookup>(
591-
SF->getReferencedNameTracker()->getDynamicLookupNames());
592-
enumerateExternalUses();
593-
enumerateCompoundUses();
594-
}
595-
596-
private:
597-
void enumerateUse(NodeKind kind, StringRef context, StringRef name,
598-
bool isCascadingUse) {
599-
// Assume that what is depended-upon is the interface
600-
createDefUse(DependencyKey(kind, DeclAspect::interface, context.str(), name.str()),
601-
isCascadingUse ? sourceFileInterface
602-
: sourceFileImplementation);
603-
}
604-
template <NodeKind kind>
605-
void enumerateSimpleUses(llvm::DenseMap<DeclBaseName, bool> cascadesByName) {
606-
for (const auto &p : cascadesByName)
607-
enumerateUse(kind, "", p.getFirst().userFacingName(), p.getSecond());
608-
}
609-
610-
void enumerateCompoundUses() {
611-
enumerateNominalUses(std::move(computeHoldersOfCascadingMembers()));
612-
enumerateMemberUses();
613-
}
614-
615-
std::unordered_set<std::string> computeHoldersOfCascadingMembers() {
616-
std::unordered_set<std::string> holdersOfCascadingMembers;
617-
for (const auto &p : SF->getReferencedNameTracker()->getUsedMembers()) {
618-
{
619-
bool isPrivate = p.getFirst().first->isPrivateToEnclosingFile();
620-
if (isPrivate && !includeIntrafileDeps)
621-
continue;
622-
}
623-
std::string context =
624-
DependencyKey::computeContextForProvidedEntity<NodeKind::nominal>(
625-
p.getFirst().first);
626-
bool isCascading = p.getSecond();
627-
if (isCascading)
628-
holdersOfCascadingMembers.insert(context);
629-
}
630-
return holdersOfCascadingMembers;
631-
}
632-
633-
void enumerateNominalUses(
634-
const std::unordered_set<std::string> &&holdersOfCascadingMembers) {
635-
for (const auto &p : SF->getReferencedNameTracker()->getUsedMembers()) {
636-
{
637-
bool isPrivate = p.getFirst().first->isPrivateToEnclosingFile();
638-
if (isPrivate && !includeIntrafileDeps)
639-
continue;
640-
}
641-
const NominalTypeDecl *nominal = p.getFirst().first;
642-
643-
std::string context =
644-
DependencyKey::computeContextForProvidedEntity<NodeKind::nominal>(
645-
nominal);
646-
const bool isCascadingUse = holdersOfCascadingMembers.count(context) != 0;
647-
enumerateUse(NodeKind::nominal, context, "", isCascadingUse);
648-
}
649-
}
650-
651-
void enumerateMemberUses() {
652-
for (const auto &p : SF->getReferencedNameTracker()->getUsedMembers()) {
653-
const NominalTypeDecl *nominal = p.getFirst().first;
654-
const auto rawName = p.getFirst().second;
655-
const bool isPotentialMember = rawName.empty();
656-
const bool isCascadingUse = p.getSecond();
657-
if (isPotentialMember) {
658-
std::string context = DependencyKey::computeContextForProvidedEntity<
659-
NodeKind::potentialMember>(nominal);
660-
enumerateUse(NodeKind::potentialMember, context, "", isCascadingUse);
661-
} else {
662-
std::string context =
663-
DependencyKey::computeContextForProvidedEntity<NodeKind::member>(
664-
nominal);
665-
std::string name = rawName.userFacingName();
666-
enumerateUse(NodeKind::member, context, name, isCascadingUse);
667-
}
668-
}
669-
}
670-
671-
void enumerateExternalUses() {
672-
// external dependencies always cascade
673-
for (StringRef s : depTracker.getDependencies())
674-
enumerateUse(NodeKind::externalDepend, "", s, true);
675-
}
676-
};
677-
} // end namespace
678-
679557
void FrontendSourceFileDepGraphFactory::addAllUsedDecls() {
680-
UsedDeclEnumerator(SF, depTracker, swiftDeps, includePrivateDeps,
681-
[&](const DependencyKey &def, const DependencyKey &use) {
682-
addAUsedDecl(def, use);
683-
})
684-
.enumerateAllUses();
558+
const DependencyKey sourceFileInterface =
559+
DependencyKey::createKeyForWholeSourceFile(DeclAspect::interface,
560+
swiftDeps);
561+
562+
const DependencyKey sourceFileImplementation =
563+
DependencyKey::createKeyForWholeSourceFile(DeclAspect::implementation,
564+
swiftDeps);
565+
566+
SF->getReferencedNameTracker()->enumerateAllUses(
567+
includePrivateDeps, depTracker,
568+
[&](const fine_grained_dependencies::NodeKind kind, StringRef context,
569+
StringRef name, const bool isCascadingUse) {
570+
addAUsedDecl(DependencyKey(kind, DeclAspect::interface, context.str(),
571+
name.str()),
572+
isCascadingUse ? sourceFileInterface
573+
: sourceFileImplementation);
574+
});
685575
}
686576

687577
//==============================================================================

lib/AST/ReferencedNameTracker.cpp

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
//===---------------------------- ReferencedNameTracker.cpp ---------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
///
13+
/// This file implements unqualified lookup, which searches for an identifier
14+
/// from a given context.
15+
///
16+
//===----------------------------------------------------------------------===//
17+
18+
#include "swift/AST/ReferencedNameTracker.h"
19+
20+
#include "swift/AST/ASTContext.h"
21+
#include "swift/AST/ASTMangler.h"
22+
#include "swift/AST/Decl.h"
23+
#include "swift/AST/DiagnosticEngine.h"
24+
#include "swift/AST/DiagnosticsFrontend.h"
25+
#include "swift/AST/FineGrainedDependencies.h"
26+
#include "swift/AST/Module.h"
27+
#include "swift/AST/ModuleLoader.h"
28+
#include "swift/AST/NameLookup.h"
29+
#include "swift/AST/SourceFile.h"
30+
#include "swift/AST/Types.h"
31+
#include "swift/Basic/FileSystem.h"
32+
#include "swift/Basic/LLVM.h"
33+
#include "swift/Basic/ReferenceDependencyKeys.h"
34+
#include "swift/Demangling/Demangle.h"
35+
#include "swift/Frontend/FrontendOptions.h"
36+
#include "llvm/ADT/MapVector.h"
37+
#include "llvm/ADT/SetVector.h"
38+
#include "llvm/ADT/SmallVector.h"
39+
#include "llvm/Support/FileSystem.h"
40+
#include "llvm/Support/Path.h"
41+
42+
using namespace swift;
43+
using NodeKind = fine_grained_dependencies::NodeKind;
44+
using EnumerateUsedDecl = ReferencedNameTracker::EnumerateUsedDecl;
45+
using DependencyKey = fine_grained_dependencies::DependencyKey;
46+
47+
void ReferencedNameTracker::enumerateAllUses(
48+
bool includeIntrafileDeps, const DependencyTracker &depTracker,
49+
EnumerateUsedDecl enumerateUsedDecl) const {
50+
enumerateSimpleUses<NodeKind::topLevel>(getTopLevelNames(),
51+
enumerateUsedDecl);
52+
enumerateSimpleUses<NodeKind::dynamicLookup>(getDynamicLookupNames(),
53+
enumerateUsedDecl);
54+
enumerateExternalUses(depTracker, enumerateUsedDecl);
55+
enumerateCompoundUses(includeIntrafileDeps, enumerateUsedDecl);
56+
}
57+
58+
template <NodeKind kind>
59+
void ReferencedNameTracker::enumerateSimpleUses(
60+
llvm::DenseMap<DeclBaseName, bool> cascadesByName,
61+
EnumerateUsedDecl enumerateUsedDecl) const {
62+
for (const auto &p : cascadesByName)
63+
enumerateUsedDecl(kind, "", p.getFirst().userFacingName(), p.getSecond());
64+
}
65+
66+
void ReferencedNameTracker::enumerateExternalUses(
67+
const DependencyTracker &depTracker,
68+
EnumerateUsedDecl enumerateUsedDecl) const {
69+
// external dependencies always cascade
70+
for (StringRef s : depTracker.getDependencies())
71+
enumerateUsedDecl(NodeKind::externalDepend, "", s, true);
72+
}
73+
74+
void ReferencedNameTracker::enumerateCompoundUses(
75+
bool includeIntrafileDeps, EnumerateUsedDecl enumerateUsedDecl) const {
76+
enumerateNominalUses(
77+
includeIntrafileDeps,
78+
std::move(computeHoldersOfCascadingMembers(includeIntrafileDeps)),
79+
enumerateUsedDecl);
80+
enumerateMemberUses(enumerateUsedDecl);
81+
}
82+
83+
std::unordered_set<std::string>
84+
ReferencedNameTracker::computeHoldersOfCascadingMembers(
85+
const bool includeIntrafileDeps) const {
86+
std::unordered_set<std::string> holdersOfCascadingMembers;
87+
for (const auto &p : getUsedMembers()) {
88+
{
89+
bool isPrivate = p.getFirst().first->isPrivateToEnclosingFile();
90+
if (isPrivate && !includeIntrafileDeps)
91+
continue;
92+
}
93+
std::string context =
94+
DependencyKey::computeContextForProvidedEntity<NodeKind::nominal>(
95+
p.getFirst().first);
96+
bool isCascading = p.getSecond();
97+
if (isCascading)
98+
holdersOfCascadingMembers.insert(context);
99+
}
100+
return holdersOfCascadingMembers;
101+
}
102+
103+
void ReferencedNameTracker::enumerateNominalUses(
104+
const bool includeIntrafileDeps,
105+
const std::unordered_set<std::string> &&holdersOfCascadingMembers,
106+
EnumerateUsedDecl enumerateUsedDecl) const {
107+
for (const auto &p : getUsedMembers()) {
108+
{
109+
bool isPrivate = p.getFirst().first->isPrivateToEnclosingFile();
110+
if (isPrivate && !includeIntrafileDeps)
111+
continue;
112+
}
113+
114+
const NominalTypeDecl *nominal = p.getFirst().first;
115+
116+
std::string context =
117+
DependencyKey::computeContextForProvidedEntity<NodeKind::nominal>(
118+
nominal);
119+
const bool isCascadingUse = holdersOfCascadingMembers.count(context) != 0;
120+
enumerateUsedDecl(NodeKind::nominal, context, "", isCascadingUse);
121+
}
122+
}
123+
124+
void ReferencedNameTracker::enumerateMemberUses(
125+
EnumerateUsedDecl enumerateUsedDecl) const {
126+
for (const auto &p : getUsedMembers()) {
127+
const NominalTypeDecl *nominal = p.getFirst().first;
128+
const auto rawName = p.getFirst().second;
129+
const bool isPotentialMember = rawName.empty();
130+
const bool isCascadingUse = p.getSecond();
131+
if (isPotentialMember) {
132+
std::string context = DependencyKey::computeContextForProvidedEntity<
133+
NodeKind::potentialMember>(nominal);
134+
enumerateUsedDecl(NodeKind::potentialMember, context, "", isCascadingUse);
135+
} else {
136+
std::string context =
137+
DependencyKey::computeContextForProvidedEntity<NodeKind::member>(
138+
nominal);
139+
std::string name = rawName.userFacingName();
140+
enumerateUsedDecl(NodeKind::member, context, name, isCascadingUse);
141+
}
142+
}
143+
}

0 commit comments

Comments
 (0)