@@ -13706,10 +13706,11 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr,
1370613706
1370713707//===--- Layout compatibility ----------------------------------------------//
1370813708
13709- static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2);
13709+ static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2);
1371013710
1371113711/// Check if two enumeration types are layout-compatible.
13712- static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) {
13712+ static bool isLayoutCompatible(const ASTContext &C, const EnumDecl *ED1,
13713+ const EnumDecl *ED2) {
1371313714 // C++11 [dcl.enum] p8:
1371413715 // Two enumeration types are layout-compatible if they have the same
1371513716 // underlying type.
@@ -13720,8 +13721,8 @@ static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) {
1372013721/// Check if two fields are layout-compatible.
1372113722/// Can be used on union members, which are exempt from alignment requirement
1372213723/// of common initial sequence.
13723- static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1,
13724- FieldDecl *Field2,
13724+ static bool isLayoutCompatible(const ASTContext &C, const FieldDecl *Field1,
13725+ const FieldDecl *Field2,
1372513726 bool AreUnionMembers = false) {
1372613727 [[maybe_unused]] const Type *Field1Parent =
1372713728 Field1->getParent()->getTypeForDecl();
@@ -13764,60 +13765,33 @@ static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1,
1376413765
1376513766/// Check if two standard-layout structs are layout-compatible.
1376613767/// (C++11 [class.mem] p17)
13767- static bool isLayoutCompatibleStruct(ASTContext &C, RecordDecl *RD1,
13768- RecordDecl *RD2) {
13769- // If both records are C++ classes, check that base classes match.
13770- if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) {
13771- // If one of records is a CXXRecordDecl we are in C++ mode,
13772- // thus the other one is a CXXRecordDecl, too.
13773- const CXXRecordDecl *D2CXX = cast<CXXRecordDecl>(RD2);
13774- // Check number of base classes.
13775- if (D1CXX->getNumBases() != D2CXX->getNumBases())
13776- return false;
13768+ static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1,
13769+ const RecordDecl *RD2) {
13770+ // Get to the class where the fields are declared
13771+ if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
13772+ RD1 = D1CXX->getStandardLayoutBaseWithFields();
1377713773
13778- // Check the base classes.
13779- for (CXXRecordDecl::base_class_const_iterator
13780- Base1 = D1CXX->bases_begin(),
13781- BaseEnd1 = D1CXX->bases_end(),
13782- Base2 = D2CXX->bases_begin();
13783- Base1 != BaseEnd1;
13784- ++Base1, ++Base2) {
13785- if (!isLayoutCompatible(C, Base1->getType(), Base2->getType()))
13786- return false;
13787- }
13788- } else if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) {
13789- // If only RD2 is a C++ class, it should have zero base classes.
13790- if (D2CXX->getNumBases() > 0)
13791- return false;
13792- }
13774+ if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
13775+ RD2 = D2CXX->getStandardLayoutBaseWithFields();
1379313776
1379413777 // Check the fields.
13795- RecordDecl::field_iterator Field2 = RD2->field_begin(),
13796- Field2End = RD2->field_end(),
13797- Field1 = RD1->field_begin(),
13798- Field1End = RD1->field_end();
13799- for ( ; Field1 != Field1End && Field2 != Field2End; ++Field1, ++Field2) {
13800- if (!isLayoutCompatible(C, *Field1, *Field2))
13801- return false;
13802- }
13803- if (Field1 != Field1End || Field2 != Field2End)
13804- return false;
13805-
13806- return true;
13778+ return llvm::equal(RD1->fields(), RD2->fields(),
13779+ [&C](const FieldDecl *F1, const FieldDecl *F2) -> bool {
13780+ return isLayoutCompatible(C, F1, F2);
13781+ });
1380713782}
1380813783
1380913784/// Check if two standard-layout unions are layout-compatible.
1381013785/// (C++11 [class.mem] p18)
13811- static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1,
13812- RecordDecl *RD2) {
13813- llvm::SmallPtrSet<FieldDecl *, 8> UnmatchedFields;
13786+ static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1,
13787+ const RecordDecl *RD2) {
13788+ llvm::SmallPtrSet<const FieldDecl *, 8> UnmatchedFields;
1381413789 for (auto *Field2 : RD2->fields())
1381513790 UnmatchedFields.insert(Field2);
1381613791
1381713792 for (auto *Field1 : RD1->fields()) {
13818- llvm::SmallPtrSet<FieldDecl *, 8>::iterator
13819- I = UnmatchedFields.begin(),
13820- E = UnmatchedFields.end();
13793+ auto I = UnmatchedFields.begin();
13794+ auto E = UnmatchedFields.end();
1382113795
1382213796 for ( ; I != E; ++I) {
1382313797 if (isLayoutCompatible(C, Field1, *I, /*IsUnionMember=*/true)) {
@@ -13834,8 +13808,8 @@ static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1,
1383413808 return UnmatchedFields.empty();
1383513809}
1383613810
13837- static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1,
13838- RecordDecl *RD2) {
13811+ static bool isLayoutCompatible(const ASTContext &C, const RecordDecl *RD1,
13812+ const RecordDecl *RD2) {
1383913813 if (RD1->isUnion() != RD2->isUnion())
1384013814 return false;
1384113815
@@ -13846,7 +13820,7 @@ static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1,
1384613820}
1384713821
1384813822/// Check if two types are layout-compatible in C++11 sense.
13849- static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2) {
13823+ static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2) {
1385013824 if (T1.isNull() || T2.isNull())
1385113825 return false;
1385213826
0 commit comments