aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/RecordLayoutBuilder.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-05-26 15:10:00 +0000
committerAnders Carlsson <andersca@mac.com>2010-05-26 15:10:00 +0000
commitc6cab68ae1f8ebdcabaf51391dba09bfbad02e4f (patch)
tree2e0fa99cb7226275cd447991aa8d5a9cffd82b1b /lib/AST/RecordLayoutBuilder.cpp
parent7e220286410422ed1dc0409a9cb9708fe50e3df0 (diff)
Add a Layout overload that takes a CXXRecordDecl.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104695 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp86
1 files changed, 48 insertions, 38 deletions
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index 36dc2b2248..e554aebf40 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -96,6 +96,7 @@ class RecordLayoutBuilder {
RecordLayoutBuilder(ASTContext &Ctx);
void Layout(const RecordDecl *D);
+ void Layout(const CXXRecordDecl *D);
void Layout(const ObjCInterfaceDecl *D);
void LayoutFields(const RecordDecl *D);
@@ -162,6 +163,9 @@ class RecordLayoutBuilder {
/// given offset.
void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset);
+ /// InitializeLayout - Initialize record layout for the given record decl.
+ void InitializeLayout(const RecordDecl *D);
+
/// FinishLayout - Finalize record layout. Adjust record size based on the
/// alignment.
void FinishLayout();
@@ -732,65 +736,71 @@ RecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD,
}
}
-void RecordLayoutBuilder::Layout(const RecordDecl *D) {
+void RecordLayoutBuilder::InitializeLayout(const RecordDecl *D) {
IsUnion = D->isUnion();
-
+
Packed = D->hasAttr<PackedAttr>();
-
+
// The #pragma pack attribute specifies the maximum field alignment.
if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
MaxFieldAlignment = PPA->getAlignment();
-
+
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
UpdateAlignment(AA->getMaxAlignment());
+}
- // If this is a C++ class, lay out the vtable and the non-virtual bases.
- const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
- if (RD) {
- ComputeEmptySubobjectSizes(RD);
- LayoutNonVirtualBases(RD);
- }
-
+void RecordLayoutBuilder::Layout(const RecordDecl *D) {
+ InitializeLayout(D);
LayoutFields(D);
+ // Finally, round the size of the total struct up to the alignment of the
+ // struct itself.
+ FinishLayout();
+}
+
+void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
+ InitializeLayout(RD);
+
+ ComputeEmptySubobjectSizes(RD);
+
+ // Lay out the vtable and the non-virtual bases.
+ LayoutNonVirtualBases(RD);
+
+ LayoutFields(RD);
+
NonVirtualSize = Size;
NonVirtualAlignment = Alignment;
- // If this is a C++ class, lay out its virtual bases and add its primary
- // virtual base offsets.
- if (RD) {
- LayoutVirtualBases(RD, RD);
+ // Lay out the virtual bases and add the primary virtual base offsets.
+ LayoutVirtualBases(RD, RD);
- VisitedVirtualBases.clear();
- AddPrimaryVirtualBaseOffsets(RD, 0, RD);
- }
+ VisitedVirtualBases.clear();
+ AddPrimaryVirtualBaseOffsets(RD, 0, RD);
// Finally, round the size of the total struct up to the alignment of the
// struct itself.
FinishLayout();
-
+
#ifndef NDEBUG
- if (RD) {
- // Check that we have base offsets for all bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
- E = RD->bases_end(); I != E; ++I) {
- if (I->isVirtual())
- continue;
-
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+ // Check that we have base offsets for all bases.
+ for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+ E = RD->bases_end(); I != E; ++I) {
+ if (I->isVirtual())
+ continue;
- assert(Bases.count(BaseDecl) && "Did not find base offset!");
- }
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ assert(Bases.count(BaseDecl) && "Did not find base offset!");
+ }
+
+ // And all virtual bases.
+ for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+ E = RD->vbases_end(); I != E; ++I) {
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
- // And all virtual bases.
- for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
- E = RD->vbases_end(); I != E; ++I) {
- const CXXRecordDecl *BaseDecl =
- cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
-
- assert(VBases.count(BaseDecl) && "Did not find base offset!");
- }
+ assert(VBases.count(BaseDecl) && "Did not find base offset!");
}
#endif
}