@@ -19084,7 +19084,8 @@ void Sema::DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr,
19084
19084
static bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2);
19085
19085
19086
19086
/// Check if two enumeration types are layout-compatible.
19087
- static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) {
19087
+ static bool isLayoutCompatible(ASTContext &C, const EnumDecl *ED1,
19088
+ const EnumDecl *ED2) {
19088
19089
// C++11 [dcl.enum] p8:
19089
19090
// Two enumeration types are layout-compatible if they have the same
19090
19091
// underlying type.
@@ -19095,8 +19096,8 @@ static bool isLayoutCompatible(ASTContext &C, EnumDecl *ED1, EnumDecl *ED2) {
19095
19096
/// Check if two fields are layout-compatible.
19096
19097
/// Can be used on union members, which are exempt from alignment requirement
19097
19098
/// of common initial sequence.
19098
- static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1,
19099
- FieldDecl *Field2,
19099
+ static bool isLayoutCompatible(ASTContext &C, const FieldDecl *Field1,
19100
+ const FieldDecl *Field2,
19100
19101
bool AreUnionMembers = false) {
19101
19102
[[maybe_unused]] const Type *Field1Parent =
19102
19103
Field1->getParent()->getTypeForDecl();
@@ -19139,52 +19140,26 @@ static bool isLayoutCompatible(ASTContext &C, FieldDecl *Field1,
19139
19140
19140
19141
/// Check if two standard-layout structs are layout-compatible.
19141
19142
/// (C++11 [class.mem] p17)
19142
- static bool isLayoutCompatibleStruct(ASTContext &C, RecordDecl *RD1,
19143
- RecordDecl *RD2) {
19144
- // If both records are C++ classes, check that base classes match.
19145
- if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) {
19146
- // If one of records is a CXXRecordDecl we are in C++ mode,
19147
- // thus the other one is a CXXRecordDecl, too.
19148
- const CXXRecordDecl *D2CXX = cast<CXXRecordDecl>(RD2);
19149
- // Check number of base classes.
19150
- if (D1CXX->getNumBases() != D2CXX->getNumBases())
19151
- return false;
19143
+ static bool isLayoutCompatibleStruct(ASTContext &C, const RecordDecl *RD1,
19144
+ const RecordDecl *RD2) {
19145
+ // Get to the class where the fields are declared
19146
+ if (const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
19147
+ RD1 = D1CXX->getStandardLayoutBaseWithFields();
19152
19148
19153
- // Check the base classes.
19154
- for (CXXRecordDecl::base_class_const_iterator
19155
- Base1 = D1CXX->bases_begin(),
19156
- BaseEnd1 = D1CXX->bases_end(),
19157
- Base2 = D2CXX->bases_begin();
19158
- Base1 != BaseEnd1;
19159
- ++Base1, ++Base2) {
19160
- if (!isLayoutCompatible(C, Base1->getType(), Base2->getType()))
19161
- return false;
19162
- }
19163
- } else if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) {
19164
- // If only RD2 is a C++ class, it should have zero base classes.
19165
- if (D2CXX->getNumBases() > 0)
19166
- return false;
19167
- }
19149
+ if (const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
19150
+ RD2 = D2CXX->getStandardLayoutBaseWithFields();
19168
19151
19169
19152
// Check the fields.
19170
- RecordDecl::field_iterator Field2 = RD2->field_begin(),
19171
- Field2End = RD2->field_end(),
19172
- Field1 = RD1->field_begin(),
19173
- Field1End = RD1->field_end();
19174
- for ( ; Field1 != Field1End && Field2 != Field2End; ++Field1, ++Field2) {
19175
- if (!isLayoutCompatible(C, *Field1, *Field2))
19176
- return false;
19177
- }
19178
- if (Field1 != Field1End || Field2 != Field2End)
19179
- return false;
19180
-
19181
- return true;
19153
+ return llvm::equal(RD1->fields(), RD2->fields(),
19154
+ [&C](const FieldDecl *F1, const FieldDecl *F2) -> bool {
19155
+ return isLayoutCompatible(C, F1, F2);
19156
+ });
19182
19157
}
19183
19158
19184
19159
/// Check if two standard-layout unions are layout-compatible.
19185
19160
/// (C++11 [class.mem] p18)
19186
- static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1,
19187
- RecordDecl *RD2) {
19161
+ static bool isLayoutCompatibleUnion(ASTContext &C, const RecordDecl *RD1,
19162
+ const RecordDecl *RD2) {
19188
19163
llvm::SmallPtrSet<FieldDecl *, 8> UnmatchedFields;
19189
19164
for (auto *Field2 : RD2->fields())
19190
19165
UnmatchedFields.insert(Field2);
@@ -19209,8 +19184,8 @@ static bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1,
19209
19184
return UnmatchedFields.empty();
19210
19185
}
19211
19186
19212
- static bool isLayoutCompatible(ASTContext &C, RecordDecl *RD1,
19213
- RecordDecl *RD2) {
19187
+ static bool isLayoutCompatible(ASTContext &C, const RecordDecl *RD1,
19188
+ const RecordDecl *RD2) {
19214
19189
if (RD1->isUnion() != RD2->isUnion())
19215
19190
return false;
19216
19191
0 commit comments