diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Lookup.h | 7 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 40 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 21 |
4 files changed, 32 insertions, 53 deletions
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; } |