[cfe-commits] r77352 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h
Anders Carlsson
andersca at mac.com
Tue Jul 28 12:24:15 PDT 2009
Author: andersca
Date: Tue Jul 28 14:24:15 2009
New Revision: 77352
URL: http://llvm.org/viewvc/llvm-project?rev=77352&view=rev
Log:
Add a field for C++ specific data to ASTRecordLayout. Use it to store the non-virtual size and alignment + base offsets.
Modified:
cfe/trunk/include/clang/AST/RecordLayout.h
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/lib/AST/RecordLayoutBuilder.h
Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=77352&r1=77351&r2=77352&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Tue Jul 28 14:24:15 2009
@@ -20,6 +20,7 @@
class ASTContext;
class FieldDecl;
class RecordDecl;
+ class CXXRecordDecl;
/// ASTRecordLayout -
/// This class contains layout information for one RecordDecl,
@@ -29,26 +30,78 @@
/// ObjCInterfaceDecl. FIXME - Find appropriate name.
/// These objects are managed by ASTContext.
class ASTRecordLayout {
- uint64_t Size; // Size of record in bits.
- uint64_t DataSize; // Size of record in bits without tail padding.
+ /// Size - Size of record in bits.
+ uint64_t Size;
+
+ /// DataSize - Size of record in bits without tail padding.
+ uint64_t DataSize;
+
+ /// FieldOffsets - Array of field offsets in bits.
uint64_t *FieldOffsets;
- unsigned Alignment; // Alignment of record in bits.
- unsigned FieldCount; // Number of fields
+
+ // Alignment - Alignment of record in bits.
+ unsigned Alignment;
+
+ // FieldCount - Number of fields.
+ unsigned FieldCount;
+
+ struct CXXRecordLayoutInfo {
+ /// NonVirtualSize - The non-virtual size (in bits) of an object, which is
+ /// the size of the object without virtual bases.
+ uint64_t NonVirtualSize;
+
+ /// NonVirtualAlign - The non-virtual alignment (in bits) of an object,
+ /// which is the alignment of the object without virtual bases.
+ uint64_t NonVirtualAlign;
+
+ /// BaseOffsets - Contains a map from base classes to their offset.
+ /// FIXME: Does it make sense to store offsets for virtual base classes
+ /// here?
+ /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
+ llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
+ };
+
+ /// CXXInfo - If the record layout is for a C++ record, this will have
+ /// C++ specific information about the record.
+ CXXRecordLayoutInfo *CXXInfo;
+
friend class ASTContext;
friend class ASTRecordLayoutBuilder;
ASTRecordLayout(uint64_t size, unsigned alignment, unsigned datasize,
const uint64_t *fieldoffsets, unsigned fieldcount)
: Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
- FieldCount(fieldcount) {
+ FieldCount(fieldcount), CXXInfo(0) {
if (FieldCount > 0) {
FieldOffsets = new uint64_t[FieldCount];
for (unsigned i = 0; i < FieldCount; ++i)
FieldOffsets[i] = fieldoffsets[i];
}
}
+
+ // Constructor for C++ records.
+ ASTRecordLayout(uint64_t size, unsigned alignment, unsigned datasize,
+ const uint64_t *fieldoffsets, unsigned fieldcount,
+ uint64_t nonvirtualsize, unsigned nonvirtualalign,
+ const CXXRecordDecl **bases, const uint64_t *baseoffsets,
+ unsigned basecount)
+ : Size(size), DataSize(datasize), FieldOffsets(0), Alignment(alignment),
+ FieldCount(fieldcount), CXXInfo(new CXXRecordLayoutInfo) {
+ if (FieldCount > 0) {
+ FieldOffsets = new uint64_t[FieldCount];
+ for (unsigned i = 0; i < FieldCount; ++i)
+ FieldOffsets[i] = fieldoffsets[i];
+ }
+
+ CXXInfo->NonVirtualSize = nonvirtualsize;
+ CXXInfo->NonVirtualAlign = nonvirtualalign;
+ for (unsigned i = 0; i != basecount; ++i)
+ CXXInfo->BaseOffsets[bases[i]] = baseoffsets[i];
+ }
+
~ASTRecordLayout() {
delete [] FieldOffsets;
+ delete CXXInfo;
}
ASTRecordLayout(const ASTRecordLayout&); // DO NOT IMPLEMENT
@@ -76,6 +129,30 @@
uint64_t getDataSize() const {
return DataSize;
}
+
+ /// getNonVirtualSize - Get the non-virtual size (in bits) of an object,
+ /// which is the size of the object without virtual bases.
+ uint64_t getNonVirtualSize() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return CXXInfo->NonVirtualSize;
+ }
+
+ /// getNonVirtualSize - Get the non-virtual alignment (in bits) of an object,
+ /// which is the alignment of the object without virtual bases.
+ unsigned getNonVirtualAlign() const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+
+ return CXXInfo->NonVirtualAlign;
+ }
+
+ /// getBaseClassOffset - Get the offset, in bits, for the given base class.
+ uint64_t getBaseClassOffset(const CXXRecordDecl *Base) const {
+ assert(CXXInfo && "Record layout does not have C++ specific info!");
+ assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
+
+ return CXXInfo->BaseOffsets[Base];
+ }
};
} // end namespace clang
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=77352&r1=77351&r2=77352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Tue Jul 28 14:24:15 2009
@@ -22,7 +22,7 @@
ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx)
: Ctx(Ctx), Size(0), Alignment(8), StructPacking(0), NextOffset(0),
- IsUnion(false) {}
+ IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8) {}
void
ASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
@@ -44,15 +44,16 @@
assert(BaseInfo.getDataSize() > 0 &&
"FIXME: Handle empty classes.");
- // FIXME: Should get the non-virtual alignment of the base.
- unsigned BaseAlign = BaseInfo.getAlignment();
-
- // FIXME: Should get the non-virtual size of the base.
- uint64_t BaseSize = BaseInfo.getDataSize();
+ unsigned BaseAlign = BaseInfo.getNonVirtualAlign();
+ uint64_t BaseSize = BaseInfo.getNonVirtualSize();
// Round up the current record size to the base's alignment boundary.
Size = (Size + (BaseAlign-1)) & ~(BaseAlign-1);
+ // Add base class offsets.
+ Bases.push_back(RD);
+ BaseOffsets.push_back(Size);
+
// Non-virtual base class has offset too.
FieldOffsets.push_back(Size);
@@ -81,6 +82,9 @@
LayoutFields(D);
+ NonVirtualSize = Size;
+ NonVirtualAlignment = Alignment;
+
// Finally, round the size of the total struct up to the alignment of the
// struct itself.
FinishLayout();
@@ -238,22 +242,33 @@
Builder.Layout(D);
- bool IsPODForThePurposeOfLayout;
- if (!Ctx.getLangOptions().CPlusPlus) {
- // In C, all record types are POD.
- IsPODForThePurposeOfLayout = true;
- } else {
- // FIXME: This is not always correct. See the part about bitfields at
- // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
- IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD();
- }
+ if (!isa<CXXRecordDecl>(D))
+ return new ASTRecordLayout(Builder.Size, Builder.Alignment, Builder.Size,
+ Builder.FieldOffsets.data(),
+ Builder.FieldOffsets.size());
+
+ // FIXME: This is not always correct. See the part about bitfields at
+ // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
+ // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout.
+ bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD();
+ assert(Builder.Bases.size() == Builder.BaseOffsets.size() &&
+ "Base offsets vector must be same size as bases vector!");
+
+ // FIXME: This should be done in FinalizeLayout.
uint64_t DataSize =
IsPODForThePurposeOfLayout ? Builder.Size : Builder.NextOffset;
+ uint64_t NonVirtualSize =
+ IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
return new ASTRecordLayout(Builder.Size, Builder.Alignment, DataSize,
Builder.FieldOffsets.data(),
- Builder.FieldOffsets.size());
+ Builder.FieldOffsets.size(),
+ NonVirtualSize,
+ Builder.NonVirtualAlignment,
+ Builder.Bases.data(),
+ Builder.BaseOffsets.data(),
+ Builder.Bases.size());
}
const ASTRecordLayout *
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=77352&r1=77351&r2=77352&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Tue Jul 28 14:24:15 2009
@@ -26,13 +26,18 @@
ASTContext &Ctx;
uint64_t Size;
- uint64_t Alignment;
+ unsigned Alignment;
llvm::SmallVector<uint64_t, 16> FieldOffsets;
unsigned StructPacking;
unsigned NextOffset;
bool IsUnion;
+ uint64_t NonVirtualSize;
+ unsigned NonVirtualAlignment;
+ llvm::SmallVector<const CXXRecordDecl *, 4> Bases;
+ llvm::SmallVector<uint64_t, 4> BaseOffsets;
+
ASTRecordLayoutBuilder(ASTContext &Ctx);
void Layout(const RecordDecl *D);
More information about the cfe-commits
mailing list