]> granicus.if.org Git - clang/commitdiff
Support for implementation of property in the case where
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 9 Dec 2008 20:23:04 +0000 (20:23 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 9 Dec 2008 20:23:04 +0000 (20:23 +0000)
the synthesis is in an implementation of s subclass of
a super class where the property has been declared.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60792 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/DeclObjC.h
lib/AST/DeclObjC.cpp
lib/CodeGen/CGObjC.cpp
lib/CodeGen/CodeGenFunction.h
lib/CodeGen/CodeGenModule.cpp
lib/Sema/SemaDeclObjC.cpp
test/CodeGenObjC/newproperty-nested-synthesis-1.m [new file with mode: 0644]

index 190c1c3509c0dad3342f8ce5dce560c8a3950c9b..ba415f90df8a2ea4374adf016938240964c11641 100644 (file)
@@ -216,7 +216,7 @@ public:
   /// implict parameters. This must be called prior to using getSelfDecl()
   /// or getCmdDecl(). The call is ignored if the implicit paramters
   /// have already been created.
-  void createImplicitParams(ASTContext &Context);
+  void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID);
 
   ImplicitParamDecl * getSelfDecl() const { return SelfDecl; }
   ImplicitParamDecl * getCmdDecl() const { return CmdDecl; }
index 85b8ec14e045f606a10d03caf86c70cea11f0fd1..1b098b5f894d80beef72f441aead652a05c422e2 100644 (file)
@@ -220,13 +220,14 @@ ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C,
 // Objective-C Decl Implementation
 //===----------------------------------------------------------------------===//
 
-void ObjCMethodDecl::createImplicitParams(ASTContext &Context) {
+void ObjCMethodDecl::createImplicitParams(ASTContext &Context, 
+                                          const ObjCInterfaceDecl *OID) {
   QualType selfTy;
   if (isInstance()) {
     // There may be no interface context due to error in declaration
     // of the interface (which has been reported). Recover gracefully.
-    if (ObjCInterfaceDecl *OID = getClassInterface()) {
-      selfTy = Context.getObjCInterfaceType(OID);
+    if (OID) {
+      selfTy = Context.getObjCInterfaceType(const_cast<ObjCInterfaceDecl *>(OID));
       selfTy = Context.getPointerType(selfTy);
     } else {
       selfTy = Context.getObjCIdType();
index 845d5ff00ccec4f5557df61caf797b3809d0d3ed..e605065848d478e6bcc628a7237cd49beba7a7b2 100644 (file)
@@ -137,14 +137,15 @@ void CodeGenFunction::GenerateObjCMethod(const ObjCMethodDecl *OMD) {
 /// GenerateObjCGetter - Generate an Objective-C property getter
 /// function. The given Decl must be either an ObjCCategoryImplDecl
 /// or an ObjCImplementationDecl.
-void CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) {
+void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP,
+                                         const ObjCPropertyImplDecl *PID) {
   ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
   assert(OMD && "Invalid call to generate getter (empty method)");
   // FIXME: This is rather murky, we create this here since they will
   // not have been created by Sema for us.
-  OMD->createImplicitParams(getContext());
+  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
   StartObjCMethod(OMD);
 
   // Determine if we should use an objc_getProperty call for
@@ -173,7 +174,7 @@ void CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) {
     QualType IdTy = getContext().getObjCIdType();
     llvm::Value *SelfAsId = 
       Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
-    llvm::Value *Offset = EmitIvarOffset(OMD->getClassInterface(), Ivar);
+    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
     llvm::Value *True =
       llvm::ConstantInt::get(Types.ConvertTypeForMem(getContext().BoolTy), 1);
     CallArgList Args;
@@ -204,14 +205,15 @@ void CodeGenFunction::GenerateObjCGetter(const ObjCPropertyImplDecl *PID) {
 /// GenerateObjCSetter - Generate an Objective-C property setter
 /// function. The given Decl must be either an ObjCCategoryImplDecl
 /// or an ObjCImplementationDecl.
-void CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) {
+void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP,
+                                         const ObjCPropertyImplDecl *PID) {
   ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl();
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
   assert(OMD && "Invalid call to generate setter (empty method)");
   // FIXME: This is rather murky, we create this here since they will
   // not have been created by Sema for us.  
-  OMD->createImplicitParams(getContext());
+  OMD->createImplicitParams(getContext(), IMP->getClassInterface());
   StartObjCMethod(OMD);
 
   bool IsCopy = PD->getSetterKind() == ObjCPropertyDecl::Copy;
@@ -244,7 +246,7 @@ void CodeGenFunction::GenerateObjCSetter(const ObjCPropertyImplDecl *PID) {
     QualType IdTy = getContext().getObjCIdType();
     llvm::Value *SelfAsId = 
       Builder.CreateBitCast(LoadObjCSelf(), Types.ConvertType(IdTy));
-    llvm::Value *Offset = EmitIvarOffset(OMD->getClassInterface(), Ivar);
+    llvm::Value *Offset = EmitIvarOffset(IMP->getClassInterface(), Ivar);
     llvm::Value *Arg = LocalDeclMap[OMD->getParamDecl(0)];
     llvm::Value *ArgAsId = 
       Builder.CreateBitCast(Builder.CreateLoad(Arg, "arg"),
index 63af44f9cb656e123d3bf950b7211abc25acffec..600582c96e76df945dfa77c23fb37e6a9a69ebec 100644 (file)
@@ -45,6 +45,7 @@ namespace clang {
   class ObjCInterfaceDecl;
   class ObjCIvarDecl;
   class ObjCMethodDecl;
+  class ObjCImplementationDecl;
   class ObjCPropertyImplDecl;
   class TargetInfo;
   class VarDecl;
@@ -176,11 +177,13 @@ public:
 
   /// GenerateObjCGetter - Synthesize an Objective-C property getter
   /// function.
-  void GenerateObjCGetter(const ObjCPropertyImplDecl *PID);
+  void GenerateObjCGetter(ObjCImplementationDecl *IMP,
+                          const ObjCPropertyImplDecl *PID);
 
   /// GenerateObjCSetter - Synthesize an Objective-C property setter
   /// function for the given property.
-  void GenerateObjCSetter(const ObjCPropertyImplDecl *PID);
+  void GenerateObjCSetter(ObjCImplementationDecl *IMP,
+                          const ObjCPropertyImplDecl *PID);
 
   void GenerateCode(const FunctionDecl *FD,
                     llvm::Function *Fn);
index c8fa994916578cdd52f079ac2b1587d6d49749b0..82e732163bd55448f3a881d7f52c77e94138893b 100644 (file)
@@ -980,10 +980,12 @@ void CodeGenModule::EmitObjCPropertyImplementations(const
       // property. What we want to know is if the method is defined in
       // this implementation.
       if (!D->getInstanceMethod(PD->getGetterName()))
-        CodeGenFunction(*this).GenerateObjCGetter(PID);
+        CodeGenFunction(*this).GenerateObjCGetter(
+                                 const_cast<ObjCImplementationDecl *>(D), PID);
       if (!PD->isReadOnly() &&
           !D->getInstanceMethod(PD->getSetterName()))
-        CodeGenFunction(*this).GenerateObjCSetter(PID);
+        CodeGenFunction(*this).GenerateObjCSetter(
+                                 const_cast<ObjCImplementationDecl *>(D), PID);
     }
   }
 }
index 308c125d9ae5aadcdbd09753b8b0b88f9fcf3f88..fa73bcf2591cec05aebaec5e32e8e6d2087e4833 100644 (file)
@@ -42,7 +42,7 @@ void Sema::ObjCActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) {
   // binding to their use.
 
   // Insert the invisible arguments, self and _cmd!
-  MDecl->createImplicitParams(Context);
+  MDecl->createImplicitParams(Context, MDecl->getClassInterface());
   
   PushOnScopeChains(MDecl->getSelfDecl(), FnBodyScope);
   PushOnScopeChains(MDecl->getCmdDecl(), FnBodyScope);
diff --git a/test/CodeGenObjC/newproperty-nested-synthesis-1.m b/test/CodeGenObjC/newproperty-nested-synthesis-1.m
new file mode 100644 (file)
index 0000000..208b162
--- /dev/null
@@ -0,0 +1,78 @@
+// RUN: clang -fnext-runtime --emit-llvm -o %t %s
+
+@interface Object
+- (id) new;
+@end
+
+@interface Tester : Object
+@property char PropertyAtomic_char;
+@property short PropertyAtomic_short;
+@property int PropertyAtomic_int;
+@property long PropertyAtomic_long;
+@property long long PropertyAtomic_longlong;
+@property float PropertyAtomic_float;
+@property double PropertyAtomic_double;
+@property(assign) id PropertyAtomic_id;
+@property(retain) id PropertyAtomicRetained_id;
+@property(copy) id PropertyAtomicRetainedCopied_id;
+@property(retain) id PropertyAtomicRetainedGCOnly_id;
+@property(copy) id PropertyAtomicRetainedCopiedGCOnly_id;
+@end
+
+@implementation Tester
+@dynamic PropertyAtomic_char;
+@dynamic PropertyAtomic_short;
+@dynamic PropertyAtomic_int;
+@dynamic PropertyAtomic_long;
+@dynamic PropertyAtomic_longlong;
+@dynamic PropertyAtomic_float;
+@dynamic PropertyAtomic_double;
+@dynamic PropertyAtomic_id;
+@dynamic PropertyAtomicRetained_id;
+@dynamic PropertyAtomicRetainedCopied_id;
+@dynamic PropertyAtomicRetainedGCOnly_id;
+@dynamic PropertyAtomicRetainedCopiedGCOnly_id;
+@end
+
+@interface SubClass : Tester
+{
+    char PropertyAtomic_char;
+    short PropertyAtomic_short;
+    int PropertyAtomic_int;
+    long PropertyAtomic_long;
+    long long PropertyAtomic_longlong;
+    float PropertyAtomic_float;
+    double PropertyAtomic_double;
+    id PropertyAtomic_id;
+    id PropertyAtomicRetained_id;
+    id PropertyAtomicRetainedCopied_id;
+    id PropertyAtomicRetainedGCOnly_id;
+    id PropertyAtomicRetainedCopiedGCOnly_id;
+}
+@end
+
+@implementation SubClass
+@synthesize PropertyAtomic_char;
+@synthesize PropertyAtomic_short;
+@synthesize PropertyAtomic_int;
+@synthesize PropertyAtomic_long;
+@synthesize PropertyAtomic_longlong;
+@synthesize PropertyAtomic_float;
+@synthesize PropertyAtomic_double;
+@synthesize PropertyAtomic_id;
+@synthesize PropertyAtomicRetained_id;
+@synthesize PropertyAtomicRetainedCopied_id;
+@synthesize PropertyAtomicRetainedGCOnly_id;
+@synthesize PropertyAtomicRetainedCopiedGCOnly_id;
+@end
+
+int main()
+{
+    SubClass *f = [SubClass new];
+    f.PropertyAtomic_int = 1;
+
+    f.PropertyAtomic_int += 3;
+
+    f.PropertyAtomic_int -= 4;
+    return f.PropertyAtomic_int;
+}