diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticKinds.def | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 3 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 42 | 
3 files changed, 46 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 2e76df17ba1..e48de866d66 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -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, diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 7f3d0f4d2ff..cfb221bf401 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -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); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 3a78024f90d..ed875166878 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -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);    }  | 

