46
46
#include " swift/Parse/Parser.h"
47
47
#include " swift/Serialization/SerializedModuleLoader.h"
48
48
#include " swift/Strings.h"
49
+ #include " swift/AST/NameLookupRequests.h"
49
50
#include " swift/AST/TypeCheckRequests.h"
50
51
#include " swift/Basic/Defer.h"
51
52
#include " llvm/ADT/APFloat.h"
@@ -1613,15 +1614,15 @@ swift::findNonImplicitRequiredInit(const ConstructorDecl *CD) {
1613
1614
return CD;
1614
1615
}
1615
1616
1616
-
1617
1617
// / For building the higher-than component of the diagnostic path,
1618
1618
// / we use the visited set, which we've embellished with information
1619
1619
// / about how we reached a particular node. This is reasonable because
1620
1620
// / we need to maintain the set anyway.
1621
- static void buildHigherThanPath (PrecedenceGroupDecl *last,
1622
- const llvm::DenseMap<PrecedenceGroupDecl *,
1623
- PrecedenceGroupDecl *> &visitedFrom,
1624
- raw_ostream &out) {
1621
+ static void buildHigherThanPath (
1622
+ PrecedenceGroupDecl *last,
1623
+ const llvm::DenseMap<PrecedenceGroupDecl *, PrecedenceGroupDecl *>
1624
+ &visitedFrom,
1625
+ raw_ostream &out) {
1625
1626
auto it = visitedFrom.find (last);
1626
1627
assert (it != visitedFrom.end ());
1627
1628
auto from = it->second ;
@@ -1634,8 +1635,7 @@ static void buildHigherThanPath(PrecedenceGroupDecl *last,
1634
1635
// / For building the lower-than component of the diagnostic path,
1635
1636
// / we just do a depth-first search to find a path.
1636
1637
static bool buildLowerThanPath (PrecedenceGroupDecl *start,
1637
- PrecedenceGroupDecl *target,
1638
- raw_ostream &out) {
1638
+ PrecedenceGroupDecl *target, raw_ostream &out) {
1639
1639
if (start == target) {
1640
1640
out << start->getName ();
1641
1641
return true ;
@@ -1654,20 +1654,21 @@ static bool buildLowerThanPath(PrecedenceGroupDecl *start,
1654
1654
return false ;
1655
1655
}
1656
1656
1657
- static void checkPrecedenceCircularity (TypeChecker &TC ,
1657
+ static void checkPrecedenceCircularity (DiagnosticEngine &D ,
1658
1658
PrecedenceGroupDecl *PGD) {
1659
1659
// Don't diagnose if this group is already marked invalid.
1660
- if (PGD->isInvalid ()) return ;
1660
+ if (PGD->isInvalid ())
1661
+ return ;
1661
1662
1662
1663
// The cycle doesn't necessarily go through this specific group,
1663
1664
// so we need a proper visited set to avoid infinite loops. We
1664
1665
// also record a back-reference so that we can easily reconstruct
1665
1666
// the cycle.
1666
- llvm::DenseMap<PrecedenceGroupDecl*, PrecedenceGroupDecl*> visitedFrom;
1667
- SmallVector<PrecedenceGroupDecl*, 4 > stack;
1667
+ llvm::DenseMap<PrecedenceGroupDecl *, PrecedenceGroupDecl *> visitedFrom;
1668
+ SmallVector<PrecedenceGroupDecl *, 4 > stack;
1668
1669
1669
1670
// Fill out the targets set.
1670
- llvm::SmallPtrSet<PrecedenceGroupDecl*, 4 > targets;
1671
+ llvm::SmallPtrSet<PrecedenceGroupDecl *, 4 > targets;
1671
1672
stack.push_back (PGD);
1672
1673
do {
1673
1674
auto cur = stack.pop_back_val ();
@@ -1681,7 +1682,8 @@ static void checkPrecedenceCircularity(TypeChecker &TC,
1681
1682
targets.insert (cur);
1682
1683
1683
1684
for (auto &rel : cur->getLowerThan ()) {
1684
- if (!rel.Group ) continue ;
1685
+ if (!rel.Group )
1686
+ continue ;
1685
1687
1686
1688
// We can't have cycles in the lower-than relationship
1687
1689
// because it has to point outside of the module.
@@ -1704,7 +1706,8 @@ static void checkPrecedenceCircularity(TypeChecker &TC,
1704
1706
}
1705
1707
1706
1708
for (auto &rel : cur->getHigherThan ()) {
1707
- if (!rel.Group ) continue ;
1709
+ if (!rel.Group )
1710
+ continue ;
1708
1711
1709
1712
// Check whether we've reached a target declaration.
1710
1713
if (!targets.count (rel.Group )) {
@@ -1730,40 +1733,20 @@ static void checkPrecedenceCircularity(TypeChecker &TC,
1730
1733
// Build the lowerThan portion of the path (rel.Group -> PGD).
1731
1734
buildLowerThanPath (PGD, rel.Group , str);
1732
1735
}
1733
-
1734
- TC .diagnose (PGD->getHigherThanLoc (), diag::precedence_group_cycle, path);
1736
+
1737
+ D .diagnose (PGD->getHigherThanLoc (), diag::precedence_group_cycle, path);
1735
1738
PGD->setInvalid ();
1736
1739
return ;
1737
1740
}
1738
1741
} while (!stack.empty ());
1739
1742
}
1740
1743
1741
- // / Do a primitive lookup for the given precedence group. This does
1742
- // / not validate the precedence group or diagnose if the lookup fails
1743
- // / (other than via ambiguity); for that, use
1744
- // / TypeChecker::lookupPrecedenceGroup.
1745
- // /
1746
- // / Pass an invalid source location to suppress diagnostics.
1747
- static PrecedenceGroupDecl *
1748
- lookupPrecedenceGroupPrimitive (DeclContext *dc, Identifier name,
1749
- SourceLoc nameLoc) {
1750
- if (auto sf = dc->getParentSourceFile ()) {
1751
- bool cascading = dc->isCascadingContextForLookup (false );
1752
- return sf->lookupPrecedenceGroup (name, cascading, nameLoc);
1753
- } else {
1754
- return dc->getParentModule ()->lookupPrecedenceGroup (name, nameLoc);
1755
- }
1756
- }
1757
-
1758
- void TypeChecker::validateDecl (PrecedenceGroupDecl *PGD) {
1759
- checkDeclAttributes (PGD);
1760
-
1744
+ static void validatePrecedenceGroup (PrecedenceGroupDecl *PGD) {
1745
+ assert (PGD && " Cannot validate a null precedence group!" );
1761
1746
if (PGD->isInvalid () || PGD->hasValidationStarted ())
1762
1747
return ;
1763
1748
DeclValidationRAII IBV (PGD);
1764
1749
1765
- bool isInvalid = false ;
1766
-
1767
1750
auto &Diags = PGD->getASTContext ().Diags ;
1768
1751
1769
1752
// Validate the higherThan relationships.
@@ -1775,7 +1758,6 @@ void TypeChecker::validateDecl(PrecedenceGroupDecl *PGD) {
1775
1758
rel.Name , rel.NameLoc );
1776
1759
if (group) {
1777
1760
rel.Group = group;
1778
- validateDecl (group);
1779
1761
addedHigherThan = true ;
1780
1762
} else if (!PGD->isInvalid ()) {
1781
1763
Diags.diagnose (rel.NameLoc , diag::unknown_precedence_group, rel.Name );
@@ -1790,42 +1772,37 @@ void TypeChecker::validateDecl(PrecedenceGroupDecl *PGD) {
1790
1772
auto dc = PGD->getDeclContext ();
1791
1773
auto group = TypeChecker::lookupPrecedenceGroup (dc, rel.Name , rel.NameLoc );
1792
1774
if (group) {
1793
- if (group->getDeclContext ()->getParentModule ()
1794
- == dc->getParentModule ()) {
1775
+ if (group->getDeclContext ()->getParentModule () == dc->getParentModule ()) {
1795
1776
if (!PGD->isInvalid ()) {
1796
- diagnose (rel.NameLoc , diag::precedence_group_lower_within_module);
1797
- diagnose (group->getNameLoc (), diag::kind_declared_here,
1798
- DescriptiveDeclKind::PrecedenceGroup);
1799
- isInvalid = true ;
1777
+ Diags.diagnose (rel.NameLoc ,
1778
+ diag::precedence_group_lower_within_module);
1779
+ Diags.diagnose (group->getNameLoc (), diag::kind_declared_here,
1780
+ DescriptiveDeclKind::PrecedenceGroup);
1781
+ PGD->setInvalid ();
1800
1782
}
1801
1783
} else {
1802
1784
rel.Group = group;
1803
- validateDecl (group);
1804
1785
}
1805
1786
} else if (!PGD->isInvalid ()) {
1806
- diagnose (rel.NameLoc , diag::unknown_precedence_group, rel.Name );
1807
- isInvalid = true ;
1787
+ Diags. diagnose (rel.NameLoc , diag::unknown_precedence_group, rel.Name );
1788
+ PGD-> setInvalid () ;
1808
1789
}
1809
1790
}
1810
-
1791
+
1811
1792
// Check for circularity.
1812
1793
if (addedHigherThan) {
1813
- checkPrecedenceCircularity (* this , PGD);
1794
+ checkPrecedenceCircularity (Diags , PGD);
1814
1795
}
1815
-
1816
- if (isInvalid) PGD->setInvalid ();
1817
1796
}
1818
1797
1819
1798
PrecedenceGroupDecl *TypeChecker::lookupPrecedenceGroup (DeclContext *dc,
1820
1799
Identifier name,
1821
1800
SourceLoc nameLoc) {
1822
- auto group = lookupPrecedenceGroupPrimitive (dc, name, nameLoc);
1823
- if (group) {
1824
- validateDecl (group);
1825
- } else if (nameLoc.isValid ()) {
1826
- // FIXME: avoid diagnosing this multiple times per source file.
1827
- diagnose (nameLoc, diag::unknown_precedence_group, name);
1828
- }
1801
+ auto *group = evaluateOrDefault (
1802
+ dc->getASTContext ().evaluator ,
1803
+ LookupPrecedenceGroupRequest ({dc, name, nameLoc}), nullptr );
1804
+ if (group)
1805
+ validatePrecedenceGroup (group);
1829
1806
return group;
1830
1807
}
1831
1808
@@ -1872,85 +1849,70 @@ static bool checkDesignatedTypes(OperatorDecl *OD,
1872
1849
// / This establishes key invariants, such as an InfixOperatorDecl's
1873
1850
// / reference to its precedence group and the transitive validity of that
1874
1851
// / group.
1875
- void TypeChecker::validateDecl (OperatorDecl *OD) {
1876
- checkDeclAttributes (OD);
1877
-
1878
- auto IOD = dyn_cast<InfixOperatorDecl>(OD);
1879
-
1852
+ llvm::Expected<PrecedenceGroupDecl *>
1853
+ OperatorPrecedenceGroupRequest::evaluate (Evaluator &evaluator,
1854
+ InfixOperatorDecl *IOD) const {
1880
1855
auto enableOperatorDesignatedTypes =
1881
- getLangOpts ().EnableOperatorDesignatedTypes ;
1882
-
1883
- // Pre- or post-fix operator?
1884
- if (!IOD) {
1885
- auto nominalTypes = OD->getDesignatedNominalTypes ();
1886
- if (nominalTypes.empty () && enableOperatorDesignatedTypes) {
1887
- auto identifiers = OD->getIdentifiers ();
1888
- auto identifierLocs = OD->getIdentifierLocs ();
1889
- if (checkDesignatedTypes (OD, identifiers, identifierLocs, *this ))
1890
- OD->setInvalid ();
1891
- }
1892
- return ;
1893
- }
1856
+ IOD->getASTContext ().LangOpts .EnableOperatorDesignatedTypes ;
1857
+
1858
+ auto &Diags = IOD->getASTContext ().Diags ;
1859
+ PrecedenceGroupDecl *group = nullptr ;
1894
1860
1895
- if (! IOD->getPrecedenceGroup ()) {
1896
- PrecedenceGroupDecl *group = nullptr ;
1861
+ auto identifiers = IOD->getIdentifiers ();
1862
+ auto identifierLocs = IOD-> getIdentifierLocs () ;
1897
1863
1898
- auto identifiers = IOD->getIdentifiers ();
1899
- auto identifierLocs = IOD->getIdentifierLocs ();
1864
+ if (!identifiers.empty ()) {
1865
+ group = TypeChecker::lookupPrecedenceGroup (
1866
+ IOD->getDeclContext (), identifiers[0 ], identifierLocs[0 ]);
1900
1867
1901
- if (!identifiers.empty ()) {
1902
- group = lookupPrecedenceGroupPrimitive (IOD->getDeclContext (),
1903
- identifiers[0 ], identifierLocs[0 ]);
1904
- if (group) {
1868
+ if (group) {
1869
+ identifiers = identifiers.slice (1 );
1870
+ identifierLocs = identifierLocs.slice (1 );
1871
+ } else {
1872
+ // If we're either not allowing types, or we are allowing them
1873
+ // and this identifier is not a type, emit an error as if it's
1874
+ // a precedence group.
1875
+ auto *DC = IOD->getDeclContext ();
1876
+ if (!(enableOperatorDesignatedTypes &&
1877
+ resolveSingleNominalTypeDecl (DC, identifierLocs[0 ], identifiers[0 ],
1878
+ IOD->getASTContext (),
1879
+ TypeResolutionFlags::SilenceErrors))) {
1880
+ Diags.diagnose (identifierLocs[0 ], diag::unknown_precedence_group,
1881
+ identifiers[0 ]);
1905
1882
identifiers = identifiers.slice (1 );
1906
1883
identifierLocs = identifierLocs.slice (1 );
1907
- } else {
1908
- // If we're either not allowing types, or we are allowing them
1909
- // and this identifier is not a type, emit an error as if it's
1910
- // a precedence group.
1911
- auto *DC = OD->getDeclContext ();
1912
- if (!(enableOperatorDesignatedTypes &&
1913
- resolveSingleNominalTypeDecl (
1914
- DC, identifierLocs[0 ], identifiers[0 ], *this ,
1915
- TypeResolutionFlags::SilenceErrors))) {
1916
- diagnose (identifierLocs[0 ], diag::unknown_precedence_group,
1917
- identifiers[0 ]);
1918
- identifiers = identifiers.slice (1 );
1919
- identifierLocs = identifierLocs.slice (1 );
1920
- }
1921
1884
}
1922
1885
}
1886
+ }
1923
1887
1924
- if (!identifiers.empty () && !enableOperatorDesignatedTypes) {
1925
- assert (!group);
1926
- diagnose (identifierLocs[0 ], diag::unknown_precedence_group,
1927
- identifiers[0 ]);
1928
- identifiers = identifiers.slice (1 );
1929
- identifierLocs = identifierLocs.slice (1 );
1930
- assert (identifiers.empty () && identifierLocs.empty ());
1931
- }
1888
+ if (!identifiers.empty () && !enableOperatorDesignatedTypes) {
1889
+ assert (!group);
1890
+ Diags. diagnose (identifierLocs[0 ], diag::unknown_precedence_group,
1891
+ identifiers[0 ]);
1892
+ identifiers = identifiers.slice (1 );
1893
+ identifierLocs = identifierLocs.slice (1 );
1894
+ assert (identifiers.empty () && identifierLocs.empty ());
1895
+ }
1932
1896
1933
- if (!group) {
1934
- group = lookupPrecedenceGroupPrimitive (
1935
- IOD->getDeclContext (), Context.Id_DefaultPrecedence , SourceLoc ());
1936
- }
1897
+ if (!group) {
1898
+ group = TypeChecker::lookupPrecedenceGroup (
1899
+ IOD->getDeclContext (), IOD->getASTContext ().Id_DefaultPrecedence ,
1900
+ SourceLoc ());
1901
+ }
1937
1902
1938
- if (group) {
1939
- validateDecl (group);
1940
- IOD->setPrecedenceGroup (group);
1941
- } else {
1942
- diagnose (IOD->getLoc (), diag::missing_builtin_precedence_group,
1943
- Context.Id_DefaultPrecedence );
1944
- }
1903
+ if (!group) {
1904
+ Diags.diagnose (IOD->getLoc (), diag::missing_builtin_precedence_group,
1905
+ IOD->getASTContext ().Id_DefaultPrecedence );
1906
+ }
1945
1907
1946
- auto nominalTypes = IOD->getDesignatedNominalTypes ();
1947
- if (nominalTypes.empty () && enableOperatorDesignatedTypes) {
1948
- if (checkDesignatedTypes (IOD, identifiers, identifierLocs, *this )) {
1949
- IOD->setInvalid ();
1950
- return ;
1951
- }
1908
+ auto nominalTypes = IOD->getDesignatedNominalTypes ();
1909
+ if (nominalTypes.empty () && enableOperatorDesignatedTypes) {
1910
+ if (checkDesignatedTypes (IOD, identifiers, identifierLocs,
1911
+ IOD->getASTContext ())) {
1912
+ IOD->setInvalid ();
1952
1913
}
1953
1914
}
1915
+ return group;
1954
1916
}
1955
1917
1956
1918
llvm::Expected<SelfAccessKind>
@@ -2115,12 +2077,26 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
2115
2077
}
2116
2078
2117
2079
void visitOperatorDecl (OperatorDecl *OD) {
2118
- TC.validateDecl (OD);
2080
+ TC.checkDeclAttributes (OD);
2081
+ auto &Ctx = OD->getASTContext ();
2082
+ if (auto *IOD = dyn_cast<InfixOperatorDecl>(OD)) {
2083
+ (void )IOD->getPrecedenceGroup ();
2084
+ } else {
2085
+ auto nominalTypes = OD->getDesignatedNominalTypes ();
2086
+ if (nominalTypes.empty () && Ctx.LangOpts .EnableOperatorDesignatedTypes ) {
2087
+ auto identifiers = OD->getIdentifiers ();
2088
+ auto identifierLocs = OD->getIdentifierLocs ();
2089
+ if (checkDesignatedTypes (OD, identifiers, identifierLocs, Ctx))
2090
+ OD->setInvalid ();
2091
+ }
2092
+ return ;
2093
+ }
2119
2094
checkAccessControl (TC, OD);
2120
2095
}
2121
2096
2122
2097
void visitPrecedenceGroupDecl (PrecedenceGroupDecl *PGD) {
2123
- TC.validateDecl (PGD);
2098
+ TC.checkDeclAttributes (PGD);
2099
+ validatePrecedenceGroup (PGD);
2124
2100
checkAccessControl (TC, PGD);
2125
2101
}
2126
2102
0 commit comments