From ddfb75f22d89c773ade4fa0df1e3a99d8b125d40 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 23 Apr 2010 02:15:47 +0000 Subject: [PATCH] Factor code to initialize an implicit member out into a separate function. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102162 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDeclCXX.cpp | 101 +++++++++++------- .../SemaCXX/illegal-member-initialization.cpp | 2 +- 2 files changed, 63 insertions(+), 40 deletions(-) diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 3bdc71add6..235c2cb8cb 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1432,8 +1432,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, } static bool -BuildImplicitBaseInitializer(Sema &SemaRef, - const CXXConstructorDecl *Constructor, +BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, CXXBaseSpecifier *BaseSpec, bool IsInheritedVirtualBase, CXXBaseOrMemberInitializer *&CXXBaseInit) { @@ -1465,6 +1464,60 @@ BuildImplicitBaseInitializer(Sema &SemaRef, return false; } +static bool +BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, + FieldDecl *Field, + CXXBaseOrMemberInitializer *&CXXMemberInit) { + QualType FieldBaseElementType = + SemaRef.Context.getBaseElementType(Field->getType()); + + if (FieldBaseElementType->isReferenceType()) { + SemaRef.Diag(Constructor->getLocation(), + diag::err_uninitialized_member_in_ctor) + << (int)Constructor->isImplicit() + << SemaRef.Context.getTagDeclType(Constructor->getParent()) + << 0 << Field->getDeclName(); + SemaRef.Diag(Field->getLocation(), diag::note_declared_at); + return true; + } + + if (FieldBaseElementType.isConstQualified()) { + SemaRef.Diag(Constructor->getLocation(), + diag::err_uninitialized_member_in_ctor) + << (int)Constructor->isImplicit() + << SemaRef.Context.getTagDeclType(Constructor->getParent()) + << 1 << Field->getDeclName(); + SemaRef.Diag(Field->getLocation(), diag::note_declared_at); + return true; + } + + if (FieldBaseElementType->isRecordType()) { + InitializedEntity InitEntity = InitializedEntity::InitializeMember(Field); + InitializationKind InitKind + = InitializationKind::CreateDefault(Constructor->getLocation()); + + InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0); + Sema::OwningExprResult MemberInit = + InitSeq.Perform(SemaRef, InitEntity, InitKind, + Sema::MultiExprArg(SemaRef, 0, 0)); + MemberInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(MemberInit)); + if (MemberInit.isInvalid()) + return true; + + CXXMemberInit = + new (SemaRef.Context) CXXBaseOrMemberInitializer(SemaRef.Context, + Field, SourceLocation(), + SourceLocation(), + MemberInit.takeAs(), + SourceLocation()); + return false; + } + + // Nothing to initialize. + CXXMemberInit = 0; + return false; +} + bool Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor, CXXBaseOrMemberInitializer **Initializers, @@ -1585,45 +1638,15 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor, if (AnyErrors) continue; - QualType FT = Context.getBaseElementType((*Field)->getType()); - if (FT->getAs()) { - InitializedEntity InitEntity - = InitializedEntity::InitializeMember(*Field); - InitializationKind InitKind - = InitializationKind::CreateDefault(Constructor->getLocation()); - - InitializationSequence InitSeq(*this, InitEntity, InitKind, 0, 0); - OwningExprResult MemberInit = InitSeq.Perform(*this, InitEntity, InitKind, - MultiExprArg(*this, 0, 0)); - MemberInit = MaybeCreateCXXExprWithTemporaries(move(MemberInit)); - if (MemberInit.isInvalid()) { - HadError = true; - continue; - } - - CXXBaseOrMemberInitializer *Member = - new (Context) CXXBaseOrMemberInitializer(Context, - *Field, SourceLocation(), - SourceLocation(), - MemberInit.takeAs(), - SourceLocation()); - - AllToInit.push_back(Member); - } - else if (FT->isReferenceType()) { - Diag(Constructor->getLocation(), diag::err_uninitialized_member_in_ctor) - << (int)Constructor->isImplicit() << Context.getTagDeclType(ClassDecl) - << 0 << (*Field)->getDeclName(); - Diag((*Field)->getLocation(), diag::note_declared_at); - HadError = true; - } - else if (FT.isConstQualified()) { - Diag(Constructor->getLocation(), diag::err_uninitialized_member_in_ctor) - << (int)Constructor->isImplicit() << Context.getTagDeclType(ClassDecl) - << 1 << (*Field)->getDeclName(); - Diag((*Field)->getLocation(), diag::note_declared_at); + CXXBaseOrMemberInitializer *Member; + if (BuildImplicitMemberInitializer(*this, Constructor, *Field, Member)) { HadError = true; + continue; } + + // If the member doesn't need to be initialized, it will be null. + if (Member) + AllToInit.push_back(Member); } NumInitializers = AllToInit.size(); diff --git a/test/SemaCXX/illegal-member-initialization.cpp b/test/SemaCXX/illegal-member-initialization.cpp index 3fb0b93fc4..775f65194d 100644 --- a/test/SemaCXX/illegal-member-initialization.cpp +++ b/test/SemaCXX/illegal-member-initialization.cpp @@ -17,7 +17,7 @@ struct X { int &value; // expected-note{{declared at}} const int cvalue; // expected-note{{declared at}} B& b; // expected-note{{declared at}} - const B cb; // expected-note{{declared here}} + const B cb; // expected-note{{declared at}} }; -- 2.40.0