aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2012-02-04 21:27:33 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2012-02-04 21:27:33 +0000
commit08ae369fbe870cfb5077fbd1c652836b8dbeab8b (patch)
tree90e0335c42cae13b03bd8feaa2993610310c350c /lib/Sema/SemaInit.cpp
parenta4e6453d42ab0c0d74c9b6e586bceaea25107662 (diff)
Don't unwrap initializer lists before calling TryConstructorInitialization, instead doing a little more work inside. This should make finding initializer list constructors easier, as well as fix one place where the ({}) vs {} issue was probably poorly handled.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149790 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r--lib/Sema/SemaInit.cpp49
1 files changed, 30 insertions, 19 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index b8892b5e97..6cbc09eeaf 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -2692,7 +2692,7 @@ static void MaybeProduceObjCObject(Sema &S,
///
/// \return True if this was a special case, false otherwise.
static bool TryListConstructionSpecialCases(Sema &S,
- Expr **Args, unsigned NumArgs,
+ InitListExpr *List,
CXXRecordDecl *DestRecordDecl,
QualType DestType,
InitializationSequence &Sequence) {
@@ -2700,7 +2700,7 @@ static bool TryListConstructionSpecialCases(Sema &S,
// List-initialization of an object of type T is defined as follows:
// - If the initializer list has no elements and T is a class type with
// a default constructor, the object is value-initialized.
- if (NumArgs == 0) {
+ if (List->getNumInits() == 0) {
if (CXXConstructorDecl *DefaultConstructor =
S.LookupDefaultConstructor(DestRecordDecl)) {
if (DefaultConstructor->isDeleted() ||
@@ -2713,11 +2713,11 @@ static bool TryListConstructionSpecialCases(Sema &S,
dyn_cast<FunctionTemplateDecl>(DefaultConstructor))
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
/*ExplicitArgs*/ 0,
- Args, NumArgs, CandidateSet,
+ 0, 0, CandidateSet,
/*SuppressUserConversions*/ false);
else
S.AddOverloadCandidate(DefaultConstructor, FoundDecl,
- Args, NumArgs, CandidateSet,
+ 0, 0, CandidateSet,
/*SuppressUserConversions*/ false);
Sequence.SetOverloadFailure(
InitializationSequence::FK_ListConstructorOverloadFailed,
@@ -2740,13 +2740,14 @@ static bool TryListConstructionSpecialCases(Sema &S,
// later.
InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary(
S.Context.getConstantArrayType(E,
- llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),NumArgs),
+ llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()),
+ List->getNumInits()),
ArrayType::Normal, 0));
InitializedEntity Element = InitializedEntity::InitializeElement(S.Context,
0, HiddenArray);
- for (unsigned i = 0; i < NumArgs; ++i) {
+ for (unsigned i = 0, n = List->getNumInits(); i < n; ++i) {
Element.setElementIndex(i);
- if (!S.CanPerformCopyInitialization(Element, Args[i])) {
+ if (!S.CanPerformCopyInitialization(Element, List->getInit(i))) {
Sequence.SetFailed(
InitializationSequence::FK_InitListElementCopyFailure);
return true;
@@ -2763,7 +2764,7 @@ static bool TryListConstructionSpecialCases(Sema &S,
/// \brief Attempt initialization by constructor (C++ [dcl.init]), which
/// enumerates the constructors of the initialized entity and performs overload
/// resolution to select the best.
-/// If FromInitList is true, this is list-initialization of a non-aggregate
+/// If InitListSyntax is true, this is list-initialization of a non-aggregate
/// class type.
static void TryConstructorInitialization(Sema &S,
const InitializedEntity &Entity,
@@ -2771,7 +2772,10 @@ static void TryConstructorInitialization(Sema &S,
Expr **Args, unsigned NumArgs,
QualType DestType,
InitializationSequence &Sequence,
- bool FromInitList = false) {
+ bool InitListSyntax = false) {
+ assert((!InitListSyntax || (NumArgs == 1 && isa<InitListExpr>(Args[0]))) &&
+ "InitListSyntax must come with a single initializer list argument.");
+
// Check constructor arguments for self reference.
if (DeclaratorDecl *DD = Entity.getDecl())
// Parameters arguments are occassionially constructed with itself,
@@ -2801,11 +2805,18 @@ static void TryConstructorInitialization(Sema &S,
CXXRecordDecl *DestRecordDecl
= cast<CXXRecordDecl>(DestRecordType->getDecl());
- if (FromInitList &&
- TryListConstructionSpecialCases(S, Args, NumArgs, DestRecordDecl,
- DestType, Sequence))
+ if (InitListSyntax &&
+ TryListConstructionSpecialCases(S, cast<InitListExpr>(Args[0]),
+ DestRecordDecl, DestType, Sequence))
return;
+ if (InitListSyntax) {
+ // Time to unwrap the init list.
+ InitListExpr *ILE = cast<InitListExpr>(Args[0]);
+ Args = ILE->getInits();
+ NumArgs = ILE->getNumInits();
+ }
+
// - Otherwise, if T is a class type, constructors are considered. The
// applicable constructors are enumerated, and the best one is chosen
// through overload resolution.
@@ -2853,7 +2864,7 @@ static void TryConstructorInitialization(Sema &S,
OverloadCandidateSet::iterator Best;
if (OverloadingResult Result
= CandidateSet.BestViableFunction(S, DeclLoc, Best)) {
- Sequence.SetOverloadFailure(FromInitList ?
+ Sequence.SetOverloadFailure(InitListSyntax ?
InitializationSequence::FK_ListConstructorOverloadFailed :
InitializationSequence::FK_ConstructorOverloadFailed,
Result);
@@ -2878,7 +2889,7 @@ static void TryConstructorInitialization(Sema &S,
Sequence.AddConstructorInitializationStep(CtorDecl,
Best->FoundDecl.getAccess(),
DestType, HadMultipleCandidates,
- FromInitList);
+ InitListSyntax);
}
static bool
@@ -3009,11 +3020,11 @@ static void TryListInitialization(Sema &S,
return;
}
if (DestType->isRecordType() && !DestType->isAggregateType()) {
- if (S.getLangOptions().CPlusPlus0x)
- TryConstructorInitialization(S, Entity, Kind, InitList->getInits(),
- InitList->getNumInits(), DestType, Sequence,
- /*FromInitList=*/true);
- else
+ if (S.getLangOptions().CPlusPlus0x) {
+ Expr *Arg = InitList;
+ TryConstructorInitialization(S, Entity, Kind, &Arg, 1, DestType,
+ Sequence, /*InitListSyntax=*/true);
+ } else
Sequence.SetFailed(InitializationSequence::FK_InitListBadDestinationType);
return;
}