Fix <rdar://problem/6552648> error: redefinition of 'XCElementAnchorDelegate' as different kind of symbol.

At first glance, this looked like a recent regression (possibly created by http://llvm.org/viewvc/llvm-project?view=rev&revision=63354, which was the only recent change to this section of Sema::ActOnStartClassInterface()). After more investigation, it looks like an edge case bug that we didn't cover in our tests.

llvm-svn: 63738
This commit is contained in:
Steve Naroff 2009-02-04 17:14:05 +00:00
parent 8a6be5ec64
commit 189d41f625
2 changed files with 34 additions and 12 deletions

View File

@ -105,26 +105,41 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
} }
if (SuperName) { if (SuperName) {
ObjCInterfaceDecl* SuperClassEntry = 0;
// Check if a different kind of symbol declared in this scope. // Check if a different kind of symbol declared in this scope.
PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName); PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
ObjCInterfaceDecl *SuperClassDecl =
dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
if (PrevDecl && SuperClassDecl == 0) {
// The previous declaration was not a class decl. Check if we have a
// typedef. If we do, get the underlying class type.
if (const TypedefDecl *TDecl = dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
QualType T = TDecl->getUnderlyingType();
if (T->isObjCInterfaceType()) {
if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl())
SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
}
}
// This handles the following case:
//
// typedef int SuperClass;
// @interface MyClass : SuperClass {} @end
//
if (!SuperClassDecl) {
Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName; Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
Diag(PrevDecl->getLocation(), diag::note_previous_definition); Diag(PrevDecl->getLocation(), diag::note_previous_definition);
} }
else { }
// Check that super class is previously defined if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
SuperClassEntry = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl); if (!SuperClassDecl)
if (!SuperClassEntry)
Diag(SuperLoc, diag::err_undef_superclass) Diag(SuperLoc, diag::err_undef_superclass)
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc); << SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
else if (SuperClassEntry->isForwardDecl()) else if (SuperClassDecl->isForwardDecl())
Diag(SuperLoc, diag::err_undef_superclass) Diag(SuperLoc, diag::err_undef_superclass)
<< SuperClassEntry->getDeclName() << ClassName << SuperClassDecl->getDeclName() << ClassName
<< SourceRange(AtInterfaceLoc, ClassLoc); << SourceRange(AtInterfaceLoc, ClassLoc);
} }
IDecl->setSuperClass(SuperClassEntry); IDecl->setSuperClass(SuperClassDecl);
IDecl->setSuperClassLoc(SuperLoc); IDecl->setSuperClassLoc(SuperLoc);
IDecl->setLocEnd(SuperLoc); IDecl->setLocEnd(SuperLoc);
} else { // we have a root class. } else { // we have a root class.

View File

@ -24,3 +24,10 @@ typedef int OBJECT; // expected-note {{previous definition is here}} \
@interface INTF3 : PROTO @end // expected-error {{cannot find interface declaration for 'PROTO', superclass of 'INTF3'}} @interface INTF3 : PROTO @end // expected-error {{cannot find interface declaration for 'PROTO', superclass of 'INTF3'}}
// Make sure we allow the following (for GCC compatibility).
@interface NSObject @end
typedef NSObject TD_NSObject;
@interface XCElementUnit : TD_NSObject {}
@end