erik.pilkington created this revision. This patch adds Objective-C interfaces support for the type trait `is_base_of`, so that `__is_base_of(NSString, NSMutableString)` is true.
rdar://24308607 Thanks for taking a look! Erik https://reviews.llvm.org/D32891 Files: lib/Sema/SemaExprCXX.cpp test/SemaObjCXX/is-base-of.mm Index: test/SemaObjCXX/is-base-of.mm =================================================================== --- test/SemaObjCXX/is-base-of.mm +++ test/SemaObjCXX/is-base-of.mm @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +@interface NSObj +@end + +@interface NSChild : NSObj +@end + +static_assert(__is_base_of(NSObj, NSChild), ""); +static_assert(!__is_base_of(NSChild, NSObj), ""); + +static_assert(__is_base_of(NSObj, NSObj), ""); + +static_assert(!__is_base_of(NSObj *, NSChild *), ""); +static_assert(!__is_base_of(NSChild *, NSObj *), ""); + +static_assert(__is_base_of(const volatile NSObj, NSChild), ""); +static_assert(__is_base_of(NSObj, const volatile NSChild), ""); + +@class NSForward; // expected-note{{forward declaration of class}} + +static_assert(!__is_base_of(NSForward, NSObj), ""); +static_assert(!__is_base_of(NSObj, NSForward), ""); // expected-error{{incomplete type 'NSForward'}} Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -4720,10 +4720,24 @@ // regard to cv-qualifiers. const RecordType *lhsRecord = LhsT->getAs<RecordType>(); - if (!lhsRecord) return false; - const RecordType *rhsRecord = RhsT->getAs<RecordType>(); - if (!rhsRecord) return false; + if (!rhsRecord || !lhsRecord) { + const ObjCObjectType *lhsObjTy = LhsT->getAs<ObjCObjectType>(); + const ObjCObjectType *rhsObjTy = RhsT->getAs<ObjCObjectType>(); + if (!lhsObjTy || !rhsObjTy) + return false; + + ObjCInterfaceDecl *BaseInterface = lhsObjTy->getInterface(); + ObjCInterfaceDecl *DerivedInterface = rhsObjTy->getInterface(); + if (!BaseInterface || !DerivedInterface) + return false; + + if (Self.RequireCompleteType( + KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr)) + return false; + + return BaseInterface->isSuperClassOf(DerivedInterface); + } assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) == (lhsRecord == rhsRecord));
Index: test/SemaObjCXX/is-base-of.mm =================================================================== --- test/SemaObjCXX/is-base-of.mm +++ test/SemaObjCXX/is-base-of.mm @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s + +@interface NSObj +@end + +@interface NSChild : NSObj +@end + +static_assert(__is_base_of(NSObj, NSChild), ""); +static_assert(!__is_base_of(NSChild, NSObj), ""); + +static_assert(__is_base_of(NSObj, NSObj), ""); + +static_assert(!__is_base_of(NSObj *, NSChild *), ""); +static_assert(!__is_base_of(NSChild *, NSObj *), ""); + +static_assert(__is_base_of(const volatile NSObj, NSChild), ""); +static_assert(__is_base_of(NSObj, const volatile NSChild), ""); + +@class NSForward; // expected-note{{forward declaration of class}} + +static_assert(!__is_base_of(NSForward, NSObj), ""); +static_assert(!__is_base_of(NSObj, NSForward), ""); // expected-error{{incomplete type 'NSForward'}} Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -4720,10 +4720,24 @@ // regard to cv-qualifiers. const RecordType *lhsRecord = LhsT->getAs<RecordType>(); - if (!lhsRecord) return false; - const RecordType *rhsRecord = RhsT->getAs<RecordType>(); - if (!rhsRecord) return false; + if (!rhsRecord || !lhsRecord) { + const ObjCObjectType *lhsObjTy = LhsT->getAs<ObjCObjectType>(); + const ObjCObjectType *rhsObjTy = RhsT->getAs<ObjCObjectType>(); + if (!lhsObjTy || !rhsObjTy) + return false; + + ObjCInterfaceDecl *BaseInterface = lhsObjTy->getInterface(); + ObjCInterfaceDecl *DerivedInterface = rhsObjTy->getInterface(); + if (!BaseInterface || !DerivedInterface) + return false; + + if (Self.RequireCompleteType( + KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr)) + return false; + + return BaseInterface->isSuperClassOf(DerivedInterface); + } assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) == (lhsRecord == rhsRecord));
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits