/// These objects are managed by ASTContext.
class ASTRecordLayout {
/// Size - Size of record in bits.
- uint64_t Size;
+ CharUnits Size;
/// DataSize - Size of record in bits without tail padding.
uint64_t DataSize;
friend class ASTContext;
- ASTRecordLayout(const ASTContext &Ctx, uint64_t size, unsigned alignment,
+ ASTRecordLayout(const ASTContext &Ctx, CharUnits size, unsigned alignment,
unsigned datasize, const uint64_t *fieldoffsets,
unsigned fieldcount);
// Constructor for C++ records.
typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
ASTRecordLayout(const ASTContext &Ctx,
- uint64_t size, unsigned alignment, uint64_t datasize,
+ CharUnits size, unsigned alignment, uint64_t datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
CharUnits nonvirtualsize, CharUnits nonvirtualalign,
CharUnits SizeOfLargestEmptySubobject,
unsigned getAlignment() const { return Alignment; }
/// getSize - Get the record size in bits.
- uint64_t getSize() const { return Size; }
+ CharUnits getSize() const { return Size; }
/// getFieldCount - Get the number of fields in the layout.
unsigned getFieldCount() const { return FieldCount; }
case Type::ObjCInterface: {
const ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
- Width = Layout.getSize();
+ Width = Layout.getSize().getQuantity() * getCharWidth();
Align = Layout.getAlignment();
break;
}
const RecordType *RT = cast<RecordType>(TT);
const ASTRecordLayout &Layout = getASTRecordLayout(RT->getDecl());
- Width = Layout.getSize();
+ Width = Layout.getSize().getQuantity() * getCharWidth();
Align = Layout.getAlignment();
break;
}
Ctx.Deallocate(this);
}
-ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, uint64_t size,
+ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx, CharUnits size,
unsigned alignment, unsigned datasize,
const uint64_t *fieldoffsets,
unsigned fieldcount)
// Constructor for C++ records.
ASTRecordLayout::ASTRecordLayout(const ASTContext &Ctx,
- uint64_t size, unsigned alignment,
+ CharUnits size, unsigned alignment,
uint64_t datasize,
const uint64_t *fieldoffsets,
unsigned fieldcount,
const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
if (BaseDecl->isEmpty()) {
// If the class decl is empty, get its size.
- EmptySize = Context.toCharUnitsFromBits(Layout.getSize());
+ EmptySize = Layout.getSize();
} else {
// Otherwise, we get the largest empty subobject for the decl.
EmptySize = Layout.getSizeOfLargestEmptySubobject();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
if (MemberDecl->isEmpty()) {
// If the class decl is empty, get its size.
- EmptySize = Context.toCharUnitsFromBits(Layout.getSize());
+ EmptySize = Layout.getSize();
} else {
// Otherwise, we get the largest empty subobject for the decl.
EmptySize = Layout.getSizeOfLargestEmptySubobject();
if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset))
return false;
- ElementOffset += Context.toCharUnitsFromBits(Layout.getSize());
+ ElementOffset += Layout.getSize();
}
}
return;
UpdateEmptyFieldSubobjects(RD, RD, ElementOffset);
- ElementOffset += Context.toCharUnitsFromBits(Layout.getSize());
+ ElementOffset += Layout.getSize();
}
}
}
// If we have an empty base class, try to place it at offset 0.
if (Base->Class->isEmpty() &&
EmptySubobjects->CanPlaceBaseAtOffset(Base, CharUnits::Zero())) {
- Size = std::max(Size, Layout.getSize());
+ Size = std::max(Size,
+ Layout.getSize().getQuantity() * Context.getCharWidth());
return CharUnits::Zero();
}
Size = std::max(Size, DataSize);
} else
- Size = std::max(Size, Offset + Layout.getSize());
+ Size = std::max(Size,
+ Offset + (Layout.getSize().getQuantity() * Context.getCharWidth()));
// Remember max struct/class alignment.
UpdateAlignment(BaseAlign, UnpackedBaseAlign);
IsPODForThePurposeOfLayout ? DataSize : Builder->NonVirtualSize;
uint64_t NonVirtualAlign = Builder->NonVirtualAlignment;
+ CharUnits RecordSize = toCharUnitsFromBits(Builder->Size);
NewEntry =
- new (*this) ASTRecordLayout(*this, Builder->Size, Builder->Alignment,
+ new (*this) ASTRecordLayout(*this, RecordSize, Builder->Alignment,
DataSize, Builder->FieldOffsets.data(),
Builder->FieldOffsets.size(),
toCharUnitsFromBits(NonVirtualSize),
RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
Builder.Layout(D);
+ CharUnits RecordSize = toCharUnitsFromBits(Builder.Size);
+
NewEntry =
- new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment,
+ new (*this) ASTRecordLayout(*this, RecordSize, Builder.Alignment,
Builder.Size,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0);
Builder.Layout(D);
+ CharUnits RecordSize = toCharUnitsFromBits(Builder.Size);
+
const ASTRecordLayout *NewEntry =
- new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment,
+ new (*this) ASTRecordLayout(*this, RecordSize, Builder.Alignment,
Builder.DataSize,
Builder.FieldOffsets.data(),
Builder.FieldOffsets.size());
/*IncludeVirtualBases=*/false);
}
- OS << " sizeof=" << Layout.getSize() / 8;
+ OS << " sizeof=" << Layout.getSize().getQuantity();
OS << ", dsize=" << Layout.getDataSize() / 8;
OS << ", align=" << Layout.getAlignment() / 8 << '\n';
OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity();
RD->dump();
OS << "\nLayout: ";
OS << "<ASTRecordLayout\n";
- OS << " Size:" << Info.getSize() << "\n";
+ OS << " Size:" << Info.getSize().getQuantity() * getCharWidth() << "\n";
OS << " DataSize:" << Info.getDataSize() << "\n";
OS << " Alignment:" << Info.getAlignment() << "\n";
OS << " FieldOffsets: [";
}
}
- uint64_t LayoutSizeInBytes = Layout.getSize() / 8;
+ uint64_t LayoutSizeInBytes = Layout.getSize().getQuantity();
if (NextFieldOffsetInBytes > LayoutSizeInBytes) {
// If the struct is bigger than the size of the record type,
}
// Append tail padding if necessary.
- AppendTailPadding(Layout.getSize());
+ AppendTailPadding(
+ Layout.getSize().getQuantity() * CGM.getContext().getCharWidth());
- assert(Layout.getSize() / 8 == NextFieldOffsetInBytes &&
+ assert(Layout.getSize().getQuantity() == NextFieldOffsetInBytes &&
"Tail padding mismatch!");
return true;
}
// Get the size of instances.
- int instanceSize = Context.getASTObjCImplementationLayout(OID).getSize() / 8;
+ int instanceSize =
+ Context.getASTObjCImplementationLayout(OID).getSize().getQuantity();
// Collect information about instance variables.
llvm::SmallVector<llvm::Constant*, 16> IvarNames;
std::vector<llvm::Constant*> IvarOffsetValues;
int superInstanceSize = !SuperClassDecl ? 0 :
- Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize() / 8;
+ Context.getASTObjCInterfaceLayout(SuperClassDecl).getSize().getQuantity();
// For non-fragile ivars, set the instance size to 0 - {the size of just this
// class}. The runtime will then set this to the correct value on load.
if (CGM.getContext().getLangOptions().ObjCNonFragileABI) {
// a synthesized ivar can never be a bit-field, so this is safe.
const ASTRecordLayout &RL =
CGF.CGM.getContext().getASTObjCInterfaceLayout(OID);
- uint64_t TypeSizeInBits = RL.getSize();
+ uint64_t TypeSizeInBits =
+ RL.getSize().getQuantity() * CGF.CGM.getContext().getCharWidth();
uint64_t FieldBitOffset = LookupFieldBitOffset(CGF.CGM, OID, 0, Ivar);
uint64_t BitOffset = FieldBitOffset % 8;
uint64_t ContainingTypeAlign = 8;
if (ID->getNumIvarInitializers())
Flags |= eClassFlags_HasCXXStructors;
unsigned Size =
- CGM.getContext().getASTObjCImplementationLayout(ID).getSize() / 8;
+ CGM.getContext().getASTObjCImplementationLayout(ID).getSize().getQuantity();
// FIXME: Set CXX-structors flag.
if (ID->getClassInterface()->getVisibility() == HiddenVisibility)
uint64_t FieldSize) {
const RecordDecl *RD = FD->getParent();
const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD);
- uint64_t ContainingTypeSizeInBits = RL.getSize();
+ uint64_t ContainingTypeSizeInBits =
+ RL.getSize().getQuantity() * Types.getContext().getCharWidth();
unsigned ContainingTypeAlign = RL.getAlignment();
return MakeInfo(Types, FD, FieldOffset, FieldSize, ContainingTypeSizeInBits,
}
// Append tail padding.
- if (Layout.getSize() / 8 > Size)
- AppendPadding(Layout.getSize() / 8, Align);
+ if (Layout.getSize().getQuantity() > Size)
+ AppendPadding(Layout.getSize().getQuantity(), Align);
}
void CGRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *BaseDecl,
// First check if we can use the same fields as for the complete class.
- if (AlignedNonVirtualTypeSize == Layout.getSize() / 8) {
+ if (AlignedNonVirtualTypeSize == Layout.getSize().getQuantity()) {
NonVirtualBaseTypeIsSameAsCompleteType = true;
return true;
}
}
// Append tail padding if necessary.
- AppendTailPadding(Layout.getSize());
+ AppendTailPadding(
+ Layout.getSize().getQuantity() * Types.getContext().getCharWidth());
return true;
}
// Verify that the computed LLVM struct size matches the AST layout size.
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(D);
- uint64_t TypeSizeInBits = Layout.getSize();
+ uint64_t TypeSizeInBits =
+ Layout.getSize().getQuantity() * getContext().getCharWidth();
assert(TypeSizeInBits == getTargetData().getTypeAllocSizeInBits(Ty) &&
"Type size mismatch!");