diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 54 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 35 |
2 files changed, 87 insertions, 2 deletions
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index a313acf2007..d873ad0746b 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -716,6 +716,60 @@ ObjCMethodDecl *ObjCImplementationDecl::getClassMethod(Selector Sel) const { return NULL; } +/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl +/// added to the list of those properties @synthesized/@dynamic in this +/// @implementation block. +/// +ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplDecl(IdentifierInfo *Id) const { + for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { + ObjCPropertyImplDecl *PID = *i; + if (PID->getPropertyDecl()->getIdentifier() == Id) + return PID; + } + return 0; +} + +/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of +/// properties implemented in this @implementation block and returns it if +/// found. +/// +ObjCPropertyImplDecl *ObjCImplementationDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { + for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { + ObjCPropertyImplDecl *PID = *i; + if (PID->getPropertyIvarDecl() && + PID->getPropertyIvarDecl()->getIdentifier() == ivarId) + return PID; + } + return 0; +} + +/// FindPropertyImplIvarDecl - This method lookup the ivar in the list of +/// properties implemented in this category @implementation block and returns it if +/// found. +/// +ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const { + for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { + ObjCPropertyImplDecl *PID = *i; + if (PID->getPropertyIvarDecl() && + PID->getPropertyIvarDecl()->getIdentifier() == ivarId) + return PID; + } + return 0; +} + +/// FindPropertyImplDecl - This method looks up a previous ObjCPropertyImplDecl +/// added to the list of those properties @synthesized/@dynamic in this +/// category @implementation block. +/// +ObjCPropertyImplDecl *ObjCCategoryImplDecl::FindPropertyImplDecl(IdentifierInfo *Id) const { + for (propimpl_iterator i = propimpl_begin(), e = propimpl_end(); i != e; ++i) { + ObjCPropertyImplDecl *PID = *i; + if (PID->getPropertyDecl()->getIdentifier() == Id) + return PID; + } + return 0; +} + // lookupInstanceMethod - This method returns an instance method by looking in // the class implementation. Unlike interfaces, we don't look outside the // implementation. diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index a58d1da6322..03c803054ca 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1506,10 +1506,41 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, ObjCPropertyImplDecl::Synthesize : ObjCPropertyImplDecl::Dynamic), Ivar); - if (IC) + if (IC) { + if (Synthesize) + if (ObjCPropertyImplDecl *PPIDecl = + IC->FindPropertyImplIvarDecl(PropertyIvar)) { + Diag(PropertyLoc, diag::error_duplicate_ivar_use) + << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() + << PropertyIvar; + Diag(PPIDecl->getLocation(), diag::note_previous_use); + } + + if (ObjCPropertyImplDecl *PPIDecl = IC->FindPropertyImplDecl(PropertyId)) { + Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; + Diag(PPIDecl->getLocation(), diag::note_previous_declaration); + return 0; + } IC->addPropertyImplementation(PIDecl); - else + } + else { + if (Synthesize) + if (ObjCPropertyImplDecl *PPIDecl = + CatImplClass->FindPropertyImplIvarDecl(PropertyIvar)) { + Diag(PropertyLoc, diag::error_duplicate_ivar_use) + << PropertyId << PPIDecl->getPropertyDecl()->getIdentifier() + << PropertyIvar; + Diag(PPIDecl->getLocation(), diag::note_previous_use); + } + + if (ObjCPropertyImplDecl *PPIDecl = + CatImplClass->FindPropertyImplDecl(PropertyId)) { + Diag(PropertyLoc, diag::error_property_implemented) << PropertyId; + Diag(PPIDecl->getLocation(), diag::note_previous_declaration); + return 0; + } CatImplClass->addPropertyImplementation(PIDecl); + } return PIDecl; } |