diff options
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 410 |
1 files changed, 350 insertions, 60 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index a33f5d0..9fbcbab 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -769,7 +769,8 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, // subaggregate, brace elision is assumed and the initializer is // considered for the initialization of the first member of // the subaggregate. - if (ElemType->isAggregateType() || ElemType->isVectorType()) { + if (!SemaRef.getLangOptions().OpenCL && + (ElemType->isAggregateType() || ElemType->isVectorType())) { CheckImplicitInitList(Entity, IList, ElemType, Index, StructuredList, StructuredIndex); ++StructuredIndex; @@ -1184,6 +1185,15 @@ void InitListChecker::CheckStructUnionTypes(const InitializedEntity &Entity, continue; } + // Make sure we can use this declaration. + if (SemaRef.DiagnoseUseOfDecl(*Field, + IList->getInit(Index)->getLocStart())) { + ++Index; + ++Field; + hadError = true; + continue; + } + InitializedEntity MemberEntity = InitializedEntity::InitializeMember(*Field, &Entity); CheckSubElementType(MemberEntity, IList, Field->getType(), Index, @@ -1443,19 +1453,23 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // was a typo for another field name. LookupResult R(SemaRef, FieldName, D->getFieldLoc(), Sema::LookupMemberName); - if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl(), false, - Sema::CTC_NoKeywords) && - (ReplacementField = R.getAsSingle<FieldDecl>()) && + TypoCorrection Corrected = SemaRef.CorrectTypo( + DeclarationNameInfo(FieldName, D->getFieldLoc()), + Sema::LookupMemberName, /*Scope=*/NULL, /*SS=*/NULL, + RT->getDecl(), false, Sema::CTC_NoKeywords); + if ((ReplacementField = Corrected.getCorrectionDeclAs<FieldDecl>()) && ReplacementField->getDeclContext()->getRedeclContext() ->Equals(RT->getDecl())) { + std::string CorrectedStr( + Corrected.getAsString(SemaRef.getLangOptions())); + std::string CorrectedQuotedStr( + Corrected.getQuoted(SemaRef.getLangOptions())); SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown_suggest) - << FieldName << CurrentObjectType << R.getLookupName() - << FixItHint::CreateReplacement(D->getFieldLoc(), - R.getLookupName().getAsString()); + << FieldName << CurrentObjectType << CorrectedQuotedStr + << FixItHint::CreateReplacement(D->getFieldLoc(), CorrectedStr); SemaRef.Diag(ReplacementField->getLocation(), - diag::note_previous_decl) - << ReplacementField->getDeclName(); + diag::note_previous_decl) << CorrectedQuotedStr; } else { SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown) << FieldName << CurrentObjectType; @@ -1499,6 +1513,12 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, StructuredList->setInitializedFieldInUnion(*Field); } + // Make sure we can use this declaration. + if (SemaRef.DiagnoseUseOfDecl(*Field, D->getFieldLoc())) { + ++Index; + return true; + } + // Update the designator with the field declaration. D->setField(*Field); @@ -2029,10 +2049,10 @@ InitializedEntity InitializedEntity::InitializeBase(ASTContext &Context, DeclarationName InitializedEntity::getName() const { switch (getKind()) { - case EK_Parameter: - if (!VariableOrMember) - return DeclarationName(); - // Fall through + case EK_Parameter: { + ParmVarDecl *D = reinterpret_cast<ParmVarDecl*>(Parameter & ~0x1); + return (D ? D->getDeclName() : DeclarationName()); + } case EK_Variable: case EK_Member: @@ -2057,10 +2077,12 @@ DeclarationName InitializedEntity::getName() const { DeclaratorDecl *InitializedEntity::getDecl() const { switch (getKind()) { case EK_Variable: - case EK_Parameter: case EK_Member: return VariableOrMember; + case EK_Parameter: + return reinterpret_cast<ParmVarDecl*>(Parameter & ~0x1); + case EK_Result: case EK_Exception: case EK_New: @@ -2123,6 +2145,9 @@ void InitializationSequence::Step::Destroy() { case SK_StringInit: case SK_ObjCObjectConversion: case SK_ArrayInit: + case SK_PassByIndirectCopyRestore: + case SK_PassByIndirectRestore: + case SK_ProduceObjCObject: break; case SK_ConversionSequence: @@ -2131,7 +2156,7 @@ void InitializationSequence::Step::Destroy() { } bool InitializationSequence::isDirectReferenceBinding() const { - return getKind() == ReferenceBinding && Steps.back().Kind == SK_BindReference; + return !Steps.empty() && Steps.back().Kind == SK_BindReference; } bool InitializationSequence::isAmbiguous() const { @@ -2306,6 +2331,22 @@ void InitializationSequence::AddArrayInitStep(QualType T) { Steps.push_back(S); } +void InitializationSequence::AddPassByIndirectCopyRestoreStep(QualType type, + bool shouldCopy) { + Step s; + s.Kind = (shouldCopy ? SK_PassByIndirectCopyRestore + : SK_PassByIndirectRestore); + s.Type = type; + Steps.push_back(s); +} + +void InitializationSequence::AddProduceObjCObjectStep(QualType T) { + Step S; + S.Kind = SK_ProduceObjCObject; + S.Type = T; + Steps.push_back(S); +} + void InitializationSequence::SetOverloadFailure(FailureKind Failure, OverloadingResult Result) { setSequenceKind(FailedSequence); @@ -2317,6 +2358,33 @@ void InitializationSequence::SetOverloadFailure(FailureKind Failure, // Attempt initialization //===----------------------------------------------------------------------===// +static void MaybeProduceObjCObject(Sema &S, + InitializationSequence &Sequence, + const InitializedEntity &Entity) { + if (!S.getLangOptions().ObjCAutoRefCount) return; + + /// When initializing a parameter, produce the value if it's marked + /// __attribute__((ns_consumed)). + if (Entity.getKind() == InitializedEntity::EK_Parameter) { + if (!Entity.isParameterConsumed()) + return; + + assert(Entity.getType()->isObjCRetainableType() && + "consuming an object of unretainable type?"); + Sequence.AddProduceObjCObjectStep(Entity.getType()); + + /// When initializing a return value, if the return type is a + /// retainable type, then returns need to immediately retain the + /// object. If an autorelease is required, it will be done at the + /// last instant. + } else if (Entity.getKind() == InitializedEntity::EK_Result) { + if (!Entity.getType()->isObjCRetainableType()) + return; + + Sequence.AddProduceObjCObjectStep(Entity.getType()); + } +} + /// \brief Attempt list initialization (C++0x [dcl.init.list]) static void TryListInitialization(Sema &S, const InitializedEntity &Entity, @@ -2380,13 +2448,16 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, bool DerivedToBase; bool ObjCConversion; + bool ObjCLifetimeConversion; assert(!S.CompareReferenceRelationship(Initializer->getLocStart(), T1, T2, DerivedToBase, - ObjCConversion) && + ObjCConversion, + ObjCLifetimeConversion) && "Must have incompatible references when binding via conversion"); (void)DerivedToBase; (void)ObjCConversion; - + (void)ObjCLifetimeConversion; + // Build the candidate set directly in the initialization sequence // structure, so that it will persist if we fail. OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet(); @@ -2513,10 +2584,12 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S, bool NewDerivedToBase = false; bool NewObjCConversion = false; + bool NewObjCLifetimeConversion = false; Sema::ReferenceCompareResult NewRefRelationship = S.CompareReferenceRelationship(DeclLoc, T1, T2.getNonLValueExprType(S.Context), - NewDerivedToBase, NewObjCConversion); + NewDerivedToBase, NewObjCConversion, + NewObjCLifetimeConversion); if (NewRefRelationship == Sema::Ref_Incompatible) { // If the type we've converted to is not reference-related to the // type we're looking for, then there is another conversion step @@ -2550,8 +2623,6 @@ static void TryReferenceInitialization(Sema &S, const InitializationKind &Kind, Expr *Initializer, InitializationSequence &Sequence) { - Sequence.setSequenceKind(InitializationSequence::ReferenceBinding); - QualType DestType = Entity.getType(); QualType cv1T1 = DestType->getAs<ReferenceType>()->getPointeeType(); Qualifiers T1Quals; @@ -2584,10 +2655,11 @@ static void TryReferenceInitialization(Sema &S, bool isRValueRef = !isLValueRef; bool DerivedToBase = false; bool ObjCConversion = false; + bool ObjCLifetimeConversion = false; Expr::Classification InitCategory = Initializer->Classify(S.Context); Sema::ReferenceCompareResult RefRelationship = S.CompareReferenceRelationship(DeclLoc, cv1T1, cv2T2, DerivedToBase, - ObjCConversion); + ObjCConversion, ObjCLifetimeConversion); // C++0x [dcl.init.ref]p5: // A reference to type "cv1 T1" is initialized by an expression of type @@ -2746,11 +2818,15 @@ static void TryReferenceInitialization(Sema &S, InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1); - if (S.TryImplicitConversion(Sequence, TempEntity, Initializer, + ImplicitConversionSequence ICS + = S.TryImplicitConversion(Initializer, TempEntity.getType(), /*SuppressUserConversions*/ false, AllowExplicit, /*FIXME:InOverloadResolution=*/false, - /*CStyle=*/Kind.isCStyleOrFunctionalCast())) { + /*CStyle=*/Kind.isCStyleOrFunctionalCast(), + /*AllowObjCWritebackConversion=*/false); + + if (ICS.isBad()) { // 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 @@ -2764,6 +2840,8 @@ static void TryReferenceInitialization(Sema &S, else Sequence.SetFailed(InitializationSequence::FK_ReferenceInitFailed); return; + } else { + Sequence.AddConversionSequenceStep(ICS, TempEntity.getType()); } // [...] If T1 is reference-related to T2, cv1 must be the @@ -2953,10 +3031,8 @@ static void TryDefaultInitialization(Sema &S, // 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(); - + QualType DestType = S.Context.getBaseElementType(Entity.getType()); + // - 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); @@ -2970,8 +3046,16 @@ static void TryDefaultInitialization(Sema &S, // 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 // default constructor. - if (DestType.isConstQualified() && S.getLangOptions().CPlusPlus) + if (DestType.isConstQualified() && S.getLangOptions().CPlusPlus) { Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst); + return; + } + + // If the destination type has a lifetime property, zero-initialize it. + if (DestType.getQualifiers().hasObjCLifetime()) { + Sequence.AddZeroInitializationStep(Entity.getType()); + return; + } } /// \brief Attempt a user-defined conversion between two types (C++ [dcl.init]), @@ -3125,6 +3209,86 @@ static void TryUserDefinedConversion(Sema &S, } } +/// The non-zero enum values here are indexes into diagnostic alternatives. +enum InvalidICRKind { IIK_okay, IIK_nonlocal, IIK_nonscalar }; + +/// Determines whether this expression is an acceptable ICR source. +static InvalidICRKind isInvalidICRSource(ASTContext &C, Expr *e, + bool isAddressOf) { + // Skip parens. + e = e->IgnoreParens(); + + // Skip address-of nodes. + if (UnaryOperator *op = dyn_cast<UnaryOperator>(e)) { + if (op->getOpcode() == UO_AddrOf) + return isInvalidICRSource(C, op->getSubExpr(), /*addressof*/ true); + + // Skip certain casts. + } else if (CastExpr *ce = dyn_cast<CastExpr>(e)) { + switch (ce->getCastKind()) { + case CK_Dependent: + case CK_BitCast: + case CK_LValueBitCast: + case CK_NoOp: + return isInvalidICRSource(C, ce->getSubExpr(), isAddressOf); + + case CK_ArrayToPointerDecay: + return IIK_nonscalar; + + case CK_NullToPointer: + return IIK_okay; + + default: + break; + } + + // If we have a declaration reference, it had better be a local variable. + } else if (isa<DeclRefExpr>(e) || isa<BlockDeclRefExpr>(e)) { + if (!isAddressOf) return IIK_nonlocal; + + VarDecl *var; + if (isa<DeclRefExpr>(e)) { + var = dyn_cast<VarDecl>(cast<DeclRefExpr>(e)->getDecl()); + if (!var) return IIK_nonlocal; + } else { + var = cast<BlockDeclRefExpr>(e)->getDecl(); + } + + return (var->hasLocalStorage() ? IIK_okay : IIK_nonlocal); + + // If we have a conditional operator, check both sides. + } else if (ConditionalOperator *cond = dyn_cast<ConditionalOperator>(e)) { + if (InvalidICRKind iik = isInvalidICRSource(C, cond->getLHS(), isAddressOf)) + return iik; + + return isInvalidICRSource(C, cond->getRHS(), isAddressOf); + + // These are never scalar. + } else if (isa<ArraySubscriptExpr>(e)) { + return IIK_nonscalar; + + // Otherwise, it needs to be a null pointer constant. + } else { + return (e->isNullPointerConstant(C, Expr::NPC_ValueDependentIsNull) + ? IIK_okay : IIK_nonlocal); + } + + return IIK_nonlocal; +} + +/// Check whether the given expression is a valid operand for an +/// indirect copy/restore. +static void checkIndirectCopyRestoreSource(Sema &S, Expr *src) { + assert(src->isRValue()); + + InvalidICRKind iik = isInvalidICRSource(S.Context, src, false); + if (iik == IIK_okay) return; + + S.Diag(src->getExprLoc(), diag::err_arc_nonlocal_writeback) + << ((unsigned) iik - 1) // shift index into diagnostic explanations + << src->getSourceRange(); +} + /// \brief Determine whether we have compatible array types for the /// purposes of GNU by-copy array initialization. static bool hasCompatibleArrayTypes(ASTContext &Context, @@ -3144,6 +3308,53 @@ static bool hasCompatibleArrayTypes(ASTContext &Context, return Source->isConstantArrayType() && Dest->isIncompleteArrayType(); } +static bool tryObjCWritebackConversion(Sema &S, + InitializationSequence &Sequence, + const InitializedEntity &Entity, + Expr *Initializer) { + bool ArrayDecay = false; + QualType ArgType = Initializer->getType(); + QualType ArgPointee; + if (const ArrayType *ArgArrayType = S.Context.getAsArrayType(ArgType)) { + ArrayDecay = true; + ArgPointee = ArgArrayType->getElementType(); + ArgType = S.Context.getPointerType(ArgPointee); + } + + // Handle write-back conversion. + QualType ConvertedArgType; + if (!S.isObjCWritebackConversion(ArgType, Entity.getType(), + ConvertedArgType)) + return false; + + // We should copy unless we're passing to an argument explicitly + // marked 'out'. + bool ShouldCopy = true; + if (ParmVarDecl *param = cast_or_null<ParmVarDecl>(Entity.getDecl())) + ShouldCopy = (param->getObjCDeclQualifier() != ParmVarDecl::OBJC_TQ_Out); + + // Do we need an lvalue conversion? + if (ArrayDecay || Initializer->isGLValue()) { + ImplicitConversionSequence ICS; + ICS.setStandard(); + ICS.Standard.setAsIdentityConversion(); + + QualType ResultType; + if (ArrayDecay) { + ICS.Standard.First = ICK_Array_To_Pointer; + ResultType = S.Context.getPointerType(ArgPointee); + } else { + ICS.Standard.First = ICK_Lvalue_To_Rvalue; + ResultType = Initializer->getType().getNonLValueExprType(S.Context); + } + + Sequence.AddConversionSequenceStep(ICS, ResultType); + } + + Sequence.AddPassByIndirectCopyRestoreStep(Entity.getType(), ShouldCopy); + return true; +} + InitializationSequence::InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, @@ -3255,12 +3466,28 @@ InitializationSequence::InitializationSequence(Sema &S, return; } - // Handle initialization in C + // Determine whether we should consider writeback conversions for + // Objective-C ARC. + bool allowObjCWritebackConversion = S.getLangOptions().ObjCAutoRefCount && + Entity.getKind() == InitializedEntity::EK_Parameter; + + // We're at the end of the line for C: it's either a write-back conversion + // or it's a C assignment. There's no need to check anything else. if (!S.getLangOptions().CPlusPlus) { + // If allowed, check whether this is an Objective-C writeback conversion. + if (allowObjCWritebackConversion && + tryObjCWritebackConversion(S, *this, Entity, Initializer)) { + return; + } + + // Handle initialization in C AddCAssignmentStep(DestType); + MaybeProduceObjCObject(S, *this, Entity); return; } + assert(S.getLangOptions().CPlusPlus); + // - If the destination type is a (possibly cv-qualified) class type: if (DestType->isRecordType()) { // - If the initialization is direct-initialization, or if it is @@ -3294,6 +3521,7 @@ InitializationSequence::InitializationSequence(Sema &S, // type, conversion functions are considered. if (!SourceType.isNull() && SourceType->isRecordType()) { TryUserDefinedConversion(S, Entity, Kind, Initializer, *this); + MaybeProduceObjCObject(S, *this, Entity); return; } @@ -3302,12 +3530,38 @@ InitializationSequence::InitializationSequence(Sema &S, // conversions (Clause 4) will be used, if necessary, to convert 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, + + ImplicitConversionSequence ICS + = S.TryImplicitConversion(Initializer, Entity.getType(), + /*SuppressUserConversions*/true, /*AllowExplicitConversions*/ false, /*InOverloadResolution*/ false, - /*CStyle=*/Kind.isCStyleOrFunctionalCast())) - { + /*CStyle=*/Kind.isCStyleOrFunctionalCast(), + allowObjCWritebackConversion); + + if (ICS.isStandard() && + ICS.Standard.Second == ICK_Writeback_Conversion) { + // Objective-C ARC writeback conversion. + + // We should copy unless we're passing to an argument explicitly + // marked 'out'. + bool ShouldCopy = true; + if (ParmVarDecl *Param = cast_or_null<ParmVarDecl>(Entity.getDecl())) + ShouldCopy = (Param->getObjCDeclQualifier() != ParmVarDecl::OBJC_TQ_Out); + + // If there was an lvalue adjustment, add it as a separate conversion. + if (ICS.Standard.First == ICK_Array_To_Pointer || + ICS.Standard.First == ICK_Lvalue_To_Rvalue) { + ImplicitConversionSequence LvalueICS; + LvalueICS.setStandard(); + LvalueICS.Standard.setAsIdentityConversion(); + LvalueICS.Standard.setAllToTypes(ICS.Standard.getToType(0)); + LvalueICS.Standard.First = ICS.Standard.First; + AddConversionSequenceStep(LvalueICS, ICS.Standard.getToType(0)); + } + + AddPassByIndirectCopyRestoreStep(Entity.getType(), ShouldCopy); + } else if (ICS.isBad()) { DeclAccessPair dap; if (Initializer->getType() == Context.OverloadTy && !S.ResolveAddressOfOverloadedFunction(Initializer @@ -3315,6 +3569,10 @@ InitializationSequence::InitializationSequence(Sema &S, SetFailed(InitializationSequence::FK_AddressOfOverloadFailed); else SetFailed(InitializationSequence::FK_ConversionFailed); + } else { + AddConversionSequenceStep(ICS, Entity.getType()); + + MaybeProduceObjCObject(S, *this, Entity); } } @@ -3560,7 +3818,7 @@ static ExprResult CopyObject(Sema &S, << (int)Entity.getKind() << CurInitExpr->getType() << CurInitExpr->getSourceRange(); S.Diag(Best->Function->getLocation(), diag::note_unavailable_here) - << Best->Function->isDeleted(); + << 1 << Best->Function->isDeleted(); return ExprError(); } @@ -3633,6 +3891,11 @@ void InitializationSequence::PrintInitLocationNote(Sema &S, } } +static bool isReferenceBinding(const InitializationSequence::Step &s) { + return s.Kind == InitializationSequence::SK_BindReference || + s.Kind == InitializationSequence::SK_BindReferenceToTemporary; +} + ExprResult InitializationSequence::Perform(Sema &S, const InitializedEntity &Entity, @@ -3684,19 +3947,9 @@ InitializationSequence::Perform(Sema &S, } } - - if (Kind.getKind() == InitializationKind::IK_Copy || Kind.isExplicitCast()) - return ExprResult(Args.release()[0]); - - if (Args.size() == 0) - return S.Owned((Expr *)0); - - unsigned NumArgs = Args.size(); - return S.Owned(new (S.Context) ParenListExpr(S.Context, - SourceLocation(), - (Expr **)Args.release(), - NumArgs, - SourceLocation())); + assert(Kind.getKind() == InitializationKind::IK_Copy || + Kind.isExplicitCast()); + return ExprResult(Args.release()[0]); } // No steps means no initialization. @@ -3733,7 +3986,10 @@ InitializationSequence::Perform(Sema &S, case SK_CAssignment: case SK_StringInit: case SK_ObjCObjectConversion: - case SK_ArrayInit: { + case SK_ArrayInit: + case SK_PassByIndirectCopyRestore: + case SK_PassByIndirectRestore: + case SK_ProduceObjCObject: { assert(Args.size() == 1); CurInit = Args.get()[0]; if (!CurInit.get()) return ExprError(); @@ -3841,12 +4097,22 @@ InitializationSequence::Perform(Sema &S, break; case SK_BindReferenceToTemporary: - // Reference binding does not have any corresponding ASTs. - // Check exception specifications if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType)) return ExprError(); + // Materialize the temporary into memory. + CurInit = new (S.Context) MaterializeTemporaryExpr( + Entity.getType().getNonReferenceType(), + CurInit.get(), + Entity.getType()->isLValueReferenceType()); + + // If we're binding to an Objective-C object that has lifetime, we + // need cleanups. + if (S.getLangOptions().ObjCAutoRefCount && + CurInit.get()->getType()->isObjCLifetimeType()) + S.ExprNeedsCleanups = true; + break; case SK_ExtraneousCopyToTemporary: @@ -3925,8 +4191,7 @@ InitializationSequence::Perform(Sema &S, CreatedObject = Conversion->getResultType()->isRecordType(); } - bool RequiresCopy = !IsCopy && - getKind() != InitializationSequence::ReferenceBinding; + bool RequiresCopy = !IsCopy && !isReferenceBinding(Steps.back()); if (RequiresCopy || shouldBindAsTemporary(Entity)) CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>()); else if (CreatedObject && shouldDestroyTemporary(Entity)) { @@ -3969,10 +4234,14 @@ InitializationSequence::Perform(Sema &S, } case SK_ConversionSequence: { + Sema::CheckedConversionKind CCK + = Kind.isCStyleCast()? Sema::CCK_CStyleCast + : Kind.isFunctionalCast()? Sema::CCK_FunctionalCast + : Kind.isExplicitCast()? Sema::CCK_OtherCast + : Sema::CCK_ImplicitConversion; ExprResult CurInitExprRes = S.PerformImplicitConversion(CurInit.get(), Step->Type, *Step->ICS, - getAssignmentAction(Entity), - Kind.isCStyleOrFunctionalCast()); + getAssignmentAction(Entity), CCK); if (CurInitExprRes.isInvalid()) return ExprError(); CurInit = move(CurInitExprRes); @@ -4182,7 +4451,20 @@ InitializationSequence::Perform(Sema &S, } } } + break; + case SK_PassByIndirectCopyRestore: + case SK_PassByIndirectRestore: + checkIndirectCopyRestoreSource(S, CurInit.get()); + CurInit = S.Owned(new (S.Context) + ObjCIndirectCopyRestoreExpr(CurInit.take(), Step->Type, + Step->Kind == SK_PassByIndirectCopyRestore)); + break; + + case SK_ProduceObjCObject: + CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, Step->Type, + CK_ObjCProduceObject, + CurInit.take(), 0, VK_RValue)); break; } } @@ -4278,7 +4560,7 @@ bool InitializationSequence::Diagnose(Sema &S, true); if (Ovl == OR_Deleted) { S.Diag(Best->Function->getLocation(), diag::note_unavailable_here) - << Best->Function->isDeleted(); + << 1 << Best->Function->isDeleted(); } else { llvm_unreachable("Inconsistent overload resolution?"); } @@ -4443,7 +4725,7 @@ bool InitializationSequence::Diagnose(Sema &S, = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); if (Ovl == OR_Deleted) { S.Diag(Best->Function->getLocation(), diag::note_unavailable_here) - << Best->Function->isDeleted(); + << 1 << Best->Function->isDeleted(); } else { llvm_unreachable("Inconsistent overload resolution?"); } @@ -4587,10 +4869,6 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const { case NormalSequence: OS << "Normal sequence: "; break; - - case ReferenceBinding: - OS << "Reference binding: "; - break; } for (step_iterator S = step_begin(), SEnd = step_end(); S != SEnd; ++S) { @@ -4674,6 +4952,18 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const { case SK_ArrayInit: OS << "array initialization"; break; + + case SK_PassByIndirectCopyRestore: + OS << "pass by indirect copy and restore"; + break; + + case SK_PassByIndirectRestore: + OS << "pass by indirect restore"; + break; + + case SK_ProduceObjCObject: + OS << "Objective-C object retension"; + break; } } } |