From 0302d8dabe6bc7b90d70126a2e8b07cce4733e85 Mon Sep 17 00:00:00 2001 From: Erik Pilkington Date: Wed, 10 May 2017 17:18:56 +0000 Subject: [PATCH] [Sema] Objective-C++ support for type trait __is_base_of rdar://24308607 Differential revision: https://reviews.llvm.org/D32891 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@302695 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprCXX.cpp | 20 +++++++++++++++++--- test/SemaObjCXX/is-base-of.mm | 25 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 test/SemaObjCXX/is-base-of.mm diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 9b88cddbc9..ee67df7bac 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4720,10 +4720,24 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT, // regard to cv-qualifiers. const RecordType *lhsRecord = LhsT->getAs(); - if (!lhsRecord) return false; - const RecordType *rhsRecord = RhsT->getAs(); - if (!rhsRecord) return false; + if (!rhsRecord || !lhsRecord) { + const ObjCObjectType *LHSObjTy = LhsT->getAs(); + const ObjCObjectType *RHSObjTy = RhsT->getAs(); + 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)); diff --git a/test/SemaObjCXX/is-base-of.mm b/test/SemaObjCXX/is-base-of.mm new file mode 100644 index 0000000000..9cf16661b0 --- /dev/null +++ b/test/SemaObjCXX/is-base-of.mm @@ -0,0 +1,25 @@ +// 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'}} + +static_assert(!__is_base_of(id, NSObj), ""); -- 2.40.0