More Sema check for ivars in class continuation.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97002 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 4ea3793..2190e3b 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1440,6 +1440,8 @@
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,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 0be3841..27eb251 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -5659,21 +5659,8 @@
}
// 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");
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 925c0db..939ccab 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -1781,6 +1781,29 @@
}
}
+/// 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 @@
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)) {