summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2008-12-09 20:23:04 +0000
committerFariborz Jahanian <fjahanian@apple.com>2008-12-09 20:23:04 +0000
commit3d8552a75d03dd1981939134a17b3918c28dc762 (patch)
treea9cd77fc44db325c0ee435c5dda28bc445ffe7b7 /clang
parentc13f26873fbda0ff998d89e564233987b6068b35 (diff)
downloadbcm5719-llvm-3d8552a75d03dd1981939134a17b3918c28dc762.tar.gz
bcm5719-llvm-3d8552a75d03dd1981939134a17b3918c28dc762.zip
Support for implementation of property in the case where
the synthesis is in an implementation of s subclass of a super class where the property has been declared. llvm-svn: 60792
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/DeclObjC.h2
-rw-r--r--clang/lib/AST/DeclObjC.cpp7
-rw-r--r--clang/lib/CodeGen/CGObjC.cpp14
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h7
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp6
-rw-r--r--clang/lib/Sema/SemaDeclObjC.cpp2
-rw-r--r--clang/test/CodeGenObjC/newproperty-nested-synthesis-1.m78
7 files changed, 101 insertions, 15 deletions
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index 190c1c3509c..ba415f90df8 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -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; }
diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp
index 85b8ec14e04..1b098b5f894 100644
--- a/clang/lib/AST/DeclObjC.cpp
+++ b/clang/lib/AST/DeclObjC.cpp
@@ -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();
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 845d5ff00cc..e605065848d 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -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"),
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 63af44f9cb6..600582c96e7 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -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);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c8fa9949165..82e732163bd 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -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);
}
}
}
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 308c125d9ae..fa73bcf2591 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -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/clang/test/CodeGenObjC/newproperty-nested-synthesis-1.m b/clang/test/CodeGenObjC/newproperty-nested-synthesis-1.m
new file mode 100644
index 00000000000..208b162b50f
--- /dev/null
+++ b/clang/test/CodeGenObjC/newproperty-nested-synthesis-1.m
@@ -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;
+}
OpenPOWER on IntegriCloud