diff options
author | Anders Carlsson <andersca@mac.com> | 2010-05-26 15:10:00 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-05-26 15:10:00 +0000 |
commit | c6cab68ae1f8ebdcabaf51391dba09bfbad02e4f (patch) | |
tree | 2e0fa99cb7226275cd447991aa8d5a9cffd82b1b /lib/AST/RecordLayoutBuilder.cpp | |
parent | 7e220286410422ed1dc0409a9cb9708fe50e3df0 (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.cpp | 86 |
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 } |