Support for @dynamic AST build.
More property semantics checking. First test case for ObjC2's property implementation. llvm-svn: 50057
This commit is contained in:
parent
74a58d780a
commit
f2a7d7c949
|
@ -1066,6 +1066,8 @@ public:
|
|||
static ObjCPropertyDecl *Create(ASTContext &C, SourceLocation L,
|
||||
IdentifierInfo *Id, QualType T);
|
||||
QualType getType() const { return DeclType; }
|
||||
QualType getCanonicalType() const { return DeclType.getCanonicalType(); }
|
||||
|
||||
PropertyAttributeKind getPropertyAttributes() const {
|
||||
return PropertyAttributeKind(PropertyAttributes);
|
||||
}
|
||||
|
|
|
@ -492,15 +492,21 @@ DIAG(error_missing_property_context, ERROR,
|
|||
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'")
|
||||
"property implementation must have its declaration in the class '%0'")
|
||||
DIAG(error_bad_category_property_decl, ERROR,
|
||||
"property implementation must have its declaration in the category '%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")
|
||||
"property implementation in a category with no category declaration")
|
||||
DIAG(error_missing_property_ivar_decl, ERROR,
|
||||
"property synthesize requires a previously declared ivar")
|
||||
DIAG(error_synthesize_category_decl, ERROR,
|
||||
"@synthesize not allowed in a category's implementation")
|
||||
DIAG(error_property_ivar_type, ERROR,
|
||||
"type of property '%0' does not match type of ivar '%1'")
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Semantic Analysis
|
||||
|
|
|
@ -1077,7 +1077,11 @@ Parser::DeclTy *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) {
|
|||
return 0;
|
||||
}
|
||||
while (Tok.is(tok::identifier)) {
|
||||
ConsumeToken(); // consume property name
|
||||
IdentifierInfo *propertyId = Tok.getIdentifierInfo();
|
||||
SourceLocation propertyLoc = ConsumeToken(); // consume property name
|
||||
Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl,
|
||||
propertyId, 0);
|
||||
|
||||
if (Tok.isNot(tok::comma))
|
||||
break;
|
||||
ConsumeToken(); // consume ','
|
||||
|
|
|
@ -952,10 +952,11 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
|
|||
if (ObjCImplementationDecl *IC =
|
||||
dyn_cast<ObjCImplementationDecl>(ClassImpDecl)) {
|
||||
IDecl = getObjCInterfaceDecl(IC->getIdentifier());
|
||||
if (!IDecl) {
|
||||
Diag(AtLoc, diag::error_missing_property_interface);
|
||||
return 0;
|
||||
}
|
||||
// We always synthesize an interface for an implementation
|
||||
// without an interface decl. So, IDecl is always non-zero.
|
||||
assert(IDecl &&
|
||||
"ActOnPropertyImplDecl - @implementation without @interface");
|
||||
|
||||
// Look for this property declaration in the @implementation's @interface
|
||||
property = IDecl->FindPropertyDeclaration(PropertyId);
|
||||
if (!property) {
|
||||
|
@ -965,6 +966,10 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
|
|||
}
|
||||
else if (ObjCCategoryImplDecl* CatImplClass =
|
||||
dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl)) {
|
||||
if (Synthesize) {
|
||||
Diag(AtLoc, diag::error_synthesize_category_decl);
|
||||
return 0;
|
||||
}
|
||||
IDecl = CatImplClass->getClassInterface();
|
||||
if (!IDecl) {
|
||||
Diag(AtLoc, diag::error_missing_property_interface);
|
||||
|
@ -980,7 +985,7 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
|
|||
// Look for this property declaration in @implementation's category
|
||||
property = Category->FindPropertyDeclaration(PropertyId);
|
||||
if (!property) {
|
||||
Diag(PropertyLoc, diag::error_bad_property_decl,
|
||||
Diag(PropertyLoc, diag::error_bad_category_property_decl,
|
||||
Category->getName());
|
||||
return 0;
|
||||
}
|
||||
|
@ -998,16 +1003,23 @@ Sema::DeclTy *Sema::ActOnPropertyImplDecl(SourceLocation AtLoc,
|
|||
return 0;
|
||||
}
|
||||
// Check that this is a previously declared 'ivar' in 'IDecl' interface
|
||||
if (!IDecl->FindIvarDeclaration(PropertyIvar)) {
|
||||
ObjCIvarDecl *Ivar = IDecl->FindIvarDeclaration(PropertyIvar);
|
||||
if (!Ivar) {
|
||||
Diag(PropertyLoc, diag::error_missing_property_ivar_decl);
|
||||
return 0;
|
||||
}
|
||||
// Check that type of property and its ivar match.
|
||||
if (Ivar->getCanonicalType() != property->getCanonicalType()) {
|
||||
Diag(PropertyLoc, diag::error_property_ivar_type, property->getName(),
|
||||
Ivar->getName());
|
||||
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
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
@interface I
|
||||
{
|
||||
int IVAR;
|
||||
}
|
||||
@property int d1;
|
||||
@property id prop_id;
|
||||
@end
|
||||
|
||||
@interface I(CAT)
|
||||
@property int d1;
|
||||
@end
|
||||
|
||||
@implementation I
|
||||
@synthesize d1; // expected-error {{property synthesize requires specification of an ivar}}
|
||||
@dynamic bad; // expected-error {{property implementation must have its declaration in the class 'I'}}
|
||||
@synthesize prop_id; // expected-error {{property synthesize requires specification of an ivar}}
|
||||
@synthesize prop_id = IVAR; // expected-error {{type of property 'prop_id' does not match type of ivar 'IVAR'}}
|
||||
@end
|
||||
|
||||
@implementation I(CAT)
|
||||
@synthesize d1; // expected-error {{@synthesize not allowed in a category's implementation}}
|
||||
@dynamic bad; // expected-error {{property implementation must have its declaration in the category 'CAT'}}
|
||||
@end
|
||||
|
||||
@implementation E // expected-warning {{cannot find interface declaration for 'E'}}
|
||||
@dynamic d; // expected-error {{property implementation must have its declaration in the class 'E'}}
|
||||
@end
|
||||
|
||||
@implementation Q(MYCAT) // expected-error {{cannot find interface declaration for 'Q'}}
|
||||
@dynamic d; // expected-error {{property implementation in a category with no category declaration}}
|
||||
@end
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue