aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.h3
-rw-r--r--lib/Sema/SemaOverload.cpp44
2 files changed, 45 insertions, 2 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index ba20ed1e1a..e6cf0599b4 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1109,6 +1109,9 @@ public:
QualType& ConvertedType, bool &IncompatibleObjC);
bool isObjCPointerConversion(QualType FromType, QualType ToType,
QualType& ConvertedType, bool &IncompatibleObjC);
+ bool FunctionArgTypesAreEqual (FunctionProtoType* OldType,
+ FunctionProtoType* NewType);
+
bool CheckPointerConversion(Expr *From, QualType ToType,
CastExpr::CastKind &Kind,
CXXBaseSpecifierArray& BasePath,
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 2a2521a32c..21f2a51040 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -374,8 +374,7 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old) {
if (OldQType != NewQType &&
(OldType->getNumArgs() != NewType->getNumArgs() ||
OldType->isVariadic() != NewType->isVariadic() ||
- !std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
- NewType->arg_type_begin())))
+ !FunctionArgTypesAreEqual(OldType, NewType)))
return true;
// C++ [temp.over.link]p4:
@@ -1332,6 +1331,47 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
return false;
}
+
+/// FunctionArgTypesAreEqual - This routine checks two function proto types
+/// for equlity of their argument types. Caller has already checked that
+/// they have same number of arguments. This routine assumes that Objective-C
+/// pointer types which only differ in their protocol qualifiers are equal.
+bool Sema::FunctionArgTypesAreEqual(FunctionProtoType* OldType,
+ FunctionProtoType* NewType){
+ if (!getLangOptions().ObjC1)
+ return std::equal(OldType->arg_type_begin(), OldType->arg_type_end(),
+ NewType->arg_type_begin());
+
+ for (FunctionProtoType::arg_type_iterator O = OldType->arg_type_begin(),
+ N = NewType->arg_type_begin(),
+ E = OldType->arg_type_end(); O && (O != E); ++O, ++N) {
+ QualType ToType = (*O);
+ QualType FromType = (*N);
+ if (ToType != FromType) {
+ if (const PointerType *PTTo = ToType->getAs<PointerType>()) {
+ if (const PointerType *PTFr = FromType->getAs<PointerType>())
+ if (PTTo->getPointeeType()->isObjCQualifiedIdType() &&
+ PTFr->getPointeeType()->isObjCQualifiedIdType() ||
+ PTTo->getPointeeType()->isObjCQualifiedClassType() &&
+ PTFr->getPointeeType()->isObjCQualifiedClassType())
+ continue;
+ }
+ else if (ToType->isObjCObjectPointerType() &&
+ FromType->isObjCObjectPointerType()) {
+ QualType ToInterfaceTy = ToType->getPointeeType();
+ QualType FromInterfaceTy = FromType->getPointeeType();
+ if (const ObjCInterfaceType *OITTo =
+ ToInterfaceTy->getAs<ObjCInterfaceType>())
+ if (const ObjCInterfaceType *OITFr =
+ FromInterfaceTy->getAs<ObjCInterfaceType>())
+ if (OITTo->getDecl() == OITFr->getDecl())
+ continue;
+ }
+ return false;
+ }
+ }
+ return true;
+}
/// CheckPointerConversion - Check the pointer conversion from the
/// expression From to the type ToType. This routine checks for