Add all final overriders to the map.

llvm-svn: 105374
This commit is contained in:
Anders Carlsson 2010-06-03 01:00:02 +00:00
parent 4029596f93
commit a2f74f3c98
2 changed files with 28 additions and 14 deletions

View File

@ -559,22 +559,23 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
for (; OverMethods.first != OverMethods.second; ++OverMethods.first) {
const CXXMethodDecl *CanonOM
= cast<CXXMethodDecl>((*OverMethods.first)->getCanonicalDecl());
// C++ [class.virtual]p2:
// A virtual member function C::vf of a class object S is
// a final overrider unless the most derived class (1.8)
// of which S is a base class subobject (if any) declares
// or inherits another member function that overrides vf.
//
// Treating this object like the most derived class, we
// replace any overrides from base classes with this
// overriding virtual function.
Overriders[CanonOM].replaceAll(
UniqueVirtualMethod(CanonM, SubobjectNumber,
InVirtualSubobject));
if (CanonOM->begin_overridden_methods()
== CanonOM->end_overridden_methods()) {
// C++ [class.virtual]p2:
// A virtual member function C::vf of a class object S is
// a final overrider unless the most derived class (1.8)
// of which S is a base class subobject (if any) declares
// or inherits another member function that overrides vf.
//
// Treating this object like the most derived class, we
// replace any overrides from base classes with this
// overriding virtual function.
Overriders[CanonOM].replaceAll(
UniqueVirtualMethod(CanonM, SubobjectNumber,
InVirtualSubobject));
== CanonOM->end_overridden_methods())
continue;
}
// Continue recursion to the methods that this virtual method
// overrides.
@ -582,6 +583,12 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
CanonOM->end_overridden_methods()));
}
}
// C++ [class.virtual]p2:
// For convenience we say that any virtual function overrides itself.
Overriders[CanonM].add(SubobjectNumber,
UniqueVirtualMethod(CanonM, SubobjectNumber,
InVirtualSubobject));
}
}

View File

@ -2326,6 +2326,10 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
CXXFinalOverriderMap FinalOverriders;
RD->getFinalOverriders(FinalOverriders);
// Keep a set of seen pure methods so we won't diagnose the same method
// more than once.
llvm::SmallPtrSet<const CXXMethodDecl *, 8> SeenPureMethods;
for (CXXFinalOverriderMap::iterator M = FinalOverriders.begin(),
MEnd = FinalOverriders.end();
M != MEnd;
@ -2345,6 +2349,9 @@ bool Sema::RequireNonAbstractType(SourceLocation Loc, QualType T,
if (!SO->second.front().Method->isPure())
continue;
if (!SeenPureMethods.insert(SO->second.front().Method))
continue;
Diag(SO->second.front().Method->getLocation(),
diag::note_pure_virtual_function)
<< SO->second.front().Method->getDeclName();