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) {
= 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;
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());
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();
} 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;
}
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;
continue;
CXXBaseOrMemberInitializer *Member;
- if (BuildImplicitMemberInitializer(*this, Constructor, *Field, Member)) {
+ if (BuildImplicitMemberInitializer(*this, Constructor, ImplicitInitKind,
+ *Field, Member)) {
HadError = true;
continue;
}