[cfe-commits] r82513 - in /cfe/trunk: include/clang/AST/DeclCXX.h lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h
Anders Carlsson
andersca at mac.com
Mon Sep 21 20:02:06 PDT 2009
Author: andersca
Date: Mon Sep 21 22:02:06 2009
New Revision: 82513
URL: http://llvm.org/viewvc/llvm-project?rev=82513&view=rev
Log:
Store the set of indirect primary bases directly in the record layout builder.
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/lib/AST/RecordLayoutBuilder.h
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=82513&r1=82512&r2=82513&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Sep 21 22:02:06 2009
@@ -433,7 +433,7 @@
virtual void Destroy(ASTContext& C);
bool isDynamicClass() const {
- return Polymorphic || NumVBases!=0;
+ return Polymorphic || NumVBases != 0;
}
/// setBases - Sets the base classes of this struct or class.
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=82513&r1=82512&r2=82513&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Mon Sep 21 22:02:06 2009
@@ -26,15 +26,14 @@
NextOffset(0), IsUnion(false), NonVirtualSize(0), NonVirtualAlignment(8) {}
/// LayoutVtable - Lay out the vtable and set PrimaryBase.
-void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD,
- llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
+void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
if (!RD->isDynamicClass()) {
// There is no primary base in this case.
setPrimaryBase(0, false);
return;
}
- SelectPrimaryBase(RD, IndirectPrimary);
+ SelectPrimaryBase(RD);
if (PrimaryBase == 0) {
int AS = 0;
UpdateAlignment(Ctx.Target.getPointerAlign(AS));
@@ -62,7 +61,7 @@
//
/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
/// no other data.
-bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) {
+bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
// FIXME: Audit the corners
if (!RD->isDynamicClass())
return false;
@@ -72,35 +71,37 @@
return false;
}
-void ASTRecordLayoutBuilder::SelectPrimaryForBase(const CXXRecordDecl *RD,
- llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
+void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
- const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
- const bool PrimaryBaseWasVirtual = Layout.getPrimaryBaseWasVirtual();
-
- if (PrimaryBaseWasVirtual)
- IndirectPrimary.insert(PrimaryBase);
-
+
+ // If the record has a primary base class that is virtual, add it to the set
+ // of primary bases.
+ if (Layout.getPrimaryBaseWasVirtual())
+ IndirectPrimaryBases.insert(Layout.getPrimaryBase());
+
+ // Now traverse all bases and find primary bases for them.
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
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: Is this correct?
if (Base->getNumVBases())
- SelectPrimaryForBase(Base, IndirectPrimary);
+ IdentifyPrimaryBases(Base);
}
}
-void ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
- const CXXRecordDecl *&FirstPrimary,
- llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
+void
+ASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD,
+ const CXXRecordDecl *&FirstPrimary) {
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
if (!i->isVirtual()) {
- SelectPrimaryVBase(Base, FirstPrimary, IndirectPrimary);
+ SelectPrimaryVBase(Base, FirstPrimary);
if (PrimaryBase)
return;
continue;
@@ -108,7 +109,7 @@
if (IsNearlyEmpty(Base)) {
if (FirstPrimary==0)
FirstPrimary = Base;
- if (!IndirectPrimary.count(Base)) {
+ if (!IndirectPrimaryBases.count(Base)) {
setPrimaryBase(Base, true);
return;
}
@@ -118,44 +119,45 @@
/// SelectPrimaryBase - Selects the primary base for the given class and
/// record that with setPrimaryBase. We also calculate the IndirectPrimaries.
-void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD,
- llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary) {
- // We compute all the primary virtual bases for all of our direct and
+void ASTRecordLayoutBuilder::SelectPrimaryBase(const CXXRecordDecl *RD) {
+ // 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;
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
e = RD->bases_end(); i != e; ++i) {
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
- SelectPrimaryForBase(Base, IndirectPrimary);
+ IdentifyPrimaryBases(Base);
}
- // The primary base is the first non-virtual indirect or direct base class,
- // if one exists.
+ // If the record has a dynamic base class, attempt to choose a primary base
+ // class. It is the first (in direct base class order) non-virtual dynamic
+ // base class, if one exists.
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());
if (Base->isDynamicClass()) {
+ // We found it.
setPrimaryBase(Base, false);
return;
}
}
}
- setPrimaryBase(0, false);
-
// Otherwise, it is the first nearly empty virtual base that is not an
// 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.
- if (RD->getNumVBases() == 0)
+ if (RD->getNumVBases() == 0) {
+ setPrimaryBase(0, false);
return;
-
+ }
+
// Then we can search for the first nearly empty virtual base itself.
- SelectPrimaryVBase(RD, FirstPrimary, IndirectPrimary);
+ const CXXRecordDecl *FirstPrimary = 0;
+ SelectPrimaryVBase(RD, FirstPrimary);
// Otherwise if is the first nearly empty virtual base, if one exists,
// otherwise there is no primary base class.
@@ -278,16 +280,14 @@
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
UpdateAlignment(AA->getAlignment());
- llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimary;
-
// If this is a C++ class, lay out the vtable and the non-virtual bases.
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
if (RD) {
- LayoutVtable(RD, IndirectPrimary);
+ LayoutVtable(RD);
// PrimaryBase goes first.
if (PrimaryBase) {
if (PrimaryBaseWasVirtual)
- IndirectPrimary.insert(PrimaryBase);
+ IndirectPrimaryBases.insert(PrimaryBase);
LayoutBaseNonVirtually(PrimaryBase, PrimaryBaseWasVirtual);
}
LayoutNonVirtualBases(RD);
@@ -300,7 +300,7 @@
if (RD) {
llvm::SmallSet<const CXXRecordDecl*, 32> mark;
- LayoutVirtualBases(RD, PrimaryBase, 0, mark, IndirectPrimary);
+ LayoutVirtualBases(RD, PrimaryBase, 0, mark, IndirectPrimaryBases);
}
// Finally, round the size of the total struct up to the alignment of the
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=82513&r1=82512&r2=82513&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Mon Sep 21 22:02:06 2009
@@ -43,9 +43,16 @@
typedef llvm::SmallVector<std::pair<const CXXRecordDecl *,
uint64_t>, 4> BaseOffsetsTy;
+ /// Bases - base classes and their offsets from the record.
BaseOffsetsTy Bases;
+
+ // VBases - virtual base classes and ehtir offsets from the record.
BaseOffsetsTy VBases;
+ /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
+ /// primary base classes for some other direct or indirect base class.
+ llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases;
+
ASTRecordLayoutBuilder(ASTContext &Ctx);
void Layout(const RecordDecl *D);
@@ -56,20 +63,23 @@
void LayoutFields(const RecordDecl *D);
void LayoutField(const FieldDecl *D);
- void SelectPrimaryBase(const CXXRecordDecl *RD,
- llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
+ void SelectPrimaryBase(const CXXRecordDecl *RD);
void SelectPrimaryVBase(const CXXRecordDecl *RD,
- const CXXRecordDecl *&FirstPrimary,
- llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
- void SelectPrimaryForBase(const CXXRecordDecl *RD,
- llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
+ const CXXRecordDecl *&FirstPrimary);
+
+ /// IdentifyPrimaryBases - Identify all virtual base classes, direct or
+ /// indirect, that are primary base classes for some other direct or indirect
+ /// base class.
+ void IdentifyPrimaryBases(const CXXRecordDecl *RD);
+
void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) {
PrimaryBase = PB;
PrimaryBaseWasVirtual = Virtual;
}
- bool IsNearlyEmpty(const CXXRecordDecl *RD);
- void LayoutVtable(const CXXRecordDecl *RD,
- llvm::SmallSet<const CXXRecordDecl*, 32> &IndirectPrimary);
+
+ bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
+
+ void LayoutVtable(const CXXRecordDecl *RD);
void LayoutNonVirtualBases(const CXXRecordDecl *RD);
void LayoutBaseNonVirtually(const CXXRecordDecl *RD, bool IsVBase);
void LayoutVirtualBase(const CXXRecordDecl *RD);
More information about the cfe-commits
mailing list