Skip to content

Commit 67caf75

Browse files
committed
fixup! decouple isEmptyXXXForLayout from isEmptyXXX
1 parent 18d373c commit 67caf75

File tree

3 files changed

+39
-24
lines changed

3 files changed

+39
-24
lines changed

clang/lib/CodeGen/ABIInfoImpl.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1,
248248
return Address(PHI, Addr1.getElementType(), Align);
249249
}
250250

251-
bool CodeGen::isEmptyField(const ASTContext &Context, const FieldDecl *FD,
251+
bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
252252
bool AllowArrays, bool AsIfNoUniqueAddr) {
253253
if (FD->isUnnamedBitField())
254254
return true;
@@ -289,6 +289,27 @@ bool CodeGen::isEmptyField(const ASTContext &Context, const FieldDecl *FD,
289289
return isEmptyRecord(Context, FT, AllowArrays, AsIfNoUniqueAddr);
290290
}
291291

292+
bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
293+
bool AsIfNoUniqueAddr) {
294+
const RecordType *RT = T->getAs<RecordType>();
295+
if (!RT)
296+
return false;
297+
const RecordDecl *RD = RT->getDecl();
298+
if (RD->hasFlexibleArrayMember())
299+
return false;
300+
301+
// If this is a C++ record, check the bases first.
302+
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
303+
for (const auto &I : CXXRD->bases())
304+
if (!isEmptyRecord(Context, I.getType(), true, AsIfNoUniqueAddr))
305+
return false;
306+
307+
for (const auto *I : RD->fields())
308+
if (!isEmptyField(Context, I, AllowArrays, AsIfNoUniqueAddr))
309+
return false;
310+
return true;
311+
}
312+
292313
bool CodeGen::isEmptyFieldForLayout(const ASTContext &Context,
293314
const FieldDecl *FD) {
294315
if (FD->isZeroLengthBitField(Context))
@@ -297,34 +318,27 @@ bool CodeGen::isEmptyFieldForLayout(const ASTContext &Context,
297318
if (FD->isUnnamedBitField())
298319
return false;
299320

300-
return isEmptyField(Context, FD, /*AllowArrays=*/false,
301-
/*AsIfNoUniqueAddr=*/true);
321+
return isEmptyRecordForLayout(Context, FD->getType());
302322
}
303323

304-
bool CodeGen::isEmptyRecord(const ASTContext &Context, QualType T,
305-
bool AllowArrays, bool AsIfNoUniqueAddr) {
324+
bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) {
306325
const RecordType *RT = T->getAs<RecordType>();
307326
if (!RT)
308327
return false;
328+
309329
const RecordDecl *RD = RT->getDecl();
310-
if (RD->hasFlexibleArrayMember())
311-
return false;
312330

313331
// If this is a C++ record, check the bases first.
314332
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
315333
for (const auto &I : CXXRD->bases())
316-
if (!isEmptyRecord(Context, I.getType(), true, AsIfNoUniqueAddr))
334+
if (!isEmptyRecordForLayout(Context, I.getType()))
317335
return false;
318336

319337
for (const auto *I : RD->fields())
320-
if (!isEmptyField(Context, I, AllowArrays, AsIfNoUniqueAddr))
338+
if (!isEmptyFieldForLayout(Context, I))
321339
return false;
322-
return true;
323-
}
324340

325-
bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) {
326-
return isEmptyRecord(Context, T, /*AllowArrays=*/false,
327-
/*AsIfNoUniqueAddr=*/true);
341+
return true;
328342
}
329343

330344
const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) {

clang/lib/CodeGen/ABIInfoImpl.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,24 +126,25 @@ Address emitMergePHI(CodeGenFunction &CGF, Address Addr1,
126126
/// is an unnamed bit-field or an (array of) empty record(s). If
127127
/// AsIfNoUniqueAddr is true, then C++ record fields are considered empty if
128128
/// the [[no_unique_address]] attribute would have made them empty.
129-
bool isEmptyField(const ASTContext &Context, const FieldDecl *FD,
130-
bool AllowArrays, bool AsIfNoUniqueAddr = false);
131-
132-
/// isEmptyFieldForLayout - Return true iff the field is "empty", that is,
133-
/// either a zero-width bit-field or an empty record.
134-
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD);
129+
bool isEmptyField(ASTContext &Context, const FieldDecl *FD, bool AllowArrays,
130+
bool AsIfNoUniqueAddr = false);
135131

136132
/// isEmptyRecord - Return true iff a structure contains only empty
137133
/// fields. Note that a structure with a flexible array member is not
138134
/// considered empty. If AsIfNoUniqueAddr is true, then C++ record fields are
139135
/// considered empty if the [[no_unique_address]] attribute would have made
140136
/// them empty.
141-
bool isEmptyRecord(const ASTContext &Context, QualType T, bool AllowArrays,
137+
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
142138
bool AsIfNoUniqueAddr = false);
143139

140+
/// isEmptyFieldForLayout - Return true iff the field is "empty", that is,
141+
/// either a zero-width bit-field or an \ref isEmptyRecordForLayout.
142+
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD);
143+
144144
/// isEmptyRecordForLayout - Return true iff a structure contains only empty
145-
/// fields. Note, C++ record fields are considered empty if the
146-
/// [[no_unique_address]] attribute would have made them empty.
145+
/// fields (per \ref isEmptyFieldForLayout). Note, C++ record fields are
146+
/// considered empty if the [[no_unique_address]] attribute would have made
147+
/// them empty.
147148
bool isEmptyRecordForLayout(const ASTContext &Context, QualType T);
148149

149150
/// isSingleElementStruct - Determine if a structure is a "single

clang/test/CodeGen/debug-info-packed-struct.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
// CHECK: %struct.layout3 = type <{ i8, [3 x i8], %struct.size8_pack4, i8, [3 x i8] }>
44
// CHECK: %struct.layout0 = type { i8, %struct.size8, i8 }
5-
// CHECK: %struct.layout1 = type { i8, [8 x i8], i8, [2 x i8] }
5+
// CHECK: %struct.layout1 = type <{ i8, %struct.size8_anon, i8, [2 x i8] }>
66
// CHECK: %struct.layout2 = type <{ i8, %struct.size8_pack1, i8 }>
77

88
// ---------------------------------------------------------------------

0 commit comments

Comments
 (0)