]> granicus.if.org Git - clang/commitdiff
Perform correct lookup when '__super' is used in class with dependent base.
authorNikola Smiljanic <popizdeh@gmail.com>
Mon, 1 Dec 2014 23:15:01 +0000 (23:15 +0000)
committerNikola Smiljanic <popizdeh@gmail.com>
Mon, 1 Dec 2014 23:15:01 +0000 (23:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@223090 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaExprMember.cpp
lib/Sema/SemaLookup.cpp
lib/Sema/SemaTemplate.cpp
test/SemaCXX/MicrosoftSuper.cpp

index 0ad86a481fa8dffb54f1c74bf4b71d7dab986276..02aa984da5608d02ff5720a823f7a2e03e13d851 100644 (file)
@@ -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);
index 5dbc41ecea9ddc04f9b3c4e629137688022f1d3b..1f52cd87faeb02379237cff74c669ecf55ba5bb4 100644 (file)
@@ -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;
index 8b0ea324e5f071cbb8cef134309b2034379cef67..e1a9a554b34ce0d2fcf490764cd9902ff3386f70 100644 (file)
@@ -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.
 ///
index 3c17bd3613309ae2ee5f987711e5215b2be8f964..07e3137f845d14ea6a5cfeecc16798236bbb5e29 100644 (file)
@@ -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()) {
index 13138ca0004de3268fabd16590fd4de6dd19373e..cb21656ab762a93e41cf26965e1ab387712165d7 100644 (file)
@@ -88,14 +88,14 @@ template <typename T>
 struct BaseTemplate {
   typedef int XXX;
 
-  void foo() {}
+  int foo() { return 0; }
 };
 
 struct DerivedFromKnownSpecialization : BaseTemplate<int> {
   __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<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;
 
     __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<int> d;
-  d.test();
+  d.foo();
   DerivedFromTemplateParameter<Base1> t;
-  t.test();
+  t.foo();
 }