================ @@ -2276,6 +2277,134 @@ static void DiagnoseNonTriviallyCopyableReason(Sema &SemaRef, SemaRef.Diag(D->getLocation(), diag::note_defined_here) << D; } +static bool hasMixedAccessSpecifier(const CXXRecordDecl *D) { + AccessSpecifier FirstAccess = AS_none; + for (const FieldDecl *Field : D->fields()) { + + if (Field->isUnnamedBitField()) + continue; + AccessSpecifier FieldAccess = Field->getAccess(); + if (FirstAccess == AS_none) { + FirstAccess = FieldAccess; + } else if (FieldAccess != FirstAccess) { + return true; + } + } + return false; +} + +static bool hasMultipleDataBaseClassesWithFields(const CXXRecordDecl *D) { + int NumBasesWithFields = 0; + for (const CXXBaseSpecifier &Base : D->bases()) { + const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl(); + if (!BaseRD || BaseRD->isInvalidDecl()) + continue; + + for (const FieldDecl *Field : BaseRD->fields()) { + if (!Field->isUnnamedBitField()) { + ++NumBasesWithFields; + break; // Only count the base once. + } + } + } + return NumBasesWithFields > 1; +} + +static void DiagnoseNonStandardLayoutReason(Sema &SemaRef, SourceLocation Loc, + const CXXRecordDecl *D) { + for (const CXXBaseSpecifier &B : D->bases()) { + assert(B.getType()->getAsCXXRecordDecl() && "invalid base?"); + if (B.isVirtual()) { + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::VBase << B.getType() + << B.getSourceRange(); + } + if (!B.getType()->isStandardLayoutType()) { + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::NonStdLayoutBase << B.getType() + << B.getSourceRange(); + } + } + if (hasMixedAccessSpecifier(D)) { + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::MixedAccess; + } + if (hasMultipleDataBaseClassesWithFields(D)) { + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::MultipleDataBase; + } + if (D->isPolymorphic()) { + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::VirtualFunction; + } + for (const FieldDecl *Field : D->fields()) { + if (!Field->getType()->isStandardLayoutType()) { + SemaRef.Diag(Loc, diag::note_unsatisfied_trait_reason) + << diag::TraitNotSatisfiedReason::NonStdLayoutMember << Field + << Field->getType() << Field->getSourceRange(); + } + } + + // if this class and an indirect base + // both have non-static data members, grab the first such base. + if (D->hasDirectFields()) { + SmallVector<const CXXRecordDecl *, 4> Records; + + // Recursive lambda to collect all bases that declare fields + std::function<void(const CXXRecordDecl *)> collect = ---------------- zwuis wrote:
We can use `CXXRecordDecl::forallBases`. https://github.com/llvm/llvm-project/pull/144161 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits