Add a member lookup criteria constructor for searching for overridden virtual member functions. Use this instead of regular name lookup when checking for overriding functions so we will see declarations that would otherwise be hidden. Fixes 6902298.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72601 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 562b2da..550a144 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2145,23 +2145,11 @@
     // Look for virtual methods in base classes that this method might override.
 
     BasePaths Paths;
-    // FIXME: This will not include hidden member functions.
     if (LookupInBases(cast<CXXRecordDecl>(DC), 
-                      MemberLookupCriteria(Name, LookupMemberName, 
-                                           // FIXME: Shouldn't IDNS_Member be
-                                           // enough here?
-                                           Decl::IDNS_Member | 
-                                           Decl::IDNS_Ordinary), Paths)) {
+                      MemberLookupCriteria(NewMD), Paths)) {
       for (BasePaths::decl_iterator I = Paths.found_decls_begin(), 
            E = Paths.found_decls_end(); I != E; ++I) {
         if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) {
-          OverloadedFunctionDecl::function_iterator MatchedDecl;
-          // FIXME: Is this OK? Should it be done by LookupInBases?
-          if (IsOverload(NewMD, OldMD, MatchedDecl))
-            continue;
-          if (!OldMD->isVirtual())
-            continue;
-         
           if (!CheckOverridingFunctionReturnType(NewMD, OldMD))
             NewMD->addOverriddenMethod(OldMD);
         }
diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp
index 5eef1eb..1eccc1f 100644
--- a/lib/Sema/SemaInherit.cpp
+++ b/lib/Sema/SemaInherit.cpp
@@ -191,6 +191,22 @@
         ++Paths.ScratchPath.Decls.first;
       }
       break;
+    case MemberLookupCriteria::LK_OverriddenMember:
+      Paths.ScratchPath.Decls = 
+        BaseRecord->lookup(Context, Criteria.Method->getDeclName());
+      while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) {
+        CXXMethodDecl *MD = 
+          cast<CXXMethodDecl>(*Paths.ScratchPath.Decls.first);
+
+        OverloadedFunctionDecl::function_iterator MatchedDecl;
+        if (MD->isVirtual() && !IsOverload(Criteria.Method, MD, MatchedDecl)) {
+          FoundPathToThisBase = true;
+          break;
+        }
+        
+        ++Paths.ScratchPath.Decls.first;
+      }
+      break;
     }
 
     if (FoundPathToThisBase) {
diff --git a/lib/Sema/SemaInherit.h b/lib/Sema/SemaInherit.h
index 3319963..b1e791a 100644
--- a/lib/Sema/SemaInherit.h
+++ b/lib/Sema/SemaInherit.h
@@ -205,7 +205,8 @@
     /// LookupKind - the kind of lookup we're doing.
     enum LookupKind {
       LK_Base,
-      LK_NamedMember
+      LK_NamedMember,
+      LK_OverriddenMember
     };
     
     /// MemberLookupCriteria - Constructs member lookup criteria to
@@ -220,6 +221,9 @@
                                   unsigned IDNS) 
       : Kind(LK_NamedMember), Name(Name), NameKind(NameKind), IDNS(IDNS) { }
 
+    explicit MemberLookupCriteria(CXXMethodDecl *MD)
+      : Kind(LK_OverriddenMember), Method(MD) { }
+    
     /// Kind - The kind of lookup we're doing.
     /// LK_Base if we are looking for a base class (whose
     /// type is Base). LK_NamedMember if we are looking for a named member of
@@ -236,6 +240,8 @@
 
     Sema::LookupNameKind NameKind;
     unsigned IDNS;
+    
+    CXXMethodDecl *Method;
   };
 }