24#include "llvm/IR/DataLayout.h" 
   25#include "llvm/IR/DerivedTypes.h" 
   26#include "llvm/IR/Type.h" 
   27#include "llvm/Support/Debug.h" 
   28#include "llvm/Support/MathExtras.h" 
   29#include "llvm/Support/raw_ostream.h" 
   73struct CGRecordLowering {
 
   79    enum InfoKind { VFPtr, VBPtr, Field, Base, VBase } Kind;
 
   83      const CXXRecordDecl *RD;
 
   85    MemberInfo(CharUnits Offset, InfoKind Kind, llvm::Type *Data,
 
   86               const FieldDecl *FD = 
nullptr)
 
   87      : Offset(Offset), Kind(Kind), Data(Data), FD(FD) {}
 
   88    MemberInfo(CharUnits Offset, InfoKind Kind, llvm::Type *Data,
 
   89               const CXXRecordDecl *RD)
 
   90      : Offset(Offset), Kind(Kind), Data(Data), RD(RD) {}
 
   92    bool operator <(
const MemberInfo& a)
 const { 
return Offset < a.Offset; }
 
   95  CGRecordLowering(CodeGenTypes &Types, 
const RecordDecl *D, 
bool Packed);
 
   98  static MemberInfo StorageInfo(CharUnits Offset, llvm::Type *
Data) {
 
   99    return MemberInfo(Offset, MemberInfo::Field, 
Data);
 
  107  bool isDiscreteBitFieldABI()
 const {
 
  108    return Context.getTargetInfo().getCXXABI().isMicrosoft() ||
 
  109           D->isMsStruct(Context);
 
  114    return Context.getTargetInfo().getABI().starts_with(
"aapcs");
 
  118  bool isBE()
 const { 
return Context.getTargetInfo().isBigEndian(); }
 
  124  bool isOverlappingVBaseABI()
 const {
 
  125    return !Context.getTargetInfo().getCXXABI().isMicrosoft();
 
  129  llvm::Type *getIntNType(uint64_t NumBits)
 const {
 
  130    unsigned AlignedBits = llvm::alignTo(NumBits, Context.getCharWidth());
 
  131    return llvm::Type::getIntNTy(Types.getLLVMContext(), AlignedBits);
 
  134  llvm::Type *getCharType()
 const {
 
  135    return llvm::Type::getIntNTy(Types.getLLVMContext(),
 
  136                                 Context.getCharWidth());
 
  139  llvm::Type *getByteArrayType(CharUnits NumChars)
 const {
 
  140    assert(!NumChars.
isZero() && 
"Empty byte arrays aren't allowed.");
 
  141    llvm::Type *
Type = getCharType();
 
  147  llvm::Type *getStorageType(
const FieldDecl *FD)
 const {
 
  148    llvm::Type *
Type = Types.ConvertTypeForMem(FD->
getType());
 
  150    if (isDiscreteBitFieldABI()) 
return Type;
 
  152                                (
unsigned)Context.toBits(getSize(
Type))));
 
  155  llvm::Type *getStorageType(
const CXXRecordDecl *RD)
 const {
 
  156    return Types.getCGRecordLayout(RD).getBaseSubobjectLLVMType();
 
  158  CharUnits bitsToCharUnits(uint64_t BitOffset)
 const {
 
  159    return Context.toCharUnitsFromBits(BitOffset);
 
  161  CharUnits getSize(llvm::Type *
Type)
 const {
 
  164  CharUnits getAlignment(llvm::Type *
Type)
 const {
 
  167  bool isZeroInitializable(
const FieldDecl *FD)
 const {
 
  168    return Types.isZeroInitializable(FD->
getType());
 
  170  bool isZeroInitializable(
const RecordDecl *RD)
 const {
 
  171    return Types.isZeroInitializable(RD);
 
  173  void appendPaddingBytes(CharUnits Size) {
 
  175      FieldTypes.push_back(getByteArrayType(Size));
 
  177  uint64_t getFieldBitOffset(
const FieldDecl *FD)
 const {
 
  181  void setBitFieldInfo(
const FieldDecl *FD, CharUnits StartOffset,
 
  182                       llvm::Type *StorageType);
 
  184  void lower(
bool NonVirtualBaseType);
 
  185  void lowerUnion(
bool isNonVirtualBaseType);
 
  186  void accumulateFields(
bool isNonVirtualBaseType);
 
  188  accumulateBitFields(
bool isNonVirtualBaseType,
 
  191  void computeVolatileBitfields();
 
  192  void accumulateBases();
 
  193  void accumulateVPtrs();
 
  194  void accumulateVBases();
 
  197  bool hasOwnStorage(
const CXXRecordDecl *
Decl,
 
  198                     const CXXRecordDecl *Query) 
const;
 
  199  void calculateZeroInit();
 
  200  CharUnits calculateTailClippingOffset(
bool isNonVirtualBaseType) 
const;
 
  201  void checkBitfieldClipping(
bool isNonVirtualBaseType) 
const;
 
  203  void determinePacked(
bool NVBaseType);
 
  205  void insertPadding();
 
  207  void fillOutputFields();
 
  210  const ASTContext &Context;
 
  212  const CXXRecordDecl *RD;
 
  213  const ASTRecordLayout &Layout;
 
  214  const llvm::DataLayout &DataLayout;
 
  216  std::vector<MemberInfo> Members;
 
  218  SmallVector<llvm::Type *, 16> FieldTypes;
 
  219  llvm::DenseMap<const FieldDecl *, unsigned> Fields;
 
  220  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
 
  221  llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
 
  222  llvm::DenseMap<const CXXRecordDecl *, unsigned> VirtualBases;
 
  223  bool IsZeroInitializable : 1;
 
  224  bool IsZeroInitializableAsBase : 1;
 
  227  CGRecordLowering(
const CGRecordLowering &) = 
delete;
 
  228  void operator =(
const CGRecordLowering &) = 
delete;
 
  234    : Types(Types), Context(Types.getContext()), D(D),
 
  236      Layout(Types.getContext().getASTRecordLayout(D)),
 
  237      DataLayout(Types.getDataLayout()), IsZeroInitializable(
true),
 
  240void CGRecordLowering::setBitFieldInfo(
 
  244  Info.
Offset = (unsigned)(getFieldBitOffset(FD) - Context.
toBits(StartOffset));
 
  246  Info.
StorageSize = (unsigned)DataLayout.getTypeAllocSizeInBits(StorageType);
 
  254  if (DataLayout.isBigEndian())
 
  262void CGRecordLowering::lower(
bool NVBaseType) {
 
  285    lowerUnion(NVBaseType);
 
  286    computeVolatileBitfields();
 
  289  accumulateFields(NVBaseType);
 
  294    if (Members.empty()) {
 
  295      appendPaddingBytes(Size);
 
  296      computeVolatileBitfields();
 
  302  llvm::stable_sort(Members);
 
  303  checkBitfieldClipping(NVBaseType);
 
  304  Members.push_back(StorageInfo(Size, getIntNType(8)));
 
  305  determinePacked(NVBaseType);
 
  310  computeVolatileBitfields();
 
  313void CGRecordLowering::lowerUnion(
bool isNonVirtualBaseType) {
 
  314  CharUnits LayoutSize =
 
  316  llvm::Type *StorageType = 
nullptr;
 
  317  bool SeenNamedMember = 
false;
 
  323  for (
const auto *Field : D->
fields()) {
 
  324    if (
Field->isBitField()) {
 
  325      if (
Field->isZeroLengthBitField())
 
  327      llvm::Type *FieldType = getStorageType(Field);
 
  328      if (LayoutSize < getSize(FieldType))
 
  329        FieldType = getByteArrayType(LayoutSize);
 
  332    Fields[
Field->getCanonicalDecl()] = 0;
 
  333    llvm::Type *FieldType = getStorageType(Field);
 
  340    if (!SeenNamedMember) {
 
  341      SeenNamedMember = 
Field->getIdentifier();
 
  342      if (!SeenNamedMember)
 
  343        if (
const auto *FieldRD = 
Field->getType()->getAsRecordDecl())
 
  344          SeenNamedMember = FieldRD->findFirstNamedDataMember();
 
  345      if (SeenNamedMember && !isZeroInitializable(Field)) {
 
  346        IsZeroInitializable = IsZeroInitializableAsBase = 
false;
 
  347        StorageType = FieldType;
 
  352    if (!IsZeroInitializable)
 
  356        getAlignment(FieldType) >  getAlignment(StorageType) ||
 
  357        (getAlignment(FieldType) == getAlignment(StorageType) &&
 
  358        getSize(FieldType) > getSize(StorageType)))
 
  359      StorageType = FieldType;
 
  363    return appendPaddingBytes(LayoutSize);
 
  366  if (LayoutSize < getSize(StorageType))
 
  367    StorageType = getByteArrayType(LayoutSize);
 
  368  FieldTypes.push_back(StorageType);
 
  369  appendPaddingBytes(LayoutSize - getSize(StorageType));
 
  371  const auto StorageAlignment = getAlignment(StorageType);
 
  374         "Union's standard layout and no_unique_address layout must agree on " 
  380void CGRecordLowering::accumulateFields(
bool isNonVirtualBaseType) {
 
  383       Field != FieldEnd;) {
 
  384    if (
Field->isBitField()) {
 
  385      Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
 
  386      assert((Field == FieldEnd || !
Field->isBitField()) &&
 
  387             "Failed to accumulate all the bitfields");
 
  394      Members.push_back(MemberInfo(
 
  395          bitsToCharUnits(getFieldBitOffset(*Field)), MemberInfo::Field,
 
  396          Field->isPotentiallyOverlapping()
 
  397              ? getStorageType(
Field->getType()->getAsCXXRecordDecl())
 
  398              : getStorageType(*Field),
 
  410CGRecordLowering::accumulateBitFields(
bool isNonVirtualBaseType,
 
  413  if (isDiscreteBitFieldABI()) {
 
  426      if (
Field->isZeroLengthBitField()) {
 
  430      uint64_t BitOffset = getFieldBitOffset(*Field);
 
  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));
 
  519  CharUnits BeginOffset;
 
  528  CharUnits BestEndOffset;
 
  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())
 
  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));
 
  613          CharUnits Align = getAlignment(
Type);
 
  623          if (InstallBest && BestEnd == Field)
 
  626            if (getSize(
Type) == AccessSize)
 
  635          CharUnits LimitOffset;
 
  636          for (
auto Probe = Field; Probe != FieldEnd; ++Probe)
 
  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;
 
  654          CharUnits TypeSize = getSize(
Type);
 
  655          if (BeginOffset + TypeSize <= LimitOffset) {
 
  658            BestEndOffset = BeginOffset + TypeSize;
 
  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));
 
  699        for (; Begin != BestEnd; ++Begin)
 
  700          if (!Begin->isZeroLengthBitField())
 
  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();
 
  720void CGRecordLowering::accumulateBases() {
 
  725                                 getStorageType(BaseDecl), BaseDecl));
 
  728  for (
const auto &Base : RD->bases()) {
 
  729    if (
Base.isVirtual())
 
  734    const CXXRecordDecl *BaseDecl = 
Base.getType()->getAsCXXRecordDecl();
 
  738          MemberInfo::Base, getStorageType(BaseDecl), BaseDecl));
 
  755void CGRecordLowering::computeVolatileBitfields() {
 
  759  for (
auto &I : BitFields) {
 
  760    const FieldDecl *
Field = I.first;
 
  761    CGBitFieldInfo &Info = I.second;
 
  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);
 
  799    const CharUnits StorageOffset =
 
  801    const CharUnits End = StorageOffset +
 
  805    const ASTRecordLayout &Layout =
 
  808    const CharUnits RecordSize = Layout.
getSize();
 
  809    if (End >= RecordSize)
 
  813    bool Conflict = 
false;
 
  814    for (
const auto *F : D->
fields()) {
 
  816      if (F->isBitField() && !F->isZeroLengthBitField())
 
  826      if (F->isZeroLengthBitField()) {
 
  827        if (End > FOffset && StorageOffset < FOffset) {
 
  833      const CharUnits FEnd =
 
  839      if (End < FOffset || FEnd < StorageOffset)
 
  859void CGRecordLowering::accumulateVPtrs() {
 
  871CGRecordLowering::calculateTailClippingOffset(
bool isNonVirtualBaseType)
 const {
 
  880  if (!isNonVirtualBaseType && isOverlappingVBaseABI())
 
  881    for (
const auto &Base : RD->vbases()) {
 
  882      const CXXRecordDecl *BaseDecl = 
Base.getType()->getAsCXXRecordDecl();
 
  887      if (Context.
isNearlyEmpty(BaseDecl) && !hasOwnStorage(RD, BaseDecl))
 
  889      ScissorOffset = std::min(ScissorOffset,
 
  893  return ScissorOffset;
 
  896void CGRecordLowering::accumulateVBases() {
 
  897  for (
const auto &Base : RD->vbases()) {
 
  898    const CXXRecordDecl *BaseDecl = 
Base.getType()->getAsCXXRecordDecl();
 
  904    if (isOverlappingVBaseABI() &&
 
  906        !hasOwnStorage(RD, BaseDecl)) {
 
  907      Members.push_back(MemberInfo(Offset, MemberInfo::VBase, 
nullptr,
 
  915    Members.push_back(MemberInfo(Offset, MemberInfo::VBase,
 
  916                                 getStorageType(BaseDecl), BaseDecl));
 
  920bool CGRecordLowering::hasOwnStorage(
const CXXRecordDecl *
Decl,
 
  921                                     const CXXRecordDecl *Query)
 const {
 
  925  for (
const auto &Base : 
Decl->bases())
 
  926    if (!hasOwnStorage(
Base.getType()->getAsCXXRecordDecl(), Query))
 
  931void CGRecordLowering::calculateZeroInit() {
 
  932  for (std::vector<MemberInfo>::const_iterator 
Member = Members.begin(),
 
  933                                               MemberEnd = Members.end();
 
  934       IsZeroInitializableAsBase && 
Member != MemberEnd; ++
Member) {
 
  935    if (
Member->Kind == MemberInfo::Field) {
 
  938      IsZeroInitializable = IsZeroInitializableAsBase = 
false;
 
  939    } 
else if (
Member->Kind == MemberInfo::Base ||
 
  940               Member->Kind == MemberInfo::VBase) {
 
  941      if (isZeroInitializable(
Member->RD))
 
  943      IsZeroInitializable = 
false;
 
  944      if (
Member->Kind == MemberInfo::Base)
 
  945        IsZeroInitializableAsBase = 
false;
 
  951void CGRecordLowering::checkBitfieldClipping(
bool IsNonVirtualBaseType)
 const {
 
  953  auto ScissorOffset = calculateTailClippingOffset(IsNonVirtualBaseType);
 
  955  for (
const auto &M : Members) {
 
  960    assert(M.Offset >= Tail && 
"Bitfield access unit is not clipped");
 
  961    Tail = M.Offset + getSize(M.Data);
 
  962    assert((Tail <= ScissorOffset || M.Offset >= ScissorOffset) &&
 
  963           "Bitfield straddles scissor offset");
 
  968void CGRecordLowering::determinePacked(
bool NVBaseType) {
 
  975  for (
const MemberInfo &
Member : Members) {
 
  980    if (!
Member.Offset.isMultipleOf(getAlignment(
Member.Data)))
 
  982    if (
Member.Offset < NVSize)
 
  983      NVAlignment = std::max(NVAlignment, getAlignment(
Member.Data));
 
  984    Alignment = std::max(Alignment, getAlignment(
Member.Data));
 
  988  if (!Members.back().Offset.isMultipleOf(Alignment))
 
  997    Members.back().Data = getIntNType(Context.
toBits(Alignment));
 
 1000void CGRecordLowering::insertPadding() {
 
 1001  std::vector<std::pair<CharUnits, CharUnits> > Padding;
 
 1003  for (
const MemberInfo &
Member : Members) {
 
 1006    CharUnits Offset = 
Member.Offset;
 
 1007    assert(Offset >= Size);
 
 1011      Padding.push_back(std::make_pair(Size, Offset - Size));
 
 1014  if (Padding.empty())
 
 1017  for (
const auto &Pad : Padding)
 
 1018    Members.push_back(StorageInfo(Pad.first, getByteArrayType(Pad.second)));
 
 1019  llvm::stable_sort(Members);
 
 1022void CGRecordLowering::fillOutputFields() {
 
 1023  for (
const MemberInfo &
Member : Members) {
 
 1025      FieldTypes.push_back(
Member.Data);
 
 1026    if (
Member.Kind == MemberInfo::Field) {
 
 1028        Fields[
Member.FD->getCanonicalDecl()] = FieldTypes.size() - 1;
 
 1032               "Member.Data is a nullptr so Member.FD should not be");
 
 1033        setBitFieldInfo(
Member.FD, 
Member.Offset, FieldTypes.back());
 
 1035    } 
else if (
Member.Kind == MemberInfo::Base)
 
 1036      NonVirtualBases[
Member.RD] = FieldTypes.size() - 1;
 
 1037    else if (
Member.Kind == MemberInfo::VBase)
 
 1038      VirtualBases[
Member.RD] = FieldTypes.size() - 1;
 
 1057  if (
Size > TypeSizeInBits) {
 
 1067    Size = TypeSizeInBits;
 
 
 1081std::unique_ptr<CGRecordLayout>
 
 1083  CGRecordLowering Builder(*
this, D, 
false);
 
 1085  Builder.lower(
false);
 
 1088  llvm::StructType *BaseTy = 
nullptr;
 
 1091    if (Builder.Layout.getNonVirtualSize() != Builder.Layout.getSize()) {
 
 1092      CGRecordLowering BaseBuilder(*
this, D, Builder.Packed);
 
 1093      BaseBuilder.lower(
true);
 
 1094      BaseTy = llvm::StructType::create(
 
 1095          getLLVMContext(), BaseBuilder.FieldTypes, 
"", BaseBuilder.Packed);
 
 1099      assert(Builder.Packed == BaseBuilder.Packed &&
 
 1100             "Non-virtual and complete types must agree on packedness");
 
 1107  Ty->setBody(Builder.FieldTypes, Builder.Packed);
 
 1109  auto RL = std::make_unique<CGRecordLayout>(
 
 1110      Ty, BaseTy, (
bool)Builder.IsZeroInitializable,
 
 1111      (
bool)Builder.IsZeroInitializableAsBase);
 
 1113  RL->NonVirtualBases.swap(Builder.NonVirtualBases);
 
 1114  RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases);
 
 1117  RL->FieldInfo.swap(Builder.Fields);
 
 1120  RL->BitFields.swap(Builder.BitFields);
 
 1123  if (
getContext().getLangOpts().DumpRecordLayouts) {
 
 1124    llvm::outs() << 
"\n*** Dumping IRgen Record Layout\n";
 
 1125    llvm::outs() << 
"Record: ";
 
 1126    D->
dump(llvm::outs());
 
 1127    llvm::outs() << 
"\nLayout: ";
 
 1128    RL->print(llvm::outs());
 
 1136  assert(TypeSizeInBits == 
getDataLayout().getTypeAllocSizeInBits(Ty) &&
 
 1137         "Type size mismatch!");
 
 1142    uint64_t AlignedNonVirtualTypeSizeInBits =
 
 1145    assert(AlignedNonVirtualTypeSizeInBits ==
 
 1147           "Type size mismatch!");
 
 1151  llvm::StructType *ST = RL->getLLVMType();
 
 1152  const llvm::StructLayout *SL = 
getDataLayout().getStructLayout(ST);
 
 1156  for (
unsigned i = 0, e = AST_RL.
getFieldCount(); i != e; ++i, ++it) {
 
 1166      unsigned FieldNo = RL->getLLVMFieldNo(FD);
 
 1167      assert(AST_RL.
getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) &&
 
 1168             "Invalid field offset!");
 
 1177    llvm::Type *ElementTy = ST->getTypeAtIndex(RL->getLLVMFieldNo(FD));
 
 1188        assert(
static_cast<unsigned>(Info.
Offset + Info.
Size) ==
 
 1190               "Big endian union bitfield does not end at the back");
 
 1192        assert(Info.
Offset == 0 &&
 
 1193               "Little endian union bitfield with a non-zero offset");
 
 1195             "Union not large enough for bitfield storage");
 
 1201             "Storage size does not match the element type size");
 
 1203    assert(Info.
Size > 0 && 
"Empty bitfield!");
 
 1205           "Bitfield outside of its allocated storage");
 
 
 1213  OS << 
"<CGRecordLayout\n";
 
 1214  OS << 
"  LLVMType:" << *CompleteObjectType << 
"\n";
 
 1215  if (BaseSubobjectType)
 
 1216    OS << 
"  NonVirtualBaseLLVMType:" << *BaseSubobjectType << 
"\n";
 
 1217  OS << 
"  IsZeroInitializable:" << IsZeroInitializable << 
"\n";
 
 1218  OS << 
"  BitFields:[\n";
 
 1221  std::vector<std::pair<unsigned, const CGBitFieldInfo*> > BFIs;
 
 1222  for (
const auto &BitField : BitFields) {
 
 1226         *it2 != BitField.first; ++it2)
 
 1228    BFIs.push_back(std::make_pair(Index, &BitField.second));
 
 1230  llvm::array_pod_sort(BFIs.begin(), BFIs.end());
 
 1231  for (
auto &BFI : BFIs) {
 
 1233    BFI.second->print(OS);
 
 
 1241  print(llvm::errs());
 
 
 1245  OS << 
"<CGBitFieldInfo" 
 
 1255  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....
static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, 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 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 ...
The JSON file list parser is used to communicate input to InstallAPI.
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...