diff options
| -rw-r--r-- | clang/include/clang/AST/DeclObjC.h | 2 | ||||
| -rw-r--r-- | clang/lib/AST/DeclObjC.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 14 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 7 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenObjC/newproperty-nested-synthesis-1.m | 78 | 
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; +}  | 

