================ @@ -6540,67 +6540,70 @@ ExprResult Sema::ActOnTypeTrait(TypeTrait Kind, SourceLocation KWLoc, return BuildTypeTrait(Kind, KWLoc, ConvertedArgs, RParenLoc); } -static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs, - const TypeSourceInfo *Rhs, SourceLocation KeyLoc) { - QualType LhsT = Lhs->getType(); - QualType RhsT = Rhs->getType(); +bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, + QualType RhsT) { + // C++0x [meta.rel]p2 + // Base is a base class of Derived without regard to cv-qualifiers or + // Base and Derived are not unions and name the same class type without + // regard to cv-qualifiers. + + const RecordType *lhsRecord = LhsT->getAs<RecordType>(); + const RecordType *rhsRecord = RhsT->getAs<RecordType>(); + if (!rhsRecord || !lhsRecord) { + const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>(); + const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>(); + if (!LHSObjTy || !RHSObjTy) + return false; - assert(!LhsT->isDependentType() && !RhsT->isDependentType() && - "Cannot evaluate traits of dependent types"); + ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface(); + ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface(); + if (!BaseInterface || !DerivedInterface) + return false; - switch(BTT) { - case BTT_IsBaseOf: { - // C++0x [meta.rel]p2 - // Base is a base class of Derived without regard to cv-qualifiers or - // Base and Derived are not unions and name the same class type without - // regard to cv-qualifiers. - - const RecordType *lhsRecord = LhsT->getAs<RecordType>(); - const RecordType *rhsRecord = RhsT->getAs<RecordType>(); - if (!rhsRecord || !lhsRecord) { - const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>(); - const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>(); - if (!LHSObjTy || !RHSObjTy) - return false; + if (RequireCompleteType(RhsTLoc, RhsT, + diag::err_incomplete_type_used_in_type_trait_expr)) + return false; - ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface(); - ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface(); - if (!BaseInterface || !DerivedInterface) - return false; + return BaseInterface->isSuperClassOf(DerivedInterface); + } - if (Self.RequireCompleteType( - Rhs->getTypeLoc().getBeginLoc(), RhsT, - diag::err_incomplete_type_used_in_type_trait_expr)) - return false; + assert(Context.hasSameUnqualifiedType(LhsT, RhsT) == + (lhsRecord == rhsRecord)); - return BaseInterface->isSuperClassOf(DerivedInterface); - } + // Unions are never base classes, and never have base classes. + // It doesn't matter if they are complete or not. See PR#41843 + if (lhsRecord && lhsRecord->getDecl()->isUnion()) + return false; + if (rhsRecord && rhsRecord->getDecl()->isUnion()) + return false; + + if (lhsRecord == rhsRecord) + return true; - assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT) - == (lhsRecord == rhsRecord)); + // C++0x [meta.rel]p2: + // If Base and Derived are class types and are different types + // (ignoring possible cv-qualifiers) then Derived shall be a + // complete type. + if (RequireCompleteType(RhsTLoc, RhsT, + diag::err_incomplete_type_used_in_type_trait_expr)) + return false; - // Unions are never base classes, and never have base classes. - // It doesn't matter if they are complete or not. See PR#41843 - if (lhsRecord && lhsRecord->getDecl()->isUnion()) - return false; - if (rhsRecord && rhsRecord->getDecl()->isUnion()) - return false; + return cast<CXXRecordDecl>(rhsRecord->getDecl()) + ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl())); +} - if (lhsRecord == rhsRecord) - return true; +static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, const TypeSourceInfo *Lhs, ---------------- philnik777 wrote:
I think so. This allows me to use them in `BuiltinInvoke` above and be very close to the wording in the standard. I guess it would be possible to call `BuildTypeTrait` instead, but that seems much less readable to me (and would require me to find a `TypeSourceInfo` somewhere). https://github.com/llvm/llvm-project/pull/116709 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits