summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-06-08 16:20:35 +0000
committerAnders Carlsson <andersca@mac.com>2010-06-08 16:20:35 +0000
commit45c1d2898e9215cd022b483c079b6723523e5357 (patch)
tree3c1defb67ff279ddf531b2bf8793259d3bbd21f5 /clang/lib
parentefac7f5e909e7c1a5867f90cb48bd92a12cab448 (diff)
downloadbcm5719-llvm-45c1d2898e9215cd022b483c079b6723523e5357.tar.gz
bcm5719-llvm-45c1d2898e9215cd022b483c079b6723523e5357.zip
When checking whether we can place a base subobject at an offset, we don't need to go past the highest offset that's known to contain an empty base subobject.
llvm-svn: 105611
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/RecordLayoutBuilder.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 704a974a88a..77b6f8a1c36 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -107,7 +107,8 @@ public:
uint64_t SizeOfLargestEmptySubobject;
EmptySubobjectMap(ASTContext &Context, const CXXRecordDecl *Class)
- : Context(Context), Class(Class), SizeOfLargestEmptySubobject(0) {
+ : Context(Context), Class(Class), MaxEmptyClassOffset(0),
+ SizeOfLargestEmptySubobject(0) {
ComputeEmptySubobjectSizes();
}
@@ -210,6 +211,11 @@ void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD,
bool
EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
uint64_t Offset) {
+ // We don't have to keep looking past the maximum offset that's known to
+ // contain an empty class.
+ if (!AnyEmptySubobjectsBeyondOffset(Offset))
+ return true;
+
if (!CanPlaceSubobjectAtOffset(Info->Class, Offset))
return false;
@@ -302,6 +308,11 @@ bool
EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD,
const CXXRecordDecl *Class,
uint64_t Offset) const {
+ // We don't have to keep looking past the maximum offset that's known to
+ // contain an empty class.
+ if (!AnyEmptySubobjectsBeyondOffset(Offset))
+ return true;
+
if (!CanPlaceSubobjectAtOffset(RD, Offset))
return false;
@@ -338,6 +349,11 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD,
bool EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD,
uint64_t Offset) const {
+ // We don't have to keep looking past the maximum offset that's known to
+ // contain an empty class.
+ if (!AnyEmptySubobjectsBeyondOffset(Offset))
+ return true;
+
QualType T = FD->getType();
if (const RecordType *RT = T->getAs<RecordType>()) {
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
@@ -357,6 +373,11 @@ bool EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD,
uint64_t NumElements = Context.getConstantArrayElementCount(AT);
uint64_t ElementOffset = Offset;
for (uint64_t I = 0; I != NumElements; ++I) {
+ // We don't have to keep looking past the maximum offset that's known to
+ // contain an empty class.
+ if (!AnyEmptySubobjectsBeyondOffset(ElementOffset))
+ return true;
+
if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset))
return false;
OpenPOWER on IntegriCloud