From: Fariborz Jahanian Date: Mon, 21 Apr 2008 19:04:53 +0000 (+0000) Subject: Continuation of work on ObjC2's properties. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=559c0c4bbecc017aab0716d546c4fefbcc194687;p=clang Continuation of work on ObjC2's properties. Added iterators, methods to find property and categories. Use them in doing semantic analysis on property implementation declarations. Fixed typos. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50050 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index e0c9563911..6a34696462 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -281,6 +281,10 @@ public: } unsigned getNumIntfRefProtocols() const { return NumReferencedProtocols; } + ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; + ObjCCategoryDecl *FindCategoryDeclaration(IdentifierInfo *CategoryId) const; + ObjCIvarDecl *FindIvarDeclaration(IdentifierInfo *IvarId) const; + typedef ObjCIvarDecl * const *ivar_iterator; ivar_iterator ivar_begin() const { return Ivars; } ivar_iterator ivar_end() const { return Ivars + ivar_size();} @@ -739,6 +743,8 @@ public: void addProperties(ObjCPropertyDecl **Properties, unsigned NumProperties); + ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; + typedef ObjCPropertyDecl * const * classprop_iterator; classprop_iterator classprop_begin() const { return PropertyDecl; } classprop_iterator classprop_end() const { @@ -798,7 +804,17 @@ public: }; /// ObjCCategoryImplDecl - An object of this class encapsulates a category -/// @implementation declaration. +/// @implementation declaration. If a category class has declaration of a +/// property, its implementation must be specified in the category's +/// @implementation declaration. Example: +/// @interface I @end +/// @interface I(CATEGORY) +/// @property int p1, d1; +/// @end +/// @implementation I(CATEGORY) +/// @dynamic p1,d1; +/// @end +/// class ObjCCategoryImplDecl : public NamedDecl { /// Class interface for this category implementation ObjCInterfaceDecl *ClassInterface; @@ -809,7 +825,7 @@ class ObjCCategoryImplDecl : public NamedDecl { /// implemented class methods llvm::SmallVector ClassMethods; - /// Propertys' being implemented + /// Property Implementations in this category llvm::SmallVector PropertyImplementations; SourceLocation EndLoc; @@ -847,6 +863,16 @@ public: unsigned getNumPropertyImplementations() const { return PropertyImplementations.size(); } + + typedef llvm::SmallVector::const_iterator + propimpl_iterator; + propimpl_iterator propimpl_begin() const { + return PropertyImplementations.begin(); + } + propimpl_iterator propimpl_end() const { + return PropertyImplementations.end(); + } + typedef llvm::SmallVector::const_iterator instmeth_iterator; instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); } @@ -930,6 +956,14 @@ public: void addPropertyImplementation(ObjCPropertyImplDecl *property) { PropertyImplementations.push_back(property); } + typedef llvm::SmallVector::const_iterator + propimpl_iterator; + propimpl_iterator propimpl_begin() const { + return PropertyImplementations.begin(); + } + propimpl_iterator propimpl_end() const { + return PropertyImplementations.end(); + } // Location information, modeled after the Stmt API. SourceLocation getLocStart() const { return getLocation(); } @@ -1063,7 +1097,7 @@ public: OBJC_PR_IMPL_DYNAMIC }; private: - SourceLocation AtLoc; // location of @syntheisze or @dynamic + SourceLocation AtLoc; // location of @synthesize or @dynamic /// Property declaration being implemented ObjCPropertyDecl *PropertyDecl; PropertyImplKind PropertyImplementation; diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 2c55d25e5f..de25ece901 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -628,7 +628,7 @@ public: } // ActOnPropertyImplDecl - called for every property implementation virtual DeclTy *ActOnPropertyImplDecl( - SourceLocation AtLoc, // location of the @syntheize/@dynamic + SourceLocation AtLoc, // location of the @synthesize/@dynamic SourceLocation PropertyNameLoc, // location for the property name bool ImplKind, // true for @synthesize, false for // @dynamic diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index a5eb07a84c..04e9993101 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -137,6 +137,47 @@ ObjCMethodDecl::~ObjCMethodDecl() { delete[] ParamInfo; } +/// FindPropertyDeclaration - Finds declaration of the property given its name +/// in 'PropertyId' and returns it. It returns 0, if not found. +/// +ObjCPropertyDecl * + ObjCInterfaceDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { + for (ObjCInterfaceDecl::classprop_iterator I = classprop_begin(), + E = classprop_end(); I != E; ++I) { + ObjCPropertyDecl *property = *I; + if (property->getIdentifier() == PropertyId) + return property; + } + return 0; +} + +/// FindCategoryDeclaration - Finds category declaration in the list of +/// categories for this class and returns it. Name of the category is passed +/// in 'CategoryId'. If category not found, return 0; +/// +ObjCCategoryDecl * + ObjCInterfaceDecl::FindCategoryDeclaration(IdentifierInfo *CategoryId) const { + for (ObjCCategoryDecl *Category = getCategoryList(); + Category; Category = Category->getNextClassCategory()) + if (Category->getIdentifier() == CategoryId) + return Category; + return 0; +} + +/// FindIvarDeclaration - Find an Ivar declaration in this class given its +/// name in 'IvarId'. On failure to find, return 0; +/// +ObjCIvarDecl * + ObjCInterfaceDecl::FindIvarDeclaration(IdentifierInfo *IvarId) const { + for (ObjCInterfaceDecl::ivar_iterator IVI = ivar_begin(), + IVE = ivar_end(); IVI != IVE; ++IVI) { + ObjCIvarDecl* Ivar = (*IVI); + if (Ivar->getIdentifier() == IvarId) + return Ivar; + } + return 0; +} + /// ObjCAddInstanceVariablesToClass - Inserts instance variables /// into ObjCInterfaceDecl's fields. /// @@ -274,6 +315,20 @@ void ObjCCategoryDecl::addMethods(ObjCMethodDecl **insMethods, AtEndLoc = endLoc; } +/// FindPropertyDeclaration - Finds declaration of the property given its name +/// in 'PropertyId' and returns it. It returns 0, if not found. +/// +ObjCPropertyDecl * +ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { + for (ObjCCategoryDecl::classprop_iterator I = classprop_begin(), + E = classprop_end(); I != E; ++I) { + ObjCPropertyDecl *property = *I; + if (property->getIdentifier() == PropertyId) + return property; + } + return 0; +} + ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { ObjCInterfaceDecl* ClassDecl = this; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 05371e7172..21130a04fa 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -929,9 +929,9 @@ Sema::DeclTy *Sema::ActOnProperty(Scope *S, SourceLocation AtLoc, return PDecl; } -/// ActOnPropertyImplDecl - This routine performas semantic checks and -/// build the AST node for a property implementation declaration; declared -/// as @synthesize ot @dynamic +/// ActOnPropertyImplDecl - This routine performs semantic checks and +/// builds the AST node for a property implementation declaration; declared +/// as @synthesize or @dynamic. /// Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, SourceLocation PropertyLoc, @@ -957,17 +957,11 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, return 0; } // Look for this property declaration in the @implementation's @interface - ObjCInterfaceDecl::classprop_iterator I,E; - for (I = IDecl->classprop_begin(), - E = IDecl->classprop_end(); I != E; ++I) { - property = *I; - if (property->getIdentifier() == PropertyId) - break; - } - if (I == E) { - Diag(PropertyLoc, diag::error_bad_property_decl, IDecl->getName()); + property = IDecl->FindPropertyDeclaration(PropertyId); + if (!property) { + Diag(PropertyLoc, diag::error_bad_property_decl, IDecl->getName()); return 0; - } + } } else if (ObjCCategoryImplDecl* CatImplClass = dyn_cast(ClassImpDecl)) { @@ -976,26 +970,18 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, Diag(AtLoc, diag::error_missing_property_interface); return 0; } - ObjCCategoryDecl *Categories; - for (Categories = IDecl->getCategoryList(); - Categories; Categories = Categories->getNextClassCategory()) - if (Categories->getIdentifier() == CatImplClass->getIdentifier()) - break; + ObjCCategoryDecl *Category = + IDecl->FindCategoryDeclaration(CatImplClass->getIdentifier()); + // If category for this implementation not found, it is an error which // has already been reported eralier. - if (!Categories) + if (!Category) return 0; // Look for this property declaration in @implementation's category - ObjCCategoryDecl::classprop_iterator I,E; - for (I = Categories->classprop_begin(), - E = Categories->classprop_end(); I != E; ++I) { - property = *I; - if (property->getIdentifier() == PropertyId) - break; - } - if (I == E) { + property = Category->FindPropertyDeclaration(PropertyId); + if (!property) { Diag(PropertyLoc, diag::error_bad_property_decl, - Categories->getName()); + Category->getName()); return 0; } } @@ -1012,14 +998,7 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc, return 0; } // Check that this is a previously declared 'ivar' in 'IDecl' interface - ObjCInterfaceDecl::ivar_iterator IVI, IVE; - for (IVI = IDecl->ivar_begin(), IVE = IDecl->ivar_end(); - IVI != IVE; ++IVI) { - ObjCIvarDecl* ImplIvar = (*IVI); - if (ImplIvar->getIdentifier() == PropertyIvar) - break; - } - if (IVI == IVE) { + if (!IDecl->FindIvarDeclaration(PropertyIvar)) { Diag(PropertyLoc, diag::error_missing_property_ivar_decl); return 0; }