diff options
author | Mike Stump <mrs@apple.com> | 2009-08-11 04:03:59 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-08-11 04:03:59 +0000 |
commit | 49520944c688a9d5fc78d0c2af544b825873477b (patch) | |
tree | 9d5c0b3825ccd360c485bbfff8699ead14acc1da /lib/AST/RecordLayoutBuilder.cpp | |
parent | 89350bee4cdee96ba7cdf43c83d7878dbb3a4a00 (diff) |
Implement more of the inductive case for vtable layout involving
virtual base primaries and improve the layout of classes with virtual
bases. WIP.
Hey, I've decided I want a change to FileCheck, I need to ensure that
the group is together, nothing in between. Can we change it to check
the match line is from the line immediately following the last matched
line, if the source for the matched line is immediately after the
source for the previously matched line?
// CHECK: 1
// CHECK: 2
// CHECK: 3
// CHECK: 4
// CHECK: 5
// CHECK: 6
would require 1 2 and 3 to be continuous in the output, and 4 5 and 6
to be continuous.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78638 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/RecordLayoutBuilder.cpp')
-rw-r--r-- | lib/AST/RecordLayoutBuilder.cpp | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 68350daa6c..8e09e9e65b 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -74,26 +74,27 @@ bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) { void ASTRecordLayoutBuilder::SelectPrimaryForBase(const CXXRecordDecl *RD, llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) { + const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); + const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); + const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual(); + if (PrimaryBaseWasVirtual) { + IndirectPrimary.insert(PrimaryBase); + } for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { - if (!i->isVirtual()) { - const CXXRecordDecl *Base = - cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); - // Only bases with virtual bases participate in computing the - // indirect primary base classes. - // FIXME: audit indirect virtual bases - if (Base->getNumVBases() == 0) - return; - // FIXME: This information is recomputed a whole lot, cache it instead. - SelectPrimaryBase(Base); - IndirectPrimary.insert(PrimaryBase); - SelectPrimaryForBase(Base, IndirectPrimary); - } + const CXXRecordDecl *Base = + cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + // Only bases with virtual bases participate in computing the + // indirect primary virtual base classes. + // FIXME: audit indirect virtual bases + if (Base->getNumVBases() == 0) + continue; + SelectPrimaryForBase(Base, IndirectPrimary); } } /// SelectPrimaryBase - Selects the primary base for the given class and -/// records that with setPrimaryBase. +/// record that with setPrimaryBase. void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { // The primary base is the first non-virtual indirect or direct base class, // if one exists. @@ -110,7 +111,7 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { } // Otherwise, it is the first nearly empty virtual base that is not an - // indirect primary base class, if one exists. + // indirect primary virtual base class, if one exists. // If we have no virtual bases at this point, bail out as the searching below // is expensive. @@ -120,21 +121,19 @@ void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) { return; } - // First, we compute all the primary bases for all of our direct and indirect - // non-virtual bases, and record all their primary base classes. + // First, we compute all the primary virtual bases for all of our direct and + // indirect bases, and record all their primary virtual base classes. const CXXRecordDecl *FirstPrimary = 0; llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimary; for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), e = RD->bases_end(); i != e; ++i) { - if (!i->isVirtual()) { - const CXXRecordDecl *Base = - cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); - SelectPrimaryForBase(Base, IndirectPrimary); - } + const CXXRecordDecl *Base = + cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + SelectPrimaryForBase(Base, IndirectPrimary); } // Then we can search for the first nearly empty virtual base itself. - // FIXME: audit indirect virtual bases + // FIXME: audit indirect virtual bases and order (backwards?) for (CXXRecordDecl::base_class_const_iterator i = RD->vbases_begin(), e = RD->vbases_end(); i != e; ++i) { const CXXRecordDecl *Base = |