From 08ae369fbe870cfb5077fbd1c652836b8dbeab8b Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sat, 4 Feb 2012 21:27:33 +0000 Subject: [PATCH] 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 --- lib/Sema/SemaInit.cpp | 49 ++++++++++++++++++++++++++----------------- 1 file 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(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(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(DestRecordType->getDecl()); - if (FromInitList && - TryListConstructionSpecialCases(S, Args, NumArgs, DestRecordDecl, - DestType, Sequence)) + if (InitListSyntax && + TryListConstructionSpecialCases(S, cast(Args[0]), + DestRecordDecl, DestType, Sequence)) return; + if (InitListSyntax) { + // Time to unwrap the init list. + InitListExpr *ILE = cast(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; } -- 2.40.0