Skip to content

Commit 4d14314

Browse files
committed
---
yaml --- r: 349146 b: refs/heads/master-next c: d992ff3 h: refs/heads/master
1 parent 3dca68d commit 4d14314

File tree

4 files changed

+107
-133
lines changed

4 files changed

+107
-133
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
refs/heads/master: 3574c513bbc5578dd9346b4ea9ab5995c5927bb5
3-
refs/heads/master-next: 62266447f2c5907d1fd10e1149a9919a9e6a03db
3+
refs/heads/master-next: d992ff367b6a47e1370f4cfaa169bc85d84e3d13
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea
66
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-b: 66d897bfcf64a82cb9a87f5e663d889189d06d07

branches/master-next/lib/Sema/TypeCheckDecl.cpp

Lines changed: 102 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "swift/Parse/Parser.h"
4747
#include "swift/Serialization/SerializedModuleLoader.h"
4848
#include "swift/Strings.h"
49+
#include "swift/AST/NameLookupRequests.h"
4950
#include "swift/AST/TypeCheckRequests.h"
5051
#include "swift/Basic/Defer.h"
5152
#include "llvm/ADT/APFloat.h"
@@ -1613,15 +1614,15 @@ swift::findNonImplicitRequiredInit(const ConstructorDecl *CD) {
16131614
return CD;
16141615
}
16151616

