25#include "llvm/IR/DataLayout.h"
26#include "llvm/IR/DerivedTypes.h"
27#include "llvm/IR/Type.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/MathExtras.h"
30#include "llvm/Support/raw_ostream.h"
74struct CGRecordLowering {
80 enum InfoKind { VFPtr, VBPtr, Field, Base, VBase } Kind;
84 const CXXRecordDecl *RD;
86 MemberInfo(CharUnits Offset, InfoKind Kind, llvm::Type *Data,
87 const FieldDecl *FD =
nullptr)
88 : Offset(Offset), Kind(Kind), Data(Data), FD(FD) {}
89 MemberInfo(CharUnits Offset, InfoKind Kind, llvm::Type *Data,
90 const CXXRecordDecl *RD)
91 : Offset(Offset), Kind(Kind), Data(Data), RD(RD) {}
93 bool operator <(
const MemberInfo& a)
const {
return Offset < a.Offset; }
96 CGRecordLowering(CodeGenTypes &Types,
const RecordDecl *D,
bool Packed);
99 static MemberInfo StorageInfo(CharUnits Offset, llvm::Type *
Data) {
100 return MemberInfo(Offset, MemberInfo::Field,
Data);
108 bool isDiscreteBitFieldABI()
const {
109 return Context.getTargetInfo().getCXXABI().isMicrosoft() ||
110 D->isMsStruct(Context);
114 bool isBE()
const {
return Context.getTargetInfo().isBigEndian(); }
120 bool isOverlappingVBaseABI()
const {
121 return !Context.getTargetInfo().getCXXABI().isMicrosoft();
125 llvm::Type *getIntNType(uint64_t NumBits)
const {
126 unsigned AlignedBits = llvm::alignTo(NumBits, Context.getCharWidth());
127 return llvm::Type::getIntNTy(Types.getLLVMContext(), AlignedBits);
130 llvm::Type *getCharType()
const {
131 return llvm::Type::getIntNTy(Types.getLLVMContext(),
132 Context.getCharWidth());
135 llvm::Type *getByteArrayType(CharUnits NumChars)
const {
136 assert(!NumChars.
isZero() &&
"Empty byte arrays aren't allowed.");
137 llvm::Type *
Type = getCharType();
143 llvm::Type *getStorageType(
const FieldDecl *FD)
const {
144 llvm::Type *
Type = Types.ConvertTypeForMem(FD->
getType());
146 if (isDiscreteBitFieldABI())
return Type;
148 (
unsigned)Context.toBits(getSize(
Type))));
151 llvm::Type *getStorageType(
const CXXRecordDecl *RD)
const {
152 return Types.getCGRecordLayout(RD).getBaseSubobjectLLVMType();
154 CharUnits bitsToCharUnits(uint64_t BitOffset)
const {
155 return Context.toCharUnitsFromBits(BitOffset);
157 CharUnits getSize(llvm::Type *
Type)
const {
160 CharUnits getAlignment(llvm::Type *
Type)
const {
163 bool isZeroInitializable(
const FieldDecl *FD)
const {
164 return Types.isZeroInitializable(FD->
getType());
166 bool isZeroInitializable(
const RecordDecl *RD)
const {
167 return Types.isZeroInitializable(RD);
169 void appendPaddingBytes(CharUnits Size) {
171 FieldTypes.push_back(getByteArrayType(Size));
173 uint64_t getFieldBitOffset(
const FieldDecl *FD)
const {
177 void setBitFieldInfo(
const FieldDecl *FD, CharUnits StartOffset,
178 llvm::Type *StorageType);
180 void lower(
bool NonVirtualBaseType);
181 void lowerUnion(
bool isNonVirtualBaseType);
182 void accumulateFields(
bool isNonVirtualBaseType);
184 accumulateBitFields(
bool isNonVirtualBaseType,
187 void computeVolatileBitfields();
188 void accumulateBases();
189 void accumulateVPtrs();
190 void accumulateVBases();
193 bool hasOwnStorage(
const CXXRecordDecl *
Decl,
194 const CXXRecordDecl *Query)
const;
195 void calculateZeroInit();
196 CharUnits calculateTailClippingOffset(
bool isNonVirtualBaseType)
const;
197 void checkBitfieldClipping(
bool isNonVirtualBaseType)
const;
199 void determinePacked(
bool NVBaseType);
201 void insertPadding();
203 void fillOutputFields();
206 const ASTContext &Context;
208 const CXXRecordDecl *RD;
209 const ASTRecordLayout &Layout;
210 const llvm::DataLayout &DataLayout;
212 std::vector<MemberInfo> Members;
214 SmallVector<llvm::Type *, 16> FieldTypes;
215 llvm::DenseMap<const FieldDecl *, unsigned> Fields;
216 llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
217 llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
218 llvm::DenseMap<const CXXRecordDecl *, unsigned> VirtualBases;
219 bool IsZeroInitializable : 1;
220 bool IsZeroInitializableAsBase : 1;
223 CGRecordLowering(
const CGRecordLowering &) =
delete;
224 void operator =(
const CGRecordLowering &) =
delete;
230 : Types(Types), Context(Types.getContext()), D(D),
232 Layout(Types.getContext().getASTRecordLayout(D)),
233 DataLayout(Types.getDataLayout()), IsZeroInitializable(
true),
236void CGRecordLowering::setBitFieldInfo(
240 Info.
Offset = (unsigned)(getFieldBitOffset(FD) - Context.
toBits(StartOffset));
242 Info.
StorageSize = (unsigned)DataLayout.getTypeAllocSizeInBits(StorageType);
250 if (DataLayout.isBigEndian())
258void CGRecordLowering::lower(
bool NVBaseType) {
281 lowerUnion(NVBaseType);
282 computeVolatileBitfields();
285 accumulateFields(NVBaseType);
290 if (Members.empty()) {
291 appendPaddingBytes(Size);
292 computeVolatileBitfields();
298 llvm::stable_sort(Members);
299 checkBitfieldClipping(NVBaseType);
300 Members.push_back(StorageInfo(Size, getIntNType(8)));
301 determinePacked(NVBaseType);
306 computeVolatileBitfields();
309void CGRecordLowering::lowerUnion(
bool isNonVirtualBaseType) {
310 CharUnits LayoutSize =
312 llvm::Type *StorageType =
nullptr;
313 bool SeenNamedMember =
false;
319 for (
const auto *Field : D->
fields()) {
320 if (
Field->isBitField()) {
321 if (
Field->isZeroLengthBitField())
323 llvm::Type *FieldType = getStorageType(Field);
324 if (LayoutSize < getSize(FieldType))
325 FieldType = getByteArrayType(LayoutSize);
328 Fields[
Field->getCanonicalDecl()] = 0;
329 llvm::Type *FieldType = getStorageType(Field);
336 if (!SeenNamedMember) {
337 SeenNamedMember =
Field->getIdentifier();
338 if (!SeenNamedMember)
339 if (
const auto *FieldRD =
Field->getType()->getAsRecordDecl())
340 SeenNamedMember = FieldRD->findFirstNamedDataMember();
341 if (SeenNamedMember && !isZeroInitializable(Field)) {
342 IsZeroInitializable = IsZeroInitializableAsBase =
false;
343 StorageType = FieldType;
348 if (!IsZeroInitializable)
352 getAlignment(FieldType) > getAlignment(StorageType) ||
353 (getAlignment(FieldType) == getAlignment(StorageType) &&
354 getSize(FieldType) > getSize(StorageType)))
355 StorageType = FieldType;
359 return appendPaddingBytes(LayoutSize);
362 if (LayoutSize < getSize(StorageType))
363 StorageType = getByteArrayType(LayoutSize);
364 FieldTypes.push_back(StorageType);
365 appendPaddingBytes(LayoutSize - getSize(StorageType));
367 const auto StorageAlignment = getAlignment(StorageType);
370 "Union's standard layout and no_unique_address layout must agree on "
376void CGRecordLowering::accumulateFields(
bool isNonVirtualBaseType) {
379 Field != FieldEnd;) {
380 if (
Field->isBitField()) {
381 Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
382 assert((Field == FieldEnd || !
Field->isBitField()) &&
383 "Failed to accumulate all the bitfields");
390 Members.push_back(MemberInfo(
391 bitsToCharUnits(getFieldBitOffset(*Field)), MemberInfo::Field,
392 Field->isPotentiallyOverlapping()
393 ? getStorageType(
Field->getType()->getAsCXXRecordDecl())
394 : getStorageType(*Field),
406CGRecordLowering::accumulateBitFields(
bool isNonVirtualBaseType,
409 if (isDiscreteBitFieldABI()) {
422 if (
Field->isZeroLengthBitField()) {
426 uint64_t BitOffset = getFieldBitOffset(*Field);
430 if (Run == FieldEnd || BitOffset >= Tail) {
432 StartBitOffset = BitOffset;
433 Tail = StartBitOffset + DataLayout.getTypeAllocSizeInBits(
Type);
437 Members.push_back(StorageInfo(bitsToCharUnits(StartBitOffset),
Type));
441 Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset),
442 MemberInfo::Field,
nullptr, *Field));
515 CharUnits BeginOffset;
524 CharUnits BestEndOffset;
532 bool AtAlignedBoundary =
false;
533 bool Barrier =
false;
535 if (Field != FieldEnd &&
Field->isBitField()) {
536 uint64_t BitOffset = getFieldBitOffset(*Field);
537 if (Begin == FieldEnd) {
542 assert((BitOffset % CharBits) == 0 &&
"Not at start of char");
543 BeginOffset = bitsToCharUnits(BitOffset);
544 BitSizeSinceBegin = 0;
545 }
else if ((BitOffset % CharBits) != 0) {
552 assert(BitOffset == Context.
toBits(BeginOffset) + BitSizeSinceBegin &&
553 "Concatenating non-contiguous bitfields");
558 if (
Field->isZeroLengthBitField())
560 AtAlignedBoundary =
true;
565 if (Begin == FieldEnd)
569 AtAlignedBoundary =
true;
575 bool InstallBest =
false;
576 if (AtAlignedBoundary) {
582 CharUnits AccessSize = bitsToCharUnits(BitSizeSinceBegin + CharBits - 1);
583 if (BestEnd == Begin) {
587 BestEndOffset = BeginOffset + AccessSize;
590 if (!BitSizeSinceBegin)
594 }
else if (AccessSize > RegSize)
602 llvm::Type *
Type = getIntNType(Context.
toBits(AccessSize));
609 CharUnits Align = getAlignment(
Type);
619 if (InstallBest && BestEnd == Field)
622 if (getSize(
Type) == AccessSize)
631 CharUnits LimitOffset;
632 for (
auto Probe = Field; Probe != FieldEnd; ++Probe)
635 assert((getFieldBitOffset(*Probe) % CharBits) == 0 &&
636 "Next storage is not byte-aligned");
637 LimitOffset = bitsToCharUnits(getFieldBitOffset(*Probe));
642 if (ScissorOffset.
isZero()) {
643 ScissorOffset = calculateTailClippingOffset(isNonVirtualBaseType);
644 assert(!ScissorOffset.
isZero() &&
"Tail clipping at zero");
647 LimitOffset = ScissorOffset;
650 CharUnits TypeSize = getSize(
Type);
651 if (BeginOffset + TypeSize <= LimitOffset) {
654 BestEndOffset = BeginOffset + TypeSize;
669 BitSizeSinceBegin = Context.
toBits(LimitOffset - BeginOffset);
675 assert((Field == FieldEnd || !
Field->isBitField() ||
676 (getFieldBitOffset(*Field) % CharBits) == 0) &&
677 "Installing but not at an aligned bitfield or limit");
678 CharUnits AccessSize = BestEndOffset - BeginOffset;
679 if (!AccessSize.
isZero()) {
685 assert(getSize(getIntNType(Context.
toBits(AccessSize))) >
687 "Clipped access need not be clipped");
688 Type = getByteArrayType(AccessSize);
690 Type = getIntNType(Context.
toBits(AccessSize));
691 assert(getSize(
Type) == AccessSize &&
692 "Unclipped access must be clipped");
694 Members.push_back(StorageInfo(BeginOffset,
Type));
695 for (; Begin != BestEnd; ++Begin)
696 if (!Begin->isZeroLengthBitField())
698 MemberInfo(BeginOffset, MemberInfo::Field,
nullptr, *Begin));
704 assert(Field != FieldEnd &&
Field->isBitField() &&
705 "Accumulating past end of bitfields");
706 assert(!Barrier &&
"Accumulating across barrier");
708 BitSizeSinceBegin +=
Field->getBitWidthValue();
716void CGRecordLowering::accumulateBases() {
721 getStorageType(BaseDecl), BaseDecl));
724 for (
const auto &Base : RD->bases()) {
725 if (
Base.isVirtual())
730 const CXXRecordDecl *BaseDecl =
Base.getType()->getAsCXXRecordDecl();
734 MemberInfo::Base, getStorageType(BaseDecl), BaseDecl));
751void CGRecordLowering::computeVolatileBitfields() {
756 for (
auto &I : BitFields) {
757 const FieldDecl *
Field = I.first;
758 CGBitFieldInfo &Info = I.second;
763 ResLTy->getPrimitiveSizeInBits())
770 const unsigned OldOffset =
773 const unsigned AbsoluteOffset =
777 const unsigned StorageSize = ResLTy->getPrimitiveSizeInBits();
780 if (Info.
StorageSize == StorageSize && (OldOffset % StorageSize == 0))
784 unsigned Offset = AbsoluteOffset & (StorageSize - 1);
789 if (Offset + Info.
Size > StorageSize)
794 Offset = StorageSize - (Offset + Info.
Size);
796 const CharUnits StorageOffset =
798 const CharUnits End = StorageOffset +
802 const ASTRecordLayout &Layout =
805 const CharUnits RecordSize = Layout.
getSize();
806 if (End >= RecordSize)
810 bool Conflict =
false;
811 for (
const auto *F : D->
fields()) {
813 if (F->isBitField() && !F->isZeroLengthBitField())
823 if (F->isZeroLengthBitField()) {
824 if (End > FOffset && StorageOffset < FOffset) {
830 const CharUnits FEnd =
836 if (End < FOffset || FEnd < StorageOffset)
856void CGRecordLowering::accumulateVPtrs() {
868CGRecordLowering::calculateTailClippingOffset(
bool isNonVirtualBaseType)
const {
877 if (!isNonVirtualBaseType && isOverlappingVBaseABI())
878 for (
const auto &Base : RD->vbases()) {
879 const CXXRecordDecl *BaseDecl =
Base.getType()->getAsCXXRecordDecl();
884 if (Context.
isNearlyEmpty(BaseDecl) && !hasOwnStorage(RD, BaseDecl))
886 ScissorOffset = std::min(ScissorOffset,
890 return ScissorOffset;
893void CGRecordLowering::accumulateVBases() {
894 for (
const auto &Base : RD->vbases()) {
895 const CXXRecordDecl *BaseDecl =
Base.getType()->getAsCXXRecordDecl();
901 if (isOverlappingVBaseABI() &&
903 !hasOwnStorage(RD, BaseDecl)) {
904 Members.push_back(MemberInfo(Offset, MemberInfo::VBase,
nullptr,
912 Members.push_back(MemberInfo(Offset, MemberInfo::VBase,
913 getStorageType(BaseDecl), BaseDecl));
917bool CGRecordLowering::hasOwnStorage(
const CXXRecordDecl *
Decl,
918 const CXXRecordDecl *Query)
const {
922 for (
const auto &Base :
Decl->bases())
923 if (!hasOwnStorage(
Base.getType()->getAsCXXRecordDecl(), Query))
928void CGRecordLowering::calculateZeroInit() {
929 for (std::vector<MemberInfo>::const_iterator
Member = Members.begin(),
930 MemberEnd = Members.end();
931 IsZeroInitializableAsBase &&
Member != MemberEnd; ++
Member) {
932 if (
Member->Kind == MemberInfo::Field) {
935 IsZeroInitializable = IsZeroInitializableAsBase =
false;
936 }
else if (
Member->Kind == MemberInfo::Base ||
937 Member->Kind == MemberInfo::VBase) {
938 if (isZeroInitializable(
Member->RD))
940 IsZeroInitializable =
false;
941 if (
Member->Kind == MemberInfo::Base)
942 IsZeroInitializableAsBase =
false;
948void CGRecordLowering::checkBitfieldClipping(
bool IsNonVirtualBaseType)
const {
950 auto ScissorOffset = calculateTailClippingOffset(IsNonVirtualBaseType);
952 for (
const auto &M : Members) {
957 assert(M.Offset >= Tail &&
"Bitfield access unit is not clipped");
958 Tail = M.Offset + getSize(M.Data);
959 assert((Tail <= ScissorOffset || M.Offset >= ScissorOffset) &&
960 "Bitfield straddles scissor offset");
965void CGRecordLowering::determinePacked(
bool NVBaseType) {
972 for (
const MemberInfo &
Member : Members) {
977 if (!
Member.Offset.isMultipleOf(getAlignment(
Member.Data)))
979 if (
Member.Offset < NVSize)
980 NVAlignment = std::max(NVAlignment, getAlignment(
Member.Data));
981 Alignment = std::max(Alignment, getAlignment(
Member.Data));
985 if (!Members.back().Offset.isMultipleOf(Alignment))
994 Members.back().Data = getIntNType(Context.
toBits(Alignment));
997void CGRecordLowering::insertPadding() {
998 std::vector<std::pair<CharUnits, CharUnits> > Padding;
1000 for (
const MemberInfo &
Member : Members) {
1003 CharUnits Offset =
Member.Offset;
1004 assert(Offset >= Size);
1008 Padding.push_back(std::make_pair(Size, Offset - Size));
1011 if (Padding.empty())
1014 for (
const auto &Pad : Padding)
1015 Members.push_back(StorageInfo(Pad.first, getByteArrayType(Pad.second)));
1016 llvm::stable_sort(Members);
1019void CGRecordLowering::fillOutputFields() {
1020 for (
const MemberInfo &
Member : Members) {
1022 FieldTypes.push_back(
Member.Data);
1023 if (
Member.Kind == MemberInfo::Field) {
1025 Fields[
Member.FD->getCanonicalDecl()] = FieldTypes.size() - 1;
1029 "Member.Data is a nullptr so Member.FD should not be");
1030 setBitFieldInfo(
Member.FD,
Member.Offset, FieldTypes.back());
1032 }
else if (
Member.Kind == MemberInfo::Base)
1033 NonVirtualBases[
Member.RD] = FieldTypes.size() - 1;
1034 else if (
Member.Kind == MemberInfo::VBase)
1035 VirtualBases[
Member.RD] = FieldTypes.size() - 1;
1054 if (
Size > TypeSizeInBits) {
1064 Size = TypeSizeInBits;
1078std::unique_ptr<CGRecordLayout>
1080 CGRecordLowering Builder(*
this, D,
false);
1082 Builder.lower(
false);
1085 llvm::StructType *BaseTy =
nullptr;
1088 if (Builder.Layout.getNonVirtualSize() != Builder.Layout.getSize()) {
1089 CGRecordLowering BaseBuilder(*
this, D, Builder.Packed);
1090 BaseBuilder.lower(
true);
1091 BaseTy = llvm::StructType::create(
1092 getLLVMContext(), BaseBuilder.FieldTypes,
"", BaseBuilder.Packed);
1096 assert(Builder.Packed == BaseBuilder.Packed &&
1097 "Non-virtual and complete types must agree on packedness");
1104 Ty->setBody(Builder.FieldTypes, Builder.Packed);
1106 auto RL = std::make_unique<CGRecordLayout>(
1107 Ty, BaseTy, (
bool)Builder.IsZeroInitializable,
1108 (
bool)Builder.IsZeroInitializableAsBase);
1110 RL->NonVirtualBases.swap(Builder.NonVirtualBases);
1111 RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases);
1114 RL->FieldInfo.swap(Builder.Fields);
1117 RL->BitFields.swap(Builder.BitFields);
1120 if (
getContext().getLangOpts().DumpRecordLayouts) {
1121 llvm::outs() <<
"\n*** Dumping IRgen Record Layout\n";
1122 llvm::outs() <<
"Record: ";
1123 D->
dump(llvm::outs());
1124 llvm::outs() <<
"\nLayout: ";
1125 RL->print(llvm::outs());
1133 assert(TypeSizeInBits ==
getDataLayout().getTypeAllocSizeInBits(Ty) &&
1134 "Type size mismatch!");
1139 uint64_t AlignedNonVirtualTypeSizeInBits =
1142 assert(AlignedNonVirtualTypeSizeInBits ==
1144 "Type size mismatch!");
1148 llvm::StructType *ST = RL->getLLVMType();
1149 const llvm::StructLayout *SL =
getDataLayout().getStructLayout(ST);
1153 for (
unsigned i = 0, e = AST_RL.
getFieldCount(); i != e; ++i, ++it) {
1163 unsigned FieldNo = RL->getLLVMFieldNo(FD);
1164 assert(AST_RL.
getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) &&
1165 "Invalid field offset!");
1174 llvm::Type *ElementTy = ST->getTypeAtIndex(RL->getLLVMFieldNo(FD));
1185 assert(
static_cast<unsigned>(Info.
Offset + Info.
Size) ==
1187 "Big endian union bitfield does not end at the back");
1189 assert(Info.
Offset == 0 &&
1190 "Little endian union bitfield with a non-zero offset");
1192 "Union not large enough for bitfield storage");
1198 "Storage size does not match the element type size");
1200 assert(Info.
Size > 0 &&
"Empty bitfield!");
1202 "Bitfield outside of its allocated storage");
1210 OS <<
"<CGRecordLayout\n";
1211 OS <<
" LLVMType:" << *CompleteObjectType <<
"\n";
1212 if (BaseSubobjectType)
1213 OS <<
" NonVirtualBaseLLVMType:" << *BaseSubobjectType <<
"\n";
1214 OS <<
" IsZeroInitializable:" << IsZeroInitializable <<
"\n";
1215 OS <<
" BitFields:[\n";
1218 std::vector<std::pair<unsigned, const CGBitFieldInfo*> > BFIs;
1219 for (
const auto &BitField : BitFields) {
1223 *it2 != BitField.first; ++it2)
1225 BFIs.push_back(std::make_pair(Index, &BitField.second));
1227 llvm::array_pod_sort(BFIs.begin(), BFIs.end());
1228 for (
auto &BFI : BFIs) {
1230 BFI.second->print(OS);
1238 print(llvm::errs());
1242 OS <<
"<CGBitFieldInfo"
1252 print(llvm::errs());
Defines the clang::ASTContext interface.
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)
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
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.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
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.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
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...
Represents a C++ struct/union/class.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
void print(raw_ostream &OS) const
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
const CodeGenOptions & getCodeGenOpts() const
ASTContext & getContext() const
std::unique_ptr< CGRecordLayout > ComputeRecordLayout(const RecordDecl *D, llvm::StructType *Ty)
Compute a new LLVM record layout object for the given record.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
llvm::LLVMContext & getLLVMContext()
const llvm::DataLayout & getDataLayout() const
void addRecordTypeName(const RecordDecl *RD, llvm::StructType *Ty, StringRef suffix)
addRecordTypeName - Compute a name from the given record decl with an optional suffix and name the gi...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a struct/union/class.
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
virtual unsigned getRegisterWidth() const
Return the "preferred" register width on this target.
bool hasCheapUnalignedBitFieldAccess() const
Return true iff unaligned accesses are cheap.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isAAPCS(const TargetInfo &TargetInfo)
Helper method to check if the underlying ABI is AAPCS.
bool isEmptyRecordForLayout(const ASTContext &Context, QualType T)
isEmptyRecordForLayout - Return true iff a structure contains only empty base classes (per isEmptyRec...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
@ Type
The name was classified as a type.
Structure with information about how a bitfield should be accessed.
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
CharUnits VolatileStorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned VolatileOffset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned VolatileStorageSize
The storage size in bits which should be used when accessing this bitfield.
void print(raw_ostream &OS) const
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types, const FieldDecl *FD, uint64_t Offset, uint64_t Size, uint64_t StorageSize, CharUnits StorageOffset)
Given a bit-field decl, build an appropriate helper object for accessing that field (which is expecte...