Note<"required for direct or indirect protocol %0">;
def warn_conflicting_ret_types : Warning<
- "conflicting return type in implementation of %0: %1 vs %2">;
+ "conflicting return type in "
+ "%select{implementation|declaration}3 of %0: %1 vs %2">;
def warn_conflicting_ret_type_modifiers : Warning<
"conflicting distributed object modifiers on return type "
- "in implementation of %0">,
+ "in %select{implementation|declaration}1 of %0">,
InGroup<DiagGroup<"distributed-object-modifiers">>;
def warn_non_covariant_ret_types : Warning<
- "conflicting return type in implementation of %0: %1 vs %2">,
+ "conflicting return type in "
+ "%select{implementation|declaration}3 of %0: %1 vs %2">,
InGroup<DiagGroup<"method-signatures">>, DefaultIgnore;
def warn_conflicting_param_types : Warning<
- "conflicting parameter types in implementation of %0: %1 vs %2">;
+ "conflicting parameter types in "
+ "%select{implementation|declaration}3 of %0: %1 vs %2">;
def warn_conflicting_param_modifiers : Warning<
"conflicting distributed object modifiers on parameter type "
- "in implementation of %0">,
+ "in %select{implementation|declaration}1 of %0">,
InGroup<DiagGroup<"distributed-object-modifiers">>;
def warn_non_contravariant_param_types : Warning<
- "conflicting parameter types in implementation of %0: %1 vs %2">,
+ "conflicting parameter types in "
+ "%select{implementation|declaration}3 of %0: %1 vs %2">,
InGroup<DiagGroup<"method-signatures">>, DefaultIgnore;
def warn_conflicting_variadic :Warning<
- "conflicting variadic declaration of method and its implementation">;
+ "conflicting variadic declaration of method and its "
+ "%select{implementation|declaration}0">;
def warn_implements_nscopying : Warning<
"default assign attribute on property %0 which implements "
static void CheckMethodOverrideReturn(Sema &S,
ObjCMethodDecl *MethodImpl,
ObjCMethodDecl *MethodDecl,
- bool IsProtocolMethodDecl) {
+ bool IsProtocolMethodDecl,
+ bool IsDeclaration) {
if (IsProtocolMethodDecl &&
(MethodDecl->getObjCDeclQualifier() !=
MethodImpl->getObjCDeclQualifier())) {
S.Diag(MethodImpl->getLocation(),
diag::warn_conflicting_ret_type_modifiers)
- << MethodImpl->getDeclName()
+ << MethodImpl->getDeclName() << IsDeclaration
<< getTypeRange(MethodImpl->getResultTypeSourceInfo());
S.Diag(MethodDecl->getLocation(), diag::note_previous_declaration)
<< getTypeRange(MethodDecl->getResultTypeSourceInfo());
<< MethodImpl->getDeclName()
<< MethodDecl->getResultType()
<< MethodImpl->getResultType()
+ << IsDeclaration
<< getTypeRange(MethodImpl->getResultTypeSourceInfo());
S.Diag(MethodDecl->getLocation(), diag::note_previous_definition)
<< getTypeRange(MethodDecl->getResultTypeSourceInfo());
ObjCMethodDecl *MethodDecl,
ParmVarDecl *ImplVar,
ParmVarDecl *IfaceVar,
- bool IsProtocolMethodDecl) {
+ bool IsProtocolMethodDecl,
+ bool IsDeclaration) {
if (IsProtocolMethodDecl &&
(ImplVar->getObjCDeclQualifier() !=
IfaceVar->getObjCDeclQualifier())) {
S.Diag(ImplVar->getLocation(),
diag::warn_conflicting_param_modifiers)
<< getTypeRange(ImplVar->getTypeSourceInfo())
- << MethodImpl->getDeclName();
+ << MethodImpl->getDeclName() << IsDeclaration;
S.Diag(IfaceVar->getLocation(), diag::note_previous_declaration)
<< getTypeRange(IfaceVar->getTypeSourceInfo());
}
S.Diag(ImplVar->getLocation(), DiagID)
<< getTypeRange(ImplVar->getTypeSourceInfo())
- << MethodImpl->getDeclName() << IfaceTy << ImplTy;
+ << MethodImpl->getDeclName() << IfaceTy << ImplTy
+ << IsDeclaration;
S.Diag(IfaceVar->getLocation(), diag::note_previous_definition)
<< getTypeRange(IfaceVar->getTypeSourceInfo());
}
void Sema::WarnConflictingTypedMethods(ObjCMethodDecl *ImpMethodDecl,
ObjCMethodDecl *MethodDecl,
- bool IsProtocolMethodDecl) {
+ bool IsProtocolMethodDecl,
+ bool IsDeclaration) {
if (getLangOptions().ObjCAutoRefCount &&
checkMethodFamilyMismatch(*this, ImpMethodDecl, MethodDecl))
return;
CheckMethodOverrideReturn(*this, ImpMethodDecl, MethodDecl,
- IsProtocolMethodDecl);
+ IsProtocolMethodDecl, IsDeclaration);
for (ObjCMethodDecl::param_iterator IM = ImpMethodDecl->param_begin(),
IF = MethodDecl->param_begin(), EM = ImpMethodDecl->param_end();
IM != EM; ++IM, ++IF)
CheckMethodOverrideParam(*this, ImpMethodDecl, MethodDecl, *IM, *IF,
- IsProtocolMethodDecl);
+ IsProtocolMethodDecl, IsDeclaration);
if (ImpMethodDecl->isVariadic() != MethodDecl->isVariadic()) {
- Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_variadic);
+ Diag(ImpMethodDecl->getLocation(), diag::warn_conflicting_variadic)
+ << IsDeclaration;
Diag(MethodDecl->getLocation(), diag::note_previous_declaration);
}
}
MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
IMPDecl,
(*PI), IncompleteImpl, false);
+
+ // Check for any type mismtch of methods declared in class
+ // and methods declared in protocol.
+ MatchMethodsInClassAndItsProtocol(I);
+
if (I->getSuperClass())
MatchAllMethodDeclarations(InsMap, ClsMap, InsMapSeen, ClsMapSeen,
IMPDecl,
}
}
+static void MatchMethodsInClassAndOneProtocol(Sema &S,
+ Sema::SelectorSet &InsMap,
+ Sema::SelectorSet &ClsMap,
+ const ObjCContainerDecl *IDecl,
+ const ObjCProtocolDecl *PDecl) {
+ if (!InsMap.empty())
+ for (ObjCInterfaceDecl::instmeth_iterator IM = PDecl->instmeth_begin(),
+ E = PDecl->instmeth_end(); IM != E; ++IM) {
+ Selector Sel = (*IM)->getSelector();
+ if (InsMap.count(Sel)) {
+ ObjCMethodDecl *ProtoMethodDecl = PDecl->getInstanceMethod(Sel);
+ ObjCMethodDecl *ClsMethodDecl = IDecl->getInstanceMethod(Sel);
+ if (ProtoMethodDecl && ClsMethodDecl)
+ S.WarnConflictingTypedMethods(
+ ClsMethodDecl,
+ ProtoMethodDecl, true, true);
+ InsMap.erase(Sel);
+ }
+ if (InsMap.empty())
+ break;
+ }
+ if (!ClsMap.empty())
+ for (ObjCInterfaceDecl::classmeth_iterator IM = PDecl->classmeth_begin(),
+ E = PDecl->classmeth_end(); IM != E; ++IM) {
+ Selector Sel = (*IM)->getSelector();
+ if (ClsMap.count(Sel)) {
+ ObjCMethodDecl *ProtoMethodDecl = PDecl->getClassMethod(Sel);
+ ObjCMethodDecl *ClsMethodDecl = IDecl->getClassMethod(Sel);
+ if (ProtoMethodDecl && ClsMethodDecl)
+ S.WarnConflictingTypedMethods(
+ ClsMethodDecl,
+ ProtoMethodDecl, true, true);
+ ClsMap.erase(Sel);
+ }
+ if (ClsMap.empty())
+ break;
+ }
+ if (InsMap.empty() && ClsMap.empty())
+ return;
+
+ for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(),
+ PE = PDecl->protocol_end(); PI != PE; ++PI)
+ MatchMethodsInClassAndOneProtocol(S, InsMap, ClsMap, IDecl, (*PI));
+}
+
+void Sema::MatchMethodsInClassAndItsProtocol(const ObjCInterfaceDecl *CDecl) {
+ if (CDecl->all_referenced_protocol_begin() ==
+ CDecl->all_referenced_protocol_end())
+ return;
+
+ SelectorSet InsMap, ClsMap;
+ for (ObjCInterfaceDecl::instmeth_iterator I = CDecl->instmeth_begin(),
+ E = CDecl->instmeth_end(); I != E; ++I)
+ if (!InsMap.count((*I)->getSelector()))
+ InsMap.insert((*I)->getSelector());
+
+ for (ObjCInterfaceDecl::classmeth_iterator
+ I = CDecl->classmeth_begin(), E = CDecl->classmeth_end(); I != E; ++I)
+ if (!ClsMap.count((*I)->getSelector()))
+ ClsMap.insert((*I)->getSelector());
+
+ if (!InsMap.empty() || !ClsMap.empty())
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ PI = CDecl->all_referenced_protocol_begin(),
+ E = CDecl->all_referenced_protocol_end(); PI != E; ++PI)
+ MatchMethodsInClassAndOneProtocol(*this, InsMap, ClsMap, CDecl, (*PI));
+
+ // Also for class extensions
+ if (!CDecl->getFirstClassExtension())
+ return;
+
+ for (const ObjCCategoryDecl *ClsExtDecl = CDecl->getFirstClassExtension();
+ ClsExtDecl; ClsExtDecl = ClsExtDecl->getNextClassExtension()) {
+ InsMap.clear();
+ ClsMap.clear();
+ for (ObjCCategoryDecl::instmeth_iterator I = ClsExtDecl->instmeth_begin(),
+ E = ClsExtDecl->instmeth_end(); I != E; ++I)
+ if (!InsMap.count((*I)->getSelector()))
+ InsMap.insert((*I)->getSelector());
+ for (ObjCCategoryDecl::classmeth_iterator I = ClsExtDecl->classmeth_begin(),
+ E = ClsExtDecl->classmeth_end(); I != E; ++I)
+ if (!ClsMap.count((*I)->getSelector()))
+ ClsMap.insert((*I)->getSelector());
+ if (InsMap.empty() && ClsMap.empty())
+ continue;
+ for (ObjCInterfaceDecl::all_protocol_iterator
+ PI = CDecl->all_referenced_protocol_begin(),
+ E = CDecl->all_referenced_protocol_end(); PI != E; ++PI)
+ MatchMethodsInClassAndOneProtocol(*this, InsMap, ClsMap, ClsExtDecl, (*PI));
+ }
+}
+
+
void Sema::ImplMethodsVsClassMethods(Scope *S, ObjCImplDecl* IMPDecl,
ObjCContainerDecl* CDecl,
bool IncompleteImpl) {