Fix a bug in declaration of property in continuation

class which was exposed by implementation of 
objc2's nonfragile abi code gen.

llvm-svn: 68259
This commit is contained in:
Fariborz Jahanian 2009-04-01 23:23:53 +00:00
parent 66b3fffa60
commit e4fd640147
3 changed files with 42 additions and 14 deletions

View File

@ -91,6 +91,16 @@ ObjCContainerDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const {
for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I) for (prop_iterator I = prop_begin(), E = prop_end(); I != E; ++I)
if ((*I)->getIdentifier() == PropertyId) if ((*I)->getIdentifier() == PropertyId)
return *I; return *I;
// Also look for property declared in its continuation class.
if (const ObjCInterfaceDecl *OID = dyn_cast<ObjCInterfaceDecl>(this))
for (ObjCCategoryDecl *Categories = OID->getCategoryList();
Categories; Categories = Categories->getNextClassCategory())
if (!Categories->getIdentifier()) {
for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(),
E = Categories->prop_end(); I != E; ++I)
if ((*I)->getIdentifier() == PropertyId)
return *I;
}
const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this); const ObjCProtocolDecl *PID = dyn_cast<ObjCProtocolDecl>(this);
if (PID) { if (PID) {

View File

@ -1596,28 +1596,26 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
// May modify Attributes. // May modify Attributes.
CheckObjCPropertyAttributes(T, AtLoc, Attributes); CheckObjCPropertyAttributes(T, AtLoc, Attributes);
ObjCMethodDecl *SetterDecl = 0;
if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl))
if (!CDecl->getIdentifier()) { if (!CDecl->getIdentifier()) {
// This is an anonymous category. property requires special // This is a continuation class. property requires special
// handling. // handling.
if (ObjCInterfaceDecl *ICDecl = CDecl->getClassInterface()) { if (ObjCInterfaceDecl *ICDecl = CDecl->getClassInterface()) {
if (ObjCPropertyDecl *PIDecl = if (ObjCPropertyDecl *PIDecl =
ICDecl->FindPropertyDeclaration(FD.D.getIdentifier())) { ICDecl->FindPropertyDeclaration(FD.D.getIdentifier())) {
// property 'PIDecl's readonly attribute will be over-ridden // property 'PIDecl's readonly attribute will be over-ridden
// with anonymous category's readwrite property attribute! // with continuation class's readwrite property attribute!
unsigned PIkind = PIDecl->getPropertyAttributes(); unsigned PIkind = PIDecl->getPropertyAttributes();
if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) { if (isReadWrite && (PIkind & ObjCPropertyDecl::OBJC_PR_readonly)) {
if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) != if ((Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) !=
(PIkind & ObjCPropertyDecl::OBJC_PR_nonatomic)) (PIkind & ObjCPropertyDecl::OBJC_PR_nonatomic))
Diag(AtLoc, diag::warn_property_attr_mismatch); Diag(AtLoc, diag::warn_property_attr_mismatch);
PIDecl->makeitReadWriteAttribute(); // Make the continuation class property attribute Read/Write
if (Attributes & ObjCDeclSpec::DQ_PR_retain) Attributes &= ~ObjCPropertyDecl::OBJC_PR_readonly;
PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_retain); Attributes |= ObjCPropertyDecl::OBJC_PR_readwrite;
if (Attributes & ObjCDeclSpec::DQ_PR_copy)
PIDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_copy);
PIDecl->setSetterName(SetterSel);
// FIXME: use a common routine with addPropertyMethods. // FIXME: use a common routine with addPropertyMethods.
ObjCMethodDecl *SetterDecl = SetterDecl =
ObjCMethodDecl::Create(Context, AtLoc, AtLoc, SetterSel, ObjCMethodDecl::Create(Context, AtLoc, AtLoc, SetterSel,
Context.VoidTy, Context.VoidTy,
ICDecl, ICDecl,
@ -1628,12 +1626,13 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
FD.D.getIdentifier(), FD.D.getIdentifier(),
T, VarDecl::None, 0); T, VarDecl::None, 0);
SetterDecl->setMethodParams(&Argument, 1, Context); SetterDecl->setMethodParams(&Argument, 1, Context);
PIDecl->setSetterMethodDecl(SetterDecl);
} }
else else {
Diag(AtLoc, diag::err_use_continuation_class) << ICDecl->getDeclName(); Diag(AtLoc,
*isOverridingProperty = true; diag::err_use_continuation_class) << ICDecl->getDeclName();
return DeclPtrTy(); *isOverridingProperty = true;
return DeclPtrTy();
}
} }
// No matching property found in the main class. Just fall thru // No matching property found in the main class. Just fall thru
// and add property to the anonymous category. It looks like // and add property to the anonymous category. It looks like
@ -1660,6 +1659,7 @@ Sema::DeclPtrTy Sema::ActOnProperty(Scope *S, SourceLocation AtLoc,
// Regardless of setter/getter attribute, we save the default getter/setter // Regardless of setter/getter attribute, we save the default getter/setter
// selector names in anticipation of declaration of setter/getter methods. // selector names in anticipation of declaration of setter/getter methods.
PDecl->setSetterMethodDecl(SetterDecl);
PDecl->setGetterName(GetterSel); PDecl->setGetterName(GetterSel);
PDecl->setSetterName(SetterSel); PDecl->setSetterName(SetterSel);

View File

@ -0,0 +1,18 @@
// RUN: clang-cc -triple x86_64-apple-darwin10 -emit-llvm -o %t %s &&
// RUN: grep '_OBJC_IVAR_$_XCOrganizerDeviceNodeInfo.viewController' %t
@interface XCOrganizerNodeInfo
@property (readonly, retain) id viewController;
@end
@interface XCOrganizerDeviceNodeInfo : XCOrganizerNodeInfo
@end
@interface XCOrganizerDeviceNodeInfo()
@property (retain) id viewController;
@end
@implementation XCOrganizerDeviceNodeInfo
@synthesize viewController;
@end