aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-05-04 04:10:48 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-05-04 04:10:48 +0000
commit3715328021f69ed55e7b4cd65465fc761a8b6457 (patch)
treea5c5be5e0fd100f2aa965fbce196c4acc86a0f1e
parent609e5c36af17bd951cba5c584a7580c575713686 (diff)
Don't allow clients to traverse into superclass synthesized properties
via CollectObjCIvars. - In places where we need them, we should have the implementation and access the properties through it. This is a fairly substantial functionality change: 1. @encode no longer encodes synthesized ivars, ever. 2. The ivar layout bitmap no longer encodes information for synthesized ivars in superclasses. Well, actually I had already broken that, but it is intentional now. We are now differing substantially from llvm-gcc and gcc here. However, in my opinion this fundamentally *must* work if non-fragile classes are to work. Without this change, the result of @encode and the ivar layout depend on the order that the implementation is seen in a file (if it is in the same file with its superclass). Since both scenarios should work the same, our behavior is now consistent with gcc behavior as if an implementation is never seen following an implementation of its superclass. Note that #2 is only a functionality change when (A) an implementation appears in the same translation unit with the implementation of its superclass, and (B) the superclass has synthesized ivars. My belief is that this situation does not occur in practice. I am not yet sure of the role/semantics of @encode when synthesized ivars are present... it's use is fairly unsound in a non-fragile world. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70822 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ASTContext.cpp9
-rw-r--r--lib/CodeGen/CGObjCMac.cpp8
-rw-r--r--test/CodeGenObjC/ivar-layout-64.m27
3 files changed, 32 insertions, 12 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 0ef672768d..d89c8c2b2e 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -667,15 +667,6 @@ static void CollectLocalObjCIvars(ASTContext *Ctx,
if (!IVDecl->isInvalidDecl())
Fields.push_back(cast<FieldDecl>(IVDecl));
}
- // Look into properties.
- //
- // FIXME: This needs to go away, synthesized ivars shouldn't be
- // accessible from the interface decl.
- for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(*Ctx),
- E = OI->prop_end(*Ctx); I != E; ++I) {
- if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl())
- Fields.push_back(cast<FieldDecl>(IV));
- }
}
void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI,
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 5441b8e362..e735efb490 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -3095,6 +3095,14 @@ llvm::Constant *CGObjCCommonMac::BuildIvarLayout(
llvm::SmallVector<FieldDecl*, 32> RecFields;
const ObjCInterfaceDecl *OI = OMD->getClassInterface();
CGM.getContext().CollectObjCIvars(OI, RecFields);
+
+ // Add this implementations synthesized ivars.
+ for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(CGM.getContext()),
+ E = OI->prop_end(CGM.getContext()); I != E; ++I) {
+ if (ObjCIvarDecl *IV = (*I)->getPropertyIvarDecl())
+ RecFields.push_back(cast<FieldDecl>(IV));
+ }
+
if (RecFields.empty())
return llvm::Constant::getNullValue(PtrTy);
diff --git a/test/CodeGenObjC/ivar-layout-64.m b/test/CodeGenObjC/ivar-layout-64.m
index 894dbfed89..0976735637 100644
--- a/test/CodeGenObjC/ivar-layout-64.m
+++ b/test/CodeGenObjC/ivar-layout-64.m
@@ -11,6 +11,7 @@ Here is a handy command for looking at llvm-gcc's output:
llvm-gcc -m64 -fobjc-gc -emit-llvm -S -o - ivar-layout-64.m | \
grep 'OBJC_CLASS_NAME.* =.*global' | \
sed -e 's#, section.*# ...#' | \
+ sed -e 's#_[0-9]*"#_NNN#' | \
sort
*/
@@ -32,14 +33,34 @@ __weak B *f2;
}
@end
+@interface C : A
+@property int p3;
+@end
+
+@implementation C
+@synthesize p3 = _p3;
+@end
+
@interface A()
@property int p0;
@property (assign) __strong id p1;
@property (assign) __weak id p2;
@end
+// FIXME: Check layout for this class, once it is clear what the right
+// answer is.
@implementation A
-@synthesize p0;
-@synthesize p1;
-@synthesize p2;
+@synthesize p0 = _p0;
+@synthesize p1 = _p1;
+@synthesize p2 = _p2;
+@end
+
+@interface D : A
+@property int p3;
+@end
+
+// FIXME: Check layout for this class, once it is clear what the right
+// answer is.
+@implementation D
+@synthesize p3 = _p3;
@end