aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2008-04-21 19:04:53 +0000
committerFariborz Jahanian <fjahanian@apple.com>2008-04-21 19:04:53 +0000
commit559c0c4bbecc017aab0716d546c4fefbcc194687 (patch)
tree1507eb52da72eb1363c5404d503a2870e6e2d399
parent393ff04a07d7fd9b212b2cbe398435813c73c9a1 (diff)
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
-rw-r--r--include/clang/AST/DeclObjC.h40
-rw-r--r--include/clang/Parse/Action.h2
-rw-r--r--lib/AST/DeclObjC.cpp55
-rw-r--r--lib/Sema/SemaDeclObjC.cpp51
4 files changed, 108 insertions, 40 deletions
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<ObjCMethodDecl*, 32> ClassMethods;
- /// Propertys' being implemented
+ /// Property Implementations in this category
llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
SourceLocation EndLoc;
@@ -847,6 +863,16 @@ public:
unsigned getNumPropertyImplementations() const
{ return PropertyImplementations.size(); }
+
+ typedef llvm::SmallVector<ObjCPropertyImplDecl*, 8>::const_iterator
+ propimpl_iterator;
+ propimpl_iterator propimpl_begin() const {
+ return PropertyImplementations.begin();
+ }
+ propimpl_iterator propimpl_end() const {
+ return PropertyImplementations.end();
+ }
+
typedef llvm::SmallVector<ObjCMethodDecl*, 32>::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<ObjCPropertyImplDecl*, 8>::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<ObjCCategoryImplDecl>(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;
}