diff options
author | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
commit | 39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df (patch) | |
tree | a9243275843fbeaa590afc07ee888e006b8d54ea /lib/Sema/SemaInit.cpp | |
parent | 69b4eca4a4255ba43baa5c1d9bbdec3ec17f479e (diff) | |
download | FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.zip FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.tar.gz |
Vendor import of clang trunk r126079:
http://llvm.org/svn/llvm-project/cfe/trunk@126079
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 1322 |
1 files changed, 713 insertions, 609 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index a28fd7f..b9a6a57 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -11,8 +11,6 @@ // point is Sema::CheckInitList(), but all of the work is performed // within the InitListChecker class. // -// This file also implements Sema::CheckInitializerTypes. -// //===----------------------------------------------------------------------===// #include "clang/Sema/Designator.h" @@ -122,7 +120,7 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, Sema &S) { /// responsible for moving that Index forward as it consumes elements. /// /// Each Check* routine also has a StructuredList/StructuredIndex -/// arguments, which contains the current the "structured" (semantic) +/// arguments, which contains the current "structured" (semantic) /// initializer list and the index into that initializer list where we /// are copying initializers as we map them over to the semantic /// list. Once we have completed our recursive walk of the subobject @@ -231,11 +229,11 @@ public: void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field, const InitializedEntity &ParentEntity, - InitListExpr *ILE, + InitListExpr *ILE, bool &RequiresSecondPass) { SourceLocation Loc = ILE->getSourceRange().getBegin(); unsigned NumInits = ILE->getNumInits(); - InitializedEntity MemberEntity + InitializedEntity MemberEntity = InitializedEntity::InitializeMember(Field, &ParentEntity); if (Init >= NumInits || !ILE->getInit(Init)) { // FIXME: We probably don't need to handle references @@ -254,7 +252,7 @@ void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field, hadError = true; return; } - + InitializationKind Kind = InitializationKind::CreateValue(Loc, Loc, Loc, true); InitializationSequence InitSeq(SemaRef, MemberEntity, Kind, 0, 0); @@ -263,14 +261,14 @@ void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field, hadError = true; return; } - + ExprResult MemberInit = InitSeq.Perform(SemaRef, MemberEntity, Kind, MultiExprArg()); if (MemberInit.isInvalid()) { hadError = true; return; } - + if (hadError) { // Do nothing } else if (Init < NumInits) { @@ -286,14 +284,14 @@ void InitListChecker::FillInValueInitForField(unsigned Init, FieldDecl *Field, } } else if (InitListExpr *InnerILE = dyn_cast<InitListExpr>(ILE->getInit(Init))) - FillInValueInitializations(MemberEntity, InnerILE, - RequiresSecondPass); + FillInValueInitializations(MemberEntity, InnerILE, + RequiresSecondPass); } /// Recursively replaces NULL values within the given initializer list /// with expressions that perform value-initialization of the /// appropriate type. -void +void InitListChecker::FillInValueInitializations(const InitializedEntity &Entity, InitListExpr *ILE, bool &RequiresSecondPass) { @@ -344,17 +342,17 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity, ElementType = AType->getElementType(); if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType)) NumElements = CAType->getSize().getZExtValue(); - ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context, + ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); } else if (const VectorType *VType = ILE->getType()->getAs<VectorType>()) { ElementType = VType->getElementType(); NumElements = VType->getNumElements(); - ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context, + ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); } else ElementType = ILE->getType(); - + for (unsigned Init = 0; Init != NumElements; ++Init) { if (hadError) return; @@ -409,7 +407,7 @@ InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity, unsigned newStructuredIndex = 0; FullyStructuredList = getStructuredSubobjectInit(IL, newIndex, T, 0, 0, IL->getSourceRange()); - CheckExplicitInitList(Entity, IL, T, newIndex, + CheckExplicitInitList(Entity, IL, T, newIndex, FullyStructuredList, newStructuredIndex, /*TopLevelObject=*/true); @@ -417,7 +415,7 @@ InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity, bool RequiresSecondPass = false; FillInValueInitializations(Entity, FullyStructuredList, RequiresSecondPass); if (RequiresSecondPass && !hadError) - FillInValueInitializations(Entity, FullyStructuredList, + FillInValueInitializations(Entity, FullyStructuredList, RequiresSecondPass); } } @@ -482,7 +480,7 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity, // Check the element types and build the structural subobject. unsigned StartIndex = Index; - CheckListElementTypes(Entity, ParentIList, T, + CheckListElementTypes(Entity, ParentIList, T, /*SubobjectIsDesignatorContext=*/false, Index, StructuredSubobjectInitList, StructuredSubobjectInitIndex, @@ -497,16 +495,16 @@ void InitListChecker::CheckImplicitInitList(const InitializedEntity &Entity, = ParentIList->getInit(EndIndex)->getSourceRange().getEnd(); StructuredSubobjectInitList->setRBraceLoc(EndLoc); } - + // Warn about missing braces. if (T->isArrayType() || T->isRecordType()) { SemaRef.Diag(StructuredSubobjectInitList->getLocStart(), diag::warn_missing_braces) << StructuredSubobjectInitList->getSourceRange() - << FixItHint::CreateInsertion(StructuredSubobjectInitList->getLocStart(), + << FixItHint::CreateInsertion(StructuredSubobjectInitList->getLocStart(), "{") << FixItHint::CreateInsertion(SemaRef.PP.getLocForEndOfToken( - StructuredSubobjectInitList->getLocEnd()), + StructuredSubobjectInitList->getLocEnd()), "}"); } } @@ -520,7 +518,7 @@ void InitListChecker::CheckExplicitInitList(const InitializedEntity &Entity, assert(IList->isExplicit() && "Illegal Implicit InitListExpr"); SyntacticToSemantic[IList] = StructuredList; StructuredList->setSyntacticForm(IList); - CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true, + CheckListElementTypes(Entity, IList, T, /*SubobjectIsDesignatorContext=*/true, Index, StructuredList, StructuredIndex, TopLevelObject); QualType ExprTy = T.getNonLValueExprType(SemaRef.Context); IList->setType(ExprTy); @@ -585,7 +583,7 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity, CheckScalarType(Entity, IList, DeclType, Index, StructuredList, StructuredIndex); } else if (DeclType->isVectorType()) { - CheckVectorType(Entity, IList, DeclType, Index, + CheckVectorType(Entity, IList, DeclType, Index, StructuredList, StructuredIndex); } else if (DeclType->isAggregateType()) { if (DeclType->isRecordType()) { @@ -598,7 +596,7 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity, llvm::APSInt Zero( SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()), false); - CheckArrayType(Entity, IList, DeclType, Zero, + CheckArrayType(Entity, IList, DeclType, Zero, SubobjectIsDesignatorContext, Index, StructuredList, StructuredIndex); } else @@ -658,7 +656,7 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, UpdateStructuredListElement(StructuredList, StructuredIndex, Str); ++Index; } else if (ElemType->isScalarType()) { - CheckScalarType(Entity, IList, ElemType, Index, + CheckScalarType(Entity, IList, ElemType, Index, StructuredList, StructuredIndex); } else if (ElemType->isReferenceType()) { CheckReferenceType(Entity, IList, ElemType, Index, @@ -672,17 +670,17 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, // member, the member is initialized. [...] // FIXME: Better EqualLoc? - InitializationKind Kind = + InitializationKind Kind = InitializationKind::CreateCopy(expr->getLocStart(), SourceLocation()); InitializationSequence Seq(SemaRef, Entity, Kind, &expr, 1); - + if (Seq) { - ExprResult Result = + ExprResult Result = Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1)); if (Result.isInvalid()) hadError = true; - - UpdateStructuredListElement(StructuredList, StructuredIndex, + + UpdateStructuredListElement(StructuredList, StructuredIndex, Result.takeAs<Expr>()); ++Index; return; @@ -699,7 +697,9 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, // initial value of the object, including unnamed members, is // that of the expression. if ((ElemType->isRecordType() || ElemType->isVectorType()) && - SemaRef.Context.hasSameUnqualifiedType(expr->getType(), ElemType)) { + SemaRef.CheckSingleAssignmentConstraints(ElemType, expr) + == Sema::Compatible) { + SemaRef.DefaultFunctionArrayLvalueConversion(expr); UpdateStructuredListElement(StructuredList, StructuredIndex, expr); ++Index; return; @@ -721,9 +721,8 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, } else { // We cannot initialize this element, so let // PerformCopyInitialization produce the appropriate diagnostic. - SemaRef.PerformCopyInitialization(Entity, SourceLocation(), + SemaRef.PerformCopyInitialization(Entity, SourceLocation(), SemaRef.Owned(expr)); - IList->setInit(Index, 0); hadError = true; ++Index; ++StructuredIndex; @@ -736,48 +735,7 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity, unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex) { - if (Index < IList->getNumInits()) { - Expr *expr = IList->getInit(Index); - if (InitListExpr *SubIList = dyn_cast<InitListExpr>(expr)) { - SemaRef.Diag(SubIList->getLocStart(), - diag::warn_many_braces_around_scalar_init) - << SubIList->getSourceRange(); - - CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList, - StructuredIndex); - return; - } else if (isa<DesignatedInitExpr>(expr)) { - SemaRef.Diag(expr->getSourceRange().getBegin(), - diag::err_designator_for_scalar_init) - << DeclType << expr->getSourceRange(); - hadError = true; - ++Index; - ++StructuredIndex; - return; - } - - ExprResult Result = - SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(), - SemaRef.Owned(expr)); - - Expr *ResultExpr = 0; - - if (Result.isInvalid()) - hadError = true; // types weren't compatible. - else { - ResultExpr = Result.takeAs<Expr>(); - - if (ResultExpr != expr) { - // The type was promoted, update initializer list. - IList->setInit(Index, ResultExpr); - } - } - if (hadError) - ++StructuredIndex; - else - UpdateStructuredListElement(StructuredList, StructuredIndex, ResultExpr); - ++Index; - } else { + if (Index >= IList->getNumInits()) { SemaRef.Diag(IList->getLocStart(), diag::err_empty_scalar_initializer) << IList->getSourceRange(); hadError = true; @@ -785,6 +743,47 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity, ++StructuredIndex; return; } + + Expr *expr = IList->getInit(Index); + if (InitListExpr *SubIList = dyn_cast<InitListExpr>(expr)) { + SemaRef.Diag(SubIList->getLocStart(), + diag::warn_many_braces_around_scalar_init) + << SubIList->getSourceRange(); + + CheckScalarType(Entity, SubIList, DeclType, Index, StructuredList, + StructuredIndex); + return; + } else if (isa<DesignatedInitExpr>(expr)) { + SemaRef.Diag(expr->getSourceRange().getBegin(), + diag::err_designator_for_scalar_init) + << DeclType << expr->getSourceRange(); + hadError = true; + ++Index; + ++StructuredIndex; + return; + } + + ExprResult Result = + SemaRef.PerformCopyInitialization(Entity, expr->getLocStart(), + SemaRef.Owned(expr)); + + Expr *ResultExpr = 0; + + if (Result.isInvalid()) + hadError = true; // types weren't compatible. + else { + ResultExpr = Result.takeAs<Expr>(); + + if (ResultExpr != expr) { + // The type was promoted, update initializer list. + IList->setInit(Index, ResultExpr); + } + } + if (hadError) + ++StructuredIndex; + else + UpdateStructuredListElement(StructuredList, StructuredIndex, ResultExpr); + ++Index; } void InitListChecker::CheckReferenceType(const InitializedEntity &Entity, @@ -839,66 +838,95 @@ void InitListChecker::CheckVectorType(const InitializedEntity &Entity, unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex) { - if (Index < IList->getNumInits()) { - const VectorType *VT = DeclType->getAs<VectorType>(); - unsigned maxElements = VT->getNumElements(); - unsigned numEltsInit = 0; - QualType elementType = VT->getElementType(); - - if (!SemaRef.getLangOptions().OpenCL) { - InitializedEntity ElementEntity = - InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); - - for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) { - // Don't attempt to go past the end of the init list - if (Index >= IList->getNumInits()) - break; - - ElementEntity.setElementIndex(Index); - CheckSubElementType(ElementEntity, IList, elementType, Index, - StructuredList, StructuredIndex); - } - } else { - InitializedEntity ElementEntity = - InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); - - // OpenCL initializers allows vectors to be constructed from vectors. - for (unsigned i = 0; i < maxElements; ++i) { - // Don't attempt to go past the end of the init list - if (Index >= IList->getNumInits()) - break; - - ElementEntity.setElementIndex(Index); - - QualType IType = IList->getInit(Index)->getType(); - if (!IType->isVectorType()) { - CheckSubElementType(ElementEntity, IList, elementType, Index, - StructuredList, StructuredIndex); - ++numEltsInit; - } else { - QualType VecType; - const VectorType *IVT = IType->getAs<VectorType>(); - unsigned numIElts = IVT->getNumElements(); - - if (IType->isExtVectorType()) - VecType = SemaRef.Context.getExtVectorType(elementType, numIElts); - else - VecType = SemaRef.Context.getVectorType(elementType, numIElts, - IVT->getAltiVecSpecific()); - CheckSubElementType(ElementEntity, IList, VecType, Index, - StructuredList, StructuredIndex); - numEltsInit += numIElts; + if (Index >= IList->getNumInits()) + return; + + const VectorType *VT = DeclType->getAs<VectorType>(); + unsigned maxElements = VT->getNumElements(); + unsigned numEltsInit = 0; + QualType elementType = VT->getElementType(); + + if (!SemaRef.getLangOptions().OpenCL) { + // If the initializing element is a vector, try to copy-initialize + // instead of breaking it apart (which is doomed to failure anyway). + Expr *Init = IList->getInit(Index); + if (!isa<InitListExpr>(Init) && Init->getType()->isVectorType()) { + ExprResult Result = + SemaRef.PerformCopyInitialization(Entity, Init->getLocStart(), + SemaRef.Owned(Init)); + + Expr *ResultExpr = 0; + if (Result.isInvalid()) + hadError = true; // types weren't compatible. + else { + ResultExpr = Result.takeAs<Expr>(); + + if (ResultExpr != Init) { + // The type was promoted, update initializer list. + IList->setInit(Index, ResultExpr); } } + if (hadError) + ++StructuredIndex; + else + UpdateStructuredListElement(StructuredList, StructuredIndex, ResultExpr); + ++Index; + return; } - // OpenCL requires all elements to be initialized. - if (numEltsInit != maxElements) - if (SemaRef.getLangOptions().OpenCL) - SemaRef.Diag(IList->getSourceRange().getBegin(), - diag::err_vector_incorrect_num_initializers) - << (numEltsInit < maxElements) << maxElements << numEltsInit; + InitializedEntity ElementEntity = + InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); + + for (unsigned i = 0; i < maxElements; ++i, ++numEltsInit) { + // Don't attempt to go past the end of the init list + if (Index >= IList->getNumInits()) + break; + + ElementEntity.setElementIndex(Index); + CheckSubElementType(ElementEntity, IList, elementType, Index, + StructuredList, StructuredIndex); + } + return; + } + + InitializedEntity ElementEntity = + InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); + + // OpenCL initializers allows vectors to be constructed from vectors. + for (unsigned i = 0; i < maxElements; ++i) { + // Don't attempt to go past the end of the init list + if (Index >= IList->getNumInits()) + break; + + ElementEntity.setElementIndex(Index); + + QualType IType = IList->getInit(Index)->getType(); + if (!IType->isVectorType()) { + CheckSubElementType(ElementEntity, IList, elementType, Index, + StructuredList, StructuredIndex); + ++numEltsInit; + } else { + QualType VecType; + const VectorType *IVT = IType->getAs<VectorType>(); + unsigned numIElts = IVT->getNumElements(); + + if (IType->isExtVectorType()) + VecType = SemaRef.Context.getExtVectorType(elementType, numIElts); + else + VecType = SemaRef.Context.getVectorType(elementType, numIElts, + IVT->getVectorKind()); + CheckSubElementType(ElementEntity, IList, VecType, Index, + StructuredList, StructuredIndex); + numEltsInit += numIElts; + } } + + // OpenCL requires all elements to be initialized. + if (numEltsInit != maxElements) + if (SemaRef.getLangOptions().OpenCL) + SemaRef.Diag(IList->getSourceRange().getBegin(), + diag::err_vector_incorrect_num_initializers) + << (numEltsInit < maxElements) << maxElements << numEltsInit; } void InitListChecker::CheckArrayType(const InitializedEntity &Entity, @@ -945,7 +973,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, if (const ConstantArrayType *CAT = SemaRef.Context.getAsConstantArrayType(DeclType)) { maxElements = CAT->getSize(); - elementIndex.extOrTrunc(maxElements.getBitWidth()); + elementIndex = elementIndex.extOrTrunc(maxElements.getBitWidth()); elementIndex.setIsUnsigned(maxElements.isUnsigned()); maxElementsKnown = true; } @@ -972,9 +1000,9 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, } if (elementIndex.getBitWidth() > maxElements.getBitWidth()) - maxElements.extend(elementIndex.getBitWidth()); + maxElements = maxElements.extend(elementIndex.getBitWidth()); else if (elementIndex.getBitWidth() < maxElements.getBitWidth()) - elementIndex.extend(maxElements.getBitWidth()); + elementIndex = elementIndex.extend(maxElements.getBitWidth()); elementIndex.setIsUnsigned(maxElements.isUnsigned()); // If the array is of incomplete type, keep track of the number of @@ -991,7 +1019,7 @@ void InitListChecker::CheckArrayType(const InitializedEntity &Entity, break; InitializedEntity ElementEntity = - InitializedEntity::InitializeElement(SemaRef.Context, StructuredIndex, + InitializedEntity::InitializeElement(SemaRef.Context, StructuredIndex, Entity); // Check this element. CheckSubElementType(ElementEntity, IList, elementType, Index, @@ -1118,7 +1146,7 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity, } // Emit warnings for missing struct field initializers. - if (InitializedSomething && CheckForMissingFields && Field != FieldEnd && + if (InitializedSomething && CheckForMissingFields && Field != FieldEnd && !Field->getType()->isIncompleteArrayType() && !DeclType->isUnionType()) { // It is possible we have one or more unnamed bitfields remaining. // Find first (if any) named field and emit warning. @@ -1158,12 +1186,12 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity, InitializedEntity MemberEntity = InitializedEntity::InitializeMember(*Field, &Entity); - + if (isa<InitListExpr>(IList->getInit(Index))) - CheckSubElementType(MemberEntity, IList, Field->getType(), Index, + CheckSubElementType(MemberEntity, IList, Field->getType(), Index, StructuredList, StructuredIndex); else - CheckImplicitInitList(MemberEntity, IList, Field->getType(), Index, + CheckImplicitInitList(MemberEntity, IList, Field->getType(), Index, StructuredList, StructuredIndex); } @@ -1171,34 +1199,25 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity, /// anonymous struct or union into a series of field designators that /// refers to the field within the appropriate subobject. /// -/// Field/FieldIndex will be updated to point to the (new) -/// currently-designated field. static void ExpandAnonymousFieldDesignator(Sema &SemaRef, DesignatedInitExpr *DIE, unsigned DesigIdx, - FieldDecl *Field, - RecordDecl::field_iterator &FieldIter, - unsigned &FieldIndex) { + IndirectFieldDecl *IndirectField) { typedef DesignatedInitExpr::Designator Designator; - // Build the path from the current object to the member of the - // anonymous struct/union (backwards). - llvm::SmallVector<FieldDecl *, 4> Path; - SemaRef.BuildAnonymousStructUnionMemberPath(Field, Path); - // Build the replacement designators. llvm::SmallVector<Designator, 4> Replacements; - for (llvm::SmallVector<FieldDecl *, 4>::reverse_iterator - FI = Path.rbegin(), FIEnd = Path.rend(); - FI != FIEnd; ++FI) { - if (FI + 1 == FIEnd) + for (IndirectFieldDecl::chain_iterator PI = IndirectField->chain_begin(), + PE = IndirectField->chain_end(); PI != PE; ++PI) { + if (PI + 1 == PE) Replacements.push_back(Designator((IdentifierInfo *)0, DIE->getDesignator(DesigIdx)->getDotLoc(), DIE->getDesignator(DesigIdx)->getFieldLoc())); else Replacements.push_back(Designator((IdentifierInfo *)0, SourceLocation(), SourceLocation())); - Replacements.back().setField(*FI); + assert(isa<FieldDecl>(*PI)); + Replacements.back().setField(cast<FieldDecl>(*PI)); } // Expand the current designator into the set of replacement @@ -1206,23 +1225,20 @@ static void ExpandAnonymousFieldDesignator(Sema &SemaRef, // member of the anonymous struct/union is actually stored. DIE->ExpandDesignator(SemaRef.Context, DesigIdx, &Replacements[0], &Replacements[0] + Replacements.size()); +} - // Update FieldIter/FieldIndex; - RecordDecl *Record = cast<RecordDecl>(Path.back()->getDeclContext()); - FieldIter = Record->field_begin(); - FieldIndex = 0; - for (RecordDecl::field_iterator FEnd = Record->field_end(); - FieldIter != FEnd; ++FieldIter) { - if (FieldIter->isUnnamedBitfield()) - continue; - - if (*FieldIter == Path.back()) - return; - - ++FieldIndex; +/// \brief Given an implicit anonymous field, search the IndirectField that +/// corresponds to FieldName. +static IndirectFieldDecl *FindIndirectFieldDesignator(FieldDecl *AnonField, + IdentifierInfo *FieldName) { + assert(AnonField->isAnonymousStructOrUnion()); + Decl *NextDecl = AnonField->getNextDeclInContext(); + while (IndirectFieldDecl *IF = dyn_cast<IndirectFieldDecl>(NextDecl)) { + if (FieldName && FieldName == IF->getAnonField()->getIdentifier()) + return IF; + NextDecl = NextDecl->getNextDeclInContext(); } - - assert(false && "Unable to find anonymous struct/union field"); + return 0; } /// @brief Check the well-formedness of a C99 designated initializer. @@ -1343,7 +1359,19 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, if (Field->isUnnamedBitfield()) continue; - if (KnownField == *Field || Field->getIdentifier() == FieldName) + // If we find a field representing an anonymous field, look in the + // IndirectFieldDecl that follow for the designated initializer. + if (!KnownField && Field->isAnonymousStructOrUnion()) { + if (IndirectFieldDecl *IF = + FindIndirectFieldDesignator(*Field, FieldName)) { + ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, IF); + D = DIE->getDesignator(DesigIdx); + break; + } + } + if (KnownField && KnownField == *Field) + break; + if (FieldName && FieldName == Field->getIdentifier()) break; ++FieldIndex; @@ -1360,19 +1388,19 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, if (Lookup.first == Lookup.second) { // Name lookup didn't find anything. Determine whether this // was a typo for another field name. - LookupResult R(SemaRef, FieldName, D->getFieldLoc(), + LookupResult R(SemaRef, FieldName, D->getFieldLoc(), Sema::LookupMemberName); if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl(), false, - Sema::CTC_NoKeywords) && + Sema::CTC_NoKeywords) && (ReplacementField = R.getAsSingle<FieldDecl>()) && ReplacementField->getDeclContext()->getRedeclContext() ->Equals(RT->getDecl())) { - SemaRef.Diag(D->getFieldLoc(), + SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown_suggest) << FieldName << CurrentObjectType << R.getLookupName() << FixItHint::CreateReplacement(D->getFieldLoc(), R.getLookupName().getAsString()); - SemaRef.Diag(ReplacementField->getLocation(), + SemaRef.Diag(ReplacementField->getLocation(), diag::note_previous_decl) << ReplacementField->getDeclName(); } else { @@ -1381,9 +1409,6 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, ++Index; return true; } - } else if (!KnownField) { - // Determine whether we found a field at all. - ReplacementField = dyn_cast<FieldDecl>(*Lookup.first); } if (!ReplacementField) { @@ -1396,16 +1421,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, return true; } - if (!KnownField && - cast<RecordDecl>((ReplacementField)->getDeclContext()) - ->isAnonymousStructOrUnion()) { - // Handle an field designator that refers to a member of an - // anonymous struct or union. - ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, - ReplacementField, - Field, FieldIndex); - D = DIE->getDesignator(DesigIdx); - } else if (!KnownField) { + if (!KnownField) { // The replacement field comes from typo correction; find it // in the list of fields. FieldIndex = 0; @@ -1414,19 +1430,13 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, if (Field->isUnnamedBitfield()) continue; - if (ReplacementField == *Field || + if (ReplacementField == *Field || Field->getIdentifier() == ReplacementField->getIdentifier()) break; ++FieldIndex; } } - } else if (!KnownField && - cast<RecordDecl>((*Field)->getDeclContext()) - ->isAnonymousStructOrUnion()) { - ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, *Field, - Field, FieldIndex); - D = DIE->getDesignator(DesigIdx); } // All of the fields of a union are located at the same place in @@ -1461,7 +1471,8 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, Invalid = true; } - if (!hadError && !isa<InitListExpr>(DIE->getInit())) { + if (!hadError && !isa<InitListExpr>(DIE->getInit()) && + !isa<StringLiteral>(DIE->getInit())) { // The initializer is not an initializer list. SemaRef.Diag(DIE->getInit()->getSourceRange().getBegin(), diag::err_flexible_array_init_needs_braces) @@ -1511,11 +1522,11 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Recurse to check later designated subobjects. QualType FieldType = (*Field)->getType(); unsigned newStructuredIndex = FieldIndex; - + InitializedEntity MemberEntity = InitializedEntity::InitializeMember(*Field, &Entity); - if (CheckDesignatedInitializer(MemberEntity, IList, DIE, DesigIdx + 1, - FieldType, 0, 0, Index, + if (CheckDesignatedInitializer(MemberEntity, IList, DIE, DesigIdx + 1, + FieldType, 0, 0, Index, StructuredList, newStructuredIndex, true, false)) return true; @@ -1544,7 +1555,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Check the remaining fields within this class/struct/union subobject. bool prevHadError = hadError; - + CheckStructUnionTypes(Entity, IList, CurrentObjectType, Field, false, Index, StructuredList, FieldIndex); return hadError && !prevHadError; @@ -1582,22 +1593,29 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, } else { assert(D->isArrayRangeDesignator() && "Need array-range designator"); - DesignatedStartIndex = DIE->getArrayRangeStart(*D)->EvaluateAsInt(SemaRef.Context); DesignatedEndIndex = DIE->getArrayRangeEnd(*D)->EvaluateAsInt(SemaRef.Context); IndexExpr = DIE->getArrayRangeEnd(*D); - if (DesignatedStartIndex.getZExtValue() !=DesignatedEndIndex.getZExtValue()) + // Codegen can't handle evaluating array range designators that have side + // effects, because we replicate the AST value for each initialized element. + // As such, set the sawArrayRangeDesignator() bit if we initialize multiple + // elements with something that has a side effect, so codegen can emit an + // "error unsupported" error instead of miscompiling the app. + if (DesignatedStartIndex.getZExtValue()!=DesignatedEndIndex.getZExtValue()&& + DIE->getInit()->HasSideEffects(SemaRef.Context)) FullyStructuredList->sawArrayRangeDesignator(); } if (isa<ConstantArrayType>(AT)) { llvm::APSInt MaxElements(cast<ConstantArrayType>(AT)->getSize(), false); - DesignatedStartIndex.extOrTrunc(MaxElements.getBitWidth()); + DesignatedStartIndex + = DesignatedStartIndex.extOrTrunc(MaxElements.getBitWidth()); DesignatedStartIndex.setIsUnsigned(MaxElements.isUnsigned()); - DesignatedEndIndex.extOrTrunc(MaxElements.getBitWidth()); + DesignatedEndIndex + = DesignatedEndIndex.extOrTrunc(MaxElements.getBitWidth()); DesignatedEndIndex.setIsUnsigned(MaxElements.isUnsigned()); if (DesignatedEndIndex >= MaxElements) { SemaRef.Diag(IndexExpr->getSourceRange().getBegin(), @@ -1610,10 +1628,12 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, } else { // Make sure the bit-widths and signedness match. if (DesignatedStartIndex.getBitWidth() > DesignatedEndIndex.getBitWidth()) - DesignatedEndIndex.extend(DesignatedStartIndex.getBitWidth()); + DesignatedEndIndex + = DesignatedEndIndex.extend(DesignatedStartIndex.getBitWidth()); else if (DesignatedStartIndex.getBitWidth() < DesignatedEndIndex.getBitWidth()) - DesignatedStartIndex.extend(DesignatedEndIndex.getBitWidth()); + DesignatedStartIndex + = DesignatedStartIndex.extend(DesignatedEndIndex.getBitWidth()); DesignatedStartIndex.setIsUnsigned(true); DesignatedEndIndex.setIsUnsigned(true); } @@ -1630,7 +1650,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Move to the next designator unsigned ElementIndex = DesignatedStartIndex.getZExtValue(); unsigned OldIndex = Index; - + InitializedEntity ElementEntity = InitializedEntity::InitializeElement(SemaRef.Context, 0, Entity); @@ -1638,10 +1658,10 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Recurse to check later designated subobjects. QualType ElementType = AT->getElementType(); Index = OldIndex; - + ElementEntity.setElementIndex(ElementIndex); - if (CheckDesignatedInitializer(ElementEntity, IList, DIE, DesigIdx + 1, - ElementType, 0, 0, Index, + if (CheckDesignatedInitializer(ElementEntity, IList, DIE, DesigIdx + 1, + ElementType, 0, 0, Index, StructuredList, ElementIndex, (DesignatedStartIndex == DesignatedEndIndex), false)) @@ -1666,7 +1686,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Check the remaining elements within this array subobject. bool prevHadError = hadError; - CheckArrayType(Entity, IList, CurrentObjectType, DesignatedStartIndex, + CheckArrayType(Entity, IList, CurrentObjectType, DesignatedStartIndex, /*SubobjectIsDesignatorContext=*/false, Index, StructuredList, ElementIndex); return hadError && !prevHadError; @@ -1812,9 +1832,9 @@ CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) { } ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, - SourceLocation Loc, - bool GNUSyntax, - ExprResult Init) { + SourceLocation Loc, + bool GNUSyntax, + ExprResult Init) { typedef DesignatedInitExpr::Designator ASTDesignator; bool Invalid = false; @@ -1865,9 +1885,9 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, if (StartDependent || EndDependent) { // Nothing to compute. } else if (StartValue.getBitWidth() > EndValue.getBitWidth()) - EndValue.extend(StartValue.getBitWidth()); + EndValue = EndValue.extend(StartValue.getBitWidth()); else if (StartValue.getBitWidth() < EndValue.getBitWidth()) - StartValue.extend(EndValue.getBitWidth()); + StartValue = StartValue.extend(EndValue.getBitWidth()); if (!StartDependent && !EndDependent && EndValue < StartValue) { Diag(D.getEllipsisLoc(), diag::err_array_designator_empty_range) @@ -1899,6 +1919,11 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, Designators.data(), Designators.size(), InitExpressions.data(), InitExpressions.size(), Loc, GNUSyntax, Init.takeAs<Expr>()); + + if (getLangOptions().CPlusPlus) + Diag(DIE->getLocStart(), diag::ext_designated_init) + << DIE->getSourceRange(); + return Owned(DIE); } @@ -1915,9 +1940,9 @@ bool Sema::CheckInitList(const InitializedEntity &Entity, // Initialization entity //===----------------------------------------------------------------------===// -InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index, +InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index, const InitializedEntity &Parent) - : Parent(&Parent), Index(Index) + : Parent(&Parent), Index(Index) { if (const ArrayType *AT = Context.getAsArrayType(Parent.getType())) { Kind = EK_ArrayElement; @@ -1928,7 +1953,7 @@ InitializedEntity::InitializedEntity(ASTContext &Context, unsigned Index, } } -InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context, +InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context, CXXBaseSpecifier *Base, bool IsInheritedVirtualBase) { @@ -1937,7 +1962,7 @@ InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context, Result.Base = reinterpret_cast<uintptr_t>(Base); if (IsInheritedVirtualBase) Result.Base |= 0x01; - + Result.Type = Base->getType(); return Result; } @@ -1963,7 +1988,7 @@ DeclarationName InitializedEntity::getName() const { case EK_BlockElement: return DeclarationName(); } - + // Silence GCC warning return DeclarationName(); } @@ -1985,7 +2010,7 @@ DeclaratorDecl *InitializedEntity::getDecl() const { case EK_BlockElement: return 0; } - + // Silence GCC warning return 0; } @@ -1995,7 +2020,7 @@ bool InitializedEntity::allowsNRVO() const { case EK_Result: case EK_Exception: return LocAndNRVO.NRVO; - + case EK_Variable: case EK_Parameter: case EK_Member: @@ -2035,7 +2060,7 @@ void InitializationSequence::Step::Destroy() { case SK_StringInit: case SK_ObjCObjectConversion: break; - + case SK_ConversionSequence: delete ICS; } @@ -2048,7 +2073,7 @@ bool InitializationSequence::isDirectReferenceBinding() const { bool InitializationSequence::isAmbiguous() const { if (getKind() != FailedSequence) return false; - + switch (getFailureKind()) { case FK_TooManyInitsForReference: case FK_ArrayNeedsInitList: @@ -2066,13 +2091,13 @@ bool InitializationSequence::isAmbiguous() const { case FK_DefaultInitOfConst: case FK_Incomplete: return false; - + case FK_ReferenceInitOverloadFailed: case FK_UserConversionOverloadFailed: case FK_ConstructorOverloadFailed: return FailedOverloadResult == OR_Ambiguous; } - + return false; } @@ -2091,7 +2116,7 @@ void InitializationSequence::AddAddressOverloadResolutionStep( Steps.push_back(S); } -void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType, +void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType, ExprValueKind VK) { Step S; switch (VK) { @@ -2104,7 +2129,7 @@ void InitializationSequence::AddDerivedToBaseCastStep(QualType BaseType, Steps.push_back(S); } -void InitializationSequence::AddReferenceBindingStep(QualType T, +void InitializationSequence::AddReferenceBindingStep(QualType T, bool BindingTemporary) { Step S; S.Kind = BindingTemporary? SK_BindReferenceToTemporary : SK_BindReference; @@ -2166,7 +2191,7 @@ void InitializationSequence::AddListInitializationStep(QualType T) { Steps.push_back(S); } -void +void InitializationSequence::AddConstructorInitializationStep( CXXConstructorDecl *Constructor, AccessSpecifier Access, @@ -2207,7 +2232,7 @@ void InitializationSequence::AddObjCObjectConversionStep(QualType T) { Steps.push_back(S); } -void InitializationSequence::SetOverloadFailure(FailureKind Failure, +void InitializationSequence::SetOverloadFailure(FailureKind Failure, OverloadingResult Result) { SequenceKind = FailedSequence; this->Failure = Failure; @@ -2218,8 +2243,8 @@ void InitializationSequence::SetOverloadFailure(FailureKind Failure, // Attempt initialization //===----------------------------------------------------------------------===// -/// \brief Attempt list initialization (C++0x [dcl.init.list]) -static void TryListInitialization(Sema &S, +/// \brief Attempt list initialization (C++0x [dcl.init.list]) +static void TryListInitialization(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, InitListExpr *InitList, @@ -2235,7 +2260,7 @@ static void TryListInitialization(Sema &S, QualType DestType = Entity.getType(); // C++ [dcl.init]p13: - // If T is a scalar type, then a declaration of the form + // If T is a scalar type, then a declaration of the form // // T x = { a }; // @@ -2282,7 +2307,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, bool DerivedToBase; bool ObjCConversion; - assert(!S.CompareReferenceRelationship(Initializer->getLocStart(), + assert(!S.CompareReferenceRelationship(Initializer->getLocStart(), T1, T2, DerivedToBase, ObjCConversion) && "Must have incompatible references when binding via conversion"); @@ -2297,7 +2322,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, // Determine whether we are allowed to call explicit constructors or // explicit conversion operators. bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct; - + const RecordType *T1RecordType = 0; if (AllowRValues && (T1RecordType = T1->getAs<RecordType>()) && !S.RequireCompleteType(Kind.getLocation(), T1, 0)) { @@ -2319,22 +2344,24 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, ConstructorTmpl->getTemplatedDecl()); else Constructor = cast<CXXConstructorDecl>(D); - + if (!Constructor->isInvalidDecl() && Constructor->isConvertingConstructor(AllowExplicit)) { if (ConstructorTmpl) S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, /*ExplicitArgs*/ 0, - &Initializer, 1, CandidateSet); + &Initializer, 1, CandidateSet, + /*SuppressUserConversions=*/true); else S.AddOverloadCandidate(Constructor, FoundDecl, - &Initializer, 1, CandidateSet); + &Initializer, 1, CandidateSet, + /*SuppressUserConversions=*/true); } - } + } } if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl()) return OR_No_Viable_Function; - + const RecordType *T2RecordType = 0; if ((T2RecordType = T2->getAs<RecordType>()) && !S.RequireCompleteType(Kind.getLocation(), T2, 0)) { @@ -2342,11 +2369,6 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, // functions. CXXRecordDecl *T2RecordDecl = cast<CXXRecordDecl>(T2RecordType->getDecl()); - // Determine the type we are converting to. If we are allowed to - // convert to an rvalue, take the type that the destination type - // refers to. - QualType ToType = AllowRValues? cv1T1 : DestType; - const UnresolvedSetImpl *Conversions = T2RecordDecl->getVisibleConversionFunctions(); for (UnresolvedSetImpl::const_iterator I = Conversions->begin(), @@ -2355,41 +2377,41 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext()); if (isa<UsingShadowDecl>(D)) D = cast<UsingShadowDecl>(D)->getTargetDecl(); - + FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D); CXXConversionDecl *Conv; if (ConvTemplate) Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl()); else Conv = cast<CXXConversionDecl>(D); - + // If the conversion function doesn't return a reference type, // it can't be considered for this conversion unless we're allowed to // consider rvalues. - // FIXME: Do we need to make sure that we only consider conversion - // candidates with reference-compatible results? That might be needed to + // FIXME: Do we need to make sure that we only consider conversion + // candidates with reference-compatible results? That might be needed to // break recursion. if ((AllowExplicit || !Conv->isExplicit()) && (AllowRValues || Conv->getConversionType()->isLValueReferenceType())){ if (ConvTemplate) S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), ActingDC, Initializer, - ToType, CandidateSet); + DestType, CandidateSet); else S.AddConversionCandidate(Conv, I.getPair(), ActingDC, - Initializer, ToType, CandidateSet); + Initializer, DestType, CandidateSet); } } } if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl()) return OR_No_Viable_Function; - + SourceLocation DeclLoc = Initializer->getLocStart(); - // Perform overload resolution. If it fails, return the failed result. + // Perform overload resolution. If it fails, return the failed result. OverloadCandidateSet::iterator Best; - if (OverloadingResult Result - = CandidateSet.BestViableFunction(S, DeclLoc, Best)) + if (OverloadingResult Result + = CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) return Result; FunctionDecl *Function = Best->Function; @@ -2404,7 +2426,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, Sequence.AddUserConversionStep(Function, Best->FoundDecl, T2.getNonLValueExprType(S.Context)); - // Determine whether we need to perform derived-to-base or + // Determine whether we need to perform derived-to-base or // cv-qualification adjustments. ExprValueKind VK = VK_RValue; if (T2->isLValueReferenceType()) @@ -2415,7 +2437,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, bool NewDerivedToBase = false; bool NewObjCConversion = false; Sema::ReferenceCompareResult NewRefRelationship - = S.CompareReferenceRelationship(DeclLoc, T1, + = S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonLValueExprType(S.Context), NewDerivedToBase, NewObjCConversion); if (NewRefRelationship == Sema::Ref_Incompatible) { @@ -2431,7 +2453,7 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, } else if (NewDerivedToBase) Sequence.AddDerivedToBaseCastStep( S.Context.getQualifiedType(T1, - T2.getNonReferenceType().getQualifiers()), + T2.getNonReferenceType().getQualifiers()), VK); else if (NewObjCConversion) Sequence.AddObjCObjectConversionStep( @@ -2440,13 +2462,13 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, if (cv1T1.getQualifiers() != T2.getNonReferenceType().getQualifiers()) Sequence.AddQualificationConversionStep(cv1T1, VK); - + Sequence.AddReferenceBindingStep(cv1T1, !T2->isReferenceType()); return OR_Success; } - -/// \brief Attempt reference initialization (C++0x [dcl.init.ref]) -static void TryReferenceInitialization(Sema &S, + +/// \brief Attempt reference initialization (C++0x [dcl.init.ref]) +static void TryReferenceInitialization(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, Expr *Initializer, @@ -2467,18 +2489,17 @@ static void TryReferenceInitialization(Sema &S, // type of the resulting function. if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) { DeclAccessPair Found; - FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer, - T1, - false, - Found); - if (!Fn) { + if (FunctionDecl *Fn = S.ResolveAddressOfOverloadedFunction(Initializer, + T1, + false, + Found)) { + Sequence.AddAddressOverloadResolutionStep(Fn, Found); + cv2T2 = Fn->getType(); + T2 = cv2T2.getUnqualifiedType(); + } else if (!T1->isRecordType()) { Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); return; } - - Sequence.AddAddressOverloadResolutionStep(Fn, Found); - cv2T2 = Fn->getType(); - T2 = cv2T2.getUnqualifiedType(); } // Compute some basic properties of the types and the initializer. @@ -2492,10 +2513,10 @@ static void TryReferenceInitialization(Sema &S, ObjCConversion); // C++0x [dcl.init.ref]p5: - // A reference to type "cv1 T1" is initialized by an expression of type + // A reference to type "cv1 T1" is initialized by an expression of type // "cv2 T2" as follows: // - // - If the reference is an lvalue reference and the initializer + // - If the reference is an lvalue reference and the initializer // expression // Note the analogous bullet points for rvlaue refs to functions. Because // there are no function rvalues in C++, rvalue refs to functions are treated @@ -2503,19 +2524,21 @@ static void TryReferenceInitialization(Sema &S, OverloadingResult ConvOvlResult = OR_Success; bool T1Function = T1->isFunctionType(); if (isLValueRef || T1Function) { - if (InitCategory.isLValue() && - RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) { - // - is an lvalue (but is not a bit-field), and "cv1 T1" is + if (InitCategory.isLValue() && + (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification || + (Kind.isCStyleOrFunctionalCast() && + RefRelationship == Sema::Ref_Related))) { + // - is an lvalue (but is not a bit-field), and "cv1 T1" is // reference-compatible with "cv2 T2," or // - // Per C++ [over.best.ics]p2, we don't diagnose whether the lvalue is a + // Per C++ [over.best.ics]p2, we don't diagnose whether the lvalue is a // bit-field when we're determining whether the reference initialization // can occur. However, we do pay attention to whether it is a bit-field // to decide whether we're actually binding to a temporary created from // the bit-field. if (DerivedToBase) Sequence.AddDerivedToBaseCastStep( - S.Context.getQualifiedType(T1, T2Quals), + S.Context.getQualifiedType(T1, T2Quals), VK_LValue); else if (ObjCConversion) Sequence.AddObjCObjectConversionStep( @@ -2528,18 +2551,18 @@ static void TryReferenceInitialization(Sema &S, Sequence.AddReferenceBindingStep(cv1T1, BindingTemporary); return; } - - // - has a class type (i.e., T2 is a class type), where T1 is not - // reference-related to T2, and can be implicitly converted to an - // lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible - // with "cv3 T3" (this conversion is selected by enumerating the + + // - has a class type (i.e., T2 is a class type), where T1 is not + // reference-related to T2, and can be implicitly converted to an + // lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible + // with "cv3 T3" (this conversion is selected by enumerating the // applicable conversion functions (13.3.1.6) and choosing the best // one through overload resolution (13.3)), // If we have an rvalue ref to function type here, the rhs must be // an rvalue. if (RefRelationship == Sema::Ref_Incompatible && T2->isRecordType() && (isLValueRef || InitCategory.isRValue())) { - ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind, + ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind, Initializer, /*AllowRValues=*/isRValueRef, Sequence); @@ -2553,37 +2576,39 @@ static void TryReferenceInitialization(Sema &S, } } - // - Otherwise, the reference shall be an lvalue reference to a + // - Otherwise, the reference shall be an lvalue reference to a // non-volatile const type (i.e., cv1 shall be const), or the reference - // shall be an rvalue reference and the initializer expression shall - // be an rvalue or have a function type. - // We handled the function type stuff above. - if (!((isLValueRef && T1Quals.hasConst() && !T1Quals.hasVolatile()) || - (isRValueRef && InitCategory.isRValue()))) { - if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty()) + // shall be an rvalue reference. + if (isLValueRef && !(T1Quals.hasConst() && !T1Quals.hasVolatile())) { + if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) + Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); + else if (ConvOvlResult && !Sequence.getFailedCandidateSet().empty()) Sequence.SetOverloadFailure( InitializationSequence::FK_ReferenceInitOverloadFailed, ConvOvlResult); - else if (isLValueRef) + else Sequence.SetFailed(InitCategory.isLValue() ? (RefRelationship == Sema::Ref_Related ? InitializationSequence::FK_ReferenceInitDropsQualifiers : InitializationSequence::FK_NonConstLValueReferenceBindingToUnrelated) : InitializationSequence::FK_NonConstLValueReferenceBindingToTemporary); - else - Sequence.SetFailed( - InitializationSequence::FK_RValueReferenceBindingToLValue); return; } - // - [If T1 is not a function type], if T2 is a class type and - if (!T1Function && T2->isRecordType()) { - bool isXValue = InitCategory.isXValue(); - // - the initializer expression is an rvalue and "cv1 T1" is - // reference-compatible with "cv2 T2", or - if (InitCategory.isRValue() && - RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) { + // - If the initializer expression + // - is an xvalue, class prvalue, array prvalue, or function lvalue and + // "cv1 T1" is reference-compatible with "cv2 T2" + // Note: functions are handled below. + if (!T1Function && + (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification || + (Kind.isCStyleOrFunctionalCast() && + RefRelationship == Sema::Ref_Related)) && + (InitCategory.isXValue() || + (InitCategory.isPRValue() && T2->isRecordType()) || + (InitCategory.isPRValue() && T2->isArrayType()))) { + ExprValueKind ValueKind = InitCategory.isXValue()? VK_XValue : VK_RValue; + if (InitCategory.isPRValue() && T2->isRecordType()) { // The corresponding bullet in C++03 [dcl.init.ref]p5 gives the // compiler the freedom to perform a copy here or bind to the // object, while C++0x requires that we bind directly to the @@ -2593,29 +2618,29 @@ static void TryReferenceInitialization(Sema &S, // // The constructor that would be used to make the copy shall // be callable whether or not the copy is actually done. - if (!S.getLangOptions().CPlusPlus0x) + if (!S.getLangOptions().CPlusPlus0x && !S.getLangOptions().Microsoft) Sequence.AddExtraneousCopyToTemporary(cv2T2); - - if (DerivedToBase) - Sequence.AddDerivedToBaseCastStep( - S.Context.getQualifiedType(T1, T2Quals), - isXValue ? VK_XValue : VK_RValue); - else if (ObjCConversion) - Sequence.AddObjCObjectConversionStep( - S.Context.getQualifiedType(T1, T2Quals)); - - if (T1Quals != T2Quals) - Sequence.AddQualificationConversionStep(cv1T1, - isXValue ? VK_XValue : VK_RValue); - Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/!isXValue); - return; } - // - T1 is not reference-related to T2 and the initializer expression - // can be implicitly converted to an rvalue of type "cv3 T3" (this - // conversion is selected by enumerating the applicable conversion - // functions (13.3.1.6) and choosing the best one through overload - // resolution (13.3)), + if (DerivedToBase) + Sequence.AddDerivedToBaseCastStep(S.Context.getQualifiedType(T1, T2Quals), + ValueKind); + else if (ObjCConversion) + Sequence.AddObjCObjectConversionStep( + S.Context.getQualifiedType(T1, T2Quals)); + + if (T1Quals != T2Quals) + Sequence.AddQualificationConversionStep(cv1T1, ValueKind); + Sequence.AddReferenceBindingStep(cv1T1, + /*bindingTemporary=*/(InitCategory.isPRValue() && !T2->isArrayType())); + return; + } + + // - has a class type (i.e., T2 is a class type), where T1 is not + // reference-related to T2, and can be implicitly converted to an + // xvalue, class prvalue, or function lvalue of type "cv3 T3", + // where "cv1 T1" is reference-compatible with "cv3 T3", + if (T2->isRecordType()) { if (RefRelationship == Sema::Ref_Incompatible) { ConvOvlResult = TryRefInitWithConversionFunction(S, Entity, Kind, Initializer, @@ -2625,23 +2650,17 @@ static void TryReferenceInitialization(Sema &S, Sequence.SetOverloadFailure( InitializationSequence::FK_ReferenceInitOverloadFailed, ConvOvlResult); - + return; } - + Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers); return; } - - // - If the initializer expression is an rvalue, with T2 an array type, - // and "cv1 T1" is reference-compatible with "cv2 T2," the reference - // is bound to the object represented by the rvalue (see 3.10). - // FIXME: How can an array type be reference-compatible with anything? - // Don't we mean the element types of T1 and T2? - - // - Otherwise, a temporary of type “cv1 T1” is created and initialized + + // - Otherwise, a temporary of type "cv1 T1" is created and initialized // from the initializer expression using the rules for a non-reference - // copy initialization (8.5). The reference is then bound to the + // copy initialization (8.5). The reference is then bound to the // temporary. [...] // Determine whether we are allowed to call explicit constructors or @@ -2653,7 +2672,8 @@ static void TryReferenceInitialization(Sema &S, if (S.TryImplicitConversion(Sequence, TempEntity, Initializer, /*SuppressUserConversions*/ false, AllowExplicit, - /*FIXME:InOverloadResolution=*/false)) { + /*FIXME:InOverloadResolution=*/false, + /*CStyle=*/Kind.isCStyleOrFunctionalCast())) { // FIXME: Use the conversion function set stored in ICS to turn // this into an overloading ambiguity diagnostic. However, we need // to keep that set as an OverloadCandidateSet rather than as some @@ -2662,6 +2682,8 @@ static void TryReferenceInitialization(Sema &S, Sequence.SetOverloadFailure( InitializationSequence::FK_ReferenceInitOverloadFailed, ConvOvlResult); + else if (S.Context.getCanonicalType(T2) == S.Context.OverloadTy) + Sequence.SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); else Sequence.SetFailed(InitializationSequence::FK_ReferenceInitFailed); return; @@ -2672,19 +2694,28 @@ static void TryReferenceInitialization(Sema &S, // than, cv2; otherwise, the program is ill-formed. unsigned T1CVRQuals = T1Quals.getCVRQualifiers(); unsigned T2CVRQuals = T2Quals.getCVRQualifiers(); - if (RefRelationship == Sema::Ref_Related && + if (RefRelationship == Sema::Ref_Related && (T1CVRQuals | T2CVRQuals) != T1CVRQuals) { Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers); return; } + // [...] If T1 is reference-related to T2 and the reference is an rvalue + // reference, the initializer expression shall not be an lvalue. + if (RefRelationship >= Sema::Ref_Related && !isLValueRef && + InitCategory.isLValue()) { + Sequence.SetFailed( + InitializationSequence::FK_RValueReferenceBindingToLValue); + return; + } + Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true); return; } /// \brief Attempt character array initialization from a string literal -/// (C++ [dcl.init.string], C99 6.7.8). -static void TryStringLiteralInitialization(Sema &S, +/// (C++ [dcl.init.string], C99 6.7.8). +static void TryStringLiteralInitialization(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, Expr *Initializer, @@ -2696,19 +2727,19 @@ static void TryStringLiteralInitialization(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. -static void TryConstructorInitialization(Sema &S, +static void TryConstructorInitialization(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, Expr **Args, unsigned NumArgs, QualType DestType, InitializationSequence &Sequence) { Sequence.setSequenceKind(InitializationSequence::ConstructorInitialization); - + // Build the candidate set directly in the initialization sequence // structure, so that it will persist if we fail. OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet(); CandidateSet.clear(); - + // Determine whether we are allowed to call explicit constructors or // explicit conversion operators. bool AllowExplicit = (Kind.getKind() == InitializationKind::IK_Direct || @@ -2720,21 +2751,21 @@ static void TryConstructorInitialization(Sema &S, Sequence.SetFailed(InitializationSequence::FK_Incomplete); return; } - + // The type we're converting to is a class type. Enumerate its constructors // to see if one is suitable. const RecordType *DestRecordType = DestType->getAs<RecordType>(); - assert(DestRecordType && "Constructor initialization requires record type"); + assert(DestRecordType && "Constructor initialization requires record type"); CXXRecordDecl *DestRecordDecl = cast<CXXRecordDecl>(DestRecordType->getDecl()); - + DeclContext::lookup_iterator Con, ConEnd; for (llvm::tie(Con, ConEnd) = S.LookupConstructors(DestRecordDecl); Con != ConEnd; ++Con) { NamedDecl *D = *Con; DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); bool SuppressUserConversions = false; - + // Find the constructor (which may be a template). CXXConstructorDecl *Constructor = 0; FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D); @@ -2744,14 +2775,14 @@ static void TryConstructorInitialization(Sema &S, else { Constructor = cast<CXXConstructorDecl>(D); - // If we're performing copy initialization using a copy constructor, we + // If we're performing copy initialization using a copy constructor, we // suppress user-defined conversions on the arguments. // FIXME: Move constructors? if (Kind.getKind() == InitializationKind::IK_Copy && Constructor->isCopyConstructor()) SuppressUserConversions = true; } - + if (!Constructor->isInvalidDecl() && (AllowExplicit || !Constructor->isExplicit())) { if (ConstructorTmpl) @@ -2764,16 +2795,16 @@ static void TryConstructorInitialization(Sema &S, Args, NumArgs, CandidateSet, SuppressUserConversions); } - } - + } + SourceLocation DeclLoc = Kind.getLocation(); - - // Perform overload resolution. If it fails, return the failed result. + + // Perform overload resolution. If it fails, return the failed result. OverloadCandidateSet::iterator Best; - if (OverloadingResult Result + if (OverloadingResult Result = CandidateSet.BestViableFunction(S, DeclLoc, Best)) { Sequence.SetOverloadFailure( - InitializationSequence::FK_ConstructorOverloadFailed, + InitializationSequence::FK_ConstructorOverloadFailed, Result); return; } @@ -2792,13 +2823,13 @@ static void TryConstructorInitialization(Sema &S, // Add the constructor initialization step. Any cv-qualification conversion is // subsumed by the initialization. Sequence.AddConstructorInitializationStep( - cast<CXXConstructorDecl>(Best->Function), + cast<CXXConstructorDecl>(Best->Function), Best->FoundDecl.getAccess(), DestType); } /// \brief Attempt value initialization (C++ [dcl.init]p7). -static void TryValueInitialization(Sema &S, +static void TryValueInitialization(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, InitializationSequence &Sequence) { @@ -2806,11 +2837,11 @@ static void TryValueInitialization(Sema &S, // // To value-initialize an object of type T means: QualType T = Entity.getType(); - + // -- if T is an array type, then each element is value-initialized; while (const ArrayType *AT = S.Context.getAsArrayType(T)) T = AT->getElementType(); - + if (const RecordType *RT = T->getAs<RecordType>()) { if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) { // -- if T is a class type (clause 9) with a user-declared @@ -2822,15 +2853,15 @@ static void TryValueInitialization(Sema &S, // but Entity doesn't have a way to capture that (yet). if (ClassDecl->hasUserDeclaredConstructor()) return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence); - + // -- if T is a (possibly cv-qualified) non-union class type // without a user-provided constructor, then the object is - // zero-initialized and, if T’s implicitly-declared default + // zero-initialized and, if T's implicitly-declared default // constructor is non-trivial, that constructor is called. if ((ClassDecl->getTagKind() == TTK_Class || ClassDecl->getTagKind() == TTK_Struct)) { Sequence.AddZeroInitializationStep(Entity.getType()); - return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence); + return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence); } } } @@ -2845,14 +2876,14 @@ static void TryDefaultInitialization(Sema &S, const InitializationKind &Kind, InitializationSequence &Sequence) { assert(Kind.getKind() == InitializationKind::IK_Default); - + // C++ [dcl.init]p6: // To default-initialize an object of type T means: // - if T is an array type, each element is default-initialized; QualType DestType = Entity.getType(); while (const ArrayType *Array = S.Context.getAsArrayType(DestType)) DestType = Array->getElementType(); - + // - if T is a (possibly cv-qualified) class type (Clause 9), the default // constructor for T is called (and the initialization is ill-formed if // T has no accessible default constructor); @@ -2860,12 +2891,12 @@ static void TryDefaultInitialization(Sema &S, TryConstructorInitialization(S, Entity, Kind, 0, 0, DestType, Sequence); return; } - + // - otherwise, no initialization is performed. Sequence.setSequenceKind(InitializationSequence::NoInitialization); - + // If a program calls for the default initialization of an object of - // a const-qualified type T, T shall be a class type with a user-provided + // a const-qualified type T, T shall be a class type with a user-provided // default constructor. if (DestType.isConstQualified() && S.getLangOptions().CPlusPlus) Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst); @@ -2874,42 +2905,42 @@ static void TryDefaultInitialization(Sema &S, /// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]), /// which enumerates all conversion functions and performs overload resolution /// to select the best. -static void TryUserDefinedConversion(Sema &S, +static void TryUserDefinedConversion(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, Expr *Initializer, InitializationSequence &Sequence) { Sequence.setSequenceKind(InitializationSequence::UserDefinedConversion); - + QualType DestType = Entity.getType(); assert(!DestType->isReferenceType() && "References are handled elsewhere"); QualType SourceType = Initializer->getType(); assert((DestType->isRecordType() || SourceType->isRecordType()) && "Must have a class type to perform a user-defined conversion"); - + // Build the candidate set directly in the initialization sequence // structure, so that it will persist if we fail. OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet(); CandidateSet.clear(); - + // Determine whether we are allowed to call explicit constructors or // explicit conversion operators. bool AllowExplicit = Kind.getKind() == InitializationKind::IK_Direct; - + if (const RecordType *DestRecordType = DestType->getAs<RecordType>()) { // The type we're converting to is a class type. Enumerate its constructors // to see if there is a suitable conversion. CXXRecordDecl *DestRecordDecl = cast<CXXRecordDecl>(DestRecordType->getDecl()); - + // Try to complete the type we're converting to. - if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) { + if (!S.RequireCompleteType(Kind.getLocation(), DestType, 0)) { DeclContext::lookup_iterator Con, ConEnd; for (llvm::tie(Con, ConEnd) = S.LookupConstructors(DestRecordDecl); Con != ConEnd; ++Con) { NamedDecl *D = *Con; DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); - + // Find the constructor (which may be a template). CXXConstructorDecl *Constructor = 0; FunctionTemplateDecl *ConstructorTmpl @@ -2919,7 +2950,7 @@ static void TryUserDefinedConversion(Sema &S, ConstructorTmpl->getTemplatedDecl()); else Constructor = cast<CXXConstructorDecl>(D); - + if (!Constructor->isInvalidDecl() && Constructor->isConvertingConstructor(AllowExplicit)) { if (ConstructorTmpl) @@ -2932,7 +2963,7 @@ static void TryUserDefinedConversion(Sema &S, &Initializer, 1, CandidateSet, /*SuppressUserConversions=*/true); } - } + } } } @@ -2947,24 +2978,24 @@ static void TryUserDefinedConversion(Sema &S, if (!S.RequireCompleteType(DeclLoc, SourceType, 0)) { CXXRecordDecl *SourceRecordDecl = cast<CXXRecordDecl>(SourceRecordType->getDecl()); - + const UnresolvedSetImpl *Conversions = SourceRecordDecl->getVisibleConversionFunctions(); for (UnresolvedSetImpl::const_iterator I = Conversions->begin(), - E = Conversions->end(); + E = Conversions->end(); I != E; ++I) { NamedDecl *D = *I; CXXRecordDecl *ActingDC = cast<CXXRecordDecl>(D->getDeclContext()); if (isa<UsingShadowDecl>(D)) D = cast<UsingShadowDecl>(D)->getTargetDecl(); - + FunctionTemplateDecl *ConvTemplate = dyn_cast<FunctionTemplateDecl>(D); CXXConversionDecl *Conv; if (ConvTemplate) Conv = cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl()); else Conv = cast<CXXConversionDecl>(D); - + if (AllowExplicit || !Conv->isExplicit()) { if (ConvTemplate) S.AddTemplateConversionCandidate(ConvTemplate, I.getPair(), @@ -2977,19 +3008,19 @@ static void TryUserDefinedConversion(Sema &S, } } } - - // Perform overload resolution. If it fails, return the failed result. + + // Perform overload resolution. If it fails, return the failed result. OverloadCandidateSet::iterator Best; if (OverloadingResult Result - = CandidateSet.BestViableFunction(S, DeclLoc, Best)) { + = CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) { Sequence.SetOverloadFailure( - InitializationSequence::FK_UserConversionOverloadFailed, + InitializationSequence::FK_UserConversionOverloadFailed, Result); return; } FunctionDecl *Function = Best->Function; - + if (isa<CXXConstructorDecl>(Function)) { // Add the user-defined conversion step. Any cv-qualification conversion is // subsumed by the initialization. @@ -3011,7 +3042,7 @@ static void TryUserDefinedConversion(Sema &S, } Sequence.AddUserConversionStep(Function, Best->FoundDecl, ConvType); - + // If the conversion following the call to the conversion function // is interesting, add it as a separate step. if (Best->FinalConversion.First || Best->FinalConversion.Second || @@ -3030,12 +3061,12 @@ InitializationSequence::InitializationSequence(Sema &S, unsigned NumArgs) : FailedCandidateSet(Kind.getLocation()) { ASTContext &Context = S.Context; - + // C++0x [dcl.init]p16: - // The semantics of initializers are as follows. The destination type is - // the type of the object or reference being initialized and the source + // The semantics of initializers are as follows. The destination type is + // the type of the object or reference being initialized and the source // type is the type of the initializer expression. The source type is not - // defined when the initializer is a braced-init-list or when it is a + // defined when the initializer is a braced-init-list or when it is a // parenthesized list of expressions. QualType DestType = Entity.getType(); @@ -3045,6 +3076,10 @@ InitializationSequence::InitializationSequence(Sema &S, return; } + for (unsigned I = 0; I != NumArgs; ++I) + if (Args[I]->getObjectKind() == OK_ObjCProperty) + S.ConvertPropertyForRValue(Args[I]); + QualType SourceType; Expr *Initializer = 0; if (NumArgs == 1) { @@ -3052,14 +3087,14 @@ InitializationSequence::InitializationSequence(Sema &S, if (!isa<InitListExpr>(Initializer)) SourceType = Initializer->getType(); } - - // - If the initializer is a braced-init-list, the object is + + // - If the initializer is a braced-init-list, the object is // list-initialized (8.5.4). if (InitListExpr *InitList = dyn_cast_or_null<InitListExpr>(Initializer)) { TryListInitialization(S, Entity, Kind, InitList, *this); return; } - + // - If the destination type is a reference type, see 8.5.3. if (DestType->isReferenceType()) { // C++0x [dcl.init.ref]p1: @@ -3073,36 +3108,36 @@ InitializationSequence::InitializationSequence(Sema &S, TryReferenceInitialization(S, Entity, Kind, Args[0], *this); return; } - - // - If the destination type is an array of characters, an array of - // char16_t, an array of char32_t, or an array of wchar_t, and the + + // - If the destination type is an array of characters, an array of + // char16_t, an array of char32_t, or an array of wchar_t, and the // initializer is a string literal, see 8.5.2. if (Initializer && IsStringInit(Initializer, DestType, Context)) { TryStringLiteralInitialization(S, Entity, Kind, Initializer, *this); return; } - + // - If the initializer is (), the object is value-initialized. if (Kind.getKind() == InitializationKind::IK_Value || (Kind.getKind() == InitializationKind::IK_Direct && NumArgs == 0)) { TryValueInitialization(S, Entity, Kind, *this); return; } - + // Handle default initialization. - if (Kind.getKind() == InitializationKind::IK_Default){ + if (Kind.getKind() == InitializationKind::IK_Default) { TryDefaultInitialization(S, Entity, Kind, *this); return; } - // - Otherwise, if the destination type is an array, the program is + // - Otherwise, if the destination type is an array, the program is // ill-formed. if (const ArrayType *AT = Context.getAsArrayType(DestType)) { if (AT->getElementType()->isAnyCharacterType()) SetFailed(FK_ArrayNeedsInitListOrStringLiteral); else SetFailed(FK_ArrayNeedsInitList); - + return; } @@ -3112,22 +3147,22 @@ InitializationSequence::InitializationSequence(Sema &S, AddCAssignmentStep(DestType); return; } - + // - If the destination type is a (possibly cv-qualified) class type: if (DestType->isRecordType()) { - // - If the initialization is direct-initialization, or if it is - // copy-initialization where the cv-unqualified version of the - // source type is the same class as, or a derived class of, the + // - If the initialization is direct-initialization, or if it is + // copy-initialization where the cv-unqualified version of the + // source type is the same class as, or a derived class of, the // class of the destination, constructors are considered. [...] if (Kind.getKind() == InitializationKind::IK_Direct || (Kind.getKind() == InitializationKind::IK_Copy && (Context.hasSameUnqualifiedType(SourceType, DestType) || S.IsDerivedFrom(SourceType, DestType)))) - TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, + TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, Entity.getType(), *this); - // - Otherwise (i.e., for the remaining copy-initialization cases), + // - Otherwise (i.e., for the remaining copy-initialization cases), // user-defined conversion sequences that can convert from the source - // type to the destination type or (when a conversion function is + // type to the destination type or (when a conversion function is // used) to a derived class thereof are enumerated as described in // 13.3.1.4, and the best one is chosen through overload resolution // (13.3). @@ -3135,30 +3170,39 @@ InitializationSequence::InitializationSequence(Sema &S, TryUserDefinedConversion(S, Entity, Kind, Initializer, *this); return; } - + if (NumArgs > 1) { SetFailed(FK_TooManyInitsForScalar); return; } assert(NumArgs == 1 && "Zero-argument case handled above"); - - // - Otherwise, if the source type is a (possibly cv-qualified) class + + // - Otherwise, if the source type is a (possibly cv-qualified) class // type, conversion functions are considered. if (!SourceType.isNull() && SourceType->isRecordType()) { TryUserDefinedConversion(S, Entity, Kind, Initializer, *this); return; } - + // - Otherwise, the initial value of the object being initialized is the // (possibly converted) value of the initializer expression. Standard // conversions (Clause 4) will be used, if necessary, to convert the - // initializer expression to the cv-unqualified version of the + // initializer expression to the cv-unqualified version of the // destination type; no user-defined conversions are considered. if (S.TryImplicitConversion(*this, Entity, Initializer, /*SuppressUserConversions*/ true, /*AllowExplicitConversions*/ false, - /*InOverloadResolution*/ false)) - SetFailed(InitializationSequence::FK_ConversionFailed); + /*InOverloadResolution*/ false, + /*CStyle=*/Kind.isCStyleOrFunctionalCast())) + { + DeclAccessPair dap; + if (Initializer->getType() == Context.OverloadTy && + !S.ResolveAddressOfOverloadedFunction(Initializer + , DestType, false, dap)) + SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); + else + SetFailed(InitializationSequence::FK_ConversionFailed); + } else setSequenceKind(StandardConversion); } @@ -3173,15 +3217,17 @@ InitializationSequence::~InitializationSequence() { //===----------------------------------------------------------------------===// // Perform initialization //===----------------------------------------------------------------------===// -static Sema::AssignmentAction +static Sema::AssignmentAction getAssignmentAction(const InitializedEntity &Entity) { switch(Entity.getKind()) { case InitializedEntity::EK_Variable: case InitializedEntity::EK_New: + case InitializedEntity::EK_Exception: + case InitializedEntity::EK_Base: return Sema::AA_Initializing; case InitializedEntity::EK_Parameter: - if (Entity.getDecl() && + if (Entity.getDecl() && isa<ObjCMethodDecl>(Entity.getDecl()->getDeclContext())) return Sema::AA_Sending; @@ -3190,15 +3236,10 @@ getAssignmentAction(const InitializedEntity &Entity) { case InitializedEntity::EK_Result: return Sema::AA_Returning; - case InitializedEntity::EK_Exception: - case InitializedEntity::EK_Base: - llvm_unreachable("No assignment action for C++-specific initialization"); - break; - case InitializedEntity::EK_Temporary: // FIXME: Can we tell apart casting vs. converting? return Sema::AA_Casting; - + case InitializedEntity::EK_Member: case InitializedEntity::EK_ArrayElement: case InitializedEntity::EK_VectorElement: @@ -3223,12 +3264,12 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_Exception: case InitializedEntity::EK_BlockElement: return false; - + case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Temporary: return true; } - + llvm_unreachable("missed an InitializedEntity kind?"); } @@ -3243,7 +3284,7 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_BlockElement: return false; - + case InitializedEntity::EK_Variable: case InitializedEntity::EK_Parameter: case InitializedEntity::EK_Temporary: @@ -3251,8 +3292,8 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_Exception: return true; } - - llvm_unreachable("missed an InitializedEntity kind?"); + + llvm_unreachable("missed an InitializedEntity kind?"); } /// \brief Make a (potentially elidable) temporary copy of the object @@ -3261,7 +3302,7 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) { /// /// \param S The Sema object used for type-checking. /// -/// \param T The type of the temporary object, which must either by +/// \param T The type of the temporary object, which must either be /// the type of the initializer expression or a superclass thereof. /// /// \param Enter The entity being initialized. @@ -3276,19 +3317,19 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) { /// a temporary object, or an error expression if a copy could not be /// created. static ExprResult CopyObject(Sema &S, - QualType T, - const InitializedEntity &Entity, - ExprResult CurInit, - bool IsExtraneousCopy) { + QualType T, + const InitializedEntity &Entity, + ExprResult CurInit, + bool IsExtraneousCopy) { // Determine which class type we're copying to. Expr *CurInitExpr = (Expr *)CurInit.get(); - CXXRecordDecl *Class = 0; + CXXRecordDecl *Class = 0; if (const RecordType *Record = T->getAs<RecordType>()) Class = cast<CXXRecordDecl>(Record->getDecl()); if (!Class) return move(CurInit); - // C++0x [class.copy]p34: + // C++0x [class.copy]p32: // When certain criteria are met, an implementation is allowed to // omit the copy/move construction of a class object, even if the // copy/move constructor and/or destructor for the object have @@ -3298,23 +3339,22 @@ static ExprResult CopyObject(Sema &S, // with the same cv-unqualified type, the copy/move operation // can be omitted by constructing the temporary object // directly into the target of the omitted copy/move - // + // // Note that the other three bullets are handled elsewhere. Copy // elision for return statements and throw expressions are handled as part - // of constructor initialization, while copy elision for exception handlers + // of constructor initialization, while copy elision for exception handlers // is handled by the run-time. - bool Elidable = CurInitExpr->isTemporaryObject() && - S.Context.hasSameUnqualifiedType(T, CurInitExpr->getType()); + bool Elidable = CurInitExpr->isTemporaryObject(S.Context, Class); SourceLocation Loc; switch (Entity.getKind()) { case InitializedEntity::EK_Result: Loc = Entity.getReturnLoc(); break; - + case InitializedEntity::EK_Exception: Loc = Entity.getThrowLoc(); break; - + case InitializedEntity::EK_Variable: Loc = Entity.getDecl()->getLocation(); break; @@ -3331,33 +3371,57 @@ static ExprResult CopyObject(Sema &S, break; } - // Make sure that the type we are copying is complete. + // Make sure that the type we are copying is complete. if (S.RequireCompleteType(Loc, T, S.PDiag(diag::err_temp_copy_incomplete))) return move(CurInit); - // Perform overload resolution using the class's copy constructors. + // Perform overload resolution using the class's copy/move constructors. DeclContext::lookup_iterator Con, ConEnd; OverloadCandidateSet CandidateSet(Loc); for (llvm::tie(Con, ConEnd) = S.LookupConstructors(Class); Con != ConEnd; ++Con) { - // Only consider copy constructors. - CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(*Con); - if (!Constructor || Constructor->isInvalidDecl() || - !Constructor->isCopyConstructor() || - !Constructor->isConvertingConstructor(/*AllowExplicit=*/false)) + // Only consider copy/move constructors and constructor templates. Per + // C++0x [dcl.init]p16, second bullet to class types, this + // initialization is direct-initialization. + CXXConstructorDecl *Constructor = 0; + + if ((Constructor = dyn_cast<CXXConstructorDecl>(*Con))) { + // Handle copy/moveconstructors, only. + if (!Constructor || Constructor->isInvalidDecl() || + !Constructor->isCopyOrMoveConstructor() || + !Constructor->isConvertingConstructor(/*AllowExplicit=*/true)) + continue; + + DeclAccessPair FoundDecl + = DeclAccessPair::make(Constructor, Constructor->getAccess()); + S.AddOverloadCandidate(Constructor, FoundDecl, + &CurInitExpr, 1, CandidateSet); + continue; + } + + // Handle constructor templates. + FunctionTemplateDecl *ConstructorTmpl = cast<FunctionTemplateDecl>(*Con); + if (ConstructorTmpl->isInvalidDecl()) + continue; + + Constructor = cast<CXXConstructorDecl>( + ConstructorTmpl->getTemplatedDecl()); + if (!Constructor->isConvertingConstructor(/*AllowExplicit=*/true)) continue; + // FIXME: Do we need to limit this to copy-constructor-like + // candidates? DeclAccessPair FoundDecl - = DeclAccessPair::make(Constructor, Constructor->getAccess()); - S.AddOverloadCandidate(Constructor, FoundDecl, - &CurInitExpr, 1, CandidateSet); + = DeclAccessPair::make(ConstructorTmpl, ConstructorTmpl->getAccess()); + S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, 0, + &CurInitExpr, 1, CandidateSet, true); } - + OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(S, Loc, Best)) { case OR_Success: break; - + case OR_No_Viable_Function: S.Diag(Loc, IsExtraneousCopy && !S.isSFINAEContext() ? diag::ext_rvalue_to_reference_temp_copy_no_viable @@ -3368,14 +3432,14 @@ static ExprResult CopyObject(Sema &S, if (!IsExtraneousCopy || S.isSFINAEContext()) return ExprError(); return move(CurInit); - + case OR_Ambiguous: S.Diag(Loc, diag::err_temp_copy_ambiguous) << (int)Entity.getKind() << CurInitExpr->getType() << CurInitExpr->getSourceRange(); CandidateSet.NoteCandidates(S, OCD_ViableCandidates, &CurInitExpr, 1); return ExprError(); - + case OR_Deleted: S.Diag(Loc, diag::err_temp_copy_deleted) << (int)Entity.getKind() << CurInitExpr->getType() @@ -3417,7 +3481,7 @@ static ExprResult CopyObject(Sema &S, return S.Owned(CurInitExpr); } - + // Determine the arguments required to actually perform the // constructor call (we might have derived-to-base conversions, or // the copy constructor may have default arguments). @@ -3429,8 +3493,9 @@ static ExprResult CopyObject(Sema &S, CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable, move_arg(ConstructorArgs), /*ZeroInit*/ false, - CXXConstructExpr::CK_Complete); - + CXXConstructExpr::CK_Complete, + SourceRange()); + // If we're supposed to bind temporaries, do so. if (!CurInit.isInvalid() && shouldBindAsTemporary(Entity)) CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>()); @@ -3451,7 +3516,7 @@ void InitializationSequence::PrintInitLocationNote(Sema &S, } } -ExprResult +ExprResult InitializationSequence::Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, @@ -3462,7 +3527,7 @@ InitializationSequence::Perform(Sema &S, Diagnose(S, Entity, Kind, (Expr **)Args.release(), NumArgs); return ExprError(); } - + if (SequenceKind == DependentSequence) { // If the declaration is a non-dependent, incomplete array type // that has an initializer, then its type will be completed once @@ -3512,14 +3577,14 @@ InitializationSequence::Perform(Sema &S, unsigned NumArgs = Args.size(); return S.Owned(new (S.Context) ParenListExpr(S.Context, SourceLocation(), - (Expr **)Args.release(), + (Expr **)Args.release(), NumArgs, SourceLocation())); } if (SequenceKind == NoInitialization) return S.Owned((Expr *)0); - + QualType DestType = Entity.getType().getNonReferenceType(); // FIXME: Ugly hack around the fact that Entity.getType() is not // the same as Entity.getDecl()->getType() in cases involving type merging, @@ -3529,10 +3594,10 @@ InitializationSequence::Perform(Sema &S, Entity.getType(); ExprResult CurInit = S.Owned((Expr *)0); - + assert(!Steps.empty() && "Cannot have an empty initialization sequence"); - - // For initialization steps that start with a single initializer, + + // For initialization steps that start with a single initializer, // grab the only argument out the Args and place it into the "current" // initializer. switch (Steps.front().Kind) { @@ -3551,32 +3616,38 @@ InitializationSequence::Perform(Sema &S, case SK_ListInitialization: case SK_CAssignment: case SK_StringInit: - case SK_ObjCObjectConversion: + case SK_ObjCObjectConversion: { assert(Args.size() == 1); - CurInit = ExprResult(((Expr **)(Args.get()))[0]->Retain()); - if (CurInit.isInvalid()) - return ExprError(); + Expr *CurInitExpr = Args.get()[0]; + if (!CurInitExpr) return ExprError(); + + // Read from a property when initializing something with it. + if (CurInitExpr->getObjectKind() == OK_ObjCProperty) + S.ConvertPropertyForRValue(CurInitExpr); + + CurInit = ExprResult(CurInitExpr); break; - + } + case SK_ConstructorInitialization: case SK_ZeroInitialization: break; } - - // Walk through the computed steps for the initialization sequence, + + // Walk through the computed steps for the initialization sequence, // performing the specified conversions along the way. bool ConstructorInitRequiresZeroInit = false; for (step_iterator Step = step_begin(), StepEnd = step_end(); Step != StepEnd; ++Step) { if (CurInit.isInvalid()) return ExprError(); - - Expr *CurInitExpr = (Expr *)CurInit.get(); + + Expr *CurInitExpr = CurInit.get(); QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType(); - + switch (Step->Kind) { case SK_ResolveAddressOfOverloadedFunction: - // Overload resolution determined which function invoke; update the + // Overload resolution determined which function invoke; update the // initializer to reflect that choice. S.CheckAddressOfMemberAccess(CurInitExpr, Step->Function.FoundDecl); S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation()); @@ -3584,29 +3655,29 @@ InitializationSequence::Perform(Sema &S, Step->Function.FoundDecl, Step->Function.Function); break; - + case SK_CastDerivedToBaseRValue: case SK_CastDerivedToBaseXValue: case SK_CastDerivedToBaseLValue: { // We have a derived-to-base cast that produces either an rvalue or an // lvalue. Perform that cast. - + CXXCastPath BasePath; // Casts to inaccessible base classes are allowed with C-style casts. bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast(); if (S.CheckDerivedToBaseConversion(SourceType, Step->Type, CurInitExpr->getLocStart(), - CurInitExpr->getSourceRange(), + CurInitExpr->getSourceRange(), &BasePath, IgnoreBaseAccess)) return ExprError(); - + if (S.BasePathInvolvesVirtualBase(BasePath)) { QualType T = SourceType; if (const PointerType *Pointer = T->getAs<PointerType>()) T = Pointer->getPointeeType(); if (const RecordType *RecordTy = T->getAs<RecordType>()) - S.MarkVTableUsed(CurInitExpr->getLocStart(), + S.MarkVTableUsed(CurInitExpr->getLocStart(), cast<CXXRecordDecl>(RecordTy->getDecl())); } @@ -3623,7 +3694,7 @@ InitializationSequence::Perform(Sema &S, &BasePath, VK)); break; } - + case SK_BindReference: if (FieldDecl *BitField = CurInitExpr->getBitField()) { // References cannot bind to bit fields (C++ [dcl.init.ref]p5). @@ -3643,7 +3714,7 @@ InitializationSequence::Perform(Sema &S, PrintInitLocationNote(S, Entity); return ExprError(); } - + // Reference binding does not have any corresponding ASTs. // Check exception specifications @@ -3660,16 +3731,16 @@ InitializationSequence::Perform(Sema &S, return ExprError(); break; - + case SK_ExtraneousCopyToTemporary: - CurInit = CopyObject(S, Step->Type, Entity, move(CurInit), + CurInit = CopyObject(S, Step->Type, Entity, move(CurInit), /*IsExtraneousCopy=*/true); break; case SK_UserConversion: { // We have a user-defined conversion that invokes either a constructor // or a conversion function. - CastKind CastKind = CK_Unknown; + CastKind CastKind; bool IsCopy = false; FunctionDecl *Fn = Step->Function.Function; DeclAccessPair FoundFn = Step->Function.FoundDecl; @@ -3687,25 +3758,26 @@ InitializationSequence::Perform(Sema &S, MultiExprArg(&CurInitExpr, 1), Loc, ConstructorArgs)) return ExprError(); - + // Build the an expression that constructs a temporary. - CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor, + CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor, move_arg(ConstructorArgs), /*ZeroInit*/ false, - CXXConstructExpr::CK_Complete); + CXXConstructExpr::CK_Complete, + SourceRange()); if (CurInit.isInvalid()) return ExprError(); S.CheckConstructorAccess(Kind.getLocation(), Constructor, Entity, FoundFn.getAccess()); S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()); - + CastKind = CK_ConstructorConversion; QualType Class = S.Context.getTypeDeclType(Constructor->getParent()); if (S.Context.hasSameUnqualifiedType(SourceType, Class) || S.IsDerivedFrom(SourceType, Class)) IsCopy = true; - + CreatedObject = true; } else { // Build a call to the conversion function. @@ -3714,8 +3786,8 @@ InitializationSequence::Perform(Sema &S, S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0, FoundFn); S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()); - - // FIXME: Should we move this initialization into a separate + + // FIXME: Should we move this initialization into a separate // derived-to-base conversion? I believe the answer is "no", because // we don't want to turn off access control here for c-style casts. if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0, @@ -3725,19 +3797,18 @@ InitializationSequence::Perform(Sema &S, // Do a little dance to make sure that CurInit has the proper // pointer. CurInit.release(); - + // Build the actual call to the conversion function. - CurInit = S.Owned(S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn, - Conversion)); + CurInit = S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn, Conversion); if (CurInit.isInvalid() || !CurInit.get()) return ExprError(); - + CastKind = CK_UserDefinedConversion; - + CreatedObject = Conversion->getResultType()->isRecordType(); } - - bool RequiresCopy = !IsCopy && + + bool RequiresCopy = !IsCopy && getKind() != InitializationSequence::ReferenceBinding; if (RequiresCopy || shouldBindAsTemporary(Entity)) CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>()); @@ -3745,21 +3816,22 @@ InitializationSequence::Perform(Sema &S, CurInitExpr = static_cast<Expr *>(CurInit.get()); QualType T = CurInitExpr->getType(); if (const RecordType *Record = T->getAs<RecordType>()) { - CXXDestructorDecl *Destructor + CXXDestructorDecl *Destructor = S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl())); - S.CheckDestructorAccess(CurInitExpr->getLocStart(), Destructor, + S.CheckDestructorAccess(CurInitExpr->getLocStart(), Destructor, S.PDiag(diag::err_access_dtor_temp) << T); S.MarkDeclarationReferenced(CurInitExpr->getLocStart(), Destructor); + S.DiagnoseUseOfDecl(Destructor, CurInitExpr->getLocStart()); } } - + CurInitExpr = CurInit.takeAs<Expr>(); // FIXME: xvalues CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, CurInitExpr->getType(), CastKind, CurInitExpr, 0, IsLvalue ? VK_LValue : VK_RValue)); - + if (RequiresCopy) CurInit = CopyObject(S, Entity.getType().getNonReferenceType(), Entity, move(CurInit), /*IsExtraneousCopy=*/false); @@ -3784,17 +3856,16 @@ InitializationSequence::Perform(Sema &S, } case SK_ConversionSequence: { - bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast(); - if (S.PerformImplicitConversion(CurInitExpr, Step->Type, *Step->ICS, - Sema::AA_Converting, IgnoreBaseAccess)) + getAssignmentAction(Entity), + Kind.isCStyleOrFunctionalCast())) return ExprError(); - + CurInit.release(); CurInit = S.Owned(CurInitExpr); break; } - + case SK_ListInitialization: { InitListExpr *InitList = cast<InitListExpr>(CurInitExpr); QualType Ty = Step->Type; @@ -3810,7 +3881,7 @@ InitializationSequence::Perform(Sema &S, unsigned NumArgs = Args.size(); CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Step->Function.Function); - + // Build a call to the selected constructor. ASTOwningVector<Expr*> ConstructorArgs(S); SourceLocation Loc = (Kind.isCopyInit() && Kind.getEqualLoc().isValid()) @@ -3830,11 +3901,11 @@ InitializationSequence::Perform(Sema &S, // Determine the arguments required to actually perform the constructor // call. - if (S.CompleteConstructorCall(Constructor, move(Args), + if (S.CompleteConstructorCall(Constructor, move(Args), Loc, ConstructorArgs)) return ExprError(); - - + + if (Entity.getKind() == InitializedEntity::EK_Temporary && NumArgs != 1 && // FIXME: Hack to work around cast weirdness (Kind.getKind() == InitializationKind::IK_Direct || @@ -3843,24 +3914,34 @@ InitializationSequence::Perform(Sema &S, unsigned NumExprs = ConstructorArgs.size(); Expr **Exprs = (Expr **)ConstructorArgs.take(); S.MarkDeclarationReferenced(Loc, Constructor); + S.DiagnoseUseOfDecl(Constructor, Loc); + + TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo(); + if (!TSInfo) + TSInfo = S.Context.getTrivialTypeSourceInfo(Entity.getType(), Loc); + CurInit = S.Owned(new (S.Context) CXXTemporaryObjectExpr(S.Context, Constructor, - Entity.getType(), - Loc, - Exprs, + TSInfo, + Exprs, NumExprs, - Kind.getParenRange().getEnd(), + Kind.getParenRange(), ConstructorInitRequiresZeroInit)); } else { CXXConstructExpr::ConstructionKind ConstructKind = CXXConstructExpr::CK_Complete; - + if (Entity.getKind() == InitializedEntity::EK_Base) { ConstructKind = Entity.getBaseSpecifier()->isVirtual() ? - CXXConstructExpr::CK_VirtualBase : + CXXConstructExpr::CK_VirtualBase : CXXConstructExpr::CK_NonVirtualBase; - } - + } + + // Only get the parenthesis range if it is a direct construction. + SourceRange parenRange = + Kind.getKind() == InitializationKind::IK_Direct ? + Kind.getParenRange() : SourceRange(); + // If the entity allows NRVO, mark the construction as elidable // unconditionally. if (Entity.allowsNRVO()) @@ -3868,13 +3949,15 @@ InitializationSequence::Perform(Sema &S, Constructor, /*Elidable=*/true, move_arg(ConstructorArgs), ConstructorInitRequiresZeroInit, - ConstructKind); + ConstructKind, + parenRange); else CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(), - Constructor, + Constructor, move_arg(ConstructorArgs), ConstructorInitRequiresZeroInit, - ConstructKind); + ConstructKind, + parenRange); } if (CurInit.isInvalid()) return ExprError(); @@ -3883,17 +3966,17 @@ InitializationSequence::Perform(Sema &S, S.CheckConstructorAccess(Loc, Constructor, Entity, Step->Function.FoundDecl.getAccess()); S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Loc); - + if (shouldBindAsTemporary(Entity)) CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>()); - + break; } - + case SK_ZeroInitialization: { step_iterator NextStep = Step; ++NextStep; - if (NextStep != StepEnd && + if (NextStep != StepEnd && NextStep->Kind == SK_ConstructorInitialization) { // The need for zero-initialization is recorded directly into // the call to the object's constructor within the next step. @@ -3901,8 +3984,14 @@ InitializationSequence::Perform(Sema &S, } else if (Kind.getKind() == InitializationKind::IK_Value && S.getLangOptions().CPlusPlus && !Kind.isImplicitValueInit()) { - CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr(Step->Type, - Kind.getRange().getBegin(), + TypeSourceInfo *TSInfo = Entity.getTypeSourceInfo(); + if (!TSInfo) + TSInfo = S.Context.getTrivialTypeSourceInfo(Step->Type, + Kind.getRange().getBegin()); + + CurInit = S.Owned(new (S.Context) CXXScalarValueInitExpr( + TSInfo->getType().getNonLValueExprType(S.Context), + TSInfo, Kind.getRange().getEnd())); } else { CurInit = S.Owned(new (S.Context) ImplicitValueInitExpr(Step->Type)); @@ -3925,7 +4014,7 @@ InitializationSequence::Perform(Sema &S, bool Complained; if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(), Step->Type, SourceType, - CurInitExpr, + CurInitExpr, getAssignmentAction(Entity), &Complained)) { PrintInitLocationNote(S, Entity); @@ -3945,7 +4034,7 @@ InitializationSequence::Perform(Sema &S, } case SK_ObjCObjectConversion: - S.ImpCastExprToType(CurInitExpr, Step->Type, + S.ImpCastExprToType(CurInitExpr, Step->Type, CK_ObjCObjectLValueCast, S.CastCategory(CurInitExpr)); CurInit.release(); @@ -3953,20 +4042,27 @@ InitializationSequence::Perform(Sema &S, break; } } - + + // Diagnose non-fatal problems with the completed initialization. + if (Entity.getKind() == InitializedEntity::EK_Member && + cast<FieldDecl>(Entity.getDecl())->isBitField()) + S.CheckBitFieldInitialization(Kind.getLocation(), + cast<FieldDecl>(Entity.getDecl()), + CurInit.get()); + return move(CurInit); } //===----------------------------------------------------------------------===// // Diagnose initialization failures //===----------------------------------------------------------------------===// -bool InitializationSequence::Diagnose(Sema &S, +bool InitializationSequence::Diagnose(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, Expr **Args, unsigned NumArgs) { if (SequenceKind != FailedSequence) return false; - + QualType DestType = Entity.getType(); switch (Failure) { case FK_TooManyInitsForReference: @@ -3978,22 +4074,22 @@ bool InitializationSequence::Diagnose(Sema &S, S.Diag(Kind.getLocation(), diag::err_reference_has_multiple_inits) << SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd()); break; - + case FK_ArrayNeedsInitList: case FK_ArrayNeedsInitListOrStringLiteral: S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << (Failure == FK_ArrayNeedsInitListOrStringLiteral); break; - + case FK_AddressOfOverloadFailed: { DeclAccessPair Found; - S.ResolveAddressOfOverloadedFunction(Args[0], + S.ResolveAddressOfOverloadedFunction(Args[0], DestType.getNonReferenceType(), true, Found); break; } - + case FK_ReferenceInitOverloadFailed: case FK_UserConversionOverloadFailed: switch (FailedOverloadResult) { @@ -4009,21 +4105,22 @@ bool InitializationSequence::Diagnose(Sema &S, FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args, NumArgs); break; - + case OR_No_Viable_Function: S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition) << Args[0]->getType() << DestType.getNonReferenceType() << Args[0]->getSourceRange(); FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs); break; - + case OR_Deleted: { S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function) << Args[0]->getType() << DestType.getNonReferenceType() << Args[0]->getSourceRange(); OverloadCandidateSet::iterator Best; OverloadingResult Ovl - = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); + = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best, + true); if (Ovl == OR_Deleted) { S.Diag(Best->Function->getLocation(), diag::note_unavailable_here) << Best->Function->isDeleted(); @@ -4032,16 +4129,16 @@ bool InitializationSequence::Diagnose(Sema &S, } break; } - + case OR_Success: llvm_unreachable("Conversion did not fail!"); break; } break; - + case FK_NonConstLValueReferenceBindingToTemporary: case FK_NonConstLValueReferenceBindingToUnrelated: - S.Diag(Kind.getLocation(), + S.Diag(Kind.getLocation(), Failure == FK_NonConstLValueReferenceBindingToTemporary ? diag::err_lvalue_reference_bind_to_temporary : diag::err_lvalue_reference_bind_to_unrelated) @@ -4050,47 +4147,54 @@ bool InitializationSequence::Diagnose(Sema &S, << Args[0]->getType() << Args[0]->getSourceRange(); break; - + case FK_RValueReferenceBindingToLValue: S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref) + << DestType.getNonReferenceType() << Args[0]->getType() << Args[0]->getSourceRange(); break; - + case FK_ReferenceInitDropsQualifiers: S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) << DestType.getNonReferenceType() << Args[0]->getType() << Args[0]->getSourceRange(); break; - + case FK_ReferenceInitFailed: S.Diag(Kind.getLocation(), diag::err_reference_bind_failed) << DestType.getNonReferenceType() - << (Args[0]->isLvalue(S.Context) == Expr::LV_Valid) + << Args[0]->isLValue() << Args[0]->getType() << Args[0]->getSourceRange(); break; - - case FK_ConversionFailed: + + case FK_ConversionFailed: { + QualType FromType = Args[0]->getType(); S.Diag(Kind.getLocation(), diag::err_init_conversion_failed) << (int)Entity.getKind() << DestType - << (Args[0]->isLvalue(S.Context) == Expr::LV_Valid) - << Args[0]->getType() + << Args[0]->isLValue() + << FromType << Args[0]->getSourceRange(); break; - + } case FK_TooManyInitsForScalar: { SourceRange R; if (InitListExpr *InitList = dyn_cast<InitListExpr>(Args[0])) - R = SourceRange(InitList->getInit(1)->getLocStart(), + R = SourceRange(InitList->getInit(0)->getLocEnd(), InitList->getLocEnd()); else - R = SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd()); + R = SourceRange(Args[0]->getLocEnd(), Args[NumArgs - 1]->getLocEnd()); - S.Diag(Kind.getLocation(), diag::err_excess_initializers) - << /*scalar=*/2 << R; + R.setBegin(S.PP.getLocForEndOfToken(R.getBegin())); + if (Kind.isCStyleOrFunctionalCast()) + S.Diag(Kind.getLocation(), diag::err_builtin_func_cast_more_than_one_arg) + << R; + else + S.Diag(Kind.getLocation(), diag::err_excess_initializers) + << /*scalar=*/2 << R; break; } @@ -4103,13 +4207,13 @@ bool InitializationSequence::Diagnose(Sema &S, S.Diag(Kind.getLocation(), diag::err_init_list_bad_dest_type) << (DestType->isRecordType()) << DestType << Args[0]->getSourceRange(); break; - + case FK_ConstructorOverloadFailed: { SourceRange ArgsRange; if (NumArgs) - ArgsRange = SourceRange(Args[0]->getLocStart(), + ArgsRange = SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd()); - + // FIXME: Using "DestType" for the entity we're printing is probably // bad. switch (FailedOverloadResult) { @@ -4119,7 +4223,7 @@ bool InitializationSequence::Diagnose(Sema &S, FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args, NumArgs); break; - + case OR_No_Viable_Function: if (Kind.getKind() == InitializationKind::IK_Default && (Entity.getKind() == InitializedEntity::EK_Base || @@ -4153,7 +4257,7 @@ bool InitializationSequence::Diagnose(Sema &S, if (const RecordType *Record = Entity.getType()->getAs<RecordType>()) - S.Diag(Record->getDecl()->getLocation(), + S.Diag(Record->getDecl()->getLocation(), diag::note_previous_decl) << S.Context.getTagDeclType(Record->getDecl()); } @@ -4164,7 +4268,7 @@ bool InitializationSequence::Diagnose(Sema &S, << DestType << ArgsRange; FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args, NumArgs); break; - + case OR_Deleted: { S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init) << true << DestType << ArgsRange; @@ -4179,14 +4283,14 @@ bool InitializationSequence::Diagnose(Sema &S, } break; } - + case OR_Success: llvm_unreachable("Conversion did not fail!"); break; } break; } - + case FK_DefaultInitOfConst: if (Entity.getKind() == InitializedEntity::EK_Member && isa<CXXConstructorDecl>(S.CurContext)) { @@ -4206,13 +4310,13 @@ bool InitializationSequence::Diagnose(Sema &S, << DestType << (bool)DestType->getAs<RecordType>(); } break; - + case FK_Incomplete: - S.RequireCompleteType(Kind.getLocation(), DestType, + S.RequireCompleteType(Kind.getLocation(), DestType, diag::err_init_incomplete_type); - break; + break; } - + PrintInitLocationNote(S, Entity); return true; } @@ -4225,95 +4329,95 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const { case FK_TooManyInitsForReference: OS << "too many initializers for reference"; break; - + case FK_ArrayNeedsInitList: OS << "array requires initializer list"; break; - + case FK_ArrayNeedsInitListOrStringLiteral: OS << "array requires initializer list or string literal"; break; - + case FK_AddressOfOverloadFailed: OS << "address of overloaded function failed"; break; - + case FK_ReferenceInitOverloadFailed: OS << "overload resolution for reference initialization failed"; break; - + case FK_NonConstLValueReferenceBindingToTemporary: OS << "non-const lvalue reference bound to temporary"; break; - + case FK_NonConstLValueReferenceBindingToUnrelated: OS << "non-const lvalue reference bound to unrelated type"; break; - + case FK_RValueReferenceBindingToLValue: OS << "rvalue reference bound to an lvalue"; break; - + case FK_ReferenceInitDropsQualifiers: OS << "reference initialization drops qualifiers"; break; - + case FK_ReferenceInitFailed: OS << "reference initialization failed"; break; - + case FK_ConversionFailed: OS << "conversion failed"; break; - + case FK_TooManyInitsForScalar: OS << "too many initializers for scalar"; break; - + case FK_ReferenceBindingToInitList: OS << "referencing binding to initializer list"; break; - + case FK_InitListBadDestinationType: OS << "initializer list for non-aggregate, non-scalar type"; break; - + case FK_UserConversionOverloadFailed: OS << "overloading failed for user-defined conversion"; break; - + case FK_ConstructorOverloadFailed: OS << "constructor overloading failed"; break; - + case FK_DefaultInitOfConst: OS << "default initialization of a const variable"; break; - + case FK_Incomplete: OS << "initialization of incomplete type"; break; - } + } OS << '\n'; return; } - + case DependentSequence: OS << "Dependent sequence: "; return; - + case UserDefinedConversion: OS << "User-defined conversion sequence: "; break; - + case ConstructorInitialization: OS << "Constructor initialization sequence: "; break; - + case ReferenceBinding: OS << "Reference binding: "; break; - + case ListInitialization: OS << "List initialization: "; break; @@ -4321,54 +4425,54 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const { case ZeroInitialization: OS << "Zero initialization\n"; return; - + case NoInitialization: OS << "No initialization\n"; return; - + case StandardConversion: OS << "Standard conversion: "; break; - + case CAssignment: OS << "C assignment: "; break; - + case StringInit: OS << "String initialization: "; break; } - + for (step_iterator S = step_begin(), SEnd = step_end(); S != SEnd; ++S) { if (S != step_begin()) { OS << " -> "; } - + switch (S->Kind) { case SK_ResolveAddressOfOverloadedFunction: OS << "resolve address of overloaded function"; break; - + case SK_CastDerivedToBaseRValue: OS << "derived-to-base case (rvalue" << S->Type.getAsString() << ")"; break; - + case SK_CastDerivedToBaseXValue: OS << "derived-to-base case (xvalue" << S->Type.getAsString() << ")"; break; - + case SK_CastDerivedToBaseLValue: OS << "derived-to-base case (lvalue" << S->Type.getAsString() << ")"; break; - + case SK_BindReference: OS << "bind reference to lvalue"; break; - + case SK_BindReferenceToTemporary: OS << "bind reference to a temporary"; break; - + case SK_ExtraneousCopyToTemporary: OS << "extraneous C++03 copy to temporary"; break; @@ -4386,29 +4490,29 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const { case SK_QualificationConversionLValue: OS << "qualification conversion (lvalue)"; break; - + case SK_ConversionSequence: OS << "implicit conversion sequence ("; S->ICS->DebugPrint(); // FIXME: use OS OS << ")"; break; - + case SK_ListInitialization: OS << "list initialization"; break; - + case SK_ConstructorInitialization: OS << "constructor initialization"; break; - + case SK_ZeroInitialization: OS << "zero initialization"; break; - + case SK_CAssignment: OS << "C assignment"; break; - + case SK_StringInit: OS << "string initialization"; break; @@ -4427,14 +4531,14 @@ void InitializationSequence::dump() const { //===----------------------------------------------------------------------===// // Initialization helper functions //===----------------------------------------------------------------------===// -ExprResult +ExprResult Sema::PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init) { if (Init.isInvalid()) return ExprError(); - Expr *InitE = (Expr *)Init.get(); + Expr *InitE = Init.get(); assert(InitE && "No initialization expression?"); if (EqualLoc.isInvalid()) |