]> granicus.if.org Git - clang/commitdiff
Add a member lookup criteria constructor for searching for overridden virtual member...
authorAnders Carlsson <andersca@mac.com>
Sat, 30 May 2009 00:52:53 +0000 (00:52 +0000)
committerAnders Carlsson <andersca@mac.com>
Sat, 30 May 2009 00:52:53 +0000 (00:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72601 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaInherit.cpp
lib/Sema/SemaInherit.h
test/SemaCXX/abstract.cpp

index 562b2dab0557ca62545727b433559e4262acff8b..550a1441ac951e9cc5ea79fc2ae832e0ccac183a 100644 (file)
@@ -2145,23 +2145,11 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
     // 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);
         }
index 5eef1eb4c0725af90e7924f635f2343e9055f815..1eccc1f193fbad8b7e5f83b4802f9389196fb27a 100644 (file)
@@ -191,6 +191,22 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
         ++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) {
index 33199636912ce9262002e1966b06cdfb528a9b45..b1e791a17ba34d1ffa51dcd37b289ed664936c14 100644 (file)
@@ -205,7 +205,8 @@ namespace clang {
     /// 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 @@ namespace clang {
                                   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 @@ namespace clang {
 
     Sema::LookupNameKind NameKind;
     unsigned IDNS;
+    
+    CXXMethodDecl *Method;
   };
 }
 
index f5ec9ab6ba4289fa0a5d0d164347b9e862d6163e..cf7322156fa2028a4028e2fb67e4e03fbc614197 100644 (file)
@@ -95,3 +95,26 @@ public:
 };
 
 bar x;
+
+// <rdar://problem/6902298>
+class A
+{
+public:
+       virtual void release() = 0;
+       virtual void release(int count) = 0;
+       virtual void retain() = 0;
+};
+
+class B : public A
+{
+public:
+       virtual void release();
+       virtual void release(int count);
+       virtual void retain();
+};
+
+void foo(void)
+{
+       B b;
+}
+