From 3501bcec7dfa088a1c743f9b724061cb259a4833 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 3 Sep 2009 19:36:46 +0000 Subject: Issue diagnostics in variety of situations involving reference/const data members when user has declared the constructor. This necessitated some non-minor refactoring. llvm-svn: 80934 --- clang/lib/AST/DeclCXX.cpp | 153 ---------------------------------------------- 1 file changed, 153 deletions(-) (limited to 'clang/lib/AST/DeclCXX.cpp') diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 96423104065..036752f5ca8 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -583,159 +583,6 @@ CXXDestructorDecl::computeBaseOrMembersToDestroy(ASTContext &C) { } } -void -CXXConstructorDecl::setBaseOrMemberInitializers( - ASTContext &C, - CXXBaseOrMemberInitializer **Initializers, - unsigned NumInitializers, - llvm::SmallVectorImpl& Bases, - llvm::SmallVectorImpl&Fields) { - // 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()); - llvm::SmallVector AllToInit; - llvm::DenseMap AllBaseFields; - bool HasDependentBaseInit = false; - - for (unsigned i = 0; i < NumInitializers; i++) { - CXXBaseOrMemberInitializer *Member = Initializers[i]; - if (Member->isBaseInitializer()) { - if (Member->getBaseClass()->isDependentType()) - HasDependentBaseInit = true; - AllBaseFields[Member->getBaseClass()->getAs()] = Member; - } else { - AllBaseFields[Member->getMember()] = Member; - } - } - - if (HasDependentBaseInit) { - // FIXME. This does not preserve the ordering of the initializers. - // Try (with -Wreorder) - // template struct A {}; - // template struct B : A { - // B() : x1(10), A() {} - // int x1; - // }; - // B x; - // On seeing one dependent type, we should essentially exit this routine - // while preserving user-declared initializer list. When this routine is - // called during instantiatiation process, this routine will rebuild the - // oderdered initializer list correctly. - - // If we have a dependent base initialization, we can't determine the - // association between initializers and bases; just dump the known - // initializers into the list, and don't try to deal with other bases. - for (unsigned i = 0; i < NumInitializers; i++) { - CXXBaseOrMemberInitializer *Member = Initializers[i]; - if (Member->isBaseInitializer()) - AllToInit.push_back(Member); - } - } else { - // Push virtual bases before others. - for (CXXRecordDecl::base_class_iterator VBase = - ClassDecl->vbases_begin(), - E = ClassDecl->vbases_end(); VBase != E; ++VBase) { - if (VBase->getType()->isDependentType()) - continue; - if (CXXBaseOrMemberInitializer *Value = - AllBaseFields.lookup(VBase->getType()->getAs())) - AllToInit.push_back(Value); - else { - CXXRecordDecl *VBaseDecl = - cast(VBase->getType()->getAs()->getDecl()); - assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null"); - if (!VBaseDecl->getDefaultConstructor(C)) - Bases.push_back(VBase); - CXXBaseOrMemberInitializer *Member = - new (C) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0, - VBaseDecl->getDefaultConstructor(C), - SourceLocation(), - 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; - // Skip dependent types. - if (Base->getType()->isDependentType()) - continue; - if (CXXBaseOrMemberInitializer *Value = - AllBaseFields.lookup(Base->getType()->getAs())) - AllToInit.push_back(Value); - else { - CXXRecordDecl *BaseDecl = - cast(Base->getType()->getAs()->getDecl()); - assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null"); - if (!BaseDecl->getDefaultConstructor(C)) - Bases.push_back(Base); - CXXBaseOrMemberInitializer *Member = - new (C) CXXBaseOrMemberInitializer(Base->getType(), 0, 0, - BaseDecl->getDefaultConstructor(C), - SourceLocation(), - SourceLocation()); - AllToInit.push_back(Member); - } - } - } - - // non-static data members. - for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), - E = ClassDecl->field_end(); Field != E; ++Field) { - if ((*Field)->isAnonymousStructOrUnion()) { - if (const RecordType *FieldClassType = - Field->getType()->getAs()) { - CXXRecordDecl *FieldClassDecl - = cast(FieldClassType->getDecl()); - for(RecordDecl::field_iterator FA = FieldClassDecl->field_begin(), - EA = FieldClassDecl->field_end(); FA != EA; FA++) { - if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*FA)) { - // 'Member' is the anonymous union field and 'AnonUnionMember' is - // set to the anonymous union data member used in the initializer - // list. - Value->setMember(*Field); - Value->setAnonUnionMember(*FA); - AllToInit.push_back(Value); - break; - } - } - } - continue; - } - if (CXXBaseOrMemberInitializer *Value = AllBaseFields.lookup(*Field)) { - AllToInit.push_back(Value); - continue; - } - - QualType FT = C.getBaseElementType((*Field)->getType()); - if (const RecordType* RT = FT->getAs()) { - CXXConstructorDecl *Ctor = - cast(RT->getDecl())->getDefaultConstructor(C); - if (!Ctor && !FT->isDependentType()) - Fields.push_back(*Field); - CXXBaseOrMemberInitializer *Member = - new (C) CXXBaseOrMemberInitializer((*Field), 0, 0, - Ctor, - SourceLocation(), - SourceLocation()); - AllToInit.push_back(Member); - } - } - - NumInitializers = AllToInit.size(); - if (NumInitializers > 0) { - NumBaseOrMemberInitializers = NumInitializers; - BaseOrMemberInitializers = - new (C) CXXBaseOrMemberInitializer*[NumInitializers]; - for (unsigned Idx = 0; Idx < NumInitializers; ++Idx) - BaseOrMemberInitializers[Idx] = AllToInit[Idx]; - } -} - void CXXConstructorDecl::Destroy(ASTContext& C) { C.Deallocate(BaseOrMemberInitializers); -- cgit v1.2.3