forked from OSchip/llvm-project
More type-checking of setter/getter methods. This is still
work in prgress. llvm-svn: 60430
This commit is contained in:
parent
027d726f10
commit
eae373ea32
|
@ -569,6 +569,10 @@ DIAG(err_use_continuation_class, ERROR,
|
|||
"use contination class to override 'readonly' property with 'readwrite'")
|
||||
DIAG(warn_property_attr_mismatch, WARNING,
|
||||
"property attribute in continuation class does not match the primary class")
|
||||
DIAG(err_accessor_property_type_mismatch, ERROR,
|
||||
"type of property %0 does not match type of accessor %1")
|
||||
DIAG(err_setter_type_void, ERROR,
|
||||
"type of setter must be void")
|
||||
|
||||
/// C++ parser diagnostics
|
||||
DIAG(err_expected_unqualified_id, ERROR,
|
||||
|
|
|
@ -1032,6 +1032,9 @@ public:
|
|||
void CheckObjCPropertyAttributes(QualType PropertyTy,
|
||||
SourceLocation Loc,
|
||||
unsigned &Attributes);
|
||||
void diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property,
|
||||
const ObjCMethodDecl *GetterMethod,
|
||||
const ObjCMethodDecl *SetterMethod);
|
||||
void DiagnosePropertyMismatch(ObjCPropertyDecl *Property,
|
||||
ObjCPropertyDecl *SuperProperty,
|
||||
const IdentifierInfo *Name);
|
||||
|
|
|
@ -855,6 +855,33 @@ void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) {
|
|||
}
|
||||
}
|
||||
|
||||
/// diagnosePropertySetterGetterMismatch - Make sure that use-defined
|
||||
/// setter/getter methods have the property type and issue diagnostics
|
||||
/// if they don't.
|
||||
///
|
||||
void
|
||||
Sema::diagnosePropertySetterGetterMismatch(ObjCPropertyDecl *property,
|
||||
const ObjCMethodDecl *GetterMethod,
|
||||
const ObjCMethodDecl *SetterMethod) {
|
||||
if (GetterMethod &&
|
||||
GetterMethod->getResultType() != property->getType())
|
||||
Diag(property->getLocation(),
|
||||
diag::err_accessor_property_type_mismatch)
|
||||
<< property->getDeclName()
|
||||
<< GetterMethod->getSelector().getAsIdentifierInfo();
|
||||
|
||||
if (SetterMethod) {
|
||||
if (SetterMethod->getResultType() != Context.VoidPtrTy)
|
||||
Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
|
||||
if (SetterMethod->getNumParams() != 1 ||
|
||||
(SetterMethod->getParamDecl(0)->getType() != property->getType()))
|
||||
Diag(property->getLocation(),
|
||||
diag::err_accessor_property_type_mismatch)
|
||||
<< property->getDeclName()
|
||||
<< SetterMethod->getSelector().getAsIdentifierInfo();
|
||||
}
|
||||
}
|
||||
|
||||
// Note: For class/category implemenations, allMethods/allProperties is
|
||||
// always null.
|
||||
void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
||||
|
@ -940,15 +967,21 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
ComparePropertiesInBaseAndSuper(I);
|
||||
MergeProtocolPropertiesIntoClass(I, I);
|
||||
for (ObjCInterfaceDecl::classprop_iterator i = I->classprop_begin(),
|
||||
e = I->classprop_end(); i != e; ++i)
|
||||
e = I->classprop_end(); i != e; ++i) {
|
||||
diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
|
||||
InsMap[(*i)->getSetterName()]);
|
||||
I->addPropertyMethods(Context, *i, insMethods, InsMap);
|
||||
}
|
||||
I->addMethods(&insMethods[0], insMethods.size(),
|
||||
&clsMethods[0], clsMethods.size(), AtEndLoc);
|
||||
|
||||
} else if (ObjCProtocolDecl *P = dyn_cast<ObjCProtocolDecl>(ClassDecl)) {
|
||||
for (ObjCProtocolDecl::classprop_iterator i = P->classprop_begin(),
|
||||
e = P->classprop_end(); i != e; ++i)
|
||||
e = P->classprop_end(); i != e; ++i) {
|
||||
diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
|
||||
InsMap[(*i)->getSetterName()]);
|
||||
P->addPropertyMethods(Context, *i, insMethods, InsMap);
|
||||
}
|
||||
P->addMethods(&insMethods[0], insMethods.size(),
|
||||
&clsMethods[0], clsMethods.size(), AtEndLoc);
|
||||
}
|
||||
|
@ -958,8 +991,11 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl,
|
|||
// FIXME: If we merge properties into class we should probably
|
||||
// merge them into category as well?
|
||||
for (ObjCCategoryDecl::classprop_iterator i = C->classprop_begin(),
|
||||
e = C->classprop_end(); i != e; ++i)
|
||||
e = C->classprop_end(); i != e; ++i) {
|
||||
diagnosePropertySetterGetterMismatch((*i), InsMap[(*i)->getGetterName()],
|
||||
InsMap[(*i)->getSetterName()]);
|
||||
C->addPropertyMethods(Context, *i, insMethods, InsMap);
|
||||
}
|
||||
C->addMethods(&insMethods[0], insMethods.size(),
|
||||
&clsMethods[0], clsMethods.size(), AtEndLoc);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue