Operator lookups may be private (non-cascading) dependencies.

This helps reduce the impact when touching a file that, say,
defines a custom ==.

Swift SVN r23718
This commit is contained in:
Jordan Rose
2014-12-05 02:24:35 +00:00
parent a4318845cc
commit 9abf77d59a
5 changed files with 33 additions and 14 deletions

View File

@@ -839,11 +839,14 @@ public:
///
/// The file must be name-bound already. If the operator is not found, or if
/// there is an ambiguity, returns null.
InfixOperatorDecl *lookupInfixOperator(Identifier name,
///
/// \param isNonPrivate If true, the lookup of this operator may affect
/// downstream files.
InfixOperatorDecl *lookupInfixOperator(Identifier name, bool isNonPrivate,
SourceLoc diagLoc = {});
PrefixOperatorDecl *lookupPrefixOperator(Identifier name,
PrefixOperatorDecl *lookupPrefixOperator(Identifier name, bool isNonPrivate,
SourceLoc diagLoc = {});
PostfixOperatorDecl *lookupPostfixOperator(Identifier name,
PostfixOperatorDecl *lookupPostfixOperator(Identifier name, bool isNonPrivate,
SourceLoc diagLoc = {});
/// @}

View File

@@ -1131,16 +1131,16 @@ Module::lookup##Kind##Operator(Identifier name, SourceLoc loc) { \
return result ? *result : nullptr; \
} \
Kind##OperatorDecl * \
SourceFile::lookup##Kind##Operator(Identifier name, SourceLoc loc) { \
SourceFile::lookup##Kind##Operator(Identifier name, bool isNonPrivate, \
SourceLoc loc) { \
auto result = lookupOperatorDeclForName(*this, loc, name, true, \
&SourceFile::Kind##Operators); \
/* FIXME: Track whether this is a private use or not. */ \
if (!result.hasValue()) \
return nullptr; \
if (ReferencedNames) {\
if (!result.getValue() || \
result.getValue()->getDeclContext()->getModuleScopeContext() != this) {\
ReferencedNames->addTopLevelName(name, true); \
ReferencedNames->addTopLevelName(name, isNonPrivate); \
} \
} \
if (!result.getValue()) { \

View File

@@ -4913,12 +4913,22 @@ public:
SourceFile &SF = *FD->getDeclContext()->getParentSourceFile();
if (FD->isUnaryOperator()) {
if (FD->getAttrs().hasAttribute<PrefixAttr>()) {
op = SF.lookupPrefixOperator(operatorName, FD->getLoc());
op = SF.lookupPrefixOperator(operatorName,
!FD->isPrivateContextForLookup(false),
FD->getLoc());
} else if (FD->getAttrs().hasAttribute<PostfixAttr>()) {
op = SF.lookupPostfixOperator(operatorName,FD->getLoc());
op = SF.lookupPostfixOperator(operatorName,
!FD->isPrivateContextForLookup(false),
FD->getLoc());
} else {
auto prefixOp = SF.lookupPrefixOperator(operatorName, FD->getLoc());
auto postfixOp = SF.lookupPostfixOperator(operatorName, FD->getLoc());
auto prefixOp =
SF.lookupPrefixOperator(operatorName,
!FD->isPrivateContextForLookup(false),
FD->getLoc());
auto postfixOp =
SF.lookupPostfixOperator(operatorName,
!FD->isPrivateContextForLookup(false),
FD->getLoc());
// If we found both prefix and postfix, or neither prefix nor postfix,
// complain. We can't fix this situation.
@@ -4967,7 +4977,9 @@ public:
static_cast<bool>(postfixOp));
}
} else if (FD->isBinaryOperator()) {
op = SF.lookupInfixOperator(operatorName, FD->getLoc());
op = SF.lookupInfixOperator(operatorName,
!FD->isPrivateContextForLookup(false),
FD->getLoc());
} else {
TC.diagnose(FD, diag::invalid_arg_count_for_operator);
return;

View File

@@ -130,13 +130,17 @@ static InfixData getInfixData(TypeChecker &TC, DeclContext *DC, Expr *E) {
} else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
SourceFile *SF = DC->getParentSourceFile();
Identifier name = DRE->getDecl()->getName();
if (InfixOperatorDecl *op = SF->lookupInfixOperator(name, E->getLoc()))
bool isPrivate = DC->isPrivateContextForLookup(true);
if (InfixOperatorDecl *op = SF->lookupInfixOperator(name, !isPrivate,
E->getLoc()))
return op->getInfixData();
} else if (OverloadedDeclRefExpr *OO = dyn_cast<OverloadedDeclRefExpr>(E)) {
SourceFile *SF = DC->getParentSourceFile();
Identifier name = OO->getDecls()[0]->getName();
if (InfixOperatorDecl *op = SF->lookupInfixOperator(name, E->getLoc()))
bool isPrivate = DC->isPrivateContextForLookup(true);
if (InfixOperatorDecl *op = SF->lookupInfixOperator(name, !isPrivate,
E->getLoc()))
return op->getInfixData();
}

View File

@@ -103,7 +103,7 @@ func lookUpManyTopLevelNames() {
// CHECK-DAG: !private "+"
let _: UInt = reduce([1,2], 0, +)
// CHECK-DAG: - "-"
// CHECK-DAG: !private "-"
let _: UInt = 3 - 2 - 1
// CHECK-DAG: !private "AliasFromOtherFile"