From: Nikola Smiljanic Date: Mon, 1 Dec 2014 23:15:01 +0000 (+0000) Subject: Perform correct lookup when '__super' is used in class with dependent base. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e03d3c217f3761218b33513bf7a4440d54d29748;p=clang Perform correct lookup when '__super' is used in class with dependent base. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@223090 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 0ad86a481f..02aa984da5 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2646,6 +2646,8 @@ public: bool AllowBuiltinCreation = false); bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup = false); + bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, + CXXScopeSpec &SS); bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation = false, bool EnteringContext = false); diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 5dbc41ecea..1f52cd87fa 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -625,7 +625,7 @@ static bool LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, } // The record definition is complete, now look up the member. - SemaRef.LookupQualifiedName(R, DC); + SemaRef.LookupQualifiedName(R, DC, SS); if (!R.empty()) return false; diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 8b0ea324e5..e1a9a554b3 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1762,6 +1762,31 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, return true; } +/// \brief Performs qualified name lookup or special type of lookup for +/// "__super::" scope specifier. +/// +/// This routine is a convenience overload meant to be called from contexts +/// that need to perform a qualified name lookup with an optional C++ scope +/// specifier that might require special kind of lookup. +/// +/// \param R captures both the lookup criteria and any lookup results found. +/// +/// \param LookupCtx The context in which qualified name lookup will +/// search. +/// +/// \param SS An optional C++ scope-specifier. +/// +/// \returns true if lookup succeeded, false if it failed. +bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, + CXXScopeSpec &SS) { + auto *NNS = SS.getScopeRep(); + if (NNS && NNS->getKind() == NestedNameSpecifier::Super) + return LookupInSuper(R, NNS->getAsRecordDecl()); + else + + return LookupQualifiedName(R, LookupCtx); +} + /// @brief Performs name lookup for a name that was parsed in the /// source code, and may contain a C++ scope specifier. /// diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 3c17bd3613..07e3137f84 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -8004,11 +8004,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword, DeclarationName Name(&II); LookupResult Result(*this, Name, IILoc, LookupOrdinaryName); - NestedNameSpecifier *NNS = SS.getScopeRep(); - if (NNS->getKind() == NestedNameSpecifier::Super) - LookupInSuper(Result, NNS->getAsRecordDecl()); - else - LookupQualifiedName(Result, Ctx); + LookupQualifiedName(Result, Ctx, SS); unsigned DiagID = 0; Decl *Referenced = nullptr; switch (Result.getResultKind()) { diff --git a/test/SemaCXX/MicrosoftSuper.cpp b/test/SemaCXX/MicrosoftSuper.cpp index 13138ca000..cb21656ab7 100644 --- a/test/SemaCXX/MicrosoftSuper.cpp +++ b/test/SemaCXX/MicrosoftSuper.cpp @@ -88,14 +88,14 @@ template struct BaseTemplate { typedef int XXX; - void foo() {} + int foo() { return 0; } }; struct DerivedFromKnownSpecialization : BaseTemplate { __super::XXX a; typedef __super::XXX b; - void test() { + void foo() { __super::XXX c; typedef __super::XXX d; @@ -111,14 +111,14 @@ struct DerivedFromDependentBase : BaseTemplate { __super::XXX c; // expected-error {{missing 'typename'}} typedef __super::XXX d; // expected-error {{missing 'typename'}} - void test() { + void foo() { typename __super::XXX e; typedef typename __super::XXX f; __super::XXX g; // expected-error {{missing 'typename'}} typedef __super::XXX h; // expected-error {{missing 'typename'}} - __super::foo(); + int x = __super::foo(); } }; @@ -130,7 +130,7 @@ struct DerivedFromTemplateParameter : T { __super::XXX c; // expected-error {{missing 'typename'}} typedef __super::XXX d; // expected-error {{missing 'typename'}} - void test() { + void foo() { typename __super::XXX e; typedef typename __super::XXX f; @@ -143,7 +143,7 @@ struct DerivedFromTemplateParameter : T { void instantiate() { DerivedFromDependentBase d; - d.test(); + d.foo(); DerivedFromTemplateParameter t; - t.test(); + t.foo(); }