@@ -136,14 +136,53 @@ template <typename D> bool shouldLookupMembers(D *decl, SourceLoc loc) {
136
136
} // end anonymous namespace
137
137
138
138
namespace {
139
+ class LegacyUnqualifiedLookup ;
140
+
139
141
class UnqualifiedLookupFactory {
140
142
public:
141
- using Flags = LegacyUnqualifiedLookup::Flags;
142
- using Options = LegacyUnqualifiedLookup::Options;
143
- using PlacesToSearch = UnqualifiedLookup::PlacesToSearch;
144
- using PerScopeLookupState = UnqualifiedLookup::PerScopeLookupState;
143
+ using Flags = UnqualifiedLookup::Flags;
144
+ using Options = UnqualifiedLookup::Options;
145
145
146
146
private:
147
+ struct PlacesToSearch {
148
+ // TODO: constify members?
149
+ // / The context in which the places where found.
150
+ DeclContext *fromWhence;
151
+ // / Nontypes are formally members of the base type
152
+ DeclContext *whereNonTypesAreMembers;
153
+ // / Types are formally members of the metatype
154
+ DeclContext *whereTypesAreMembers;
155
+ // / Places to search for the lookup.
156
+ SmallVector<NominalTypeDecl *, 2 > places;
157
+
158
+ PlacesToSearch (DeclContext *fromWhence,
159
+ DeclContext *whereNonTypesAreMembers,
160
+ DeclContext *whereTypesAreMembers,
161
+ DeclContext *placesHolder);
162
+ bool empty () const {
163
+ return whereNonTypesAreMembers == nullptr || places.empty ();
164
+ }
165
+ // Classify this declaration.
166
+ // Types are formally members of the metatype.
167
+ DeclContext *whereValueIsMember (const ValueDecl *const member) const {
168
+ return dyn_cast<TypeDecl>(member) ? whereTypesAreMembers
169
+ : whereNonTypesAreMembers;
170
+ }
171
+ void addToResults (const DeclName &Name, bool isCascadingUse,
172
+ NLOptions baseNLOptions, DeclContext *contextForLookup,
173
+ SmallVectorImpl<LookupResultEntry> &results) const ;
174
+ void dump () const ;
175
+ };
176
+
177
+ struct PerScopeLookupState {
178
+ bool isDone;
179
+ DeclContext *childOfNextDC;
180
+ Optional<PlacesToSearch> placesToSearch;
181
+ Optional<bool > isCascadingUse;
182
+
183
+ void dump () const ;
184
+ };
185
+
147
186
// Inputs
148
187
const DeclName Name;
149
188
DeclContext *const DC;
@@ -162,15 +201,14 @@ class UnqualifiedLookupFactory {
162
201
// Outputs
163
202
SmallVectorImpl<LookupResultEntry> &Results;
164
203
size_t &IndexOfFirstOuterResult;
165
-
166
- // For debugging:
167
- SourceFile const *&recordedSF;
168
- DeclName &recordedName;
169
- bool &recordedIsCascadingUse;
170
- std::vector<PerScopeLookupState> &breadcrumbs;
171
-
172
204
SmallVector<LookupResultEntry, 4 > UnavailableInnerResults;
173
205
206
+ public: // for exp debugging
207
+ std::vector<PerScopeLookupState> breadcrumbs;
208
+ SourceFile const *recordedSF = nullptr ;
209
+ DeclName recordedName;
210
+ bool recordedIsCascadingUse = false ;
211
+
174
212
public:
175
213
// clang-format off
176
214
UnqualifiedLookupFactory (DeclName Name,
@@ -311,12 +349,17 @@ class UnqualifiedLookupFactory {
311
349
312
350
#pragma mark common helper declarations
313
351
static NLOptions
314
- computeBaseNLOptions (const LegacyUnqualifiedLookup ::Options options,
352
+ computeBaseNLOptions (const UnqualifiedLookup ::Options options,
315
353
const bool isOriginallyTypeLookup);
316
354
317
355
static bool resolveIsCascadingUse (const DeclContext *const dc,
318
356
Optional<bool > isCascadingUse,
319
357
bool onlyCareAboutFunctionBody);
358
+
359
+ void dumpBreadcrumbs () const ;
360
+
361
+ public:
362
+ bool verifyEqualToLegacy (const LegacyUnqualifiedLookup &&LUL) const ;
320
363
};
321
364
} // namespace
322
365
@@ -344,11 +387,8 @@ isOriginallyTypeLookup(options.contains(Flags::TypeLookup)),
344
387
baseNLOptions(computeBaseNLOptions(options, isOriginallyTypeLookup)),
345
388
Consumer(Name, lookupToBeCreated.Results, isOriginallyTypeLookup),
346
389
Results(lookupToBeCreated.Results),
347
- IndexOfFirstOuterResult(lookupToBeCreated.IndexOfFirstOuterResult),
348
- recordedSF(lookupToBeCreated.recordedSF),
349
- recordedName(lookupToBeCreated.recordedName),
350
- recordedIsCascadingUse(lookupToBeCreated.recordedIsCascadingUse),
351
- breadcrumbs(lookupToBeCreated.breadcrumbs) {}
390
+ IndexOfFirstOuterResult(lookupToBeCreated.IndexOfFirstOuterResult)
391
+ {}
352
392
// clang-format on
353
393
354
394
void UnqualifiedLookupFactory::fillInLookup () {
@@ -948,7 +988,7 @@ bool UnqualifiedLookupFactory::addLocalVariableResults(DeclContext *dc) {
948
988
return false ;
949
989
}
950
990
951
- void UnqualifiedLookup ::PlacesToSearch::addToResults (
991
+ void UnqualifiedLookupFactory ::PlacesToSearch::addToResults (
952
992
const DeclName &Name, bool isCascadingUse, NLOptions baseNLOptions,
953
993
DeclContext *contextForLookup,
954
994
SmallVectorImpl<LookupResultEntry> &results) const {
@@ -1102,6 +1142,47 @@ bool UnqualifiedLookupFactory::resolveIsCascadingUse(
1102
1142
/* functionsAreNonCascading=*/ onlyCareAboutFunctionBody);
1103
1143
}
1104
1144
1145
+ namespace {
1146
+ // / This class implements and represents the result of performing
1147
+ // / unqualified lookup (i.e. lookup for a plain identifier).
1148
+ // / It is being kept around in order to check the refactoring against the new
1149
+ // / UnqualifiedLookup above.
1150
+ class LegacyUnqualifiedLookup {
1151
+ public:
1152
+ using Flags = UnqualifiedLookup::Flags;
1153
+ using Options = UnqualifiedLookup::Options;
1154
+
1155
+ // / Lookup an unqualified identifier \p Name in the context.
1156
+ // /
1157
+ // / If the current DeclContext is nested in a function body, the SourceLoc
1158
+ // / is used to determine which declarations in that body are visible.
1159
+ LegacyUnqualifiedLookup (DeclName Name, DeclContext *DC,
1160
+ LazyResolver *TypeResolver,
1161
+ SourceLoc Loc = SourceLoc(),
1162
+ Options options = Options());
1163
+
1164
+ SmallVector<LookupResultEntry, 4 > Results;
1165
+ // / The index of the first result that isn't from the innermost scope
1166
+ // / with results.
1167
+ // /
1168
+ // / That is, \c makeArrayRef(Results).take_front(IndexOfFirstOuterResults)
1169
+ // / will be Results from the innermost scope that had results, and the
1170
+ // / remaining elements of Results will be from parent scopes of this one.
1171
+ size_t IndexOfFirstOuterResult;
1172
+
1173
+ // / Return true if anything was found by the name lookup.
1174
+ bool isSuccess () const { return !Results.empty (); }
1175
+
1176
+ // / Get the result as a single type, or a null type if that fails.
1177
+ TypeDecl *getSingleTypeResult () const ;
1178
+
1179
+ public: // for exp debugging
1180
+ SourceFile const *recordedSF = nullptr ;
1181
+ DeclName recordedName;
1182
+ bool recordedIsCascadingUse = false ;
1183
+ };
1184
+ }; // namespace
1185
+
1105
1186
LegacyUnqualifiedLookup::LegacyUnqualifiedLookup (DeclName Name, DeclContext *DC,
1106
1187
LazyResolver *TypeResolver,
1107
1188
SourceLoc Loc, Options options)
@@ -1624,15 +1705,15 @@ TypeDecl *LegacyUnqualifiedLookup::getSingleTypeResult() const {
1624
1705
return dyn_cast<TypeDecl>(Results.back ().getValueDecl ());
1625
1706
}
1626
1707
1627
- UnqualifiedLookup ::PlacesToSearch::PlacesToSearch (
1708
+ UnqualifiedLookupFactory ::PlacesToSearch::PlacesToSearch (
1628
1709
DeclContext *fromWhence, DeclContext *whereNonTypesAreMembers,
1629
1710
DeclContext *whereTypesAreMembers, DeclContext *placesHolder)
1630
1711
: fromWhence(fromWhence), whereNonTypesAreMembers(whereNonTypesAreMembers),
1631
1712
whereTypesAreMembers(whereTypesAreMembers) {
1632
1713
populateLookupDeclsFromContext (placesHolder, places);
1633
1714
}
1634
1715
1635
- void UnqualifiedLookup ::PlacesToSearch::dump () const {
1716
+ void UnqualifiedLookupFactory ::PlacesToSearch::dump () const {
1636
1717
llvm::errs () << " fromWhence: " ;
1637
1718
fromWhence->dumpContext ();
1638
1719
llvm::errs () << " whereNonTypesAreMembers: " ;
@@ -1655,9 +1736,9 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name,
1655
1736
Options options)
1656
1737
// clang-format on
1657
1738
: IndexOfFirstOuterResult(0 ) {
1658
- UnqualifiedLookupFactory (Name, DC, TypeResolver, Loc, options, *this )
1659
- .fillInLookup ();
1660
- assert (verifyEqual (
1739
+ UnqualifiedLookupFactory factory (Name, DC, TypeResolver, Loc, options, *this );
1740
+ factory .fillInLookup ();
1741
+ assert (factory. verifyEqualToLegacy (
1661
1742
LegacyUnqualifiedLookup (Name, DC, TypeResolver, Loc, options)) &&
1662
1743
" bad refactoring" );
1663
1744
}
@@ -1668,29 +1749,7 @@ TypeDecl *UnqualifiedLookup::getSingleTypeResult() const {
1668
1749
return dyn_cast<TypeDecl>(Results.back ().getValueDecl ());
1669
1750
}
1670
1751
1671
- bool UnqualifiedLookup::verifyEqual (
1672
- const LegacyUnqualifiedLookup &&other) const {
1673
- assert (Results.size () == other.Results .size ());
1674
- for (size_t i : indices (Results)) {
1675
- const auto &e = Results[i];
1676
- const auto &oe = other.Results [i];
1677
- assert (e.getValueDecl () == oe.getValueDecl ());
1678
- assert (e.getDeclContext () == oe.getDeclContext ());
1679
- // unsigned printContext(llvm::raw_ostream &OS, unsigned indent = 0,
1680
- // bool onlyAPartialLine = false) const;
1681
- assert (e.getBaseDecl () == oe.getBaseDecl ());
1682
- }
1683
- assert (IndexOfFirstOuterResult == other.IndexOfFirstOuterResult );
1684
- assert (recordedSF == other.recordedSF );
1685
- assert (recordedName == other.recordedName );
1686
- if (recordedIsCascadingUse)
1687
- assert (other.recordedIsCascadingUse );
1688
- else
1689
- assert (!other.recordedIsCascadingUse );
1690
- return true ;
1691
- }
1692
-
1693
- void UnqualifiedLookup::dumpBreadcrumbs () const {
1752
+ void UnqualifiedLookupFactory::dumpBreadcrumbs () const {
1694
1753
auto &e = llvm::errs ();
1695
1754
for (size_t i : indices (breadcrumbs)) {
1696
1755
e << i << " \n " ;
@@ -1699,11 +1758,33 @@ void UnqualifiedLookup::dumpBreadcrumbs() const {
1699
1758
}
1700
1759
}
1701
1760
1702
- void UnqualifiedLookup ::PerScopeLookupState::dump () const {
1761
+ void UnqualifiedLookupFactory ::PerScopeLookupState::dump () const {
1703
1762
auto &e = llvm::errs ();
1704
1763
e << (isDone ? " done: " : " not done: " );
1705
1764
e << " dc: " ;
1706
1765
childOfNextDC->dumpContext ();
1707
1766
if (placesToSearch.hasValue ())
1708
1767
placesToSearch.getValue ().dump ();
1709
1768
}
1769
+
1770
+ bool UnqualifiedLookupFactory::verifyEqualToLegacy (
1771
+ const LegacyUnqualifiedLookup &&LUL) const {
1772
+ assert (Results.size () == LUL.Results .size ());
1773
+ for (size_t i : indices (Results)) {
1774
+ const auto &e = Results[i];
1775
+ const auto &oe = LUL.Results [i];
1776
+ assert (e.getValueDecl () == oe.getValueDecl ());
1777
+ assert (e.getDeclContext () == oe.getDeclContext ());
1778
+ // unsigned printContext(llvm::raw_ostream &OS, unsigned indent = 0,
1779
+ // bool onlyAPartialLine = false) const;
1780
+ assert (e.getBaseDecl () == oe.getBaseDecl ());
1781
+ }
1782
+ assert (IndexOfFirstOuterResult == LUL.IndexOfFirstOuterResult );
1783
+ assert (recordedSF == LUL.recordedSF );
1784
+ assert (recordedName == LUL.recordedName );
1785
+ if (recordedIsCascadingUse)
1786
+ assert (LUL.recordedIsCascadingUse );
1787
+ else
1788
+ assert (!LUL.recordedIsCascadingUse );
1789
+ return true ;
1790
+ }
0 commit comments