aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-05-30 00:52:53 +0000
committerAnders Carlsson <andersca@mac.com>2009-05-30 00:52:53 +0000
commitd12ef8d142868889867f9dd968b5f3ea02d463c1 (patch)
treea179abe7ca42a72745c60e7cbac09d36440d755d
parentdb23b154bb62e95e63c6412965835a510c7771d1 (diff)
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
-rw-r--r--lib/Sema/SemaDecl.cpp14
-rw-r--r--lib/Sema/SemaInherit.cpp16
-rw-r--r--lib/Sema/SemaInherit.h8
-rw-r--r--test/SemaCXX/abstract.cpp23
4 files changed, 47 insertions, 14 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 562b2dab05..550a1441ac 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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);
}
diff --git a/lib/Sema/SemaInherit.cpp b/lib/Sema/SemaInherit.cpp
index 5eef1eb4c0..1eccc1f193 100644
--- a/lib/Sema/SemaInherit.cpp
+++ b/lib/Sema/SemaInherit.cpp
@@ -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) {
diff --git a/lib/Sema/SemaInherit.h b/lib/Sema/SemaInherit.h
index 3319963691..b1e791a17b 100644
--- a/lib/Sema/SemaInherit.h
+++ b/lib/Sema/SemaInherit.h
@@ -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;
};
}
diff --git a/test/SemaCXX/abstract.cpp b/test/SemaCXX/abstract.cpp
index f5ec9ab6ba..cf7322156f 100644
--- a/test/SemaCXX/abstract.cpp
+++ b/test/SemaCXX/abstract.cpp
@@ -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;
+}
+