aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-04-23 02:15:47 +0000
committerAnders Carlsson <andersca@mac.com>2010-04-23 02:15:47 +0000
commitddfb75f22d89c773ade4fa0df1e3a99d8b125d40 (patch)
treebbdb5a5d71994406c01586f75858bd52a0acbc7b
parent4074eefc4c2dc0c554f2e79f7114b309053f9885 (diff)
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
-rw-r--r--lib/Sema/SemaDeclCXX.cpp101
-rw-r--r--test/SemaCXX/illegal-member-initialization.cpp2
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<Expr>(),
+ 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<RecordType>()) {
- 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<Expr>(),
- 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}}
};