diff options
Diffstat (limited to 'clang/lib/Sema/SemaObjCProperty.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaObjCProperty.cpp | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 269c65e6082..e49edc908aa 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -714,6 +714,58 @@ static void setImpliedPropertyAttributeForReadOnlyProperty( return; } +/// DiagnosePropertyMismatchDeclInProtocols - diagnose properties declared +/// in inherited protocols with mismatched types. Since any of them can +/// be candidate for synthesis. +void DiagnosePropertyMismatchDeclInProtocols(Sema &S, SourceLocation AtLoc, + ObjCInterfaceDecl *ClassDecl, + ObjCPropertyDecl *Property) { + ObjCInterfaceDecl::ProtocolPropertyMap PropMap; + for (ObjCInterfaceDecl::all_protocol_iterator + PI = ClassDecl->all_referenced_protocol_begin(), + E = ClassDecl->all_referenced_protocol_end(); PI != E; ++PI) { + if (const ObjCProtocolDecl *PDecl = (*PI)->getDefinition()) + PDecl->collectInheritedProtocolProperties(Property, PropMap); + } + if (ObjCInterfaceDecl *SDecl = ClassDecl->getSuperClass()) + while (SDecl) { + for (ObjCInterfaceDecl::all_protocol_iterator + PI = SDecl->all_referenced_protocol_begin(), + E = SDecl->all_referenced_protocol_end(); PI != E; ++PI) { + if (const ObjCProtocolDecl *PDecl = (*PI)->getDefinition()) + PDecl->collectInheritedProtocolProperties(Property, PropMap); + } + SDecl = SDecl->getSuperClass(); + } + + if (PropMap.empty()) + return; + + QualType RHSType = S.Context.getCanonicalType(Property->getType()); + bool FirsTime = true; + for (ObjCInterfaceDecl::ProtocolPropertyMap::iterator + I = PropMap.begin(), E = PropMap.end(); I != E; I++) { + ObjCPropertyDecl *Prop = I->second; + QualType LHSType = S.Context.getCanonicalType(Prop->getType()); + if (!S.Context.propertyTypesAreCompatible(LHSType, RHSType)) { + bool IncompatibleObjC = false; + QualType ConvertedType; + if (!S.isObjCPointerConversion(RHSType, LHSType, ConvertedType, IncompatibleObjC) + || IncompatibleObjC) { + if (FirsTime) { + S.Diag(Property->getLocation(), diag::warn_protocol_property_mismatch) + << Property->getType(); + FirsTime = false; + } + S.Diag(Prop->getLocation(), diag::note_protocol_property_declare) + << Prop->getType(); + } + } + } + if (!FirsTime && AtLoc.isValid()) + S.Diag(AtLoc, diag::note_property_synthesize); +} + /// DiagnoseClassAndClassExtPropertyMismatch - diagnose inconsistant property /// attribute declared in primary class and attributes overridden in any of its /// class extensions. @@ -879,6 +931,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, } } } + if (Synthesize && isa<ObjCProtocolDecl>(property->getDeclContext())) + DiagnosePropertyMismatchDeclInProtocols(*this, AtLoc, IDecl, property); DiagnoseClassAndClassExtPropertyMismatch(*this, IDecl, property); |

