23#include "llvm/IR/DataLayout.h"
24#include "llvm/IR/DerivedTypes.h"
25#include "llvm/IR/Type.h"
26#include "llvm/Support/Debug.h"
27#include "llvm/Support/MathExtras.h"
28#include "llvm/Support/raw_ostream.h"
30using namespace CodeGen;
72struct CGRecordLowering {
78 enum InfoKind { VFPtr, VBPtr,
Field,
Base, VBase, Scissor }
Kind;
84 MemberInfo(
CharUnits Offset, InfoKind Kind, llvm::Type *Data,
87 MemberInfo(
CharUnits Offset, InfoKind Kind, llvm::Type *Data,
91 bool operator <(
const MemberInfo& a)
const {
return Offset < a.Offset; }
97 static MemberInfo StorageInfo(
CharUnits Offset, llvm::Type *
Data) {
98 return MemberInfo(Offset, MemberInfo::Field,
Data);
106 bool isDiscreteBitFieldABI()
const {
108 D->isMsStruct(Context);
123 bool isOverlappingVBaseABI()
const {
128 llvm::Type *getIntNType(uint64_t NumBits)
const {
129 unsigned AlignedBits = llvm::alignTo(NumBits, Context.
getCharWidth());
130 return llvm::Type::getIntNTy(Types.getLLVMContext(), AlignedBits);
133 llvm::Type *getCharType()
const {
134 return llvm::Type::getIntNTy(Types.getLLVMContext(),
138 llvm::Type *getByteArrayType(
CharUnits NumChars)
const {
139 assert(!NumChars.
isZero() &&
"Empty byte arrays aren't allowed.");
140 llvm::Type *
Type = getCharType();
146 llvm::Type *getStorageType(
const FieldDecl *FD)
const {
147 llvm::Type *
Type = Types.ConvertTypeForMem(FD->
getType());
149 if (isDiscreteBitFieldABI())
return Type;
155 return Types.getCGRecordLayout(RD).getBaseSubobjectLLVMType();
157 CharUnits bitsToCharUnits(uint64_t BitOffset)
const {
166 bool isZeroInitializable(
const FieldDecl *FD)
const {
167 return Types.isZeroInitializable(FD->
getType());
169 bool isZeroInitializable(
const RecordDecl *RD)
const {
170 return Types.isZeroInitializable(RD);
172 void appendPaddingBytes(
CharUnits Size) {
174 FieldTypes.push_back(getByteArrayType(Size));
181 llvm::Type *StorageType);
183 void lower(
bool NonVirtualBaseType);
184 void lowerUnion(
bool isNoUniqueAddress);
185 void accumulateFields(
bool isNonVirtualBaseType);
187 accumulateBitFields(
bool isNonVirtualBaseType,
190 void computeVolatileBitfields();
191 void accumulateBases();
192 void accumulateVPtrs();
193 void accumulateVBases();
198 void calculateZeroInit();
199 CharUnits calculateTailClippingOffset(
bool isNonVirtualBaseType)
const;
200 void checkBitfieldClipping()
const;
202 void determinePacked(
bool NVBaseType);
204 void insertPadding();
206 void fillOutputFields();
213 const llvm::DataLayout &DataLayout;
215 std::vector<MemberInfo> Members;
218 llvm::DenseMap<const FieldDecl *, unsigned> Fields;
219 llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
220 llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
221 llvm::DenseMap<const CXXRecordDecl *, unsigned> VirtualBases;
222 bool IsZeroInitializable : 1;
223 bool IsZeroInitializableAsBase : 1;
226 CGRecordLowering(
const CGRecordLowering &) =
delete;
227 void operator =(
const CGRecordLowering &) =
delete;
233 : Types(Types), Context(Types.getContext()), D(D),
235 Layout(Types.getContext().getASTRecordLayout(D)),
236 DataLayout(Types.getDataLayout()), IsZeroInitializable(
true),
237 IsZeroInitializableAsBase(
true), Packed(Packed) {}
239void CGRecordLowering::setBitFieldInfo(
253 if (DataLayout.isBigEndian())
261void CGRecordLowering::lower(
bool NVBaseType) {
282 CharUnits Size = NVBaseType ? Layout.getNonVirtualSize() : Layout.getSize();
284 lowerUnion(NVBaseType);
285 computeVolatileBitfields();
288 accumulateFields(NVBaseType);
293 if (Members.empty()) {
294 appendPaddingBytes(Size);
295 computeVolatileBitfields();
301 llvm::stable_sort(Members);
302 Members.push_back(StorageInfo(Size, getIntNType(8)));
303 checkBitfieldClipping();
304 determinePacked(NVBaseType);
309 computeVolatileBitfields();
312void CGRecordLowering::lowerUnion(
bool isNoUniqueAddress) {
314 isNoUniqueAddress ? Layout.getDataSize() : Layout.getSize();
315 llvm::Type *StorageType =
nullptr;
316 bool SeenNamedMember =
false;
322 for (
const auto *Field : D->fields()) {
323 if (
Field->isBitField()) {
324 if (
Field->isZeroLengthBitField(Context))
326 llvm::Type *FieldType = getStorageType(Field);
327 if (LayoutSize < getSize(FieldType))
328 FieldType = getByteArrayType(LayoutSize);
331 Fields[
Field->getCanonicalDecl()] = 0;
332 llvm::Type *FieldType = getStorageType(Field);
339 if (!SeenNamedMember) {
340 SeenNamedMember =
Field->getIdentifier();
341 if (!SeenNamedMember)
342 if (
const auto *FieldRD =
Field->getType()->getAsRecordDecl())
343 SeenNamedMember = FieldRD->findFirstNamedDataMember();
344 if (SeenNamedMember && !isZeroInitializable(Field)) {
345 IsZeroInitializable = IsZeroInitializableAsBase =
false;
346 StorageType = FieldType;
351 if (!IsZeroInitializable)
355 getAlignment(FieldType) > getAlignment(StorageType) ||
356 (getAlignment(FieldType) == getAlignment(StorageType) &&
357 getSize(FieldType) > getSize(StorageType)))
358 StorageType = FieldType;
362 return appendPaddingBytes(LayoutSize);
365 if (LayoutSize < getSize(StorageType))
366 StorageType = getByteArrayType(LayoutSize);
367 FieldTypes.push_back(StorageType);
368 appendPaddingBytes(LayoutSize - getSize(StorageType));
370 const auto StorageAlignment = getAlignment(StorageType);
371 assert((Layout.getSize() % StorageAlignment == 0 ||
372 Layout.getDataSize() % StorageAlignment) &&
373 "Union's standard layout and no_unique_address layout must agree on "
375 if (Layout.getDataSize() % StorageAlignment)
379void CGRecordLowering::accumulateFields(
bool isNonVirtualBaseType) {
381 FieldEnd = D->field_end();
382 Field != FieldEnd;) {
383 if (
Field->isBitField()) {
384 Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
385 assert((Field == FieldEnd || !
Field->isBitField()) &&
386 "Failed to accumulate all the bitfields");
387 }
else if (
Field->isZeroSize(Context)) {
393 Members.push_back(MemberInfo(
394 bitsToCharUnits(getFieldBitOffset(*Field)), MemberInfo::Field,
395 Field->isPotentiallyOverlapping()
396 ? getStorageType(
Field->getType()->getAsCXXRecordDecl())
397 : getStorageType(*Field),
409CGRecordLowering::accumulateBitFields(
bool isNonVirtualBaseType,
412 if (isDiscreteBitFieldABI()) {
425 if (
Field->isZeroLengthBitField(Context)) {
429 uint64_t BitOffset = getFieldBitOffset(*Field);
431 Types.ConvertTypeForMem(
Field->getType(),
true);
434 if (Run == FieldEnd || BitOffset >= Tail) {
436 StartBitOffset = BitOffset;
437 Tail = StartBitOffset + DataLayout.getTypeAllocSizeInBits(
Type);
441 Members.push_back(StorageInfo(bitsToCharUnits(StartBitOffset),
Type));
445 Members.push_back(MemberInfo(bitsToCharUnits(StartBitOffset),
446 MemberInfo::Field,
nullptr, *Field));
536 bool AtAlignedBoundary =
false;
537 bool Barrier =
false;
539 if (Field != FieldEnd &&
Field->isBitField()) {
540 uint64_t BitOffset = getFieldBitOffset(*Field);
541 if (
Begin == FieldEnd) {
546 assert((BitOffset % CharBits) == 0 &&
"Not at start of char");
547 BeginOffset = bitsToCharUnits(BitOffset);
548 BitSizeSinceBegin = 0;
549 }
else if ((BitOffset % CharBits) != 0) {
556 assert(BitOffset == Context.
toBits(BeginOffset) + BitSizeSinceBegin &&
557 "Concatenating non-contiguous bitfields");
562 if (
Field->isZeroLengthBitField(Context))
564 AtAlignedBoundary =
true;
569 if (
Begin == FieldEnd)
573 AtAlignedBoundary =
true;
579 bool InstallBest =
false;
580 if (AtAlignedBoundary) {
586 CharUnits AccessSize = bitsToCharUnits(BitSizeSinceBegin + CharBits - 1);
587 if (BestEnd ==
Begin) {
591 BestEndOffset = BeginOffset + AccessSize;
594 if (!BitSizeSinceBegin)
598 }
else if (AccessSize > RegSize)
606 llvm::Type *
Type = getIntNType(Context.
toBits(AccessSize));
614 if (Align > Layout.getAlignment())
623 if (InstallBest && BestEnd == Field)
626 if (getSize(
Type) == AccessSize)
636 for (
auto Probe = Field; Probe != FieldEnd; ++Probe)
637 if (!Probe->isZeroSize(Context)) {
639 assert((getFieldBitOffset(*Probe) % CharBits) == 0 &&
640 "Next storage is not byte-aligned");
641 LimitOffset = bitsToCharUnits(getFieldBitOffset(*Probe));
646 if (ScissorOffset.
isZero()) {
647 ScissorOffset = calculateTailClippingOffset(isNonVirtualBaseType);
648 assert(!ScissorOffset.
isZero() &&
"Tail clipping at zero");
651 LimitOffset = ScissorOffset;
655 if (BeginOffset + TypeSize <= LimitOffset) {
658 BestEndOffset = BeginOffset + TypeSize;
666 else if (Types.getCodeGenOpts().FineGrainedBitfieldAccesses)
673 BitSizeSinceBegin = Context.
toBits(LimitOffset - BeginOffset);
679 assert((Field == FieldEnd || !
Field->isBitField() ||
680 (getFieldBitOffset(*Field) % CharBits) == 0) &&
681 "Installing but not at an aligned bitfield or limit");
682 CharUnits AccessSize = BestEndOffset - BeginOffset;
683 if (!AccessSize.
isZero()) {
689 assert(getSize(getIntNType(Context.
toBits(AccessSize))) >
691 "Clipped access need not be clipped");
692 Type = getByteArrayType(AccessSize);
694 Type = getIntNType(Context.
toBits(AccessSize));
695 assert(getSize(
Type) == AccessSize &&
696 "Unclipped access must be clipped");
698 Members.push_back(StorageInfo(BeginOffset,
Type));
700 if (!
Begin->isZeroLengthBitField(Context))
702 MemberInfo(BeginOffset, MemberInfo::Field,
nullptr, *
Begin));
708 assert(Field != FieldEnd &&
Field->isBitField() &&
709 "Accumulating past end of bitfields");
710 assert(!Barrier &&
"Accumulating across barrier");
712 BitSizeSinceBegin +=
Field->getBitWidthValue(Context);
720void CGRecordLowering::accumulateBases() {
722 if (Layout.isPrimaryBaseVirtual()) {
725 getStorageType(BaseDecl), BaseDecl));
728 for (
const auto &
Base : RD->bases()) {
729 if (
Base.isVirtual())
737 Members.push_back(MemberInfo(Layout.getBaseClassOffset(BaseDecl),
738 MemberInfo::Base, getStorageType(BaseDecl), BaseDecl));
755void CGRecordLowering::computeVolatileBitfields() {
756 if (!
isAAPCS() || !Types.getCodeGenOpts().AAPCSBitfieldWidth)
759 for (
auto &I : BitFields) {
762 llvm::Type *ResLTy = Types.ConvertTypeForMem(
Field->getType());
765 if ((uint64_t)(Context.
toBits(Layout.getAlignment())) <
766 ResLTy->getPrimitiveSizeInBits())
773 const unsigned OldOffset =
776 const unsigned AbsoluteOffset =
780 const unsigned StorageSize = ResLTy->getPrimitiveSizeInBits();
783 if (Info.
StorageSize == StorageSize && (OldOffset % StorageSize == 0))
787 unsigned Offset = AbsoluteOffset & (StorageSize - 1);
792 if (Offset + Info.
Size > StorageSize)
797 Offset = StorageSize - (Offset + Info.
Size);
809 if (End >= RecordSize)
813 bool Conflict =
false;
814 for (
const auto *F : D->fields()) {
816 if (F->isBitField() && !F->isZeroLengthBitField(Context))
826 if (F->isZeroLengthBitField(Context)) {
827 if (End > FOffset && StorageOffset < FOffset) {
836 Types.ConvertTypeForMem(F->getType())->getPrimitiveSizeInBits()) -
839 if (End < FOffset || FEnd < StorageOffset)
859void CGRecordLowering::accumulateVPtrs() {
863 llvm::PointerType::getUnqual(Types.getLLVMContext())));
867 llvm::PointerType::getUnqual(Types.getLLVMContext())));
871CGRecordLowering::calculateTailClippingOffset(
bool isNonVirtualBaseType)
const {
880 if (!isNonVirtualBaseType && isOverlappingVBaseABI())
881 for (
const auto &
Base : RD->vbases()) {
887 if (Context.
isNearlyEmpty(BaseDecl) && !hasOwnStorage(RD, BaseDecl))
889 ScissorOffset = std::min(ScissorOffset,
893 return ScissorOffset;
896void CGRecordLowering::accumulateVBases() {
897 Members.push_back(MemberInfo(calculateTailClippingOffset(
false),
898 MemberInfo::Scissor,
nullptr, RD));
899 for (
const auto &
Base : RD->vbases()) {
906 if (isOverlappingVBaseABI() &&
908 !hasOwnStorage(RD, BaseDecl)) {
909 Members.push_back(MemberInfo(Offset, MemberInfo::VBase,
nullptr,
917 Members.push_back(MemberInfo(Offset, MemberInfo::VBase,
918 getStorageType(BaseDecl), BaseDecl));
927 for (
const auto &
Base :
Decl->bases())
928 if (!hasOwnStorage(
Base.getType()->getAsCXXRecordDecl(), Query))
933void CGRecordLowering::calculateZeroInit() {
934 for (std::vector<MemberInfo>::const_iterator
Member = Members.begin(),
935 MemberEnd = Members.end();
936 IsZeroInitializableAsBase &&
Member != MemberEnd; ++
Member) {
937 if (
Member->Kind == MemberInfo::Field) {
940 IsZeroInitializable = IsZeroInitializableAsBase =
false;
941 }
else if (
Member->Kind == MemberInfo::Base ||
942 Member->Kind == MemberInfo::VBase) {
943 if (isZeroInitializable(
Member->RD))
945 IsZeroInitializable =
false;
946 if (
Member->Kind == MemberInfo::Base)
947 IsZeroInitializableAsBase =
false;
953void CGRecordLowering::checkBitfieldClipping()
const {
956 for (
const auto &M : Members) {
958 if (!M.Data && M.Kind != MemberInfo::Scissor)
961 assert(M.Offset >= Tail &&
"Bitfield access unit is not clipped");
964 Tail += getSize(M.Data);
969void CGRecordLowering::determinePacked(
bool NVBaseType) {
976 for (std::vector<MemberInfo>::const_iterator
Member = Members.begin(),
977 MemberEnd = Members.end();
985 if (
Member->Offset < NVSize)
986 NVAlignment = std::max(NVAlignment, getAlignment(
Member->Data));
987 Alignment = std::max(Alignment, getAlignment(
Member->Data));
991 if (Members.back().Offset % Alignment)
996 if (NVSize % NVAlignment)
1000 Members.back().Data = getIntNType(Context.
toBits(Alignment));
1003void CGRecordLowering::insertPadding() {
1004 std::vector<std::pair<CharUnits, CharUnits> > Padding;
1006 for (std::vector<MemberInfo>::const_iterator
Member = Members.begin(),
1007 MemberEnd = Members.end();
1012 assert(Offset >= Size);
1016 Padding.push_back(std::make_pair(Size, Offset - Size));
1019 if (Padding.empty())
1022 for (std::vector<std::pair<CharUnits, CharUnits> >::const_iterator
1023 Pad = Padding.begin(), PadEnd = Padding.end();
1024 Pad != PadEnd; ++Pad)
1025 Members.push_back(StorageInfo(Pad->first, getByteArrayType(Pad->second)));
1026 llvm::stable_sort(Members);
1029void CGRecordLowering::fillOutputFields() {
1030 for (std::vector<MemberInfo>::const_iterator
Member = Members.begin(),
1031 MemberEnd = Members.end();
1034 FieldTypes.push_back(
Member->Data);
1035 if (
Member->Kind == MemberInfo::Field) {
1037 Fields[
Member->FD->getCanonicalDecl()] = FieldTypes.size() - 1;
1040 setBitFieldInfo(
Member->FD,
Member->Offset, FieldTypes.back());
1041 }
else if (
Member->Kind == MemberInfo::Base)
1042 NonVirtualBases[
Member->RD] = FieldTypes.size() - 1;
1043 else if (
Member->Kind == MemberInfo::VBase)
1044 VirtualBases[
Member->RD] = FieldTypes.size() - 1;
1050 uint64_t Offset, uint64_t Size,
1051 uint64_t StorageSize,
1056 llvm::Type *Ty = Types.ConvertTypeForMem(FD->
getType());
1059 uint64_t TypeSizeInBits = Types.getContext().toBits(TypeSizeInBytes);
1063 if (
Size > TypeSizeInBits) {
1073 Size = TypeSizeInBits;
1080 if (Types.getDataLayout().isBigEndian()) {
1087std::unique_ptr<CGRecordLayout>
1089 CGRecordLowering Builder(*
this, D,
false);
1091 Builder.lower(
false);
1094 llvm::StructType *BaseTy =
nullptr;
1095 if (isa<CXXRecordDecl>(D)) {
1097 if (Builder.Layout.getNonVirtualSize() != Builder.Layout.getSize()) {
1098 CGRecordLowering BaseBuilder(*
this, D, Builder.Packed);
1099 BaseBuilder.lower(
true);
1100 BaseTy = llvm::StructType::create(
1101 getLLVMContext(), BaseBuilder.FieldTypes,
"", BaseBuilder.Packed);
1105 assert(Builder.Packed == BaseBuilder.Packed &&
1106 "Non-virtual and complete types must agree on packedness");
1113 Ty->setBody(Builder.FieldTypes, Builder.Packed);
1115 auto RL = std::make_unique<CGRecordLayout>(
1116 Ty, BaseTy, (
bool)Builder.IsZeroInitializable,
1117 (
bool)Builder.IsZeroInitializableAsBase);
1119 RL->NonVirtualBases.swap(Builder.NonVirtualBases);
1120 RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases);
1123 RL->FieldInfo.swap(Builder.Fields);
1126 RL->BitFields.swap(Builder.BitFields);
1129 if (
getContext().getLangOpts().DumpRecordLayouts) {
1130 llvm::outs() <<
"\n*** Dumping IRgen Record Layout\n";
1131 llvm::outs() <<
"Record: ";
1132 D->
dump(llvm::outs());
1133 llvm::outs() <<
"\nLayout: ";
1134 RL->print(llvm::outs());
1142 assert(TypeSizeInBits ==
getDataLayout().getTypeAllocSizeInBits(Ty) &&
1143 "Type size mismatch!");
1148 uint64_t AlignedNonVirtualTypeSizeInBits =
1151 assert(AlignedNonVirtualTypeSizeInBits ==
1153 "Type size mismatch!");
1157 llvm::StructType *ST = RL->getLLVMType();
1158 const llvm::StructLayout *SL =
getDataLayout().getStructLayout(ST);
1162 for (
unsigned i = 0, e = AST_RL.
getFieldCount(); i != e; ++i, ++it) {
1172 unsigned FieldNo = RL->getLLVMFieldNo(FD);
1173 assert(AST_RL.
getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) &&
1174 "Invalid field offset!");
1183 llvm::Type *ElementTy = ST->getTypeAtIndex(RL->getLLVMFieldNo(FD));
1194 assert(
static_cast<unsigned>(Info.
Offset + Info.
Size) ==
1196 "Big endian union bitfield does not end at the back");
1198 assert(Info.
Offset == 0 &&
1199 "Little endian union bitfield with a non-zero offset");
1201 "Union not large enough for bitfield storage");
1207 "Storage size does not match the element type size");
1209 assert(Info.
Size > 0 &&
"Empty bitfield!");
1211 "Bitfield outside of its allocated storage");
1219 OS <<
"<CGRecordLayout\n";
1220 OS <<
" LLVMType:" << *CompleteObjectType <<
"\n";
1221 if (BaseSubobjectType)
1222 OS <<
" NonVirtualBaseLLVMType:" << *BaseSubobjectType <<
"\n";
1223 OS <<
" IsZeroInitializable:" << IsZeroInitializable <<
"\n";
1224 OS <<
" BitFields:[\n";
1227 std::vector<std::pair<unsigned, const CGBitFieldInfo*> > BFIs;
1228 for (llvm::DenseMap<const FieldDecl*, CGBitFieldInfo>::const_iterator
1229 it = BitFields.begin(), ie = BitFields.end();
1234 it2 = RD->
field_begin(); *it2 != it->first; ++it2)
1236 BFIs.push_back(std::make_pair(Index, &it->second));
1238 llvm::array_pod_sort(BFIs.begin(), BFIs.end());
1239 for (
unsigned i = 0, e = BFIs.size(); i != e; ++i) {
1241 BFIs[i].second->print(OS);
1249 print(llvm::errs());
1253 OS <<
"<CGBitFieldInfo"
1263 print(llvm::errs());
Defines the clang::ASTContext interface.
static bool isAAPCS(const TargetInfo &TargetInfo)
Helper method to check if the underlying ABI is AAPCS.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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 ...
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 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.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
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.
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::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...
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Decl - This represents one declaration (or definition), e.g.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
unsigned getBitWidthValue(const ASTContext &Ctx) const
Computes the bit width of this field, if this is a bit field.
bool isZeroSize(const ASTContext &Ctx) const
Determine if this field is a subobject of zero size, that is, either a zero-length bit-field or a fie...
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.
specific_decl_iterator< FieldDecl > field_iterator
field_iterator field_begin() const
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
virtual unsigned getRegisterWidth() const
Return the "preferred" register width on this target.
bool hasCheapUnalignedBitFieldAccess() const
Return true iff unaligned accesses are cheap.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual StringRef getABI() const
Get the ABI currently in use.
The base class of the type hierarchy.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
The JSON file list parser is used to communicate input to InstallAPI.
bool operator<(DeclarationName LHS, DeclarationName RHS)
Ordering on two declaration names.
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...