forked from OSchip/llvm-project
Rewrite PureVirtualMethodCollector to use the overridden methods. Fixes <rdar://problem/6854087>
llvm-svn: 71970
This commit is contained in:
parent
776a1403ed
commit
3c01271e93
|
@ -786,34 +786,38 @@ namespace {
|
|||
}
|
||||
|
||||
// Next, zero out any pure virtual methods that this class overrides.
|
||||
for (size_t i = 0, e = Methods.size(); i != e; ++i) {
|
||||
const CXXMethodDecl *VMD = dyn_cast_or_null<CXXMethodDecl>(Methods[i]);
|
||||
if (!VMD)
|
||||
continue;
|
||||
|
||||
DeclContext::lookup_const_iterator I, E;
|
||||
for (llvm::tie(I, E) = RD->lookup(Context, VMD->getDeclName());
|
||||
I != E; ++I) {
|
||||
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*I)) {
|
||||
if (Context.getCanonicalType(MD->getType()) ==
|
||||
Context.getCanonicalType(VMD->getType())) {
|
||||
// We did find a matching method, which means that this is not a
|
||||
// pure virtual method in the current class. Zero it out.
|
||||
Methods[i] = 0;
|
||||
}
|
||||
typedef llvm::SmallPtrSet<const CXXMethodDecl*, 4> MethodSetTy;
|
||||
|
||||
MethodSetTy OverriddenMethods;
|
||||
size_t MethodsSize = Methods.size();
|
||||
|
||||
for (RecordDecl::decl_iterator i = RD->decls_begin(Context),
|
||||
e = RD->decls_end(Context);
|
||||
i != e; ++i) {
|
||||
// Traverse the record, looking for methods.
|
||||
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*i)) {
|
||||
// If the method is pre virtual, add it to the methods vector.
|
||||
if (MD->isPure()) {
|
||||
Methods.push_back(MD);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, record all the overridden methods in our set.
|
||||
for (CXXMethodDecl::method_iterator I = MD->begin_overridden_methods(),
|
||||
E = MD->end_overridden_methods(); I != E; ++I) {
|
||||
// Keep track of the overridden methods.
|
||||
OverriddenMethods.insert(*I);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, add pure virtual methods from this class.
|
||||
for (RecordDecl::decl_iterator i = RD->decls_begin(Context),
|
||||
e = RD->decls_end(Context);
|
||||
i != e; ++i) {
|
||||
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(*i)) {
|
||||
if (MD->isPure())
|
||||
Methods.push_back(MD);
|
||||
}
|
||||
// Now go through the methods and zero out all the ones we know are
|
||||
// overridden.
|
||||
for (size_t i = 0, e = MethodsSize; i != e; ++i) {
|
||||
if (OverriddenMethods.count(Methods[i]))
|
||||
Methods[i] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,3 +82,16 @@ namespace N {
|
|||
class Abstract {
|
||||
virtual void f() = 0; // expected-note {{pure virtual function 'f'}}
|
||||
};
|
||||
|
||||
// <rdar://problem/6854087>
|
||||
class foo {
|
||||
public:
|
||||
virtual foo *getFoo() = 0;
|
||||
};
|
||||
|
||||
class bar : public foo {
|
||||
public:
|
||||
virtual bar *getFoo();
|
||||
};
|
||||
|
||||
bar x;
|
||||
|
|
Loading…
Reference in New Issue