From af3e72285238369c2ea4ebd40a1c9a87bd3eabb7 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 31 Mar 2009 00:06:29 +0000 Subject: [PATCH] fe support for objc2's nonfragile-abi synthesized ivars. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68077 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclObjC.h | 23 ++++++++++------------- lib/AST/ASTContext.cpp | 7 +++++++ lib/AST/DeclObjC.cpp | 10 ++++++++++ lib/Sema/SemaDeclObjC.cpp | 17 +++++++++++------ test/SemaObjC/property-nonfragile-abi.m | 3 +-- test/SemaObjC/synthesized-ivar.m | 13 +++++++++++++ 6 files changed, 52 insertions(+), 21 deletions(-) create mode 100644 test/SemaObjC/synthesized-ivar.m diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 8ca0a378d7..76e4c0211e 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -1009,6 +1009,7 @@ private: ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method + ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T) @@ -1016,7 +1017,7 @@ private: PropertyAttributes(OBJC_PR_noattr), PropertyImplementation(None), GetterName(Selector()), SetterName(Selector()), - GetterMethodDecl(0), SetterMethodDecl(0) {} + GetterMethodDecl(0), SetterMethodDecl(0) , PropertyIvarDecl(0) {} public: static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, @@ -1074,6 +1075,13 @@ public: return PropertyControl(PropertyImplementation); } + void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { + PropertyIvarDecl = Ivar; + } + ObjCIvarDecl *getPropertyIvarDecl() const { + return PropertyIvarDecl; + } + static bool classof(const Decl *D) { return D->getKind() == ObjCProperty; } @@ -1091,7 +1099,6 @@ public: Dynamic }; private: - unsigned IvarKind : 1; SourceLocation AtLoc; // location of @synthesize or @dynamic /// Property declaration being implemented ObjCPropertyDecl *PropertyDecl; @@ -1103,7 +1110,7 @@ private: ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivarDecl) - : Decl(ObjCPropertyImpl, DC, L), IvarKind(false), AtLoc(atLoc), + : Decl(ObjCPropertyImpl, DC, L), AtLoc(atLoc), PropertyDecl(property), PropertyIvarDecl(ivarDecl) { assert (PK == Dynamic || PropertyIvarDecl); } @@ -1128,16 +1135,6 @@ public: ObjCIvarDecl *getPropertyIvarDecl() const { return PropertyIvarDecl; } - void SetPropertyIvarDecl(ObjCIvarDecl *Ivar) { - assert(PropertyIvarDecl && "PropertyIvarDecl is already defined"); - PropertyIvarDecl = Ivar; - } - void SetIvarSynthesized() { - IvarKind = true; - } - bool IsIvarSynthesized() const { - return IvarKind; - } static bool classof(const Decl *D) { return D->getKind() == ObjCPropertyImpl; diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index bb17954727..b62438cd61 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -608,6 +608,13 @@ void ASTContext::CollectObjCIvars(const ObjCInterfaceDecl *OI, if (!IVDecl->isInvalidDecl()) Fields.push_back(cast(IVDecl)); } + // look into properties. + for (ObjCInterfaceDecl::prop_iterator I = OI->prop_begin(), + E = OI->prop_end(); I != E; ++I) { + ObjCPropertyDecl *PDecl = (*I); + if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) + Fields.push_back(cast(IV)); + } } /// addRecordToClass - produces record info. for the class for its diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 4d2fcb69ac..855764fdbd 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -137,6 +137,16 @@ ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( return *I; } } + // look into properties. + for (ObjCInterfaceDecl::prop_iterator I = ClassDecl->prop_begin(), + E = ClassDecl->prop_end(); I != E; ++I) { + ObjCPropertyDecl *PDecl = (*I); + if (ObjCIvarDecl *IV = PDecl->getPropertyIvarDecl()) + if (IV->getIdentifier() == ID) { + clsDeclared = ClassDecl; + return IV; + } + } ClassDecl = ClassDecl->getSuperClass(); } return NULL; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 18e3e4f909..c68eede104 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -1765,17 +1765,22 @@ Sema::DeclPtrTy Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, // @synthesize if (!PropertyIvar) PropertyIvar = PropertyId; + QualType PropType = Context.getCanonicalType(property->getType()); // Check that this is a previously declared 'ivar' in 'IDecl' interface Ivar = IDecl->lookupInstanceVariable(PropertyIvar); if (!Ivar) { - if (getLangOptions().ObjCNonFragileABI) - Diag(PropertyLoc, diag::error_synthesized_ivar_yet_not_supported) - << PropertyId; - else + if (getLangOptions().ObjCNonFragileABI) { + Ivar = ObjCIvarDecl::Create(Context, CurContext, PropertyLoc, + PropertyIvar, PropType, + ObjCIvarDecl::Private, + (Expr *)0); + property->setPropertyIvarDecl(Ivar); + } + else { Diag(PropertyLoc, diag::error_missing_property_ivar_decl) << PropertyId; - return DeclPtrTy(); + return DeclPtrTy(); + } } - QualType PropType = Context.getCanonicalType(property->getType()); QualType IvarType = Context.getCanonicalType(Ivar->getType()); // Check that type of property and its ivar are type compatible. diff --git a/test/SemaObjC/property-nonfragile-abi.m b/test/SemaObjC/property-nonfragile-abi.m index 31d415e2ac..e2de77d3a2 100644 --- a/test/SemaObjC/property-nonfragile-abi.m +++ b/test/SemaObjC/property-nonfragile-abi.m @@ -16,7 +16,6 @@ typedef signed char BOOL; @end @implementation XCDeviceWillExecuteInfoBaton - // Produce an error when compiling for -arch x86_64 (or "non-fragile" ABI) - @synthesize sdkPath; // expected-error{{instance variable synthesis not yet supported (need to declare 'sdkPath' explicitly)}} + @synthesize sdkPath; @end diff --git a/test/SemaObjC/synthesized-ivar.m b/test/SemaObjC/synthesized-ivar.m new file mode 100644 index 0000000000..de44857934 --- /dev/null +++ b/test/SemaObjC/synthesized-ivar.m @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -triple x86_64-apple-darwin9 -verify %s +@interface I +{ +} +@property int IP; +@end + +@implementation I +@synthesize IP; +- (int) Meth { + return IP; +} +@end