diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2008-12-05 22:32:48 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2008-12-05 22:32:48 +0000 |
commit | fbbaf6afaea9715fdba1d2c868287b94eeae189c (patch) | |
tree | 6dd94f0b42f8994f49e833977ff7f9d37d8b755e /clang/lib | |
parent | b49d7cf19e943878c24745da2d061bb8f7f1cb5e (diff) | |
download | bcm5719-llvm-fbbaf6afaea9715fdba1d2c868287b94eeae189c.tar.gz bcm5719-llvm-fbbaf6afaea9715fdba1d2c868287b94eeae189c.zip |
This test checks for duplicate implementation of the same
property. It also checks for duplicate use of the same ivar
in two different iproperty implementations. It also caught
an error for a test case used in CodeGen :).
llvm-svn: 60610
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; } |