1616-
16171617
/// For building the higher-than component of the diagnostic path,
16181618
/// we use the visited set, which we've embellished with information
16191619
/// about how we reached a particular node. This is reasonable because
16201620
/// 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) {
16251626
auto it = visitedFrom.find(last);
16261627
assert(it != visitedFrom.end());
16271628
auto from = it->second;
@@ -1634,8 +1635,7 @@ static void buildHigherThanPath(PrecedenceGroupDecl *last,
16341635
/// For building the lower-than component of the diagnostic path,
16351636
/// we just do a depth-first search to find a path.
16361637
static bool buildLowerThanPath(PrecedenceGroupDecl *start,
1637-
PrecedenceGroupDecl *target,
1638-
raw_ostream &out) {
1638+
PrecedenceGroupDecl *target, raw_ostream &out) {
16391639
if (start == target) {
16401640
out << start->getName();
16411641
return true;
@@ -1654,20 +1654,21 @@ static bool buildLowerThanPath(PrecedenceGroupDecl *start,
16541654
return false;
16551655
}
16561656

1657-
static void checkPrecedenceCircularity(TypeChecker &TC,
1657+
static void checkPrecedenceCircularity(DiagnosticEngine &D,
16581658
PrecedenceGroupDecl *PGD) {
16591659
// Don't diagnose if this group is already marked invalid.
1660-
if (PGD->isInvalid()) return;
1660+
if (PGD->isInvalid())
1661+
return;
16611662

16621663
// The cycle doesn't necessarily go through this specific group,
16631664
// so we need a proper visited set to avoid infinite loops. We
16641665
// also record a back-reference so that we can easily reconstruct
16651666
// the cycle.
1666-
llvm::DenseMap<PrecedenceGroupDecl*, PrecedenceGroupDecl*> visitedFrom;
1667-
SmallVector<PrecedenceGroupDecl*, 4> stack;
1667+
llvm::DenseMap<PrecedenceGroupDecl *, PrecedenceGroupDecl *> visitedFrom;
1668+
SmallVector<PrecedenceGroupDecl *, 4> stack;
16681669

16691670
// Fill out the targets set.
1670-
llvm::SmallPtrSet<PrecedenceGroupDecl*, 4> targets;
1671+
llvm::SmallPtrSet<PrecedenceGroupDecl *, 4> targets;
16711672
stack.push_back(PGD);
16721673
do {
16731674
auto cur = stack.pop_back_val();
@@ -1681,7 +1682,8 @@ static void checkPrecedenceCircularity(TypeChecker &TC,
16811682
targets.insert(cur);
16821683

16831684
for (auto &rel : cur->getLowerThan()) {
1684-
if (!rel.Group) continue;
1685+
if (!rel.Group)
1686+
continue;
16851687

16861688
// We can't have cycles in the lower-than relationship
16871689
// because it has to point outside of the module.
@@ -1704,7 +1706,8 @@ static void checkPrecedenceCircularity(TypeChecker &TC,
17041706
}
17051707

17061708
for (auto &rel : cur->getHigherThan()) {
1707-
if (!rel.Group) continue;
1709+
if (!rel.Group)
1710+
continue;
17081711

17091712
// Check whether we've reached a target declaration.
17101713
if (!targets.count(rel.Group)) {
@@ -1730,40 +1733,20 @@ static void checkPrecedenceCircularity(TypeChecker &TC,
17301733
// Build the lowerThan portion of the path (rel.Group -> PGD).
17311734
buildLowerThanPath(PGD, rel.Group, str);
17321735
}
1733-
1734-
TC.diagnose(PGD->getHigherThanLoc(), diag::precedence_group_cycle, path);
1736+
1737+
D.diagnose(PGD->getHigherThanLoc(), diag::precedence_group_cycle, path);
17351738
PGD->setInvalid();
17361739
return;
17371740
}
17381741
} while (!stack.empty());
17391742
}
17401743

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!");
17611746
if (PGD->isInvalid() || PGD->hasValidationStarted())
17621747
return;
17631748
DeclValidationRAII IBV(PGD);
17641749

1765-
bool isInvalid = false;
1766-
17671750
auto &Diags = PGD->getASTContext().Diags;
17681751

17691752
// Validate the higherThan relationships.
@@ -1775,7 +1758,6 @@ void TypeChecker::validateDecl(PrecedenceGroupDecl *PGD) {
17751758
rel.Name, rel.NameLoc);
17761759
if (group) {
17771760
rel.Group = group;
1778-
validateDecl(group);
17791761
addedHigherThan = true;
17801762
} else if (!PGD->isInvalid()) {
17811763
Diags.diagnose(rel.NameLoc, diag::unknown_precedence_group, rel.Name);
@@ -1790,42 +1772,37 @@ void TypeChecker::validateDecl(PrecedenceGroupDecl *PGD) {
17901772
auto dc = PGD->getDeclContext();
17911773
auto group = TypeChecker::lookupPrecedenceGroup(dc, rel.Name, rel.NameLoc);
17921774
if (group) {
1793-
if (group->getDeclContext()->getParentModule()
1794-
== dc->getParentModule()) {
1775+
if (group->getDeclContext()->getParentModule() == dc->getParentModule()) {
17951776
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();
18001782
}
18011783
} else {
18021784
rel.Group = group;
1803-
validateDecl(group);
18041785
}
18051786
} 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();
18081789
}
18091790
}
1810-
1791+
18111792
// Check for circularity.
18121793
if (addedHigherThan) {
1813-
checkPrecedenceCircularity(*this, PGD);
1794+
checkPrecedenceCircularity(Diags, PGD);
18141795
}
1815-
1816-
if (isInvalid) PGD->setInvalid();
18171796
}
18181797

18191798
PrecedenceGroupDecl *TypeChecker::lookupPrecedenceGroup(DeclContext *dc,
18201799
Identifier name,
18211800
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);
18291806
return group;
18301807
}
18311808

@@ -1872,85 +1849,70 @@ static bool checkDesignatedTypes(OperatorDecl *OD,
18721849
/// This establishes key invariants, such as an InfixOperatorDecl's
18731850
/// reference to its precedence group and the transitive validity of that
18741851
/// 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 {
18801855
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;
18941860

1895-
if (!IOD->getPrecedenceGroup()) {
1896-
PrecedenceGroupDecl *group = nullptr;
1861+
auto identifiers = IOD->getIdentifiers();
1862+
auto identifierLocs = IOD->getIdentifierLocs();
18971863

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]);
19001867

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]);
19051882
identifiers = identifiers.slice(1);
19061883
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-
}
19211884
}
19221885
}
1886+
}
19231887

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+
}
19321896

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+
}
19371902

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+
}
19451907

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();
19521913
}
19531914
}
1915+
return group;
19541916
}
19551917

19561918
llvm::Expected<SelfAccessKind>
@@ -2115,12 +2077,26 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
21152077
}
21162078

21172079
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+
}
21192094
checkAccessControl(TC, OD);
21202095
}
21212096

21222097
void visitPrecedenceGroupDecl(PrecedenceGroupDecl *PGD) {
2123-
TC.validateDecl(PGD);
2098+
TC.checkDeclAttributes(PGD);
2099+
validatePrecedenceGroup(PGD);
21242100
checkAccessControl(TC, PGD);
21252101
}
21262102

branches/master-next/lib/Sema/TypeChecker.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -782,8 +782,6 @@ class TypeChecker final : public LazyResolver {
782782
DeclContext *DC);
783783

784784
void validateDecl(ValueDecl *D);
785-
void validateDecl(OperatorDecl *decl);
786-
void validateDecl(PrecedenceGroupDecl *decl);
787785

788786
/// Validate the given extension declaration, ensuring that it
789787
/// properly extends the nominal type it names.

0 commit comments

Comments
 (0)