From: Fariborz Jahanian Date: Wed, 22 Jul 2009 20:25:00 +0000 (+0000) Subject: Improved on performance of the algorithm for proper ordering of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aa26650966e13fc462985d9b8fbe420c01edf014;p=clang Improved on performance of the algorithm for proper ordering of ctor's initialization of bases and fields. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76776 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 3f5320b8f1..fa9beb0c38 100644 --- a/lib/AST/DeclCXX.cpp +++ b/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(getDeclContext()); - // FIXME. We probably don't need to use AllToInit. But it is cleaner. llvm::SmallVector AllToInit; + llvm::DenseMap AllBaseFields; + + for (unsigned i = 0; i < NumInitializers; i++) { + CXXBaseOrMemberInitializer *Member = Initializers[i]; + const void * Key = Member->isBaseInitializer() ? + reinterpret_cast( + Member->getBaseClass()->getAsRecordType()) : + reinterpret_cast(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( + 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( + 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(*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();