forked from OSchip/llvm-project
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:
parent
8a6be5ec64
commit
189d41f625
|
@ -105,26 +105,41 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
|
|||
}
|
||||
|
||||
if (SuperName) {
|
||||
ObjCInterfaceDecl* SuperClassEntry = 0;
|
||||
// Check if a different kind of symbol declared in this scope.
|
||||
PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
|
||||
if (PrevDecl && !isa<ObjCInterfaceDecl>(PrevDecl)) {
|
||||
Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
}
|
||||
else {
|
||||
// Check that super class is previously defined
|
||||
SuperClassEntry = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
|
||||
|
||||
if (!SuperClassEntry)
|
||||
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(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
}
|
||||
}
|
||||
if (!dyn_cast_or_null<TypedefDecl>(PrevDecl)) {
|
||||
if (!SuperClassDecl)
|
||||
Diag(SuperLoc, diag::err_undef_superclass)
|
||||
<< SuperName << ClassName << SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
else if (SuperClassEntry->isForwardDecl())
|
||||
else if (SuperClassDecl->isForwardDecl())
|
||||
Diag(SuperLoc, diag::err_undef_superclass)
|
||||
<< SuperClassEntry->getDeclName() << ClassName
|
||||
<< SuperClassDecl->getDeclName() << ClassName
|
||||
<< SourceRange(AtInterfaceLoc, ClassLoc);
|
||||
}
|
||||
IDecl->setSuperClass(SuperClassEntry);
|
||||
IDecl->setSuperClass(SuperClassDecl);
|
||||
IDecl->setSuperClassLoc(SuperLoc);
|
||||
IDecl->setLocEnd(SuperLoc);
|
||||
} else { // we have a root class.
|
||||
|
|
|
@ -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'}}
|
||||
|
||||
// Make sure we allow the following (for GCC compatibility).
|
||||
@interface NSObject @end
|
||||
typedef NSObject TD_NSObject;
|
||||
@interface XCElementUnit : TD_NSObject {}
|
||||
@end
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue