diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-04-01 19:37:34 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-04-01 19:37:34 +0000 |
commit | 78be1651e2d9b057009cc1c6a74215703f459146 (patch) | |
tree | 9af7b7105bc8fb472da9176ba147fc9bcc50691d | |
parent | d854c8d8a6992d412e58b52ffc2ae2ba05e0735a (diff) | |
download | bcm5719-llvm-78be1651e2d9b057009cc1c6a74215703f459146.tar.gz bcm5719-llvm-78be1651e2d9b057009cc1c6a74215703f459146.zip |
Nonfragile ivar synthesis with property is in a continuation
class.
llvm-svn: 68234
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 24 | ||||
-rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 16 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 38 | ||||
-rw-r--r-- | clang/test/CodeGenObjC/synthesize_ivar.m | 13 |
4 files changed, 90 insertions, 1 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index fc1e0a20627..8da7b3aa1dc 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -614,6 +614,17 @@ void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI, if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl()) Fields.push_back(cast<FieldDecl>(IV)); } + // look into continuation class. + for (ObjCCategoryDecl *Categories = OI->getCategoryList(); + Categories; Categories = Categories->getNextClassCategory()) + if (!Categories->getIdentifier()) { + for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(), + E = Categories->prop_end(); I != E; ++I) { + if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl()) + Fields.push_back(cast<FieldDecl>(IV)); + } + break; + } } /// addRecordToClass - produces record info. for the class for its @@ -711,7 +722,18 @@ ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) { if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl()) NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this); } - + // Also continuation class. + for (ObjCCategoryDecl *Categories = D->getCategoryList(); + Categories; Categories = Categories->getNextClassCategory()) + if (!Categories->getIdentifier()) { + for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(), + E = Categories->prop_end(); I != E; ++I) { + if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl()) + NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this); + } + break; + } + // Finally, round the size of the total struct up to the alignment of the // struct itself. NewEntry->FinalizeLayout(); diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index cd1b979dcb0..57bd8eab1ef 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -147,6 +147,22 @@ ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( return IV; } } + // look into continuation class. + for (ObjCCategoryDecl *Categories = ClassDecl->getCategoryList(); + Categories; Categories = Categories->getNextClassCategory()) + if (!Categories->getIdentifier()) { + for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(), + E = Categories->prop_end(); I != E; ++I) { + ObjCPropertyDecl *PDecl = (*I); + if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) + if (IV->getIdentifier() == ID) { + clsDeclared = ClassDecl; + return IV; + } + } + break; + } + ClassDecl = ClassDecl->getSuperClass(); } return NULL; diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 6b3ced08bf4..580641643f7 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -1674,6 +1674,18 @@ static int countInheritedIvars(const ObjCInterfaceDecl *OI) { if ((*I)->getPropertyIvarDecl()) ++count; } + // look into continuation class. + for (ObjCCategoryDecl *Categories = OI->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)->getPropertyIvarDecl()) + ++count; + } + break; + } + } return count; } @@ -1702,6 +1714,20 @@ static const ObjCInterfaceDecl *getInterfaceDeclForIvar( if (IV->getIdentifier() == IVD->getIdentifier()) return OI; } + // look into continuation class. + for (ObjCCategoryDecl *Categories = OI->getCategoryList(); + Categories; Categories = Categories->getNextClassCategory()) { + if (!Categories->getIdentifier()) { + for (ObjCInterfaceDecl::prop_iterator I = Categories->prop_begin(), + E = Categories->prop_end(); I != E; ++I) { + ObjCPropertyDecl *PDecl = (*I); + if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) + if (IV->getIdentifier() == IVD->getIdentifier()) + return OI; + } + break; + } + } return getInterfaceDeclForIvar(OI->getSuperClass(), IVD); } @@ -4566,6 +4592,18 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( E = OID->prop_end(); I != E; ++I) if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl()) OIvars.push_back(IV); + // look into continuation class. + 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 (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl()) + OIvars.push_back(IV); + } + break; + } + unsigned iv = 0; for (RecordDecl::field_iterator e = RD->field_end(); i != e; ++i) { FieldDecl *Field = *i; diff --git a/clang/test/CodeGenObjC/synthesize_ivar.m b/clang/test/CodeGenObjC/synthesize_ivar.m index 8999691fe1c..7646f707bf7 100644 --- a/clang/test/CodeGenObjC/synthesize_ivar.m +++ b/clang/test/CodeGenObjC/synthesize_ivar.m @@ -12,3 +12,16 @@ return IP; } @end + +// Test for synthesis of ivar for a property +// declared in continuation class. +@interface OrganizerViolatorView +@end + +@interface OrganizerViolatorView() +@property (retain) id bindingInfo; +@end + +@implementation OrganizerViolatorView +@synthesize bindingInfo; +@end |