summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-05-08 23:06:26 +0000
committerAnders Carlsson <andersca@mac.com>2010-05-08 23:06:26 +0000
commit15837f8f639cb41e8b8412e3fa9cd3920fbdb849 (patch)
treef812158e65866a7aac9603c00c4a24da0364c1fd /clang/lib
parent14f232ea2062aa9ec9c3279c092dee4649be81cb (diff)
downloadbcm5719-llvm-15837f8f639cb41e8b8412e3fa9cd3920fbdb849.tar.gz
bcm5719-llvm-15837f8f639cb41e8b8412e3fa9cd3920fbdb849.zip
Actually compute the empty subobject sizes. No functionality change yet.
llvm-svn: 103363
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp58
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.h6
2 files changed, 60 insertions, 4 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 745e68f38f1..2d4b7697355 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -24,8 +24,8 @@ using namespace clang;
ASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Context)
: Context(Context), Size(0), Alignment(8), Packed(false),
UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0), IsUnion(false),
- SizeOfLargestEmptySubobject(0), NonVirtualSize(0), NonVirtualAlignment(8),
- FirstNearlyEmptyVBase(0) { }
+ NonVirtualSize(0), NonVirtualAlignment(8), FirstNearlyEmptyVBase(0),
+ SizeOfLargestEmptySubobject(0) { }
/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but
/// no other data.
@@ -39,6 +39,56 @@ bool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const {
return false;
}
+void
+ASTRecordLayoutBuilder::ComputeEmptySubobjectSizes(const CXXRecordDecl *RD) {
+ // Check the bases.
+ for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+ E = RD->bases_end(); I != E; ++I) {
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ uint64_t EmptySize = 0;
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl);
+ if (BaseDecl->isEmpty()) {
+ // If the class decl is empty, get its size.
+ EmptySize = Layout.getSize();
+ } else {
+ // Otherwise, we get the largest empty subobject for the decl.
+ EmptySize = Layout.getSizeOfLargestEmptySubobject();
+ }
+
+ SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
+ EmptySize);
+ }
+
+ // Check the fields.
+ for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
+ I != E; ++I) {
+ const FieldDecl *FD = *I;
+
+ const RecordType *RT =
+ Context.getBaseElementType(FD->getType())->getAs<RecordType>();
+
+ // We only care about record types.
+ if (!RT)
+ continue;
+
+ uint64_t EmptySize = 0;
+ const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl());
+ const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl);
+ if (MemberDecl->isEmpty()) {
+ // If the class decl is empty, get its size.
+ EmptySize = Layout.getSize();
+ } else {
+ // Otherwise, we get the largest empty subobject for the decl.
+ EmptySize = Layout.getSizeOfLargestEmptySubobject();
+ }
+
+ SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject,
+ EmptySize);
+ }
+}
+
void ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) {
const ASTRecordLayout::PrimaryBaseInfo &BaseInfo =
Context.getASTRecordLayout(RD).getPrimaryBaseInfo();
@@ -522,8 +572,10 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
// If this is a C++ class, lay out the vtable and the non-virtual bases.
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
- if (RD)
+ if (RD) {
+ ComputeEmptySubobjectSizes(RD);
LayoutNonVirtualBases(RD);
+ }
LayoutFields(D);
diff --git a/clang/lib/AST/RecordLayoutBuilder.h b/clang/lib/AST/RecordLayoutBuilder.h
index acbee9e1dc6..f3da315ead8 100644
--- a/clang/lib/AST/RecordLayoutBuilder.h
+++ b/clang/lib/AST/RecordLayoutBuilder.h
@@ -77,7 +77,7 @@ class ASTRecordLayoutBuilder {
/// VisitedVirtualBases - A set of all the visited virtual bases, used to
/// avoid visiting virtual bases more than once.
llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
-
+
/// SizeOfLargestEmptySubobject - When laying out C++ classes, this holds the
/// size of the largest empty subobject (either a base or a member).
/// Will be zero if the record being built doesn't contain any empty classes.
@@ -99,6 +99,10 @@ class ASTRecordLayoutBuilder {
void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize);
void LayoutBitField(const FieldDecl *D);
+ /// ComputeEmptySubobjectSizes - Compute the size of the largest base or
+ /// member subobject that is empty.
+ void ComputeEmptySubobjectSizes(const CXXRecordDecl *RD);
+
/// DeterminePrimaryBase - Determine the primary base of the given class.
void DeterminePrimaryBase(const CXXRecordDecl *RD);
OpenPOWER on IntegriCloud