aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-04-23 03:10:23 +0000
committerAnders Carlsson <andersca@mac.com>2010-04-23 03:10:23 +0000
commite5ef740266891d8f68f35c8365b3142608f36a5f (patch)
treea0c1ab734ef65328935e76968fa356b4cfae881b
parent114a297ef02a722b3afcd719210c060811d431e0 (diff)
Add an ImplicitInitializerKind enum and pass it to BuildImplicitBaseInitializer and BuildImplicitMemberInitializer.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102166 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp73
1 files changed, 62 insertions, 11 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 98f74aeccd..26b55548b7 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1431,8 +1431,17 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
RParenLoc);
}
+/// ImplicitInitializerKind - How an implicit base or member initializer should
+/// initialize its base or member.
+enum ImplicitInitializerKind {
+ IIK_Default,
+ IIK_Copy,
+ IIK_Move
+};
+
static bool
BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
+ ImplicitInitializerKind ImplicitInitKind,
CXXBaseSpecifier *BaseSpec,
bool IsInheritedVirtualBase,
CXXBaseOrMemberInitializer *&CXXBaseInit) {
@@ -1440,14 +1449,41 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
= InitializedEntity::InitializeBase(SemaRef.Context, BaseSpec,
IsInheritedVirtualBase);
- InitializationKind InitKind
- = InitializationKind::CreateDefault(Constructor->getLocation());
+ Sema::OwningExprResult BaseInit(SemaRef);
+
+ switch (ImplicitInitKind) {
+ case IIK_Default: {
+ InitializationKind InitKind
+ = InitializationKind::CreateDefault(Constructor->getLocation());
+ InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
+ BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
+ Sema::MultiExprArg(SemaRef, 0, 0));
+ break;
+ }
- InitializationSequence InitSeq(SemaRef, InitEntity, InitKind, 0, 0);
- Sema::OwningExprResult BaseInit =
- InitSeq.Perform(SemaRef, InitEntity, InitKind,
- Sema::MultiExprArg(SemaRef, 0, 0));
+ case IIK_Copy: {
+ ParmVarDecl *Param = Constructor->getParamDecl(0);
+ QualType ParamType = Param->getType().getNonReferenceType();
+
+ Expr *CopyCtorArg =
+ DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param,
+ SourceLocation(), ParamType, 0);
+
+ InitializationKind InitKind
+ = InitializationKind::CreateDirect(Constructor->getLocation(),
+ SourceLocation(), SourceLocation());
+ InitializationSequence InitSeq(SemaRef, InitEntity, InitKind,
+ &CopyCtorArg, 1);
+ BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind,
+ Sema::MultiExprArg(SemaRef,
+ (void**)&CopyCtorArg, 1));
+ break;
+ }
+ case IIK_Move:
+ assert(false && "Unhandled initializer kind!");
+ }
+
BaseInit = SemaRef.MaybeCreateCXXExprWithTemporaries(move(BaseInit));
if (BaseInit.isInvalid())
return true;
@@ -1466,8 +1502,15 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
static bool
BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
+ ImplicitInitializerKind ImplicitInitKind,
FieldDecl *Field,
CXXBaseOrMemberInitializer *&CXXMemberInit) {
+ // FIXME: Handle copy initialization.
+ if (ImplicitInitKind != IIK_Default) {
+ CXXMemberInit = 0;
+ return false;
+ }
+
QualType FieldBaseElementType =
SemaRef.Context.getBaseElementType(Field->getType());
@@ -1538,6 +1581,12 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
return false;
}
+ ImplicitInitializerKind ImplicitInitKind = IIK_Default;
+
+ // FIXME: Handle implicit move constructors.
+ if (Constructor->isImplicit() && Constructor->isCopyConstructor())
+ ImplicitInitKind = IIK_Copy;
+
// We need to build the initializer AST according to order of construction
// and not what user specified in the Initializers list.
CXXRecordDecl *ClassDecl = Constructor->getParent()->getDefinition();
@@ -1575,8 +1624,9 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
} else if (!AnyErrors) {
bool IsInheritedVirtualBase = !DirectVBases.count(VBase);
CXXBaseOrMemberInitializer *CXXBaseInit;
- if (BuildImplicitBaseInitializer(*this, Constructor, VBase,
- IsInheritedVirtualBase, CXXBaseInit)) {
+ if (BuildImplicitBaseInitializer(*this, Constructor, ImplicitInitKind,
+ VBase, IsInheritedVirtualBase,
+ CXXBaseInit)) {
HadError = true;
continue;
}
@@ -1596,8 +1646,8 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
AllToInit.push_back(Value);
} else if (!AnyErrors) {
CXXBaseOrMemberInitializer *CXXBaseInit;
- if (BuildImplicitBaseInitializer(*this, Constructor, Base,
- /*IsInheritedVirtualBase=*/false,
+ if (BuildImplicitBaseInitializer(*this, Constructor, ImplicitInitKind,
+ Base, /*IsInheritedVirtualBase=*/false,
CXXBaseInit)) {
HadError = true;
continue;
@@ -1639,7 +1689,8 @@ Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
continue;
CXXBaseOrMemberInitializer *Member;
- if (BuildImplicitMemberInitializer(*this, Constructor, *Field, Member)) {
+ if (BuildImplicitMemberInitializer(*this, Constructor, ImplicitInitKind,
+ *Field, Member)) {
HadError = true;
continue;
}