More Sema check for ivars in class continuation.

llvm-svn: 97002
This commit is contained in:
Fariborz Jahanian 2010-02-23 23:41:11 +00:00
parent 625916df32
commit 545643c309
4 changed files with 64 additions and 15 deletions

View File

@ -1440,6 +1440,8 @@ public:
void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl,
ObjCContainerDecl* IDecl);
void DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID, ObjCInterfaceDecl *SID);
/// MatchTwoMethodDeclarations - Checks if two methods' type match and returns
/// true, or false, accordingly.
bool MatchTwoMethodDeclarations(const ObjCMethodDecl *Method,

View File

@ -5659,21 +5659,8 @@ void Sema::ActOnFields(Scope* S,
}
// Must enforce the rule that ivars in the base classes may not be
// duplicates.
if (ID->getSuperClass()) {
for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
ObjCIvarDecl* Ivar = (*IVI);
if (IdentifierInfo *II = Ivar->getIdentifier()) {
ObjCIvarDecl* prevIvar =
ID->getSuperClass()->lookupInstanceVariable(II);
if (prevIvar) {
Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
Diag(prevIvar->getLocation(), diag::note_previous_declaration);
}
}
}
}
if (ID->getSuperClass())
DiagnoseDuplicateIvars(ID, ID->getSuperClass());
} else if (ObjCImplementationDecl *IMPDecl =
dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) {
assert(IMPDecl && "ActOnFields - missing ObjCImplementationDecl");

View File

@ -1781,6 +1781,29 @@ void Sema::CompareMethodParamsInBaseAndSuper(Decl *ClassDecl,
}
}
/// DiagnoseDuplicateIvars -
/// Check for duplicate ivars in the entire class at the start of
/// @implementation. This becomes necesssary because class extension can
/// add ivars to a class in random order which will not be known until
/// class's @implementation is seen.
void Sema::DiagnoseDuplicateIvars(ObjCInterfaceDecl *ID,
ObjCInterfaceDecl *SID) {
for (ObjCInterfaceDecl::ivar_iterator IVI = ID->ivar_begin(),
IVE = ID->ivar_end(); IVI != IVE; ++IVI) {
ObjCIvarDecl* Ivar = (*IVI);
if (Ivar->isInvalidDecl())
continue;
if (IdentifierInfo *II = Ivar->getIdentifier()) {
ObjCIvarDecl* prevIvar = SID->lookupInstanceVariable(II);
if (prevIvar) {
Diag(Ivar->getLocation(), diag::err_duplicate_member) << II;
Diag(prevIvar->getLocation(), diag::note_previous_declaration);
Ivar->setInvalidDecl();
}
}
}
}
// Note: For class/category implemenations, allMethods/allProperties is
// always null.
void Sema::ActOnAtEnd(SourceRange AtEnd,
@ -1892,6 +1915,11 @@ void Sema::ActOnAtEnd(SourceRange AtEnd,
if (ObjCInterfaceDecl* IDecl = IC->getClassInterface()) {
ImplMethodsVsClassMethods(IC, IDecl);
AtomicPropertySetterGetterRules(IC, IDecl);
if (LangOpts.ObjCNonFragileABI2)
while (IDecl->getSuperClass()) {
DiagnoseDuplicateIvars(IDecl, IDecl->getSuperClass());
IDecl = IDecl->getSuperClass();
}
}
} else if (ObjCCategoryImplDecl* CatImplClass =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {

View File

@ -0,0 +1,32 @@
// RUN: %clang_cc1 -fsyntax-only -fobjc-nonfragile-abi2 -verify %s
@interface Root @end
@interface SuperClass : Root
{
int iSuper; // expected-note {{previous declaration is here}}
}
@end
@interface SubClass : SuperClass {
int ivar; // expected-error {{duplicate member 'ivar'}}
int another_ivar; // expected-error {{duplicate member 'another_ivar'}}
int iSuper; // expected-error {{duplicate member 'iSuper'}}
}
@end
@interface SuperClass () {
int ivar; // expected-note {{previous declaration is here}}
}
@end
@interface Root () {
int another_ivar; // expected-note {{previous declaration is here}}
}
@end
@implementation SubClass
-(int) method {
return self->ivar; // would be ambiguous if the duplicate ivar were allowed
}
@end