forked from OSchip/llvm-project
Initial work for property implementation declarations.
Mostly semantic checking in this patch. This is on going and incomplete. llvm-svn: 49882
This commit is contained in:
parent
be89ba0c38
commit
ffe97a3925
|
@ -27,6 +27,7 @@ class ObjCMethodDecl;
|
|||
class ObjCProtocolDecl;
|
||||
class ObjCCategoryDecl;
|
||||
class ObjCPropertyDecl;
|
||||
class ObjCPropertyImplDecl;
|
||||
|
||||
/// ObjCMethodDecl - Represents an instance or class method declaration.
|
||||
/// ObjC methods can be declared within 4 contexts: class interfaces,
|
||||
|
@ -807,6 +808,9 @@ class ObjCCategoryImplDecl : public NamedDecl {
|
|||
|
||||
/// implemented class methods
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
|
||||
|
||||
/// Propertys' being implemented
|
||||
llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
|
||||
|
||||
SourceLocation EndLoc;
|
||||
|
||||
|
@ -829,13 +833,20 @@ public:
|
|||
}
|
||||
void addClassMethod(ObjCMethodDecl *method) {
|
||||
ClassMethods.push_back(method);
|
||||
}
|
||||
}
|
||||
// Get the instance method definition for this implementation.
|
||||
ObjCMethodDecl *getInstanceMethod(Selector Sel);
|
||||
|
||||
// Get the class method definition for this implementation.
|
||||
ObjCMethodDecl *getClassMethod(Selector Sel);
|
||||
|
||||
void addPropertyImplementation(ObjCPropertyImplDecl *property) {
|
||||
PropertyImplementations.push_back(property);
|
||||
}
|
||||
|
||||
unsigned getNumPropertyImplementations() const
|
||||
{ return PropertyImplementations.size(); }
|
||||
|
||||
typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
|
||||
instmeth_iterator;
|
||||
instmeth_iterator instmeth_begin() const { return InstanceMethods.begin(); }
|
||||
|
@ -888,6 +899,9 @@ class ObjCImplementationDecl : public NamedDecl {
|
|||
/// implemented class methods
|
||||
llvm::SmallVector<ObjCMethodDecl*, 32> ClassMethods;
|
||||
|
||||
/// Propertys' being implemented
|
||||
llvm::SmallVector<ObjCPropertyImplDecl*, 8> PropertyImplementations;
|
||||
|
||||
SourceLocation EndLoc;
|
||||
|
||||
ObjCImplementationDecl(SourceLocation L, IdentifierInfo *Id,
|
||||
|
@ -912,6 +926,11 @@ public:
|
|||
void addClassMethod(ObjCMethodDecl *method) {
|
||||
ClassMethods.push_back(method);
|
||||
}
|
||||
|
||||
void addPropertyImplementation(ObjCPropertyImplDecl *property) {
|
||||
PropertyImplementations.push_back(property);
|
||||
}
|
||||
|
||||
// Location information, modeled after the Stmt API.
|
||||
SourceLocation getLocStart() const { return getLocation(); }
|
||||
SourceLocation getLocEnd() const { return EndLoc; }
|
||||
|
@ -926,6 +945,9 @@ public:
|
|||
|
||||
unsigned getNumInstanceMethods() const { return InstanceMethods.size(); }
|
||||
unsigned getNumClassMethods() const { return ClassMethods.size(); }
|
||||
|
||||
unsigned getNumPropertyImplementations() const
|
||||
{ return PropertyImplementations.size(); }
|
||||
|
||||
typedef llvm::SmallVector<ObjCMethodDecl*, 32>::const_iterator
|
||||
instmeth_iterator;
|
||||
|
@ -1041,14 +1063,15 @@ public:
|
|||
OBJC_PR_IMPL_DYNAMIC
|
||||
};
|
||||
private:
|
||||
SourceLocation AtLoc; // location of @syntheisze or @dynamic
|
||||
/// Property declaration being implemented
|
||||
ObjCPropertyDecl *PropertyDecl;
|
||||
PropertyImplKind PropertyImplementation;
|
||||
/// Null for @dynamic. Required for @synthesize.
|
||||
ObjCIvarDecl *PropertyIvarDecl;
|
||||
public:
|
||||
ObjCPropertyImplDecl(SourceLocation L)
|
||||
: Decl(ObjCPropertyImpl, L), PropertyDecl(0),
|
||||
ObjCPropertyImplDecl(SourceLocation atLoc, SourceLocation L)
|
||||
: Decl(ObjCPropertyImpl, L), AtLoc(atLoc), PropertyDecl(0),
|
||||
PropertyImplementation(OBJC_PR_IMPL_None), PropertyIvarDecl(0) {}
|
||||
|
||||
void setPropertyDecl(ObjCPropertyDecl *property) { PropertyDecl = property; }
|
||||
|
|
|
@ -487,6 +487,20 @@ DIAG(error_bad_receiver_type, ERROR,
|
|||
"bad receiver type '%0'")
|
||||
DIAG(error_no_super_class, ERROR,
|
||||
"no super class declared in @interface for '%0'")
|
||||
DIAG(error_missing_property_context, ERROR,
|
||||
"missing context for property implementation declaration")
|
||||
DIAG(error_bad_property_context, ERROR,
|
||||
"property implementation must be in a class or category implementation")
|
||||
DIAG(error_bad_property_decl, ERROR,
|
||||
"property implementation must have the declaration in the class '%0'")
|
||||
DIAG(error_property_ivar_decl, ERROR,
|
||||
"property synthesize requires specification of an ivar")
|
||||
DIAG(error_dynamic_property_ivar_decl, ERROR,
|
||||
"dynamic property can not have ivar specification")
|
||||
DIAG(error_missing_property_interface, ERROR,
|
||||
"property implementation in a class/category implementation with no interface")
|
||||
DIAG(error_missing_property_ivar_decl, ERROR,
|
||||
"property synthesize requires a previously declared ivar")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Semantic Analysis
|
||||
|
|
|
@ -626,6 +626,18 @@ public:
|
|||
SourceLocation CatLoc) {
|
||||
return 0;
|
||||
}
|
||||
// ActOnPropertyImplDecl - called for every property implementation
|
||||
virtual DeclTy *ActOnPropertyImplDecl(
|
||||
SourceLocation AtLoc, // location of the @syntheize/@dynamic
|
||||
SourceLocation PropertyNameLoc, // location for the property name
|
||||
bool ImplKind, // true for @synthesize, false for
|
||||
// @dynamic
|
||||
DeclTy *ClassImplDecl, // class or category implementation
|
||||
IdentifierInfo *propertyId, // name of property
|
||||
IdentifierInfo *propertyIvar) { // name of the ivar
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ActOnMethodDeclaration - called for all method declarations.
|
||||
virtual DeclTy *ActOnMethodDeclaration(
|
||||
SourceLocation BeginLoc, // location of the + or -.
|
||||
|
|
|
@ -1031,13 +1031,15 @@ Parser::DeclTy *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) {
|
|||
Parser::DeclTy *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
|
||||
assert(Tok.isObjCAtKeyword(tok::objc_synthesize) &&
|
||||
"ParseObjCPropertyDynamic(): Expected '@synthesize'");
|
||||
SourceLocation loc = ConsumeToken(); // consume dynamic
|
||||
SourceLocation loc = ConsumeToken(); // consume synthesize
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_expected_ident);
|
||||
return 0;
|
||||
}
|
||||
while (Tok.is(tok::identifier)) {
|
||||
ConsumeToken(); // consume property name
|
||||
IdentifierInfo *propertyIvar = 0;
|
||||
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
|
||||
SourceLocation propertyLoc = ConsumeToken(); // consume property name
|
||||
if (Tok.is(tok::equal)) {
|
||||
// property '=' ivar-name
|
||||
ConsumeToken(); // consume '='
|
||||
|
@ -1045,8 +1047,11 @@ Parser::DeclTy *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) {
|
|||
Diag(Tok, diag::err_expected_ident);
|
||||
break;
|
||||
}
|
||||
propertyIvar = Tok.getIdentifierInfo();
|
||||
ConsumeToken(); // consume ivar-name
|
||||
}
|
||||
Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl,
|
||||
propertyId, propertyIvar);
|
||||
if (Tok.isNot(tok::comma))
|
||||
break;
|
||||
ConsumeToken(); // consume ','
|
||||
|
|
|
@ -656,7 +656,13 @@ public:
|
|||
DeclTy **allProperties = 0, unsigned pNum = 0);
|
||||
|
||||
virtual DeclTy *ActOnProperty(Scope *S, SourceLocation AtLoc,
|
||||
FieldDeclarator &FD, ObjCDeclSpec &ODS);
|
||||
FieldDeclarator &FD, ObjCDeclSpec &ODS);
|
||||
virtual DeclTy *ActOnPropertyImplDecl(SourceLocation AtLoc,
|
||||
SourceLocation PropertyLoc,
|
||||
bool ImplKind, DeclTy *ClassImplDecl,
|
||||
IdentifierInfo *PropertyId,
|
||||
IdentifierInfo *PropertyIvar);
|
||||
|
||||
virtual DeclTy *ActOnMethodDeclaration(
|
||||
SourceLocation BeginLoc, // location of the + or -.
|
||||
SourceLocation EndLoc, // location of the ; or {.
|
||||
|
|
|
@ -929,5 +929,116 @@ 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
|
||||
///
|
||||
Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
|
||||
SourceLocation PropertyLoc,
|
||||
bool Synthesize,
|
||||
DeclTy *ClassCatImpDecl,
|
||||
IdentifierInfo *PropertyId,
|
||||
IdentifierInfo *PropertyIvar) {
|
||||
Decl *ClassImpDecl = static_cast<Decl*>(ClassCatImpDecl);
|
||||
// Make sure we have a context for the property implementation declaration.
|
||||
if (!ClassImpDecl) {
|
||||
Diag(AtLoc, diag::error_missing_property_context);
|
||||
return 0;
|
||||
}
|
||||
ObjCPropertyDecl *property = 0;
|
||||
ObjCInterfaceDecl* IDecl = 0;
|
||||
// Find the class or category class where this property must have
|
||||
// a declaration.
|
||||
if (ObjCImplementationDecl *IC =
|
||||
dyn_cast<ObjCImplementationDecl>(ClassImpDecl)) {
|
||||
IDecl = getObjCInterfaceDecl(IC->getIdentifier());
|
||||
if (!IDecl) {
|
||||
Diag(AtLoc, diag::error_missing_property_interface);
|
||||
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());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (ObjCCategoryImplDecl* CatImplClass =
|
||||
dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl)) {
|
||||
IDecl = CatImplClass->getClassInterface();
|
||||
if (!IDecl) {
|
||||
Diag(AtLoc, diag::error_missing_property_interface);
|
||||
return 0;
|
||||
}
|
||||
ObjCCategoryDecl *Categories;
|
||||
for (ObjCCategoryDecl *Categories = IDecl->getCategoryList();
|
||||
Categories; Categories = Categories->getNextClassCategory())
|
||||
if (Categories->getIdentifier() == CatImplClass->getIdentifier())
|
||||
break;
|
||||
// If category for this implementation not found, it is an error which
|
||||
// has already been reported eralier.
|
||||
if (!Categories)
|
||||
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) {
|
||||
Diag(PropertyLoc, diag::error_bad_property_decl,
|
||||
Categories->getName());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Diag(AtLoc, diag::error_bad_property_context);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check that we have a valid, previously declared ivar for @synthesize
|
||||
if (Synthesize) {
|
||||
// @synthesize
|
||||
if (!PropertyIvar) {
|
||||
Diag(PropertyLoc, diag::error_property_ivar_decl);
|
||||
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) {
|
||||
Diag(PropertyLoc, diag::error_missing_property_ivar_decl);
|
||||
return 0;
|
||||
}
|
||||
} else if (PropertyIvar) {
|
||||
// @dynamic
|
||||
Diag(PropertyLoc, diag::error_dynamic_property_ivar_decl);
|
||||
return 0;
|
||||
}
|
||||
// TODO: More diagnostics go here !!
|
||||
assert (property && "ActOnPropertyImplDecl - property declaration missing");
|
||||
// TODO: Build the property implementation AST, pushes it into its
|
||||
// class/cateogory implementation's vector of property implementations
|
||||
#if 0
|
||||
ObjCCategoryImplDecl *PIDecl =
|
||||
ObjCCategoryImplDecl::Create(AtLoc, PropertyLoc, property,
|
||||
Synthesize ? ObjCPropertyImplDecl::OBJC_PR_IMPL_SYNTHSIZE
|
||||
: ObjCPropertyImplDecl::OBJC_PR_IMPL_DYNAMIC,
|
||||
PropertyId, PropertyIvar);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue