summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-07-22 20:25:00 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-07-22 20:25:00 +0000
commitf87fbc058d7c4c889eb6aaef98bd9df68991d6f3 (patch)
treee5a769962912ca535807e861440e02cb805c8fff /clang/lib
parent1e2a04ba99034eabb18e5fa41cddac8dbb871679 (diff)
downloadbcm5719-llvm-f87fbc058d7c4c889eb6aaef98bd9df68991d6f3.tar.gz
bcm5719-llvm-f87fbc058d7c4c889eb6aaef98bd9df68991d6f3.zip
Improved on performance of the algorithm for proper ordering of
ctor's initialization of bases and fields. llvm-svn: 76776
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/DeclCXX.cpp83
1 files changed, 39 insertions, 44 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 3f5320b8f13..fa9beb0c388 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -567,74 +567,69 @@ CXXConstructorDecl::setBaseOrMemberInitializers(
// We need to build the initializer AST according to order of construction
// and not what user specified in the Initializers list.
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext());
- // FIXME. We probably don't need to use AllToInit. But it is cleaner.
llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToInit;
+ llvm::DenseMap<const void *, CXXBaseOrMemberInitializer*> AllBaseFields;
+
+ for (unsigned i = 0; i < NumInitializers; i++) {
+ CXXBaseOrMemberInitializer *Member = Initializers[i];
+ const void * Key = Member->isBaseInitializer() ?
+ reinterpret_cast<const void *>(
+ Member->getBaseClass()->getAsRecordType()) :
+ reinterpret_cast<const void *>(Member->getMember());
+ AllBaseFields[Key] = Member;
+ }
+
// Push virtual bases before others.
for (CXXRecordDecl::base_class_iterator VBase =
ClassDecl->vbases_begin(),
E = ClassDecl->vbases_end(); VBase != E; ++VBase) {
- const Type * T = VBase->getType()->getAsRecordType();
- unsigned int i = 0;
- for (i = 0; i < NumInitializers; i++) {
- CXXBaseOrMemberInitializer *Member = Initializers[i];
- if (Member->isBaseInitializer() &&
- Member->getBaseClass()->getAsRecordType() == T) {
- AllToInit.push_back(Member);
- break;
- }
- }
- if (i == NumInitializers) {
+ const void *Key = reinterpret_cast<const void *>(
+ VBase->getType()->getAsRecordType());
+ if (AllBaseFields[Key])
+ AllToInit.push_back(AllBaseFields[Key]);
+ else {
CXXBaseOrMemberInitializer *Member =
- new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
- SourceLocation());
+ new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
+ SourceLocation());
AllToInit.push_back(Member);
}
}
+
for (CXXRecordDecl::base_class_iterator Base =
ClassDecl->bases_begin(),
E = ClassDecl->bases_end(); Base != E; ++Base) {
// Virtuals are in the virtual base list and already constructed.
if (Base->isVirtual())
continue;
- const Type * T = Base->getType()->getAsRecordType();
- unsigned int i = 0;
- for (i = 0; i < NumInitializers; i++) {
- CXXBaseOrMemberInitializer *Member = Initializers[i];
- if (Member->isBaseInitializer() &&
- Member->getBaseClass()->getAsRecordType() == T) {
- AllToInit.push_back(Member);
- break;
- }
- }
- if (i == NumInitializers) {
+ const void *Key = reinterpret_cast<const void *>(
+ Base->getType()->getAsRecordType());
+ if (AllBaseFields[Key])
+ AllToInit.push_back(AllBaseFields[Key]);
+ else {
CXXBaseOrMemberInitializer *Member =
- new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
- SourceLocation());
+ new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
+ SourceLocation());
AllToInit.push_back(Member);
}
}
+
// non-static data members.
for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
E = ClassDecl->field_end(); Field != E; ++Field) {
- unsigned int i = 0;
- for (i = 0; i < NumInitializers; i++) {
- CXXBaseOrMemberInitializer *Member = Initializers[i];
- if (Member->isMemberInitializer() && Member->getMember() == (*Field)) {
- AllToInit.push_back(Member);
- break;
- }
+ const void * Key = reinterpret_cast<const void *>(*Field);
+ if (AllBaseFields[Key]) {
+ AllToInit.push_back(AllBaseFields[Key]);
+ continue;
}
- if (i == NumInitializers) {
- QualType FieldType = C.getCanonicalType((*Field)->getType());
- while (const ArrayType *AT = C.getAsArrayType(FieldType))
- FieldType = AT->getElementType();
+ QualType FieldType = C.getCanonicalType((*Field)->getType());
+ while (const ArrayType *AT = C.getAsArrayType(FieldType))
+ FieldType = AT->getElementType();
- if (FieldType->getAsRecordType()) {
- CXXBaseOrMemberInitializer *Member =
- new (C) CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation());
- AllToInit.push_back(Member);
- }
- }
+ if (FieldType->getAsRecordType()) {
+ CXXBaseOrMemberInitializer *Member =
+ new (C) CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation());
+ AllToInit.push_back(Member);
+ }
}
NumInitializers = AllToInit.size();
OpenPOWER on IntegriCloud