From 76d326448d7e4c10b2896edc2ee855d1e68d1b88 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sat, 24 Apr 2010 01:30:58 +0000 Subject: [PATCH] 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 --- include/clang/AST/DeclBase.h | 15 ++++++++- lib/Frontend/PCHReaderDecl.cpp | 5 +++ lib/Sema/Lookup.h | 7 +---- lib/Sema/SemaDecl.cpp | 17 ++++++---- lib/Sema/SemaLookup.cpp | 40 +++++------------------- lib/Sema/SemaTemplateInstantiateDecl.cpp | 21 ++++++++----- 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(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(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(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(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; } -- 2.40.0