[cfe-commits] r90018 - in /cfe/trunk: include/clang/AST/RecordLayout.h lib/AST/RecordLayoutBuilder.cpp lib/AST/RecordLayoutBuilder.h
Anders Carlsson
andersca at mac.com
Fri Nov 27 14:05:05 PST 2009
Author: andersca
Date: Fri Nov 27 16:05:05 2009
New Revision: 90018
URL: http://llvm.org/viewvc/llvm-project?rev=90018&view=rev
Log:
Add a new PrimaryBaseInfo struct that combines the record decl of a primary base with whether it's virtual or not.
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=90018&r1=90017&r2=90018&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Fri Nov 27 16:05:05 2009
@@ -47,6 +47,23 @@
// FieldCount - Number of fields.
unsigned FieldCount;
+public:
+ /// PrimaryBaseInfo - Contains info about a primary base.
+ struct PrimaryBaseInfo {
+ PrimaryBaseInfo() : Base(0), IsVirtual(false) {}
+
+ PrimaryBaseInfo(const CXXRecordDecl *Base, bool IsVirtual)
+ : Base(Base), IsVirtual(IsVirtual) {}
+
+ /// Base - The primary base.
+ const CXXRecordDecl *Base;
+
+ /// IsVirtual - Whether the primary base is virtual or not.
+ bool IsVirtual;
+ };
+
+private:
+ /// CXXRecordLayoutInfo - Contains C++ specific layout information.
struct CXXRecordLayoutInfo {
/// NonVirtualSize - The non-virtual size (in bits) of an object, which is
/// the size of the object without virtual bases.
@@ -56,11 +73,9 @@
/// which is the alignment of the object without virtual bases.
uint64_t NonVirtualAlign;
- /// PrimaryBase - The primary base for our vtable.
- const CXXRecordDecl *PrimaryBase;
- /// PrimaryBase - Wether or not the primary base was a virtual base.
- bool PrimaryBaseWasVirtual;
-
+ /// PrimaryBase - The primary base info for this record.
+ PrimaryBaseInfo PrimaryBase;
+
/// BaseOffsets - Contains a map from base classes to their offset.
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsets;
@@ -92,7 +107,7 @@
ASTRecordLayout(uint64_t size, unsigned alignment, uint64_t datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
uint64_t nonvirtualsize, unsigned nonvirtualalign,
- const CXXRecordDecl *PB, bool PBVirtual,
+ const PrimaryBaseInfo &PrimaryBase,
const std::pair<const CXXRecordDecl *, uint64_t> *bases,
unsigned numbases,
const std::pair<const CXXRecordDecl *, uint64_t> *vbases,
@@ -105,8 +120,7 @@
FieldOffsets[i] = fieldoffsets[i];
}
- CXXInfo->PrimaryBase = PB;
- CXXInfo->PrimaryBaseWasVirtual = PBVirtual;
+ CXXInfo->PrimaryBase = PrimaryBase;
CXXInfo->NonVirtualSize = nonvirtualsize;
CXXInfo->NonVirtualAlign = nonvirtualalign;
for (unsigned i = 0; i != numbases; ++i)
@@ -162,17 +176,21 @@
return CXXInfo->NonVirtualAlign;
}
- /// getPrimaryBase - Get the primary base.
- const CXXRecordDecl *getPrimaryBase() const {
+ /// getPrimaryBaseInfo - Get the primary base info.
+ const PrimaryBaseInfo &getPrimaryBaseInfo() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->PrimaryBase;
}
- /// getPrimaryBaseWasVirtual - Indicates if the primary base was virtual.
- bool getPrimaryBaseWasVirtual() const {
- assert(CXXInfo && "Record layout does not have C++ specific info!");
- return CXXInfo->PrimaryBaseWasVirtual;
+ // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+ const CXXRecordDecl *getPrimaryBase() const {
+ return getPrimaryBaseInfo().Base;
+ }
+
+ // FIXME: Migrate off of this function and use getPrimaryBaseInfo directly.
+ bool getPrimaryBaseWasVirtual() const {
+ return getPrimaryBaseInfo().IsVirtual;
}
/// getBaseClassOffset - Get the offset, in bits, for the given base class.
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=90018&r1=90017&r2=90018&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Fri Nov 27 16:05:05 2009
@@ -14,7 +14,6 @@
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/RecordLayout.h"
#include "clang/Basic/TargetInfo.h"
#include <llvm/ADT/SmallSet.h>
#include <llvm/Support/MathExtras.h>
@@ -24,7 +23,7 @@
ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx)
: Ctx(Ctx), Size(0), Alignment(8), Packed(false), UnfilledBitsInLastByte(0),
MaxFieldAlignment(0), DataSize(0), IsUnion(false), NonVirtualSize(0),
- NonVirtualAlignment(8), PrimaryBase(0), PrimaryBaseWasVirtual(false) {}
+ NonVirtualAlignment(8) { }
/// LayoutVtable - Lay out the vtable and set PrimaryBase.
void ASTRecordLayoutBuilder::LayoutVtable(const CXXRecordDecl *RD) {
@@ -34,7 +33,7 @@
}
SelectPrimaryBase(RD);
- if (PrimaryBase == 0) {
+ if (!PrimaryBase.Base) {
int AS = 0;
UpdateAlignment(Ctx.Target.getPointerAlign(AS));
Size += Ctx.Target.getPointerWidth(AS);
@@ -52,7 +51,7 @@
const CXXRecordDecl *Base =
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
// Skip the PrimaryBase here, as it is laid down first.
- if (Base != PrimaryBase || PrimaryBaseWasVirtual)
+ if (Base != PrimaryBase.Base || PrimaryBase.IsVirtual)
LayoutBaseNonVirtually(Base, false);
}
}
@@ -74,12 +73,13 @@
}
void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
- const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
+ const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
+ Ctx.getASTRecordLayout(RD).getPrimaryBaseInfo();
// 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());
+ if (BaseInfo.IsVirtual)
+ IndirectPrimaryBases.insert(BaseInfo.Base);
// Now traverse all bases and find primary bases for them.
for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
@@ -107,7 +107,7 @@
cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
if (!i->isVirtual()) {
SelectPrimaryVBase(Base, FirstPrimary);
- if (PrimaryBase)
+ if (PrimaryBase.Base)
return;
continue;
}
@@ -115,7 +115,7 @@
if (FirstPrimary==0)
FirstPrimary = Base;
if (!IndirectPrimaryBases.count(Base)) {
- setPrimaryBase(Base, true);
+ setPrimaryBase(Base, /*IsVirtual=*/true);
return;
}
}
@@ -141,14 +141,17 @@
// 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;
- }
+ // Ignore virtual bases.
+ if (i->isVirtual())
+ continue;
+
+ const CXXRecordDecl *Base =
+ cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
+
+ if (Base->isDynamicClass()) {
+ // We found it.
+ PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false);
+ return;
}
}
@@ -166,8 +169,8 @@
// Otherwise if is the first nearly empty virtual base, if one exists,
// otherwise there is no primary base class.
- if (!PrimaryBase)
- setPrimaryBase(FirstPrimary, true);
+ if (!PrimaryBase.Base)
+ setPrimaryBase(FirstPrimary, /*IsVirtual=*/true);
}
void ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
@@ -232,9 +235,10 @@
}
if (Base->getNumVBases()) {
- const ASTRecordLayout &L = Ctx.getASTRecordLayout(Base);
- const CXXRecordDecl *PB = L.getPrimaryBase();
- LayoutVirtualBases(Class, Base, PB, BaseOffset, mark, IndirectPrimary);
+ const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Base);
+ const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBaseInfo().Base;
+ LayoutVirtualBases(Class, Base, PrimaryBase, BaseOffset, mark,
+ IndirectPrimary);
}
}
}
@@ -455,10 +459,10 @@
if (RD) {
LayoutVtable(RD);
// PrimaryBase goes first.
- if (PrimaryBase) {
- if (PrimaryBaseWasVirtual)
- IndirectPrimaryBases.insert(PrimaryBase);
- LayoutBaseNonVirtually(PrimaryBase, PrimaryBaseWasVirtual);
+ if (PrimaryBase.Base) {
+ if (PrimaryBase.IsVirtual)
+ IndirectPrimaryBases.insert(PrimaryBase.Base);
+ LayoutBaseNonVirtually(PrimaryBase.Base, PrimaryBase.IsVirtual);
}
LayoutNonVirtualBases(RD);
}
@@ -470,7 +474,7 @@
if (RD) {
llvm::SmallSet<const CXXRecordDecl*, 32> mark;
- LayoutVirtualBases(RD, RD, PrimaryBase, 0, mark, IndirectPrimaryBases);
+ LayoutVirtualBases(RD, RD, PrimaryBase.Base, 0, mark, IndirectPrimaryBases);
}
// Finally, round the size of the total struct up to the alignment of the
@@ -687,7 +691,6 @@
NonVirtualSize,
Builder.NonVirtualAlignment,
Builder.PrimaryBase,
- Builder.PrimaryBaseWasVirtual,
Builder.Bases.data(),
Builder.Bases.size(),
Builder.VBases.data(),
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.h?rev=90018&r1=90017&r2=90018&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.h (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.h Fri Nov 27 16:05:05 2009
@@ -10,6 +10,7 @@
#ifndef LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
#define LLVM_CLANG_AST_RECORDLAYOUTBUILDER_H
+#include "clang/AST/RecordLayout.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/System/DataTypes.h"
@@ -54,8 +55,8 @@
uint64_t NonVirtualSize;
unsigned NonVirtualAlignment;
- const CXXRecordDecl *PrimaryBase;
- bool PrimaryBaseWasVirtual;
+
+ ASTRecordLayout::PrimaryBaseInfo PrimaryBase;
typedef llvm::SmallVector<std::pair<const CXXRecordDecl *,
uint64_t>, 4> BaseOffsetsTy;
@@ -94,9 +95,8 @@
/// base class.
void IdentifyPrimaryBases(const CXXRecordDecl *RD);
- void setPrimaryBase(const CXXRecordDecl *PB, bool Virtual) {
- PrimaryBase = PB;
- PrimaryBaseWasVirtual = Virtual;
+ void setPrimaryBase(const CXXRecordDecl *Base, bool IsVirtual) {
+ PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, IsVirtual);
}
bool IsNearlyEmpty(const CXXRecordDecl *RD) const;
More information about the cfe-commits
mailing list