Make sure redeclaration chains are properly linked, even through invalid decls. This fixes PR5415.

llvm-svn: 89777
This commit is contained in:
Sebastian Redl 2009-11-24 17:14:34 +00:00
parent dcf1962405
commit 03b67ea1a2
2 changed files with 19 additions and 2 deletions

View File

@ -91,6 +91,11 @@ public:
return D;
}
/// \brief Returns the most recent (re)declaration of this declaration.
decl_type *getMostRecentDeclaration() {
return getFirstDeclaration()->RedeclLink.getNext();
}
/// \brief Returns the most recent (re)declaration of this declaration.
const decl_type *getMostRecentDeclaration() const {
return getFirstDeclaration()->RedeclLink.getNext();
@ -102,8 +107,11 @@ public:
decl_type *First;
if (PrevDecl) {
// Point to previous.
RedeclLink = PreviousDeclLink(PrevDecl);
// Point to previous. Make sure that this is actually the most recent
// redeclaration, or we can build invalid chains. If the most recent
// redeclaration is invalid, it won't be PrevDecl, but we want it anyway.
RedeclLink = PreviousDeclLink(cast<decl_type>(
PrevDecl->getMostRecentDeclaration()));
First = PrevDecl->getFirstDeclaration();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
} else {

View File

@ -110,3 +110,12 @@ struct C4 {
void f(); // expected-note{{previous declaration is here}}
int f; // expected-error{{duplicate member 'f'}}
};
// PR5415 - don't hang!
struct S
{
void f(); // expected-note 2 {{previous declaration}}
// FIXME: the out-of-line error shouldn't be there
void S::f() {} // expected-error {{class member cannot be redeclared}} expected-error {{out-of-line}} expected-note {{previous definition}}
void f() {} // expected-error {{class member cannot be redeclared}} expected-error {{redefinition}}
};