bool Elidable : 1;
bool HadMultipleCandidates : 1;
bool ListInitialization : 1;
+ bool StdInitListInitialization : 1;
bool ZeroInitialization : 1;
unsigned ConstructKind : 2;
Stmt **Args;
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
ArrayRef<Expr *> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange);
bool isListInitialization() const { return ListInitialization; }
void setListInitialization(bool V) { ListInitialization = V; }
+ /// \brief Whether this constructor call was written as list-initialization,
+ /// but was interpreted as forming a std::initializer_list<T> from the list
+ /// and passing that as a single constructor argument.
+ /// See C++11 [over.match.list]p1 bullet 1.
+ bool isStdInitListInitialization() const { return StdInitListInitialization; }
+ void setStdInitListInitialization(bool V) { StdInitListInitialization = V; }
+
/// \brief Whether this construction first requires
/// zero-initialization before the initializer is called.
bool requiresZeroInitialization() const { return ZeroInitialization; }
SourceRange ParenOrBraceRange,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
SK_ConversionSequenceNoNarrowing,
/// \brief Perform list-initialization without a constructor.
SK_ListInitialization,
- /// \brief Perform list-initialization with an initializer list constructor.
- SK_ListConstructorCall,
/// \brief Unwrap the single-element initializer list for a reference.
SK_UnwrapInitList,
/// \brief Rewrap the single-element initializer list for a reference.
SK_ProduceObjCObject,
/// \brief Construct a std::initializer_list from an initializer list.
SK_StdInitializerList,
+ /// \brief Perform initialization via a constructor taking a single
+ /// std::initializer_list argument.
+ SK_StdInitializerListConstructorCall,
/// \brief Initialize an OpenCL sampler from an integer.
SK_OCLSamplerInit,
/// \brief Passing zero to a function where OpenCL event_t is expected.
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, MultiExprArg Exprs,
bool HadMultipleCandidates, bool IsListInitialization,
+ bool IsStdInitListInitialization,
bool RequiresZeroInit, unsigned ConstructKind,
SourceRange ParenRange);
- // FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
+ // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if
// the constructor can be elidable?
ExprResult
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg Exprs, bool HadMultipleCandidates,
- bool IsListInitialization, bool RequiresZeroInit,
+ bool IsListInitialization,
+ bool IsStdInitListInitialization, bool RequiresZeroInit,
unsigned ConstructKind, SourceRange ParenRange);
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
SourceRange ParenOrBraceRange,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization)
: CXXConstructExpr(C, CXXTemporaryObjectExprClass,
Type->getType().getNonReferenceType(),
Type->getTypeLoc().getBeginLoc(),
Cons, false, Args,
HadMultipleCandidates,
- ListInitialization, ZeroInitialization,
+ ListInitialization,
+ StdInitListInitialization,
+ ZeroInitialization,
CXXConstructExpr::CK_Complete, ParenOrBraceRange),
Type(Type) {
}
ArrayRef<Expr*> Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange) {
return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Elidable, Args,
HadMultipleCandidates, ListInitialization,
+ StdInitListInitialization,
ZeroInitialization, ConstructKind,
ParenOrBraceRange);
}
ArrayRef<Expr*> args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenOrBraceRange)
NumArgs(args.size()),
Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates),
ListInitialization(ListInitialization),
+ StdInitListInitialization(StdInitListInitialization),
ZeroInitialization(ZeroInitialization),
ConstructKind(ConstructKind), Args(nullptr)
{
ConstructorArgs,
CXXConstExpr->hadMultipleCandidates(),
CXXConstExpr->isListInitialization(),
+ CXXConstExpr->isStdInitListInitialization(),
CXXConstExpr->requiresZeroInitialization(),
CXXConstExpr->getConstructionKind(),
SourceRange());
MultiExprArg ExprArgs,
bool HadMultipleCandidates,
bool IsListInitialization,
+ bool IsStdInitListInitialization,
bool RequiresZeroInit,
unsigned ConstructKind,
SourceRange ParenRange) {
return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
Elidable, ExprArgs, HadMultipleCandidates,
- IsListInitialization, RequiresZeroInit,
+ IsListInitialization,
+ IsStdInitListInitialization, RequiresZeroInit,
ConstructKind, ParenRange);
}
MultiExprArg ExprArgs,
bool HadMultipleCandidates,
bool IsListInitialization,
+ bool IsStdInitListInitialization,
bool RequiresZeroInit,
unsigned ConstructKind,
SourceRange ParenRange) {
MarkFunctionReferenced(ConstructLoc, Constructor);
return CXXConstructExpr::Create(
Context, DeclInitType, ConstructLoc, Constructor, Elidable, ExprArgs,
- HadMultipleCandidates, IsListInitialization, RequiresZeroInit,
+ HadMultipleCandidates, IsListInitialization, IsStdInitListInitialization,
+ RequiresZeroInit,
static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
ParenRange);
}
InitializedEntity::InitializeTemporary(Ty),
Constructor->getAccess());
- ExprResult Result
- = S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
- ConstructorArgs, HadMultipleCandidates,
- /*ListInit*/ false, /*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete, SourceRange());
+ ExprResult Result = S.BuildCXXConstructExpr(
+ CastLoc, Ty, cast<CXXConstructorDecl>(Method),
+ ConstructorArgs, HadMultipleCandidates,
+ /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete, SourceRange());
if (Result.isInvalid())
return ExprError();
From, /*FIXME:ConstructLoc*/SourceLocation(),
ConstructorArgs))
return ExprError();
- return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
- ToType, SCS.CopyConstructor,
- ConstructorArgs,
- /*HadMultipleCandidates*/ false,
- /*ListInit*/ false, /*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete,
- SourceRange());
+ return BuildCXXConstructExpr(
+ /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.CopyConstructor,
+ ConstructorArgs, /*HadMultipleCandidates*/ false,
+ /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete, SourceRange());
}
- return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
- ToType, SCS.CopyConstructor,
- From, /*HadMultipleCandidates*/ false,
- /*ListInit*/ false, /*ZeroInit*/ false,
- CXXConstructExpr::CK_Complete,
- SourceRange());
+ return BuildCXXConstructExpr(
+ /*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.CopyConstructor,
+ From, /*HadMultipleCandidates*/ false,
+ /*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
+ CXXConstructExpr::CK_Complete, SourceRange());
}
// Resolve overloaded function references.
case SK_QualificationConversionLValue:
case SK_LValueToRValue:
case SK_ListInitialization:
- case SK_ListConstructorCall:
case SK_UnwrapInitList:
case SK_RewrapInitList:
case SK_ConstructorInitialization:
case SK_PassByIndirectRestore:
case SK_ProduceObjCObject:
case SK_StdInitializerList:
+ case SK_StdInitializerListConstructorCall:
case SK_OCLSamplerInit:
case SK_OCLZeroEvent:
break;
bool HadMultipleCandidates,
bool FromInitList, bool AsInitList) {
Step S;
- S.Kind = FromInitList ? AsInitList ? SK_ListConstructorCall
+ S.Kind = FromInitList ? AsInitList ? SK_StdInitializerListConstructorCall
: SK_ConstructorInitializationFromList
: SK_ConstructorInitialization;
S.Type = T;
ConstructorArgs,
HadMultipleCandidates,
/*ListInit*/ false,
+ /*StdInitListInit*/ false,
/*ZeroInit*/ false,
CXXConstructExpr::CK_Complete,
SourceRange());
const InitializationSequence::Step& Step,
bool &ConstructorInitRequiresZeroInit,
bool IsListInitialization,
+ bool IsStdInitListInitialization,
SourceLocation LBraceLoc,
SourceLocation RBraceLoc) {
unsigned NumArgs = Args.size();
CurInit = new (S.Context) CXXTemporaryObjectExpr(
S.Context, Constructor, TSInfo, ConstructorArgs, ParenOrBraceRange,
HadMultipleCandidates, IsListInitialization,
- ConstructorInitRequiresZeroInit);
+ IsStdInitListInitialization, ConstructorInitRequiresZeroInit);
} else {
CXXConstructExpr::ConstructionKind ConstructKind =
CXXConstructExpr::CK_Complete;
ConstructorArgs,
HadMultipleCandidates,
IsListInitialization,
+ IsStdInitListInitialization,
ConstructorInitRequiresZeroInit,
ConstructKind,
ParenOrBraceRange);
ConstructorArgs,
HadMultipleCandidates,
IsListInitialization,
+ IsStdInitListInitialization,
ConstructorInitRequiresZeroInit,
ConstructKind,
ParenOrBraceRange);
case SK_ConstructorInitialization:
case SK_ConstructorInitializationFromList:
- case SK_ListConstructorCall:
+ case SK_StdInitializerListConstructorCall:
case SK_ZeroInitialization:
break;
}
ConstructorArgs,
HadMultipleCandidates,
/*ListInit*/ false,
+ /*StdInitListInit*/ false,
/*ZeroInit*/ false,
CXXConstructExpr::CK_Complete,
SourceRange());
Kind, Arg, *Step,
ConstructorInitRequiresZeroInit,
/*IsListInitialization*/true,
+ /*IsStdInitListInit*/false,
InitList->getLBraceLoc(),
InitList->getRBraceLoc());
break;
}
case SK_ConstructorInitialization:
- case SK_ListConstructorCall: {
+ case SK_StdInitializerListConstructorCall: {
// When an initializer list is passed for a parameter of type "reference
// to object", we don't get an EK_Temporary entity, but instead an
// EK_Parameter entity with reference type.
InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(
Entity.getType().getNonReferenceType());
bool UseTemporary = Entity.getType()->isReferenceType();
+ bool IsStdInitListInit =
+ Step->Kind == SK_StdInitializerListConstructorCall;
CurInit = PerformConstructorInitialization(
S, UseTemporary ? TempEntity : Entity, Kind, Args, *Step,
ConstructorInitRequiresZeroInit,
- /*IsListInitialization*/Step->Kind == SK_ListConstructorCall,
+ /*IsListInitialization*/IsStdInitListInit,
+ /*IsStdInitListInitialization*/IsStdInitListInit,
/*LBraceLoc*/SourceLocation(),
/*RBraceLoc*/SourceLocation());
break;
OS << "list initialization via constructor";
break;
- case SK_ListConstructorCall:
- OS << "list initialization via initializer list constructor";
- break;
-
case SK_ZeroInitialization:
OS << "zero initialization";
break;
OS << "std::initializer_list from initializer list";
break;
+ case SK_StdInitializerListConstructorCall:
+ OS << "list initialization from std::initializer_list";
+ break;
+
case SK_OCLSamplerInit:
OS << "OpenCL sampler_t from integer constant";
break;
MultiExprArg Args,
bool HadMultipleCandidates,
bool ListInitialization,
+ bool StdInitListInitialization,
bool RequiresZeroInit,
CXXConstructExpr::ConstructionKind ConstructKind,
SourceRange ParenRange) {
ConvertedArgs,
HadMultipleCandidates,
ListInitialization,
+ StdInitListInitialization,
RequiresZeroInit, ConstructKind,
ParenRange);
}
if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
return getDerived().TransformExpr(Init);
+ // If the initialization implicitly converted an initializer list to a
+ // std::initializer_list object, unwrap the std::initializer_list too.
+ if (Construct && Construct->isStdInitListInitialization())
+ return TransformInitializer(Construct->getArg(0), CXXDirectInit);
+
SmallVector<Expr*, 8> NewArgs;
bool ArgChanged = false;
if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
Args,
E->hadMultipleCandidates(),
E->isListInitialization(),
+ E->isStdInitListInitialization(),
E->requiresZeroInitialization(),
E->getConstructionKind(),
E->getParenOrBraceRange());
E->setElidable(Record[Idx++]);
E->setHadMultipleCandidates(Record[Idx++]);
E->setListInitialization(Record[Idx++]);
+ E->setStdInitListInitialization(Record[Idx++]);
E->setRequiresZeroInitialization(Record[Idx++]);
E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]);
E->ParenOrBraceRange = ReadSourceRange(Record, Idx);
Record.push_back(E->isElidable());
Record.push_back(E->hadMultipleCandidates());
Record.push_back(E->isListInitialization());
+ Record.push_back(E->isStdInitListInitialization());
Record.push_back(E->requiresZeroInitialization());
Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
Writer.AddSourceRange(E->getParenOrBraceRange(), Record);
namespace ListInitInstantiate {
struct A {
A(std::initializer_list<A>);
+ A(std::initializer_list<int>);
};
struct B : A {
B(int);
template<typename T> X<T>::X() : a{B{0}, B{1}} {}
X<int> x;
+
+ int f(const A&);
+ template<typename T> void g() { int k = f({0}); }
+ template void g<int>();
}