aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-04-24 01:30:58 +0000
committerJohn McCall <rjmccall@apple.com>2010-04-24 01:30:58 +0000
commit76d326448d7e4c10b2896edc2ee855d1e68d1b88 (patch)
treeb1935e979807f280a84d889baee246b4d657b72f
parentba5f6eced29937e4e4851a2c0980744768413d66 (diff)
Recommit r102215, this time being more careful to only set the "principal
declaration" (i.e. the only which will actually be looked up) to have the non-member-operator bit. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102231 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/DeclBase.h15
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp5
-rw-r--r--lib/Sema/Lookup.h7
-rw-r--r--lib/Sema/SemaDecl.cpp17
-rw-r--r--lib/Sema/SemaLookup.cpp40
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp21
6 files changed, 51 insertions, 54 deletions
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 30628e692c..a9b948eee5 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -132,7 +132,12 @@ public:
/// *introduces* a number of other declarations into the current
/// scope, and those declarations use the IDNS of their targets,
/// but the actual using declarations go in this namespace.
- IDNS_Using = 0x0200
+ IDNS_Using = 0x0200,
+
+ /// This declaration is a C++ operator declared in a non-class
+ /// context. All such operators are also in IDNS_Ordinary.
+ /// C++ lexical operator lookup looks for these.
+ IDNS_NonMemberOperator = 0x0400
};
/// ObjCDeclQualifier - Qualifier used on types in method declarations
@@ -533,6 +538,14 @@ public:
FOK_Declared : FOK_Undeclared);
}
+ /// Specifies that this declaration is a C++ overloaded non-member.
+ void setNonMemberOperator() {
+ assert(getKind() == Function || getKind() == FunctionTemplate);
+ assert((IdentifierNamespace & IDNS_Ordinary) &&
+ "visible non-member operators should be in ordinary namespace");
+ IdentifierNamespace |= IDNS_NonMemberOperator;
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *) { return true; }
static bool classofKind(Kind K) { return true; }
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 45f7e496ba..53647badff 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -197,6 +197,11 @@ void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
for (unsigned I = 0; I != NumParams; ++I)
Params.push_back(cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++])));
FD->setParams(Params.data(), NumParams);
+
+ // FIXME: order this properly w.r.t. friendness
+ // FIXME: this same thing needs to happen for function templates
+ if (FD->isOverloadedOperator() && !FD->getDeclContext()->isRecord())
+ FD->setNonMemberOperator();
}
void PCHDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) {
diff --git a/lib/Sema/Lookup.h b/lib/Sema/Lookup.h
index 97bc4f25a5..0961299587 100644
--- a/lib/Sema/Lookup.h
+++ b/lib/Sema/Lookup.h
@@ -124,7 +124,6 @@ public:
};
typedef UnresolvedSetImpl::iterator iterator;
- typedef bool (*ResultFilter)(NamedDecl*, unsigned IDNS);
LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
Sema::LookupNameKind LookupKind,
@@ -136,7 +135,6 @@ public:
Name(Name),
NameLoc(NameLoc),
LookupKind(LookupKind),
- IsAcceptableFn(0),
IDNS(0),
Redecl(Redecl != Sema::NotForRedeclaration),
HideTags(true),
@@ -156,7 +154,6 @@ public:
Name(Other.Name),
NameLoc(Other.NameLoc),
LookupKind(Other.LookupKind),
- IsAcceptableFn(Other.IsAcceptableFn),
IDNS(Other.IDNS),
Redecl(Other.Redecl),
HideTags(Other.HideTags),
@@ -242,8 +239,7 @@ public:
/// \brief Tests whether the given declaration is acceptable.
bool isAcceptableDecl(NamedDecl *D) const {
- assert(IsAcceptableFn);
- return IsAcceptableFn(D, IDNS);
+ return D->isInIdentifierNamespace(IDNS);
}
/// \brief Returns the identifier namespace mask for this lookup.
@@ -575,7 +571,6 @@ private:
SourceLocation NameLoc;
SourceRange NameContextRange;
Sema::LookupNameKind LookupKind;
- ResultFilter IsAcceptableFn; // set by configure()
unsigned IDNS; // set by configure()
bool Redecl;
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 3964b755ba..cdfd0553f2 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3255,20 +3255,25 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Previous.getResultKind() != LookupResult::FoundOverloaded) &&
"previous declaration set still overloaded");
+ NamedDecl *PrincipalDecl = (FunctionTemplate
+ ? cast<NamedDecl>(FunctionTemplate)
+ : NewFD);
+
if (isFriend && Redeclaration) {
AccessSpecifier Access = AS_public;
if (!NewFD->isInvalidDecl())
Access = NewFD->getPreviousDeclaration()->getAccess();
- if (FunctionTemplate) {
- FunctionTemplate->setObjectOfFriendDecl(true);
- FunctionTemplate->setAccess(Access);
- } else {
- NewFD->setObjectOfFriendDecl(true);
- }
NewFD->setAccess(Access);
+ if (FunctionTemplate) FunctionTemplate->setAccess(Access);
+
+ PrincipalDecl->setObjectOfFriendDecl(true);
}
+ if (NewFD->isOverloadedOperator() && !DC->isRecord() &&
+ PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+ PrincipalDecl->setNonMemberOperator();
+
// If we have a function template, check the template parameter
// list. This will check and merge default template arguments.
if (FunctionTemplate) {
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index a7a1084d31..0609eef3c9 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -193,37 +193,6 @@ namespace {
};
}
-static bool IsAcceptableIDNS(NamedDecl *D, unsigned IDNS) {
- return D->isInIdentifierNamespace(IDNS);
-}
-
-static bool IsAcceptableOperatorName(NamedDecl *D, unsigned IDNS) {
- return D->isInIdentifierNamespace(IDNS) &&
- !D->getDeclContext()->isRecord();
-}
-
-/// Gets the default result filter for the given lookup.
-static inline
-LookupResult::ResultFilter getResultFilter(Sema::LookupNameKind NameKind) {
- switch (NameKind) {
- case Sema::LookupOrdinaryName:
- case Sema::LookupTagName:
- case Sema::LookupMemberName:
- case Sema::LookupRedeclarationWithLinkage: // FIXME: check linkage, scoping
- case Sema::LookupUsingDeclName:
- case Sema::LookupObjCProtocolName:
- case Sema::LookupNestedNameSpecifierName:
- case Sema::LookupNamespaceName:
- return &IsAcceptableIDNS;
-
- case Sema::LookupOperatorName:
- return &IsAcceptableOperatorName;
- }
-
- llvm_unreachable("unkknown lookup kind");
- return 0;
-}
-
// Retrieve the set of identifier namespaces that correspond to a
// specific kind of name lookup.
static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
@@ -232,7 +201,6 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
unsigned IDNS = 0;
switch (NameKind) {
case Sema::LookupOrdinaryName:
- case Sema::LookupOperatorName:
case Sema::LookupRedeclarationWithLinkage:
IDNS = Decl::IDNS_Ordinary;
if (CPlusPlus) {
@@ -241,6 +209,13 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
}
break;
+ case Sema::LookupOperatorName:
+ // Operator lookup is its own crazy thing; it is not the same
+ // as (e.g.) looking up an operator name for redeclaration.
+ assert(!Redeclaration && "cannot do redeclaration operator lookup");
+ IDNS = Decl::IDNS_NonMemberOperator;
+ break;
+
case Sema::LookupTagName:
if (CPlusPlus) {
IDNS = Decl::IDNS_Type;
@@ -287,7 +262,6 @@ void LookupResult::configure() {
IDNS = getIDNS(LookupKind,
SemaRef.getLangOptions().CPlusPlus,
isForRedeclaration());
- IsAcceptableFn = getResultFilter(LookupKind);
// If we're looking for one of the allocation or deallocation
// operators, make sure that the implicitly-declared new and delete
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index fe60be062c..d14ea1a9ff 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1124,22 +1124,27 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
isExplicitSpecialization, Redeclaration,
/*FIXME:*/OverloadableAttrRequired);
+ NamedDecl *PrincipalDecl = (TemplateParams
+ ? cast<NamedDecl>(FunctionTemplate)
+ : Function);
+
// If the original function was part of a friend declaration,
// inherit its namespace state and add it to the owner.
if (isFriend) {
- NamedDecl *ToFriendD = 0;
NamedDecl *PrevDecl;
- if (TemplateParams) {
- ToFriendD = cast<NamedDecl>(FunctionTemplate);
+ if (TemplateParams)
PrevDecl = FunctionTemplate->getPreviousDeclaration();
- } else {
- ToFriendD = Function;
+ else
PrevDecl = Function->getPreviousDeclaration();
- }
- ToFriendD->setObjectOfFriendDecl(PrevDecl != NULL);
- DC->makeDeclVisibleInContext(ToFriendD, /*Recoverable=*/ false);
+
+ PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
+ DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false);
}
+ if (Function->isOverloadedOperator() && !DC->isRecord() &&
+ PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary))
+ PrincipalDecl->setNonMemberOperator();
+
return Function;
}