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