clang 24.0.0git
CIRGenRecordLayoutBuilder.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This contains code to compute the layout of a record.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenBuilder.h"
14#include "CIRGenModule.h"
15#include "CIRGenTypes.h"
16#include "TargetInfo.h"
17
19#include "clang/AST/Decl.h"
20#include "clang/AST/DeclCXX.h"
25#include "llvm/Support/Casting.h"
26
27#include <memory>
28
29using namespace llvm;
30using namespace clang;
31using namespace clang::CIRGen;
32
33namespace {
34/// The CIRRecordLowering is responsible for lowering an ASTRecordLayout to an
35/// mlir::Type. Some of the lowering is straightforward, some is not.
36// TODO: Detail some of the complexities and weirdnesses?
37// (See CGRecordLayoutBuilder.cpp)
38struct CIRRecordLowering final {
39
40 // MemberInfo is a helper structure that contains information about a record
41 // member. In addition to the standard member types, there exists a sentinel
42 // member type that ensures correct rounding.
43 struct MemberInfo final {
44 CharUnits offset;
45 enum class InfoKind { VFPtr, Field, Base, VBase } kind;
46 mlir::Type data;
47 /// What this member holds, recorded on the CIR record type.
48 cir::RecordMemberKind memberKind;
49 union {
50 const FieldDecl *fieldDecl;
51 const CXXRecordDecl *cxxRecordDecl;
52 };
53 MemberInfo(CharUnits offset, InfoKind kind, mlir::Type data,
54 cir::RecordMemberKind memberKind,
55 const FieldDecl *fieldDecl = nullptr)
56 : offset{offset}, kind{kind}, data{data}, memberKind{memberKind},
58 MemberInfo(CharUnits offset, InfoKind kind, mlir::Type data,
59 cir::RecordMemberKind memberKind, const CXXRecordDecl *rd)
60 : offset{offset}, kind{kind}, data{data}, memberKind{memberKind},
61 cxxRecordDecl{rd} {}
62 // MemberInfos are sorted so we define a < operator.
63 bool operator<(const MemberInfo &other) const {
64 return offset < other.offset;
65 }
66 };
67 // The constructor.
68 CIRRecordLowering(CIRGenTypes &cirGenTypes, const RecordDecl *recordDecl,
69 bool packed);
70
71 /// Constructs a MemberInfo instance from an offset and mlir::Type.
72 MemberInfo makeStorageInfo(CharUnits offset, mlir::Type data,
73 cir::RecordMemberKind memberKind) {
74 return MemberInfo(offset, MemberInfo::InfoKind::Field, data, memberKind);
75 }
76
77 // Layout routines.
78 void setBitFieldInfo(const FieldDecl *fd, CharUnits startOffset,
79 mlir::Type storageType);
80
81 void lower(bool nonVirtualBaseType);
82 void lowerUnion(bool nonVirtualBaseType);
83
84 /// Determines if we need a packed llvm struct.
85 void determinePacked(bool nvBaseType);
86 /// Inserts padding everywhere it's needed.
87 void insertPadding();
88
89 void computeVolatileBitfields();
90 void accumulateBases();
91 void accumulateVPtrs();
92 void accumulateVBases();
93 void accumulateFields(bool nonVirtualBaseType);
95 accumulateBitFields(RecordDecl::field_iterator field,
97
98 mlir::Type getVFPtrType();
99
100 bool isAAPCS() const {
101 return astContext.getTargetInfo().getABI().starts_with("aapcs");
102 }
103
104 /// Helper function to check if the target machine is BigEndian.
105 bool isBigEndian() const { return astContext.getTargetInfo().isBigEndian(); }
106
107 // The Itanium base layout rule allows virtual bases to overlap
108 // other bases, which complicates layout in specific ways.
109 //
110 // Note specifically that the ms_struct attribute doesn't change this.
111 bool isOverlappingVBaseABI() {
112 return !astContext.getTargetInfo().getCXXABI().isMicrosoft();
113 }
114 // Recursively searches all of the bases to find out if a vbase is
115 // not the primary vbase of some base class.
116 bool hasOwnStorage(const CXXRecordDecl *decl, const CXXRecordDecl *query);
117
118 /// The Microsoft bitfield layout rule allocates discrete storage
119 /// units of the field's formal type and only combines adjacent
120 /// fields of the same formal type. We want to emit a layout with
121 /// these discrete storage units instead of combining them into a
122 /// continuous run.
123 bool isDiscreteBitFieldABI() {
124 return astContext.getTargetInfo().getCXXABI().isMicrosoft() ||
125 recordDecl->isMsStruct(astContext);
126 }
127
128 CharUnits bitsToCharUnits(uint64_t bitOffset) {
129 return astContext.toCharUnitsFromBits(bitOffset);
130 }
131
132 void calculateZeroInit();
133
134 CharUnits getSize(mlir::Type Ty) {
135 return CharUnits::fromQuantity(dataLayout.layout.getTypeSize(Ty));
136 }
137 CharUnits getSizeInBits(mlir::Type ty) {
138 return CharUnits::fromQuantity(dataLayout.layout.getTypeSizeInBits(ty));
139 }
140 CharUnits getAlignment(mlir::Type Ty) {
141 return CharUnits::fromQuantity(dataLayout.layout.getTypeABIAlignment(Ty));
142 }
143
144 bool isZeroInitializable(const FieldDecl *fd) {
145 return cirGenTypes.isZeroInitializable(fd->getType());
146 }
147 bool isZeroInitializable(const RecordDecl *rd) {
148 return cirGenTypes.isZeroInitializable(rd);
149 }
150
151 /// The mark for a field.
152 cir::RecordMemberKind getFieldMemberKind(const FieldDecl *fd) {
153 return isEmptyFieldForABI(astContext, fd) ? cir::RecordMemberKind::Empty
154 : cir::RecordMemberKind::Data;
155 }
156
157 /// The mark for a base subobject. A base contributes no ABI data when it is
158 /// empty for the ABI, which is not the same as CXXRecordDecl::isEmpty(): a
159 /// base holding only unnamed bit-fields is laid out but carries no data.
160 cir::RecordMemberKind getBaseMemberKind(const CXXRecordDecl *baseDecl) {
161 return isEmptyRecordForABI(astContext,
162 astContext.getCanonicalTagType(baseDecl))
163 ? cir::RecordMemberKind::Empty
164 : cir::RecordMemberKind::Data;
165 }
166
167 /// Wraps cir::IntType with some implicit arguments.
168 mlir::Type getUIntNType(uint64_t numBits) {
169 unsigned alignedBits = llvm::PowerOf2Ceil(numBits);
170 alignedBits = std::max(8u, alignedBits);
171 return cir::IntType::get(&cirGenTypes.getMLIRContext(), alignedBits,
172 /*isSigned=*/false);
173 }
174
175 mlir::Type getCharType() {
176 return cir::IntType::get(&cirGenTypes.getMLIRContext(),
177 astContext.getCharWidth(),
178 /*isSigned=*/false);
179 }
180
181 mlir::Type getByteArrayType(CharUnits numberOfChars) {
182 assert(!numberOfChars.isZero() && "Empty byte arrays aren't allowed.");
183 mlir::Type type = getCharType();
184 return numberOfChars == CharUnits::One()
185 ? type
186 : cir::ArrayType::get(type, numberOfChars.getQuantity());
187 }
188
189 // Gets the CIR BaseSubobject type from a CXXRecordDecl.
190 mlir::Type getStorageType(const CXXRecordDecl *RD) {
191 return cirGenTypes.getCIRGenRecordLayout(RD).getBaseSubobjectCIRType();
192 }
193 // This is different from LLVM traditional codegen because CIRGen uses arrays
194 // of bytes instead of arbitrary-sized integers. This is important for packed
195 // structures support.
196 mlir::Type getBitfieldStorageType(unsigned numBits) {
197 unsigned alignedBits = llvm::alignTo(numBits, astContext.getCharWidth());
198 if (cir::isValidFundamentalIntWidth(alignedBits))
199 return builder.getUIntNTy(alignedBits);
200
201 mlir::Type type = getCharType();
202 return cir::ArrayType::get(type, alignedBits / astContext.getCharWidth());
203 }
204
205 mlir::Type getStorageType(const FieldDecl *fieldDecl) {
206 mlir::Type type = cirGenTypes.convertTypeForMem(fieldDecl->getType());
207 if (fieldDecl->isBitField()) {
208 cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(),
209 "getStorageType for bitfields");
210 }
211 return type;
212 }
213
214 uint64_t getFieldBitOffset(const FieldDecl *fieldDecl) {
215 return astRecordLayout.getFieldOffset(fieldDecl->getFieldIndex());
216 }
217
218 /// Fills out the structures that are ultimately consumed.
219 void fillOutputFields();
220
221 void appendPaddingBytes(CharUnits size) {
222 if (size.isZero())
223 return;
224 mlir::Type padTy = getByteArrayType(size);
225 if (recordDecl->isUnion()) {
226 assert(!unionPadding && "at most one union tail-padding type");
227 unionPadding = padTy;
228 } else {
229 addField(padTy, cir::RecordMemberKind::Pad);
230 }
231 }
232
233 void addField(mlir::Type ty, cir::RecordMemberKind memberKind) {
234 fieldTypes.push_back(ty);
235 fieldKinds.push_back(memberKind);
236 }
237
238 void clearFields() {
239 fieldTypes.clear();
240 fieldKinds.clear();
241 }
242
243 llvm::ArrayRef<mlir::Type> getFieldTypes() const { return fieldTypes; }
244 llvm::ArrayRef<cir::RecordMemberKind> getFieldKinds() const {
245 return fieldKinds;
246 }
247
248 CIRGenTypes &cirGenTypes;
249 CIRGenBuilderTy &builder;
250 const ASTContext &astContext;
251 const RecordDecl *recordDecl;
252 const CXXRecordDecl *cxxRecordDecl;
253 const ASTRecordLayout &astRecordLayout;
254 // Helpful intermediate data-structures
255 std::vector<MemberInfo> members;
256 mlir::Type unionPadding;
257 llvm::DenseMap<const FieldDecl *, CIRGenBitFieldInfo> bitFields;
258 llvm::DenseMap<const FieldDecl *, unsigned> fieldIdxMap;
259 llvm::DenseMap<const CXXRecordDecl *, unsigned> nonVirtualBases;
260 llvm::DenseMap<const CXXRecordDecl *, unsigned> virtualBases;
261 cir::CIRDataLayout dataLayout;
262
263 LLVM_PREFERRED_TYPE(bool)
264 unsigned zeroInitializable : 1;
265 LLVM_PREFERRED_TYPE(bool)
266 unsigned zeroInitializableAsBase : 1;
267 LLVM_PREFERRED_TYPE(bool)
268 unsigned packed : 1;
269
270private:
271 // Output fields, consumed by CIRGenTypes::computeRecordLayout. Private so
272 // that every append goes through addField and fieldKinds stays parallel to
273 // fieldTypes.
274 llvm::SmallVector<mlir::Type, 16> fieldTypes;
275 llvm::SmallVector<cir::RecordMemberKind> fieldKinds;
276
277 CIRRecordLowering(const CIRRecordLowering &) = delete;
278 void operator=(const CIRRecordLowering &) = delete;
279}; // CIRRecordLowering
280} // namespace
281
282CIRRecordLowering::CIRRecordLowering(CIRGenTypes &cirGenTypes,
283 const RecordDecl *recordDecl, bool packed)
284 : cirGenTypes{cirGenTypes}, builder{cirGenTypes.getBuilder()},
285 astContext{cirGenTypes.getASTContext()}, recordDecl{recordDecl},
287 astRecordLayout{
288 cirGenTypes.getASTContext().getASTRecordLayout(recordDecl)},
289 dataLayout{cirGenTypes.getCGModule().getModule()},
290 zeroInitializable{true}, zeroInitializableAsBase{true}, packed{packed} {}
291
292void CIRRecordLowering::setBitFieldInfo(const FieldDecl *fd,
293 CharUnits startOffset,
294 mlir::Type storageType) {
295 CIRGenBitFieldInfo &info = bitFields[fd->getCanonicalDecl()];
297 info.offset =
298 (unsigned)(getFieldBitOffset(fd) - astContext.toBits(startOffset));
299 info.size = fd->getBitWidthValue();
300 info.storageSize = getSizeInBits(storageType).getQuantity();
301 info.storageOffset = startOffset;
302 info.storageType = storageType;
303 info.name = fd->getName();
304
305 if (info.size > info.storageSize)
306 info.size = info.storageSize;
307 // Reverse the bit offsets for big endian machines. Since bitfields are laid
308 // out as packed bits within an integer-sized unit, we can imagine the bits
309 // counting from the most-significant-bit instead of the
310 // least-significant-bit.
311 if (dataLayout.isBigEndian())
312 info.offset = info.storageSize - (info.offset + info.size);
313
314 info.volatileStorageSize = 0;
315 info.volatileOffset = 0;
316 info.volatileStorageOffset = CharUnits::Zero();
317}
318
319void CIRRecordLowering::lower(bool nonVirtualBaseType) {
320 if (recordDecl->isUnion()) {
321 lowerUnion(nonVirtualBaseType);
322 computeVolatileBitfields();
323 return;
324 }
325
326 CharUnits size = nonVirtualBaseType ? astRecordLayout.getNonVirtualSize()
327 : astRecordLayout.getSize();
328
329 accumulateFields(nonVirtualBaseType);
330
331 if (cxxRecordDecl) {
332 accumulateVPtrs();
333 accumulateBases();
334 if (members.empty()) {
335 appendPaddingBytes(size);
336 computeVolatileBitfields();
337 return;
338 }
339 if (!nonVirtualBaseType)
340 accumulateVBases();
341 }
342
343 llvm::stable_sort(members);
344 // TODO: Verify bitfield clipping
346
347 // The sentinel is popped before fillOutputFields, so its kind never reaches
348 // the type.
349 members.push_back(
350 makeStorageInfo(size, getUIntNType(8), cir::RecordMemberKind::Data));
351 determinePacked(nonVirtualBaseType);
352 insertPadding();
353 members.pop_back();
354
355 calculateZeroInit();
356 fillOutputFields();
357 computeVolatileBitfields();
358}
359
360void CIRRecordLowering::fillOutputFields() {
361 for (const MemberInfo &member : members) {
362 if (member.data)
363 addField(member.data, member.memberKind);
364 if (member.kind == MemberInfo::InfoKind::Field) {
365 if (member.fieldDecl)
366 fieldIdxMap[member.fieldDecl->getCanonicalDecl()] =
367 fieldTypes.size() - 1;
368 // A field without storage must be a bitfield.
369 if (!member.data) {
370 assert(member.fieldDecl &&
371 "member.data is a nullptr so member.fieldDecl should not be");
372 setBitFieldInfo(member.fieldDecl, member.offset, fieldTypes.back());
373 }
374 } else if (member.kind == MemberInfo::InfoKind::Base) {
375 nonVirtualBases[member.cxxRecordDecl] = fieldTypes.size() - 1;
376 } else if (member.kind == MemberInfo::InfoKind::VBase) {
377 virtualBases[member.cxxRecordDecl] = fieldTypes.size() - 1;
378 }
379 }
380}
381
383CIRRecordLowering::accumulateBitFields(RecordDecl::field_iterator field,
385 if (isDiscreteBitFieldABI()) {
386 // run stores the first element of the current run of bitfields. fieldEnd is
387 // used as a special value to note that we don't have a current run. A
388 // bitfield run is a contiguous collection of bitfields that can be stored
389 // in the same storage block. Zero-sized bitfields and bitfields that would
390 // cross an alignment boundary break a run and start a new one.
392 // tail is the offset of the first bit off the end of the current run. It's
393 // used to determine if the ASTRecordLayout is treating these two bitfields
394 // as contiguous. StartBitOffset is offset of the beginning of the Run.
395 uint64_t startBitOffset, tail = 0;
396 // Where the current run's storage member sits in members, so that a named
397 // occupant joining the run can promote it to data.
398 size_t storageIdx = 0;
399 for (; field != fieldEnd && field->isBitField(); ++field) {
400 // Zero-width bitfields end runs.
401 if (field->isZeroLengthBitField()) {
402 run = fieldEnd;
403 continue;
404 }
405 uint64_t bitOffset = getFieldBitOffset(*field);
406 mlir::Type type = cirGenTypes.convertTypeForMem(field->getType());
407 // If we don't have a run yet, or don't live within the previous run's
408 // allocated storage then we allocate some storage and start a new run.
409 if (run == fieldEnd || bitOffset >= tail) {
410 run = field;
411 startBitOffset = bitOffset;
412 tail = startBitOffset + dataLayout.getTypeAllocSizeInBits(type);
413 // Add the storage member to the record. This must be added to the
414 // record before the bitfield members so that it gets laid out before
415 // the bitfields it contains get laid out. The run is only known one
416 // field at a time here, so the unit starts out holding no data and is
417 // promoted below when a named occupant lands in it.
418 storageIdx = members.size();
419 members.push_back(makeStorageInfo(bitsToCharUnits(startBitOffset), type,
420 cir::RecordMemberKind::Empty));
421 }
422 assert(members[storageIdx].offset == bitsToCharUnits(startBitOffset) &&
423 "storageIdx must name the current run's storage");
424 if (!field->isUnnamedBitField())
425 members[storageIdx].memberKind = cir::RecordMemberKind::Data;
426 // Bitfields get the offset of their storage but come afterward and remain
427 // there after a stable sort.
428 members.push_back(MemberInfo(bitsToCharUnits(startBitOffset),
429 MemberInfo::InfoKind::Field, nullptr,
430 cir::RecordMemberKind::Data, *field));
431 }
432 return field;
433 }
434
435 CharUnits regSize =
436 bitsToCharUnits(astContext.getTargetInfo().getRegisterWidth());
437 unsigned charBits = astContext.getCharWidth();
438
439 // Data about the start of the span we're accumulating to create an access
440 // unit from. 'Begin' is the first bitfield of the span. If 'begin' is
441 // 'fieldEnd', we've not got a current span. The span starts at the
442 // 'beginOffset' character boundary. 'bitSizeSinceBegin' is the size (in bits)
443 // of the span -- this might include padding when we've advanced to a
444 // subsequent bitfield run.
445 RecordDecl::field_iterator begin = fieldEnd;
446 CharUnits beginOffset;
447 uint64_t bitSizeSinceBegin;
448
449 // The (non-inclusive) end of the largest acceptable access unit we've found
450 // since 'begin'. If this is 'begin', we're gathering the initial set of
451 // bitfields of a new span. 'bestEndOffset' is the end of that acceptable
452 // access unit -- it might extend beyond the last character of the bitfield
453 // run, using available padding characters.
454 RecordDecl::field_iterator bestEnd = begin;
455 CharUnits bestEndOffset;
456 bool bestClipped; // Whether the representation must be in a byte array.
457
458 for (;;) {
459 // atAlignedBoundary is true if 'field' is the (potential) start of a new
460 // span (or the end of the bitfields). When true, limitOffset is the
461 // character offset of that span and barrier indicates whether the new
462 // span cannot be merged into the current one.
463 bool atAlignedBoundary = false;
464 bool barrier = false; // a barrier can be a zero Bit Width or non bit member
465 if (field != fieldEnd && field->isBitField()) {
466 uint64_t bitOffset = getFieldBitOffset(*field);
467 if (begin == fieldEnd) {
468 // Beginning a new span.
469 begin = field;
470 bestEnd = begin;
471
472 assert((bitOffset % charBits) == 0 && "Not at start of char");
473 beginOffset = bitsToCharUnits(bitOffset);
474 bitSizeSinceBegin = 0;
475 } else if ((bitOffset % charBits) != 0) {
476 // Bitfield occupies the same character as previous bitfield, it must be
477 // part of the same span. This can include zero-length bitfields, should
478 // the target not align them to character boundaries. Such non-alignment
479 // is at variance with the standards, which require zero-length
480 // bitfields be a barrier between access units. But of course we can't
481 // achieve that in the middle of a character.
482 assert(bitOffset ==
483 astContext.toBits(beginOffset) + bitSizeSinceBegin &&
484 "Concatenating non-contiguous bitfields");
485 } else {
486 // Bitfield potentially begins a new span. This includes zero-length
487 // bitfields on non-aligning targets that lie at character boundaries
488 // (those are barriers to merging).
489 if (field->isZeroLengthBitField())
490 barrier = true;
491 atAlignedBoundary = true;
492 }
493 } else {
494 // We've reached the end of the bitfield run. Either we're done, or this
495 // is a barrier for the current span.
496 if (begin == fieldEnd)
497 break;
498
499 barrier = true;
500 atAlignedBoundary = true;
501 }
502
503 // 'installBest' indicates whether we should create an access unit for the
504 // current best span: fields ['begin', 'bestEnd') occupying characters
505 // ['beginOffset', 'bestEndOffset').
506 bool installBest = false;
507 if (atAlignedBoundary) {
508 // 'field' is the start of a new span or the end of the bitfields. The
509 // just-seen span now extends to 'bitSizeSinceBegin'.
510
511 // Determine if we can accumulate that just-seen span into the current
512 // accumulation.
513 CharUnits accessSize = bitsToCharUnits(bitSizeSinceBegin + charBits - 1);
514 if (bestEnd == begin) {
515 // This is the initial run at the start of a new span. By definition,
516 // this is the best seen so far.
517 bestEnd = field;
518 bestEndOffset = beginOffset + accessSize;
519 // Assume clipped until proven not below.
520 bestClipped = true;
521 if (!bitSizeSinceBegin)
522 // A zero-sized initial span -- this will install nothing and reset
523 // for another.
524 installBest = true;
525 } else if (accessSize > regSize) {
526 // Accumulating the just-seen span would create a multi-register access
527 // unit, which would increase register pressure.
528 installBest = true;
529 }
530
531 if (!installBest) {
532 // Determine if accumulating the just-seen span will create an expensive
533 // access unit or not.
534 mlir::Type type = getUIntNType(astContext.toBits(accessSize));
536 cirGenTypes.getCGModule().errorNYI(
537 field->getSourceRange(), "NYI CheapUnalignedBitFieldAccess");
538
539 if (!installBest) {
540 // Find the next used storage offset to determine what the limit of
541 // the current span is. That's either the offset of the next field
542 // with storage (which might be field itself) or the end of the
543 // non-reusable tail padding.
544 CharUnits limitOffset;
545 for (auto probe = field; probe != fieldEnd; ++probe)
546 if (!isEmptyFieldForLayout(astContext, *probe)) {
547 // A member with storage sets the limit.
548 assert((getFieldBitOffset(*probe) % charBits) == 0 &&
549 "Next storage is not byte-aligned");
550 limitOffset = bitsToCharUnits(getFieldBitOffset(*probe));
551 goto FoundLimit;
552 }
553 limitOffset = cxxRecordDecl ? astRecordLayout.getNonVirtualSize()
554 : astRecordLayout.getDataSize();
555
556 FoundLimit:
557 CharUnits typeSize = getSize(type);
558 if (beginOffset + typeSize <= limitOffset) {
559 // There is space before limitOffset to create a naturally-sized
560 // access unit.
561 bestEndOffset = beginOffset + typeSize;
562 bestEnd = field;
563 bestClipped = false;
564 }
565 if (barrier) {
566 // The next field is a barrier that we cannot merge across.
567 installBest = true;
568 } else if (cirGenTypes.getCGModule()
570 .FineGrainedBitfieldAccesses) {
571 installBest = true;
572 } else {
573 // Otherwise, we're not installing. Update the bit size
574 // of the current span to go all the way to limitOffset, which is
575 // the (aligned) offset of next bitfield to consider.
576 bitSizeSinceBegin = astContext.toBits(limitOffset - beginOffset);
577 }
578 }
579 }
580 }
581
582 if (installBest) {
583 assert((field == fieldEnd || !field->isBitField() ||
584 (getFieldBitOffset(*field) % charBits) == 0) &&
585 "Installing but not at an aligned bitfield or limit");
586 CharUnits accessSize = bestEndOffset - beginOffset;
587 if (!accessSize.isZero()) {
588 // Add the storage member for the access unit to the record. The
589 // bitfields get the offset of their storage but come afterward and
590 // remain there after a stable sort.
591 mlir::Type type;
592 if (bestClipped) {
593 assert(getSize(getUIntNType(astContext.toBits(accessSize))) >
594 accessSize &&
595 "Clipped access need not be clipped");
596 type = getByteArrayType(accessSize);
597 } else {
598 type = getUIntNType(astContext.toBits(accessSize));
599 assert(getSize(type) == accessSize &&
600 "Unclipped access must be clipped");
601 }
602 // An unnamed bit-field of any width occupies no ABI class, so the unit
603 // starts out holding no data and is promoted below when a named
604 // occupant lands in it.
605 const size_t storageIdx = members.size();
606 members.push_back(
607 makeStorageInfo(beginOffset, type, cir::RecordMemberKind::Empty));
608 for (; begin != bestEnd; ++begin) {
609 if (!begin->isUnnamedBitField())
610 members[storageIdx].memberKind = cir::RecordMemberKind::Data;
611 if (!begin->isZeroLengthBitField())
612 members.push_back(MemberInfo(beginOffset,
613 MemberInfo::InfoKind::Field, nullptr,
614 cir::RecordMemberKind::Data, *begin));
615 }
616 }
617 // Reset to start a new span.
618 field = bestEnd;
619 begin = fieldEnd;
620 } else {
621 assert(field != fieldEnd && field->isBitField() &&
622 "Accumulating past end of bitfields");
623 assert(!barrier && "Accumulating across barrier");
624 // Accumulate this bitfield into the current (potential) span.
625 bitSizeSinceBegin += field->getBitWidthValue();
626 ++field;
627 }
628 }
629
630 return field;
631}
632
633void CIRRecordLowering::accumulateFields(bool nonVirtualBaseType) {
634 for (RecordDecl::field_iterator field = recordDecl->field_begin(),
635 fieldEnd = recordDecl->field_end();
636 field != fieldEnd;) {
637 if (field->isBitField()) {
638 field = accumulateBitFields(field, fieldEnd);
639 assert((field == fieldEnd || !field->isBitField()) &&
640 "Failed to accumulate all the bitfields");
641 } else if (isEmptyFieldForLayout(astContext, *field) &&
642 field->isPotentiallyOverlapping()) {
643 // We lay out normal empty fields, as they are required for GEPs/getting
644 // function pointers. However 'no-unique-address' lends some additional
645 // complexity. These fields take up no real space, but would also have to
646 // be the correct 'GEP' offset to work here, but then mess with the
647 // layout. We likely need to come up with a new 'type' to support these,
648 // then figure out some way to lower these to the correct offset, likely
649 // by calculating the correct offset into the struct, and forming a
650 // replacement by-byte GEP in LowerToLLVM. However, this is only a
651 // problem with taking the address of one of these, so it is in practice
652 // not a horrifyingly problematic issue.
654 // Dropping the field leaves no member to mark, so its bytes read as
655 // padding. That is only sound when the field carries no ABI data
656 // either, which isEmptyFieldForLayout does not guarantee. Report the
657 // gap rather than claim an emptiness the record does not have. The base
658 // subobject lowering sees the same field, so only the complete object
659 // reports it.
660 if (!nonVirtualBaseType && !isEmptyFieldForABI(astContext, *field))
661 cirGenTypes.getCGModule().errorNYI(
662 field->getSourceRange(),
663 "[[no_unique_address]] field that is empty for layout but holds "
664 "data for the ABI");
665 ++field;
666 } else {
667 // Use base subobject layout for potentially-overlapping fields,
668 // as it is done in RecordLayoutBuilder.
669 //
670 // The mark comes from isEmptyFieldForABI, not the isEmptyFieldForLayout
671 // above. Neither predicate subsumes the other.
672 members.push_back(MemberInfo(
673 bitsToCharUnits(getFieldBitOffset(*field)),
674 MemberInfo::InfoKind::Field,
675 field->isPotentiallyOverlapping()
676 ? getStorageType(field->getType()->getAsCXXRecordDecl())
677 : getStorageType(*field),
678 getFieldMemberKind(*field), *field));
679 ++field;
680 }
681 }
682}
683
684void CIRRecordLowering::calculateZeroInit() {
685 for (const MemberInfo &member : members) {
686 if (member.kind == MemberInfo::InfoKind::Field) {
687 if (!member.fieldDecl || isZeroInitializable(member.fieldDecl))
688 continue;
689 zeroInitializable = zeroInitializableAsBase = false;
690 return;
691 } else if (member.kind == MemberInfo::InfoKind::Base ||
692 member.kind == MemberInfo::InfoKind::VBase) {
693 if (isZeroInitializable(member.cxxRecordDecl))
694 continue;
695 zeroInitializable = false;
696 if (member.kind == MemberInfo::InfoKind::Base)
697 zeroInitializableAsBase = false;
698 }
699 }
700}
701
702void CIRRecordLowering::determinePacked(bool nvBaseType) {
703 if (packed)
704 return;
705 CharUnits alignment = CharUnits::One();
706 CharUnits nvAlignment = CharUnits::One();
707 CharUnits nvSize = !nvBaseType && cxxRecordDecl
708 ? astRecordLayout.getNonVirtualSize()
709 : CharUnits::Zero();
710
711 for (const MemberInfo &member : members) {
712 if (!member.data)
713 continue;
714 // If any member falls at an offset that it not a multiple of its alignment,
715 // then the entire record must be packed.
716 if (!member.offset.isMultipleOf(getAlignment(member.data)))
717 packed = true;
718 if (member.offset < nvSize)
719 nvAlignment = std::max(nvAlignment, getAlignment(member.data));
720 alignment = std::max(alignment, getAlignment(member.data));
721 }
722 // If the size of the record (the capstone's offset) is not a multiple of the
723 // record's alignment, it must be packed.
724 if (!members.back().offset.isMultipleOf(alignment))
725 packed = true;
726 // If the non-virtual sub-object is not a multiple of the non-virtual
727 // sub-object's alignment, it must be packed. We cannot have a packed
728 // non-virtual sub-object and an unpacked complete object or vise versa.
729 if (!nvSize.isMultipleOf(nvAlignment))
730 packed = true;
731 // Update the alignment of the sentinel.
732 if (!packed)
733 members.back().data = getUIntNType(astContext.toBits(alignment));
734}
735
736void CIRRecordLowering::insertPadding() {
737 std::vector<std::pair<CharUnits, CharUnits>> padding;
738 CharUnits size = CharUnits::Zero();
739 for (const MemberInfo &member : members) {
740 if (!member.data)
741 continue;
742 CharUnits offset = member.offset;
743 assert(offset >= size);
744 // Insert padding if we need to.
745 if (offset !=
746 size.alignTo(packed ? CharUnits::One() : getAlignment(member.data)))
747 padding.push_back(std::make_pair(size, offset - size));
748 size = offset + getSize(member.data);
749 }
750 if (padding.empty())
751 return;
752 // Add the padding to the Members list and sort it.
753 for (const std::pair<CharUnits, CharUnits> &paddingPair : padding)
754 members.push_back(makeStorageInfo(paddingPair.first,
755 getByteArrayType(paddingPair.second),
756 cir::RecordMemberKind::Pad));
757 llvm::stable_sort(members);
758}
759
760static cir::ArgPassingKind
762 switch (kind) {
764 return cir::ArgPassingKind::CanPassInRegs;
766 return cir::ArgPassingKind::CannotPassInRegs;
768 return cir::ArgPassingKind::CanNeverPassInRegs;
769 }
770 llvm_unreachable("unknown RecordArgPassingKind");
771}
772
773/// Whether the member kinds on \p recordTy answer the record's ABI emptiness
774/// the same way the AST predicate does.
775[[maybe_unused]] static bool
776marksMatchABIEmptiness(const ASTContext &astContext, const RecordDecl *rd,
777 cir::RecordType recordTy) {
778 return recordTy.isEmptyForABI() ==
779 isEmptyRecordForABI(astContext, astContext.getCanonicalTagType(rd));
780}
781
782std::unique_ptr<CIRGenRecordLayout>
784 CIRRecordLowering lowering(*this, rd, /*packed=*/false);
785 assert(ty->isIncomplete() && "recomputing record layout?");
786 lowering.lower(/*nonVirtualBaseType=*/false);
787
788 // If we're in C++, compute the base subobject type. For C++ records baseTy
789 // defaults to the complete object type and is replaced by a distinct,
790 // smaller record only when the record has tail padding an enclosing
791 // [[no_unique_address]] field can reuse. We must populate baseTy even when
792 // it equals ty because callers such as getStorageType(const CXXRecordDecl *)
793 // read it unconditionally when laying out potentially-overlapping
794 // ([[no_unique_address]]) fields; a null baseTy would otherwise propagate as
795 // a null mlir::Type into the members vector and trip the !empty() assertion
796 // in fillOutputFields.
797 cir::RecordType baseTy;
798 if (llvm::isa<CXXRecordDecl>(rd)) {
799 baseTy = *ty;
800 // A record needs a distinct base-subobject type when its tail padding can
801 // be reused by an enclosing [[no_unique_address]] field, i.e. when the
802 // non-virtual size differs from the complete size. This matches classic
803 // CodeGen and covers unions too: a union's non-virtual size already tracks
804 // its reusable tail padding (and stays at the minimum union size when the
805 // union is empty, so a zero-data union does not spuriously qualify).
806 if (lowering.astRecordLayout.getNonVirtualSize() !=
807 lowering.astRecordLayout.getSize()) {
808 CIRRecordLowering baseLowering(*this, rd, /*Packed=*/lowering.packed);
809 baseLowering.lower(/*nonVirtualBaseType=*/true);
810 std::string baseIdentifier = getRecordTypeName(rd, ".base");
811 baseTy = builder.getCompleteNamedRecordType(
812 baseLowering.getFieldTypes(), baseLowering.packed, baseIdentifier,
813 baseLowering.getFieldKinds());
814 // TODO(cir): add something like addRecordTypeName
815
816 // BaseTy and Ty must agree on their packedness for getCIRFieldNo to work
817 // on both of them with the same index. Unions are exempt: CIR derives a
818 // union's packedness from its layout size, which is the data size for the
819 // base subobject but the full size for the complete object, so the two
820 // can legitimately disagree. (Classic CodeGen derives both from the data
821 // size and so needs no such exemption.)
822 assert((rd->isUnion() || lowering.packed == baseLowering.packed) &&
823 "Non-virtual and complete types must agree on packedness");
824 // Emptiness is a property of the decl, so the base subobject must answer
825 // the same way the complete object does. The two are not comparable
826 // mark by mark: they see different sizes and so different tail padding.
827 assert((marksMatchABIEmptiness(astContext, rd, baseTy) ||
828 cgm.getDiags().hasErrorOccurred()) &&
829 "base subobject member kinds must reproduce its ABI emptiness");
830 }
831 }
832
833 // Fill in the record *after* computing the base type. Filling in the body
834 // signifies that the type is no longer opaque and record layout is complete,
835 // but we may need to recursively layout rd while laying D out as a base type.
837 ty->complete(lowering.getFieldTypes(), lowering.packed, lowering.unionPadding,
838 lowering.getFieldKinds());
839
840 // The marks exist so that emptiness can be read off the type, so check that
841 // answer against the AST predicate on every record CIRGen lays out. This
842 // does not check the individual marks, only what they add up to. The marks
843 // themselves are pinned by clang/test/CIR/CodeGen/record-member-kinds.*.
844 assert((marksMatchABIEmptiness(astContext, rd, *ty) ||
845 cgm.getDiags().hasErrorOccurred()) &&
846 "member kinds must reproduce the ABI emptiness of the record");
847
848 // Queue ABI metadata for the module-level cir.record_layouts attribute.
849 if (ty->getName()) {
850 mlir::MLIRContext *mlirCtx = ty->getContext();
851 cir::ArgPassingKind apk =
853
854 bool hasTrivialDestructor = true;
855 if (auto *cxxRD = dyn_cast<CXXRecordDecl>(rd))
856 hasTrivialDestructor = cxxRD->hasTrivialDestructor();
857 const auto &astLayout = astContext.getASTRecordLayout(rd);
858 uint64_t recordAlignInBytes = astLayout.getAlignment().getQuantity();
859
860 cgm.addRecordLayout(ty->getName(), cir::RecordLayoutAttr::get(
861 mlirCtx, apk, hasTrivialDestructor,
862 recordAlignInBytes));
863 }
864
865 auto rl = std::make_unique<CIRGenRecordLayout>(
866 ty ? *ty : cir::RecordType{}, baseTy ? baseTy : cir::RecordType{},
867 (bool)lowering.zeroInitializable, (bool)lowering.zeroInitializableAsBase);
868
869 rl->nonVirtualBases.swap(lowering.nonVirtualBases);
870 rl->completeObjectVirtualBases.swap(lowering.virtualBases);
871
872 // Add all the field numbers.
873 rl->fieldIdxMap.swap(lowering.fieldIdxMap);
874
875 rl->bitFields.swap(lowering.bitFields);
876
877 // Dump the layout, if requested.
878 if (getASTContext().getLangOpts().DumpRecordLayouts) {
879 llvm::outs() << "\n*** Dumping CIRgen Record Layout\n";
880 llvm::outs() << "Record: ";
881 rd->dump(llvm::outs());
882 llvm::outs() << "\nLayout: ";
883 rl->print(llvm::outs());
884 }
885
886 // TODO: implement verification
887 return rl;
888}
889
890void CIRGenRecordLayout::print(raw_ostream &os) const {
891 os << "<CIRecordLayout\n";
892 os << " CIR Type:" << completeObjectType << "\n";
893 if (baseSubobjectType)
894 os << " NonVirtualBaseCIRType:" << baseSubobjectType << "\n";
895 os << " IsZeroInitializable:" << zeroInitializable << "\n";
896 os << " BitFields:[\n";
897 std::vector<std::pair<unsigned, const CIRGenBitFieldInfo *>> bitInfo;
898 for (auto &[decl, info] : bitFields) {
899 const RecordDecl *rd = decl->getParent();
900 unsigned index = 0;
901 for (RecordDecl::field_iterator it = rd->field_begin(); *it != decl; ++it)
902 ++index;
903 bitInfo.push_back(std::make_pair(index, &info));
904 }
905 llvm::array_pod_sort(bitInfo.begin(), bitInfo.end());
906 for (std::pair<unsigned, const CIRGenBitFieldInfo *> &info : bitInfo) {
907 os.indent(4);
908 info.second->print(os);
909 os << "\n";
910 }
911 os << " ]>\n";
912}
913
914void CIRGenBitFieldInfo::print(raw_ostream &os) const {
915 os << "<CIRBitFieldInfo" << " name:" << name << " offset:" << offset
916 << " size:" << size << " isSigned:" << isSigned
917 << " storageSize:" << storageSize
918 << " storageOffset:" << storageOffset.getQuantity()
919 << " volatileOffset:" << volatileOffset
920 << " volatileStorageSize:" << volatileStorageSize
921 << " volatileStorageOffset:" << volatileStorageOffset.getQuantity() << ">";
922}
923
924void CIRGenRecordLayout::dump() const { print(llvm::errs()); }
925
926void CIRGenBitFieldInfo::dump() const { print(llvm::errs()); }
927
928void CIRRecordLowering::lowerUnion(bool nonVirtualBaseType) {
929 // The base-subobject layout of a union is sized to its data size rather than
930 // its full size. A union can have reusable tail padding when one of its
931 // members is a [[no_unique_address]] field that itself has tail padding, so
932 // an enclosing [[no_unique_address]] union field must use this smaller type.
933 CharUnits layoutSize = nonVirtualBaseType ? astRecordLayout.getDataSize()
934 : astRecordLayout.getSize();
935 // Accumulate bitfields and fields, and figure out what our difference between
936 // storage type and padding is.
937
938 // First, accumulate all the types.
939 for (const FieldDecl *field : recordDecl->fields()) {
940 mlir::Type fieldType;
941 if (field->isBitField()) {
942 if (field->isZeroLengthBitField())
943 continue;
944 fieldType = getBitfieldStorageType(field->getBitWidthValue());
945 setBitFieldInfo(field, CharUnits::Zero(), fieldType);
946 } else {
947 fieldType = getStorageType(field);
948 }
949
950 fieldIdxMap[field->getCanonicalDecl()] = 0;
951 addField(fieldType, isEmptyFieldForABI(astContext, field)
952 ? cir::RecordMemberKind::Empty
953 : cir::RecordMemberKind::Data);
954 }
955
956 // Compute zero-initializable status.
957 // This union might not be zero initialized: it may contain a pointer to
958 // data member which might have some exotic initialization sequence.
959 // This chooses the first 'named' member and is zero-initializable based on
960 // that.
961 auto hasNamedMember = [](const FieldDecl *curField) -> bool {
962 const auto *rd = curField->getType()->getAsRecordDecl();
963 return rd && rd->findFirstNamedDataMember();
964 };
965 // Whether this is usable for zero-init as a 'named member'. It is a field
966 // with a name (or a record type with a named member itself), that isn't a
967 // zero-width bitfield.
968 auto isNamedMember = [hasNamedMember](const FieldDecl *curField) -> bool {
969 if (curField->isZeroLengthBitField())
970 return false;
971 return curField->getIdentifier() || hasNamedMember(curField);
972 };
973 auto firstNamedMemberItr = llvm::find_if(recordDecl->fields(), isNamedMember);
974
975 if (firstNamedMemberItr != recordDecl->fields().end() &&
976 !isZeroInitializable(*firstNamedMemberItr))
977 zeroInitializable = zeroInitializableAsBase = false;
978
979 // If we have no candidates for storage, we are JUST padding.
980 if (getFieldTypes().empty()) {
981 appendPaddingBytes(layoutSize);
982 return;
983 }
984
985 mlir::Type storageType =
986 cir::UnionType::getUnionStorageType(dataLayout.layout, getFieldTypes());
987
988 // If our storage size was bigger than our required size (can happen in the
989 // case of packed bitfields on Itanium) then just use an I8 array.
990 if (layoutSize < getSize(storageType))
991 storageType = getByteArrayType(layoutSize);
992
993 // The base-subobject record is built as a struct from fieldTypes, so add
994 // the storage type and any trailing padding as ordinary fields rather than
995 // routing padding through the union's single tail-padding slot.
996 if (nonVirtualBaseType) {
997 // One member stands in for every variant, so it holds data unless no
998 // variant does. Computed before clearFields() drops the variant marks.
999 const cir::RecordMemberKind storageKind =
1000 llvm::is_contained(getFieldKinds(), cir::RecordMemberKind::Data)
1001 ? cir::RecordMemberKind::Data
1002 : cir::RecordMemberKind::Empty;
1003 clearFields();
1004 addField(storageType, storageKind);
1005 CharUnits padding = layoutSize - getSize(storageType);
1006 if (!padding.isZero())
1007 addField(getByteArrayType(padding), cir::RecordMemberKind::Pad);
1008 } else {
1009 // Else we just add padding normally.
1010 appendPaddingBytes(layoutSize - getSize(storageType));
1011 }
1012 packed = !layoutSize.isMultipleOf(getAlignment(storageType));
1013}
1014
1015bool CIRRecordLowering::hasOwnStorage(const CXXRecordDecl *decl,
1016 const CXXRecordDecl *query) {
1017 const ASTRecordLayout &declLayout = astContext.getASTRecordLayout(decl);
1018 if (declLayout.isPrimaryBaseVirtual() && declLayout.getPrimaryBase() == query)
1019 return false;
1020 for (const auto &base : decl->bases())
1021 if (!hasOwnStorage(base.getType()->getAsCXXRecordDecl(), query))
1022 return false;
1023 return true;
1024}
1025
1026/// The AAPCS that defines that, when possible, bit-fields should
1027/// be accessed using containers of the declared type width:
1028/// When a volatile bit-field is read, and its container does not overlap with
1029/// any non-bit-field member or any zero length bit-field member, its container
1030/// must be read exactly once using the access width appropriate to the type of
1031/// the container. When a volatile bit-field is written, and its container does
1032/// not overlap with any non-bit-field member or any zero-length bit-field
1033/// member, its container must be read exactly once and written exactly once
1034/// using the access width appropriate to the type of the container. The two
1035/// accesses are not atomic.
1036///
1037/// Enforcing the width restriction can be disabled using
1038/// -fno-aapcs-bitfield-width.
1039void CIRRecordLowering::computeVolatileBitfields() {
1040 if (!isAAPCS() ||
1041 !cirGenTypes.getCGModule().getCodeGenOpts().AAPCSBitfieldWidth)
1042 return;
1043
1044 for (auto &[field, info] : bitFields) {
1045 mlir::Type resLTy = cirGenTypes.convertTypeForMem(field->getType());
1046
1047 if (astContext.toBits(astRecordLayout.getAlignment()) <
1048 getSizeInBits(resLTy).getQuantity())
1049 continue;
1050
1051 // CIRRecordLowering::setBitFieldInfo() pre-adjusts the bit-field offsets
1052 // for big-endian targets, but it assumes a container of width
1053 // info.storageSize. Since AAPCS uses a different container size (width
1054 // of the type), we first undo that calculation here and redo it once
1055 // the bit-field offset within the new container is calculated.
1056 const unsigned oldOffset =
1057 isBigEndian() ? info.storageSize - (info.offset + info.size)
1058 : info.offset;
1059 // Offset to the bit-field from the beginning of the struct.
1060 const unsigned absoluteOffset =
1061 astContext.toBits(info.storageOffset) + oldOffset;
1062
1063 // Container size is the width of the bit-field type.
1064 const unsigned storageSize = getSizeInBits(resLTy).getQuantity();
1065 // Nothing to do if the access uses the desired
1066 // container width and is naturally aligned.
1067 if (info.storageSize == storageSize && (oldOffset % storageSize == 0))
1068 continue;
1069
1070 // Offset within the container.
1071 unsigned offset = absoluteOffset & (storageSize - 1);
1072 // Bail out if an aligned load of the container cannot cover the entire
1073 // bit-field. This can happen for example, if the bit-field is part of a
1074 // packed struct. AAPCS does not define access rules for such cases, we let
1075 // clang to follow its own rules.
1076 if (offset + info.size > storageSize)
1077 continue;
1078
1079 // Re-adjust offsets for big-endian targets.
1080 if (isBigEndian())
1081 offset = storageSize - (offset + info.size);
1082
1083 const CharUnits storageOffset =
1084 astContext.toCharUnitsFromBits(absoluteOffset & ~(storageSize - 1));
1085 const CharUnits end = storageOffset +
1086 astContext.toCharUnitsFromBits(storageSize) -
1088
1089 const ASTRecordLayout &layout =
1090 astContext.getASTRecordLayout(field->getParent());
1091 // If we access outside memory outside the record, than bail out.
1092 const CharUnits recordSize = layout.getSize();
1093 if (end >= recordSize)
1094 continue;
1095
1096 // Bail out if performing this load would access non-bit-fields members.
1097 bool conflict = false;
1098 for (const auto *f : recordDecl->fields()) {
1099 // Allow sized bit-fields overlaps.
1100 if (f->isBitField() && !f->isZeroLengthBitField())
1101 continue;
1102
1103 const CharUnits fOffset = astContext.toCharUnitsFromBits(
1104 layout.getFieldOffset(f->getFieldIndex()));
1105
1106 // As C11 defines, a zero sized bit-field defines a barrier, so
1107 // fields after and before it should be race condition free.
1108 // The AAPCS acknowledges it and imposes no restritions when the
1109 // natural container overlaps a zero-length bit-field.
1110 if (f->isZeroLengthBitField()) {
1111 if (end > fOffset && storageOffset < fOffset) {
1112 conflict = true;
1113 break;
1114 }
1115 }
1116
1117 const CharUnits fEnd =
1118 fOffset +
1119 astContext.toCharUnitsFromBits(
1120 getSizeInBits(cirGenTypes.convertTypeForMem(f->getType()))
1121 .getQuantity()) -
1123 // If no overlap, continue.
1124 if (end < fOffset || fEnd < storageOffset)
1125 continue;
1126
1127 // The desired load overlaps a non-bit-field member, bail out.
1128 conflict = true;
1129 break;
1130 }
1131
1132 if (conflict)
1133 continue;
1134 // Write the new bit-field access parameters.
1135 // As the storage offset now is defined as the number of elements from the
1136 // start of the structure, we should divide the Offset by the element size.
1137 info.volatileStorageOffset =
1138 storageOffset /
1139 astContext.toCharUnitsFromBits(storageSize).getQuantity();
1140 info.volatileStorageSize = storageSize;
1141 info.volatileOffset = offset;
1142 }
1143}
1144
1145void CIRRecordLowering::accumulateBases() {
1146 // If we've got a primary virtual base, we need to add it with the bases.
1147 if (astRecordLayout.isPrimaryBaseVirtual()) {
1148 const CXXRecordDecl *baseDecl = astRecordLayout.getPrimaryBase();
1149 members.push_back(MemberInfo(CharUnits::Zero(), MemberInfo::InfoKind::Base,
1150 getStorageType(baseDecl),
1151 getBaseMemberKind(baseDecl), baseDecl));
1152 }
1153
1154 // Accumulate the non-virtual bases.
1155 for (const auto &base : cxxRecordDecl->bases()) {
1156 if (base.isVirtual())
1157 continue;
1158 // Bases can be zero-sized even if not technically empty if they
1159 // contain only a trailing array member.
1160 const CXXRecordDecl *baseDecl = base.getType()->getAsCXXRecordDecl();
1161 if (!baseDecl->isEmpty() &&
1162 !astContext.getASTRecordLayout(baseDecl).getNonVirtualSize().isZero()) {
1163 members.push_back(MemberInfo(astRecordLayout.getBaseClassOffset(baseDecl),
1164 MemberInfo::InfoKind::Base,
1165 getStorageType(baseDecl),
1166 getBaseMemberKind(baseDecl), baseDecl));
1167 }
1168 }
1169}
1170
1171void CIRRecordLowering::accumulateVBases() {
1172 for (const auto &base : cxxRecordDecl->vbases()) {
1173 const CXXRecordDecl *baseDecl = base.getType()->getAsCXXRecordDecl();
1174 if (isEmptyRecordForLayout(astContext, base.getType()))
1175 continue;
1176 CharUnits offset = astRecordLayout.getVBaseClassOffset(baseDecl);
1177 // If the vbase is a primary virtual base of some base, then it doesn't
1178 // get its own storage location but instead lives inside of that base.
1179 if (isOverlappingVBaseABI() && astContext.isNearlyEmpty(baseDecl) &&
1180 !hasOwnStorage(cxxRecordDecl, baseDecl)) {
1181 members.push_back(MemberInfo(offset, MemberInfo::InfoKind::VBase, nullptr,
1182 cir::RecordMemberKind::Data, baseDecl));
1183 continue;
1184 }
1185 // If we've got a vtordisp, add it as a storage type.
1186 if (astRecordLayout.getVBaseOffsetsMap()
1187 .find(baseDecl)
1188 ->second.hasVtorDisp())
1189 members.push_back(makeStorageInfo(offset - CharUnits::fromQuantity(4),
1190 getUIntNType(32),
1191 cir::RecordMemberKind::Data));
1192 members.push_back(MemberInfo(offset, MemberInfo::InfoKind::VBase,
1193 getStorageType(baseDecl),
1194 getBaseMemberKind(baseDecl), baseDecl));
1195 }
1196}
1197
1198void CIRRecordLowering::accumulateVPtrs() {
1199 if (astRecordLayout.hasOwnVFPtr())
1200 members.push_back(MemberInfo(CharUnits::Zero(), MemberInfo::InfoKind::VFPtr,
1201 getVFPtrType(), cir::RecordMemberKind::Data));
1202
1203 if (astRecordLayout.hasOwnVBPtr())
1204 cirGenTypes.getCGModule().errorNYI(recordDecl->getSourceRange(),
1205 "accumulateVPtrs: hasOwnVBPtr");
1206}
1207
1208mlir::Type CIRRecordLowering::getVFPtrType() {
1209 return cir::VPtrType::get(builder.getContext());
1210}
Defines the clang::ASTContext interface.
static bool isAAPCS(const TargetInfo &targetInfo)
Helper method to check if the underlying ABI is AAPCS.
static bool marksMatchABIEmptiness(const ASTContext &astContext, const RecordDecl *rd, cir::RecordType recordTy)
Whether the member kinds on recordTy answer the record's ABI emptiness the same way the AST predicate...
static cir::ArgPassingKind convertRecordArgPassingKind(RecordArgPassingKind kind)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static void print(llvm::raw_ostream &OS, const T &V, const Context &Ctx, QualType Ty)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
mlir::DataLayout layout
bool isBigEndian() const
llvm::TypeSize getTypeAllocSizeInBits(mlir::Type ty) const
Returns the offset in bits between successive objects of the specified type, including alignment padd...
C++ view class that accepts both !cir.struct and !cir.union types.
Definition CIRTypes.h:104
bool isIncomplete() const
Definition CIRTypes.cpp:600
bool isEmptyForABI() const
Whether no member holds data.
Definition CIRTypes.cpp:683
mlir::StringAttr getName() const
Definition CIRTypes.cpp:595
void complete(llvm::ArrayRef< mlir::Type > members, bool packed, mlir::Type padding, llvm::ArrayRef< RecordMemberKind > memberKinds)
padding is union-only.
Definition CIRTypes.cpp:638
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
bool isNearlyEmpty(const CXXRecordDecl *RD) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:942
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
bool hasOwnVBPtr() const
hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...
CharUnits getSize() const
getSize - Get the record size in characters.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getDataSize() const
getDataSize() - Get the record data size, which is the record size without tail padding,...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef)
Helpers to emit "not yet implemented" error diagnostics.
const clang::CodeGenOptions & getCodeGenOpts() const
This class organizes the cross-module state that is used while lowering AST types to CIR types.
Definition CIRGenTypes.h:51
CIRGenModule & getCGModule() const
Definition CIRGenTypes.h:91
std::string getRecordTypeName(const clang::RecordDecl *, llvm::StringRef suffix)
clang::ASTContext & getASTContext() const
std::unique_ptr< CIRGenRecordLayout > computeRecordLayout(const clang::RecordDecl *rd, cir::RecordType *ty)
mlir::Type convertTypeForMem(clang::QualType, bool forBitField=false)
Convert type T into an mlir::Type.
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
Definition DeclCXX.h:1191
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
bool isZero() const
isZero - Test whether the quantity equals zero.
Definition CharUnits.h:122
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
static CharUnits One()
One - Construct a CharUnits quantity of one.
Definition CharUnits.h:58
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
Definition CharUnits.h:143
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
Definition CharUnits.h:201
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Definition CharUnits.h:53
void dump() const
Represents a member of a struct/union/class.
Definition Decl.h:3294
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
Definition Decl.cpp:4815
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
Definition Decl.h:3541
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
Represents a struct/union/class.
Definition Decl.h:4459
RecordArgPassingKind getArgPassingRestrictions() const
Definition Decl.h:4600
const FieldDecl * findFirstNamedDataMember() const
Finds the first data member which has a name.
Definition Decl.cpp:5467
specific_decl_iterator< FieldDecl > field_iterator
Definition Decl.h:4659
field_iterator field_begin() const
Definition Decl.cpp:5338
bool isUnion() const
Definition Decl.h:4062
virtual unsigned getRegisterWidth() const
Return the "preferred" register width on this target.
Definition TargetInfo.h:913
bool hasCheapUnalignedBitFieldAccess() const
Return true iff unaligned accesses are cheap.
Definition TargetInfo.h:927
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
Definition Type.cpp:2319
QualType getType() const
Definition Decl.h:723
bool isValidFundamentalIntWidth(unsigned width)
bool isEmptyRecordForABI(const ASTContext &context, QualType t)
isEmptyRecordForABI - Return true if a structure contains only empty base classes and fields.
bool isEmptyFieldForABI(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForABI - Return true if the field is "empty", that is, it is an unnamed bit-field or an (...
bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd)
isEmptyFieldForLayout - Return true if the field is "empty", that is, either a zero-width bit-field o...
bool isEmptyRecordForLayout(const ASTContext &context, QualType t)
isEmptyRecordForLayout - Return true if a structure contains only empty base classes (per isEmptyReco...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicDynCastAllOfMatcher< Decl, FieldDecl > fieldDecl
Matches field declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Decl, RecordDecl > recordDecl
Matches class, struct, and union declarations.
void info(bool Verbose, unsigned Level, const char *Fmt, Ts &&...Args)
Prints an indented note to stderr when Verbose is set.
Definition Utils.h:57
RangeSelector member(std::string ID)
Given a MemberExpr, selects the member token. ID is the node's binding in the match result.
Stencil run(MatchConsumer< std::string > C)
Wraps a MatchConsumer in a Stencil, so that it can be used in a Stencil.
Definition Stencil.cpp:489
Top level wrappers for InstallAPI frontend operations.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
RecordArgPassingKind
Enum that represents the different ways arguments are passed to and returned from function calls.
Definition Decl.h:4436
@ CanPassInRegs
The argument of this type can be passed directly in registers.
Definition Decl.h:4438
@ CanNeverPassInRegs
The argument of this type cannot be passed directly in registers.
Definition Decl.h:4452
@ CannotPassInRegs
The argument of this type cannot be passed directly in registers.
Definition Decl.h:4447
unsigned long uint64_t
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
void __ovld __conv barrier(cl_mem_fence_flags)
All work-items in a work-group executing the kernel on a processor must execute this function before ...
#define true
Definition stdbool.h:25
static bool noUniqueAddressLayout()
static bool checkBitfieldClipping()
static bool astRecordDeclAttr()
unsigned offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
void print(llvm::raw_ostream &os) const
unsigned storageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned volatileStorageSize
The storage size in bits which should be used when accessing this bitfield.
clang::CharUnits storageOffset
The offset of the bitfield storage from the start of the record.
unsigned size
The total size of the bit-field, in bits.
unsigned isSigned
Whether the bit-field is signed.
clang::CharUnits volatileStorageOffset
The offset of the bitfield storage from the start of the record.
unsigned volatileOffset
The offset within a contiguous run of bitfields that are represented as a single "field" within the c...
llvm::StringRef name
The name of a bitfield.