From 02edb98b457c1be3fabe63f7390fe75fd6689def Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 1 May 2008 00:03:38 +0000 Subject: [PATCH] More ObjC2 property semantics work. Work in progress. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50508 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticKinds.def | 6 +++ include/clang/Parse/Action.h | 7 ---- lib/Sema/Sema.h | 9 +++-- lib/Sema/SemaDeclObjC.cpp | 50 +++++++++++++++---------- 4 files changed, 42 insertions(+), 30 deletions(-) diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 79b28cb889..07d1519440 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -508,6 +508,12 @@ 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'") +DIAG(warn_readonly_property, WARNING, + "attribute 'readonly' of property '%0' restricts attribute " + "'readwrite' of '%1' property in super class") +DIAG(warn_property_attribute, WARNING, + "property '%0' '%1' attribute does not match super class '%2' " + "property") //===----------------------------------------------------------------------===// // Semantic Analysis diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index f283fff22c..f0d5158297 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -733,13 +733,6 @@ public: Protocols) { } - /// ComparePropertiesInBaseAndSuper - This routine compares property - /// declarations in base and its super class, if any, and issues - /// diagnostics in a variety of inconsistant situations. - /// - virtual void ComparePropertiesInBaseAndSuper(SourceLocation *PropertyLoc, - DeclTy *ClassInterface) { - } //===----------------------- Obj-C Expressions --------------------------===// virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 37b9805d0a..8b8535154a 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -61,6 +61,7 @@ namespace clang { class ObjCCategoryDecl; class ObjCIvarDecl; class ObjCMethodDecl; + class ObjCPropertyDecl; /// Sema - This implements semantic analysis and AST building for C. class Sema : public Action { @@ -658,9 +659,11 @@ public: unsigned NumProtocols, llvm::SmallVector & Protocols); - - virtual void ComparePropertiesInBaseAndSuper(SourceLocation *PropertyLoc, - DeclTy *ClassInterface); + + void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, + ObjCPropertyDecl *SuperProperty, + ObjCInterfaceDecl*SuperIDecl); + void ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl); virtual void ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, DeclTy **allMethods = 0, unsigned allNum = 0, diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 3b5be29730..da7b1513c8 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -249,37 +249,47 @@ Sema::FindProtocolDeclaration(SourceLocation TypeLoc, /// // TODO: Incomplete. // -static void -DiagnosePropertyMismatch(ObjCPropertyDecl *Property, - ObjCPropertyDecl *SuperProperty) { +void +Sema::DiagnosePropertyMismatch(ObjCPropertyDecl *Property, + ObjCPropertyDecl *SuperProperty, + ObjCInterfaceDecl *SuperIDecl) { ObjCPropertyDecl::PropertyAttributeKind CAttr = Property->getPropertyAttributes(); ObjCPropertyDecl::PropertyAttributeKind SAttr = SuperProperty->getPropertyAttributes(); if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) && (SAttr & ObjCPropertyDecl::OBJC_PR_readwrite)) - ; // ??? - + Diag(Property->getLocation(), diag::warn_readonly_property, + Property->getName(), SuperIDecl->getName()); if ((CAttr & ObjCPropertyDecl::OBJC_PR_copy) != (SAttr & ObjCPropertyDecl::OBJC_PR_copy)) - ; // + Diag(Property->getLocation(), diag::warn_property_attribute, + Property->getName(), "copy", SuperIDecl->getName(), + SourceRange()); else if ((CAttr & ObjCPropertyDecl::OBJC_PR_retain) != (SAttr & ObjCPropertyDecl::OBJC_PR_retain)) - ; // ??? + Diag(Property->getLocation(), diag::warn_property_attribute, + Property->getName(), "retain", SuperIDecl->getName(), + SourceRange()); if ((CAttr & ObjCPropertyDecl::OBJC_PR_nonatomic) != (SAttr & ObjCPropertyDecl::OBJC_PR_nonatomic)) - ; // - + Diag(Property->getLocation(), diag::warn_property_attribute, + Property->getName(), "atomic", SuperIDecl->getName(), + SourceRange()); if (Property->getSetterName() != SuperProperty->getSetterName()) - ; // + Diag(Property->getLocation(), diag::warn_property_attribute, + Property->getName(), "setter", SuperIDecl->getName(), + SourceRange()); if (Property->getGetterName() != SuperProperty->getGetterName()) - ; // + Diag(Property->getLocation(), diag::warn_property_attribute, + Property->getName(), "getter", SuperIDecl->getName(), + SourceRange()); if (Property->getCanonicalType() != SuperProperty->getCanonicalType()) { if ((CAttr & ObjCPropertyDecl::OBJC_PR_readonly) && (SAttr & ObjCPropertyDecl::OBJC_PR_readonly)) - // && objc_compare_types(...)) + // && objc_compare_types(...)) ; else ; // @@ -292,22 +302,19 @@ DiagnosePropertyMismatch(ObjCPropertyDecl *Property, /// diagnostics in a variety of inconsistant situations. /// void -Sema::ComparePropertiesInBaseAndSuper(SourceLocation *PropertyLoc, - DeclTy *D) { - ObjCInterfaceDecl *IDecl = - dyn_cast(static_cast(D)); +Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) { ObjCInterfaceDecl *SDecl = IDecl->getSuperClass(); if (!SDecl) return; - for (ObjCInterfaceDecl::classprop_iterator I = SDecl->classprop_begin(), - E = SDecl->classprop_end(); I != E; ++I) { - ObjCPropertyDecl *SuperPDecl = (*I); + for (ObjCInterfaceDecl::classprop_iterator S = SDecl->classprop_begin(), + E = SDecl->classprop_end(); S != E; ++S) { + ObjCPropertyDecl *SuperPDecl = (*S); // Does property in super class has declaration in current class? for (ObjCInterfaceDecl::classprop_iterator I = IDecl->classprop_begin(), E = IDecl->classprop_end(); I != E; ++I) { ObjCPropertyDecl *PDecl = (*I); if (SuperPDecl->getIdentifier() == PDecl->getIdentifier()) - DiagnosePropertyMismatch(PDecl, SuperPDecl); + DiagnosePropertyMismatch(PDecl, SuperPDecl, SDecl); } } } @@ -815,6 +822,9 @@ void Sema::ActOnAtEnd(SourceLocation AtEndLoc, DeclTy *classDecl, if (ObjCInterfaceDecl *I = dyn_cast(ClassDecl)) { I->addMethods(&insMethods[0], insMethods.size(), &clsMethods[0], clsMethods.size(), AtEndLoc); + // Compares properties declaraed in this class to those of its + // super class. + ComparePropertiesInBaseAndSuper (I); } else if (ObjCProtocolDecl *P = dyn_cast(ClassDecl)) { P->addMethods(&insMethods[0], insMethods.size(), &clsMethods[0], clsMethods.size(), AtEndLoc);