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 /// The file must be name-bound already. If the operator is not found, or if
/// there is an ambiguity, returns null. /// 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 = {}); SourceLoc diagLoc = {});
PrefixOperatorDecl *lookupPrefixOperator(Identifier name, PrefixOperatorDecl *lookupPrefixOperator(Identifier name, bool isNonPrivate,
SourceLoc diagLoc = {}); SourceLoc diagLoc = {});
PostfixOperatorDecl *lookupPostfixOperator(Identifier name, PostfixOperatorDecl *lookupPostfixOperator(Identifier name, bool isNonPrivate,
SourceLoc diagLoc = {}); SourceLoc diagLoc = {});
/// @} /// @}

View File

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

View File

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

View File

@@ -130,13 +130,17 @@ static InfixData getInfixData(TypeChecker &TC, DeclContext *DC, Expr *E) {
} else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) { } else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
SourceFile *SF = DC->getParentSourceFile(); SourceFile *SF = DC->getParentSourceFile();
Identifier name = DRE->getDecl()->getName(); 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(); return op->getInfixData();
} else if (OverloadedDeclRefExpr *OO = dyn_cast<OverloadedDeclRefExpr>(E)) { } else if (OverloadedDeclRefExpr *OO = dyn_cast<OverloadedDeclRefExpr>(E)) {
SourceFile *SF = DC->getParentSourceFile(); SourceFile *SF = DC->getParentSourceFile();
Identifier name = OO->getDecls()[0]->getName(); 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(); return op->getInfixData();
} }

View File

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