@@ -1523,21 +1523,29 @@ Type AbstractStorageDecl::getStorageInterfaceType() const {
1523
1523
llvm_unreachable (" unhandled storage decl kind" );
1524
1524
}
1525
1525
1526
- bool DeclContext::lookupQualified (Type type,
1527
- DeclName member,
1528
- NLOptions options,
1529
- LazyResolver *typeResolver,
1530
- SmallVectorImpl<ValueDecl *> &decls) const {
1531
- using namespace namelookup ;
1532
- assert (decls.empty () && " additive lookup not supported" );
1526
+ // / Configure name lookup for the given declaration context and options.
1527
+ // /
1528
+ // / This utility is used by qualified name lookup.
1529
+ static void configureLookup (const DeclContext *dc,
1530
+ NLOptions &options,
1531
+ ReferencedNameTracker *&tracker,
1532
+ bool &isLookupCascading) {
1533
+ auto &ctx = dc->getASTContext ();
1534
+ if (!ctx.LangOpts .EnableAccessControl )
1535
+ options |= NL_IgnoreAccessControl;
1533
1536
1534
- if (!typeResolver)
1535
- typeResolver = getASTContext ().getLazyResolver ();
1536
-
1537
- auto checkLookupCascading = [this , options]() -> Optional<bool > {
1537
+ // Find the dependency tracker we'll need for this lookup.
1538
+ tracker = nullptr ;
1539
+ if (auto containingSourceFile =
1540
+ dyn_cast<SourceFile>(dc->getModuleScopeContext ())) {
1541
+ tracker = containingSourceFile->getReferencedNameTracker ();
1542
+ }
1543
+
1544
+ auto checkLookupCascading = [dc, options]() -> Optional<bool > {
1538
1545
switch (static_cast <unsigned >(options & NL_KnownDependencyMask)) {
1539
1546
case 0 :
1540
- return isCascadingContextForLookup (/* functionsAreNonCascading=*/ false );
1547
+ return dc->isCascadingContextForLookup (
1548
+ /* functionsAreNonCascading=*/ false );
1541
1549
case NL_KnownNonCascadingDependency:
1542
1550
return false ;
1543
1551
case NL_KnownCascadingDependency:
@@ -1554,14 +1562,93 @@ bool DeclContext::lookupQualified(Type type,
1554
1562
}
1555
1563
};
1556
1564
1565
+ // Determine whether a lookup here will cascade.
1566
+ isLookupCascading = false ;
1567
+ if (tracker) {
1568
+ if (auto maybeLookupCascade = checkLookupCascading ())
1569
+ isLookupCascading = maybeLookupCascade.getValue ();
1570
+ else
1571
+ tracker = nullptr ;
1572
+ }
1573
+ }
1574
+
1575
+ // / Determine whether the given declaration is an acceptable lookup
1576
+ // / result when searching from the given DeclContext.
1577
+ static bool isAcceptableLookupResult (const DeclContext *dc,
1578
+ NLOptions options,
1579
+ ValueDecl *decl,
1580
+ bool onlyCompleteObjectInits) {
1581
+ // Filter out designated initializers, if requested.
1582
+ if (onlyCompleteObjectInits) {
1583
+ if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
1584
+ if (isa<ClassDecl>(ctor->getDeclContext ()) && !ctor->isInheritable ())
1585
+ return false ;
1586
+ } else {
1587
+ return false ;
1588
+ }
1589
+ }
1590
+
1591
+ // Ignore stub implementations.
1592
+ if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
1593
+ if (ctor->hasStubImplementation ())
1594
+ return false ;
1595
+ }
1596
+
1597
+ // Check access.
1598
+ if (!(options & NL_IgnoreAccessControl)) {
1599
+ return decl->isAccessibleFrom (dc);
1600
+ }
1601
+
1602
+ return true ;
1603
+ }
1604
+
1605
+ // / Only name lookup has gathered a set of results, perform any necessary
1606
+ // / steps to prune the result set before returning it to the caller.
1607
+ static bool finishLookup (const DeclContext *dc, NLOptions options,
1608
+ SmallVectorImpl<ValueDecl *> &decls) {
1609
+ // If we're supposed to remove overridden declarations, do so now.
1610
+ if (options & NL_RemoveOverridden)
1611
+ removeOverriddenDecls (decls);
1612
+
1613
+ // If we're supposed to remove shadowed/hidden declarations, do so now.
1614
+ ModuleDecl *M = dc->getParentModule ();
1615
+ if (options & NL_RemoveNonVisible)
1616
+ removeShadowedDecls (decls, M);
1617
+
1618
+ if (auto *debugClient = M->getDebugClient ())
1619
+ filterForDiscriminator (decls, debugClient);
1620
+
1621
+ // We're done. Report success/failure.
1622
+ return !decls.empty ();
1623
+ }
1624
+
1625
+ bool DeclContext::lookupQualified (Type type,
1626
+ DeclName member,
1627
+ NLOptions options,
1628
+ LazyResolver *typeResolver,
1629
+ SmallVectorImpl<ValueDecl *> &decls) const {
1630
+ using namespace namelookup ;
1631
+ assert (decls.empty () && " additive lookup not supported" );
1632
+
1633
+ // Handle AnyObject lookup.
1634
+ if (type->isAnyObject ())
1635
+ return lookupAnyObject (member, options, decls);
1636
+
1637
+ if (!typeResolver)
1638
+ typeResolver = getASTContext ().getLazyResolver ();
1639
+
1640
+ // Configure lookup and dig out the tracker.
1641
+ ReferencedNameTracker *tracker = nullptr ;
1642
+ bool isLookupCascading;
1643
+ configureLookup (this , options, tracker, isLookupCascading);
1644
+
1557
1645
// Look for module references.
1558
1646
if (auto moduleTy = type->getAs <ModuleType>()) {
1559
1647
ModuleDecl *module = moduleTy->getModule ();
1560
1648
auto topLevelScope = getModuleScopeContext ();
1561
1649
if (module == topLevelScope->getParentModule ()) {
1562
- if (auto maybeLookupCascade = checkLookupCascading ()) {
1563
- recordLookupOfTopLevelName (topLevelScope, member,
1564
- maybeLookupCascade.getValue ());
1650
+ if (tracker) {
1651
+ recordLookupOfTopLevelName (topLevelScope, member, isLookupCascading);
1565
1652
}
1566
1653
lookupInModule (module , /* accessPath=*/ {}, member, decls,
1567
1654
NLKind::QualifiedLookup, ResolutionKind::Overloadable,
@@ -1603,10 +1690,6 @@ bool DeclContext::lookupQualified(Type type,
1603
1690
return !decls.empty ();
1604
1691
}
1605
1692
1606
- auto &ctx = getASTContext ();
1607
- if (!ctx.LangOpts .EnableAccessControl )
1608
- options |= NL_IgnoreAccessControl;
1609
-
1610
1693
// The set of nominal type declarations we should (and have) visited.
1611
1694
SmallVector<NominalTypeDecl *, 4 > stack;
1612
1695
llvm::SmallPtrSet<NominalTypeDecl *, 4 > visited;
@@ -1622,7 +1705,6 @@ bool DeclContext::lookupQualified(Type type,
1622
1705
1623
1706
// Handle nominal types.
1624
1707
bool wantProtocolMembers = (options & NL_ProtocolMembers);
1625
- bool wantLookupInAllClasses = false ;
1626
1708
if (auto nominal = type->getAnyNominal ()) {
1627
1709
visited.insert (nominal);
1628
1710
stack.push_back (nominal);
@@ -1647,10 +1729,6 @@ bool DeclContext::lookupQualified(Type type,
1647
1729
else if (auto compositionTy = type->getAs <ProtocolCompositionType>()) {
1648
1730
auto layout = compositionTy->getExistentialLayout ();
1649
1731
1650
- if (layout.isAnyObject () &&
1651
- (options & NL_DynamicLookup))
1652
- wantLookupInAllClasses = true ;
1653
-
1654
1732
for (auto proto : layout.getProtocols ()) {
1655
1733
auto *protoDecl = proto->getDecl ();
1656
1734
if (visited.insert (protoDecl).second )
@@ -1666,46 +1744,8 @@ bool DeclContext::lookupQualified(Type type,
1666
1744
llvm_unreachable (" Bad type for qualified lookup" );
1667
1745
}
1668
1746
1669
- // Allow filtering of the visible declarations based on various
1670
- // criteria.
1747
+ // Whether we only want to return complete object initializers.
1671
1748
bool onlyCompleteObjectInits = false ;
1672
- auto isAcceptableDecl = [&](NominalTypeDecl *current, ValueDecl *decl) -> bool {
1673
- // Filter out designated initializers, if requested.
1674
- if (onlyCompleteObjectInits) {
1675
- if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
1676
- if (isa<ClassDecl>(ctor->getDeclContext ()) &&
1677
- !ctor->isInheritable ())
1678
- return false ;
1679
- } else {
1680
- return false ;
1681
- }
1682
- }
1683
-
1684
- // Ignore stub implementations.
1685
- if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
1686
- if (ctor->hasStubImplementation ())
1687
- return false ;
1688
- }
1689
-
1690
- // Check access.
1691
- if (!(options & NL_IgnoreAccessControl)) {
1692
- return decl->isAccessibleFrom (this );
1693
- }
1694
-
1695
- return true ;
1696
- };
1697
-
1698
- ReferencedNameTracker *tracker = nullptr ;
1699
- if (auto containingSourceFile = dyn_cast<SourceFile>(getModuleScopeContext ()))
1700
- tracker = containingSourceFile->getReferencedNameTracker ();
1701
-
1702
- bool isLookupCascading;
1703
- if (tracker) {
1704
- if (auto maybeLookupCascade = checkLookupCascading ())
1705
- isLookupCascading = maybeLookupCascade.getValue ();
1706
- else
1707
- tracker = nullptr ;
1708
- }
1709
1749
1710
1750
// Visit all of the nominal types we know about, discovering any others
1711
1751
// we need along the way.
@@ -1732,7 +1772,8 @@ bool DeclContext::lookupQualified(Type type,
1732
1772
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(decl))
1733
1773
continue ;
1734
1774
1735
- if (isAcceptableDecl (current, decl))
1775
+ if (isAcceptableLookupResult (this , options, decl,
1776
+ onlyCompleteObjectInits))
1736
1777
decls.push_back (decl);
1737
1778
}
1738
1779
@@ -1784,66 +1825,58 @@ bool DeclContext::lookupQualified(Type type,
1784
1825
wantProtocolMembers = false ;
1785
1826
}
1786
1827
1787
- // If we want to perform lookup into all classes, do so now.
1788
- if (wantLookupInAllClasses) {
1789
- if (tracker)
1790
- tracker->addDynamicLookupName (member.getBaseName (), isLookupCascading);
1791
-
1792
- // Collect all of the visible declarations.
1793
- SmallVector<ValueDecl *, 4 > allDecls;
1794
- forAllVisibleModules (this , [&](ModuleDecl::ImportedModule import ) {
1795
- import .second ->lookupClassMember (import .first , member, allDecls);
1796
- });
1797
-
1798
- // For each declaration whose context is not something we've
1799
- // already visited above, add it to the list of declarations.
1800
- llvm::SmallPtrSet<ValueDecl *, 4 > knownDecls;
1801
- for (auto decl : allDecls) {
1802
- // If we're performing a type lookup, don't even attempt to validate
1803
- // the decl if its not a type.
1804
- if ((options & NL_OnlyTypes) && !isa<TypeDecl>(decl))
1805
- continue ;
1828
+ return finishLookup (this , options, decls);
1829
+ }
1806
1830
1807
- // If the declaration is not @objc, it cannot be called dynamically.
1808
- if (!decl->isObjC ())
1809
- continue ;
1831
+ bool DeclContext::lookupAnyObject (DeclName member, NLOptions options,
1832
+ SmallVectorImpl<ValueDecl *> &decls) const {
1833
+ // Configure lookup and dig out the tracker.
1834
+ ReferencedNameTracker *tracker = nullptr ;
1835
+ bool isLookupCascading;
1836
+ configureLookup (this , options, tracker, isLookupCascading);
1810
1837
1811
- // If the declaration has an override, name lookup will also have
1812
- // found the overridden method. Skip this declaration, because we
1813
- // prefer the overridden method.
1814
- if (decl->getOverriddenDecl ())
1815
- continue ;
1838
+ // Record this lookup.
1839
+ if (tracker)
1840
+ tracker->addDynamicLookupName (member.getBaseName (), isLookupCascading);
1816
1841
1817
- auto dc = decl->getDeclContext ();
1818
- auto nominal = dyn_cast<NominalTypeDecl>(dc);
1819
- if (!nominal) {
1820
- auto ext = cast<ExtensionDecl>(dc);
1821
- nominal = ext->getExtendedType ()->getAnyNominal ();
1822
- assert (nominal && " Couldn't find nominal type?" );
1823
- }
1842
+ // Type-only lookup won't find anything on AnyObject.
1843
+ if (options & NL_OnlyTypes)
1844
+ return false ;
1824
1845
1825
- // If we didn't visit this nominal type above, add this
1826
- // declaration to the list.
1827
- if (!visited.count (nominal) && knownDecls.insert (decl).second &&
1828
- isAcceptableDecl (nominal, decl))
1829
- decls.push_back (decl);
1830
- }
1831
- }
1846
+ // Collect all of the visible declarations.
1847
+ SmallVector<ValueDecl *, 4 > allDecls;
1848
+ forAllVisibleModules (this , [&](ModuleDecl::ImportedModule import ) {
1849
+ import .second ->lookupClassMember (import .first , member, allDecls);
1850
+ });
1832
1851
1833
- // If we're supposed to remove overridden declarations, do so now.
1834
- if (options & NL_RemoveOverridden)
1835
- removeOverriddenDecls (decls);
1852
+ // For each declaration whose context is not something we've
1853
+ // already visited above, add it to the list of declarations.
1854
+ llvm::SmallPtrSet<ValueDecl *, 4 > knownDecls;
1855
+ for (auto decl : allDecls) {
1856
+ // If the declaration is not @objc, it cannot be called dynamically.
1857
+ if (!decl->isObjC ())
1858
+ continue ;
1836
1859
1837
- // If we're supposed to remove shadowed/hidden declarations, do so now.
1838
- ModuleDecl *M = getParentModule ();
1839
- if (options & NL_RemoveNonVisible)
1840
- removeShadowedDecls (decls, M);
1860
+ // If the declaration has an override, name lookup will also have
1861
+ // found the overridden method. Skip this declaration, because we
1862
+ // prefer the overridden method.
1863
+ if (decl->getOverriddenDecl ())
1864
+ continue ;
1841
1865
1842
- if (auto *debugClient = M->getDebugClient ())
1843
- filterForDiscriminator (decls, debugClient);
1866
+ auto dc = decl->getDeclContext ();
1867
+ auto nominal = dc->getAsNominalTypeOrNominalTypeExtensionContext ();
1868
+ assert (nominal && " Couldn't find nominal type?" );
1869
+
1870
+ // If we didn't see this declaration before, and it's an acceptable
1871
+ // result, add it to the list.
1872
+ // declaration to the list.
1873
+ if (knownDecls.insert (decl).second &&
1874
+ isAcceptableLookupResult (this , options, decl,
1875
+ /* onlyCompleteObjectInits=*/ false ))
1876
+ decls.push_back (decl);
1877
+ }
1844
1878
1845
- // We're done. Report success/failure.
1846
- return !decls.empty ();
1879
+ return finishLookup (this , options, decls);
1847
1880
}
1848
1881
1849
1882
void DeclContext::lookupAllObjCMethods (
0 commit comments