diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 328 |
1 files changed, 183 insertions, 145 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 89d495d..529ba12 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -42,13 +42,15 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl, bool HadMultipleCandidates, SourceLocation Loc = SourceLocation(), const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){ + if (S.DiagnoseUseOfDecl(FoundDecl, Loc)) + return ExprError(); + DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo); if (HadMultipleCandidates) DRE->setHadMultipleCandidates(true); S.MarkDeclRefReferenced(DRE); - S.DiagnoseUseOfDecl(FoundDecl, Loc); ExprResult E = S.Owned(DRE); E = S.DefaultFunctionArrayConversion(E.take()); @@ -940,6 +942,9 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, continue; } + if (!shouldLinkPossiblyHiddenDecl(*I, New)) + continue; + Match = *I; return Ovl_Match; } @@ -1832,7 +1837,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { // conversion. using llvm::APSInt; if (From) - if (FieldDecl *MemberDecl = From->getBitField()) { + if (FieldDecl *MemberDecl = From->getSourceBitField()) { APSInt BitWidth; if (FromType->isIntegralType(Context) && MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) { @@ -5024,7 +5029,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, Expr::EvalResult Eval; Eval.Diag = &Notes; - if (!Result.get()->EvaluateAsRValue(Eval, Context)) { + if (!Result.get()->EvaluateAsRValue(Eval, Context) || !Eval.Val.isInt()) { // The expression can't be folded, so we can't keep it at this position in // the AST. Result = ExprError(); @@ -5473,7 +5478,7 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions) { NamedDecl *Decl = FoundDecl.getDecl(); @@ -5488,12 +5493,12 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, AddMethodTemplateCandidate(TD, FoundDecl, ActingContext, /*ExplicitArgs*/ 0, ObjectType, ObjectClassification, - llvm::makeArrayRef(Args, NumArgs), CandidateSet, + Args, CandidateSet, SuppressUserConversions); } else { AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext, ObjectType, ObjectClassification, - llvm::makeArrayRef(Args, NumArgs), + Args, CandidateSet, SuppressUserConversions); } } @@ -5721,6 +5726,14 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, if (!CandidateSet.isNewCandidate(Conversion)) return; + // If the conversion function has an undeduced return type, trigger its + // deduction now. + if (getLangOpts().CPlusPlus1y && ConvType->isUndeducedType()) { + if (DeduceReturnType(Conversion, From->getExprLoc())) + return; + ConvType = Conversion->getConversionType().getNonReferenceType(); + } + // Overload resolution is always an unevaluated context. EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); @@ -5800,7 +5813,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, // there are 0 arguments (i.e., nothing is allocated using ASTContext's // allocator). QualType CallResultType = ConversionType.getNonLValueExprType(Context); - CallExpr Call(Context, &ConversionFn, MultiExprArg(), CallResultType, VK, + CallExpr Call(Context, &ConversionFn, None, CallResultType, VK, From->getLocStart()); ImplicitConversionSequence ICS = TryCopyInitialization(*this, &Call, ToType, @@ -5963,7 +5976,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, // Determine the implicit conversion sequences for each of the // arguments. - for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { if (ArgIdx < NumArgsInProto) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence @@ -6000,7 +6013,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, /// [over.match.oper]). void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, SourceRange OpRange) { DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); @@ -6015,13 +6028,15 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, // constructed as follows: QualType T1 = Args[0]->getType(); - // -- If T1 is a class type, the set of member candidates is the - // result of the qualified lookup of T1::operator@ - // (13.3.1.1.1); otherwise, the set of member candidates is - // empty. + // -- If T1 is a complete class type or a class currently being + // defined, the set of member candidates is the result of the + // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, + // the set of member candidates is empty. if (const RecordType *T1Rec = T1->getAs<RecordType>()) { - // Complete the type if it can be completed. Otherwise, we're done. - if (RequireCompleteType(OpLoc, T1, 0)) + // Complete the type if it can be completed. + RequireCompleteType(OpLoc, T1, 0); + // If the type is neither complete nor being defined, bail out now. + if (!T1Rec->getDecl()->getDefinition()) return; LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName); @@ -6033,7 +6048,8 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, Oper != OperEnd; ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), - Args[0]->Classify(Context), Args + 1, NumArgs - 1, + Args[0]->Classify(Context), + Args.slice(1), CandidateSet, /* SuppressUserConversions = */ false); } @@ -6048,7 +6064,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, /// (at the beginning of the argument list) that will be contextually /// converted to bool. void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, - Expr **Args, unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool IsAssignmentOperator, unsigned NumContextualBoolArguments) { @@ -6056,20 +6072,20 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); // Add this candidate - OverloadCandidate &Candidate = CandidateSet.addCandidate(NumArgs); + OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); Candidate.FoundDecl = DeclAccessPair::make(0, AS_none); Candidate.Function = 0; Candidate.IsSurrogate = false; Candidate.IgnoreObjectArgument = false; Candidate.BuiltinTypes.ResultTy = ResultTy; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) Candidate.BuiltinTypes.ParamTypes[ArgIdx] = ParamTys[ArgIdx]; // Determine the implicit conversion sequences for each of the // arguments. Candidate.Viable = true; - Candidate.ExplicitCallArguments = NumArgs; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + Candidate.ExplicitCallArguments = Args.size(); + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { // C++ [over.match.oper]p4: // For the built-in assignment operators, conversions of the // left operand are restricted as follows: @@ -6395,15 +6411,14 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty, /// given type to the candidate set. static void AddBuiltinAssignmentOperatorCandidates(Sema &S, QualType T, - Expr **Args, - unsigned NumArgs, + ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet) { QualType ParamTypes[2]; // T& operator=(T&, T) ParamTypes[0] = S.Context.getLValueReferenceType(T); ParamTypes[1] = T; - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); if (!S.Context.getCanonicalType(T).isVolatileQualified()) { @@ -6411,7 +6426,7 @@ static void AddBuiltinAssignmentOperatorCandidates(Sema &S, ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(T)); ParamTypes[1] = T; - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/true); } } @@ -6482,8 +6497,7 @@ namespace { class BuiltinOperatorOverloadBuilder { // Common instance state available to all overload candidate addition methods. Sema &S; - Expr **Args; - unsigned NumArgs; + ArrayRef<Expr *> Args; Qualifiers VisibleTypeConversionsQuals; bool HasArithmeticOrEnumeralCandidateType; SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes; @@ -6606,10 +6620,10 @@ class BuiltinOperatorOverloadBuilder { }; // Non-volatile version. - if (NumArgs == 1) - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet); + if (Args.size() == 1) + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); else - S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet); // Use a heuristic to reduce number of builtin candidates in the set: // add volatile version only if there are conversions to a volatile type. @@ -6617,10 +6631,10 @@ class BuiltinOperatorOverloadBuilder { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getVolatileType(CandidateTy)); - if (NumArgs == 1) - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet); + if (Args.size() == 1) + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); else - S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet); } // Add restrict version only if there are conversions to a restrict type @@ -6630,10 +6644,10 @@ class BuiltinOperatorOverloadBuilder { ParamTypes[0] = S.Context.getLValueReferenceType( S.Context.getCVRQualifiedType(CandidateTy, Qualifiers::Restrict)); - if (NumArgs == 1) - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet); + if (Args.size() == 1) + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); else - S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet); if (HasVolatile) { ParamTypes[0] @@ -6641,11 +6655,10 @@ class BuiltinOperatorOverloadBuilder { S.Context.getCVRQualifiedType(CandidateTy, (Qualifiers::Volatile | Qualifiers::Restrict))); - if (NumArgs == 1) - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, - CandidateSet); + if (Args.size() == 1) + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); else - S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(CandidateTy, ParamTypes, Args, CandidateSet); } } @@ -6653,12 +6666,12 @@ class BuiltinOperatorOverloadBuilder { public: BuiltinOperatorOverloadBuilder( - Sema &S, Expr **Args, unsigned NumArgs, + Sema &S, ArrayRef<Expr *> Args, Qualifiers VisibleTypeConversionsQuals, bool HasArithmeticOrEnumeralCandidateType, SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes, OverloadCandidateSet &CandidateSet) - : S(S), Args(Args), NumArgs(NumArgs), + : S(S), Args(Args), VisibleTypeConversionsQuals(VisibleTypeConversionsQuals), HasArithmeticOrEnumeralCandidateType( HasArithmeticOrEnumeralCandidateType), @@ -6760,7 +6773,7 @@ public: continue; S.AddBuiltinCandidate(S.Context.getLValueReferenceType(PointeeTy), - &ParamTy, Args, 1, CandidateSet); + &ParamTy, Args, CandidateSet); } } @@ -6777,7 +6790,7 @@ public: for (unsigned Arith = FirstPromotedArithmeticType; Arith < LastPromotedArithmeticType; ++Arith) { QualType ArithTy = getArithmeticType(Arith); - S.AddBuiltinCandidate(ArithTy, &ArithTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(ArithTy, &ArithTy, Args, CandidateSet); } // Extension: We also add these operators for vector types. @@ -6786,7 +6799,7 @@ public: VecEnd = CandidateTypes[0].vector_end(); Vec != VecEnd; ++Vec) { QualType VecTy = *Vec; - S.AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(VecTy, &VecTy, Args, CandidateSet); } } @@ -6801,7 +6814,7 @@ public: PtrEnd = CandidateTypes[0].pointer_end(); Ptr != PtrEnd; ++Ptr) { QualType ParamTy = *Ptr; - S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, CandidateSet); } } @@ -6817,7 +6830,7 @@ public: for (unsigned Int = FirstPromotedIntegralType; Int < LastPromotedIntegralType; ++Int) { QualType IntTy = getArithmeticType(Int); - S.AddBuiltinCandidate(IntTy, &IntTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(IntTy, &IntTy, Args, CandidateSet); } // Extension: We also add this operator for vector types. @@ -6826,7 +6839,7 @@ public: VecEnd = CandidateTypes[0].vector_end(); Vec != VecEnd; ++Vec) { QualType VecTy = *Vec; - S.AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet); + S.AddBuiltinCandidate(VecTy, &VecTy, Args, CandidateSet); } } @@ -6840,7 +6853,7 @@ public: /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet<QualType, 8> AddedTypes; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator MemPtr = CandidateTypes[ArgIdx].member_pointer_begin(), MemPtrEnd = CandidateTypes[ArgIdx].member_pointer_end(); @@ -6851,8 +6864,7 @@ public: continue; QualType ParamTypes[2] = { *MemPtr, *MemPtr }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } } } @@ -6884,7 +6896,7 @@ public: llvm::DenseSet<std::pair<CanQualType, CanQualType> > UserDefinedBinaryOperators; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { if (CandidateTypes[ArgIdx].enumeration_begin() != CandidateTypes[ArgIdx].enumeration_end()) { for (OverloadCandidateSet::iterator C = CandidateSet.begin(), @@ -6917,7 +6929,7 @@ public: /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet<QualType, 8> AddedTypes; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes[ArgIdx].pointer_begin(), PtrEnd = CandidateTypes[ArgIdx].pointer_end(); @@ -6927,8 +6939,7 @@ public: continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator Enum = CandidateTypes[ArgIdx].enumeration_begin(), @@ -6944,17 +6955,16 @@ public: continue; QualType ParamTypes[2] = { *Enum, *Enum }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } if (CandidateTypes[ArgIdx].hasNullPtrType()) { CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy); if (AddedTypes.insert(NullPtrTy) && - !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy, + !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy, NullPtrTy))) { QualType ParamTypes[2] = { NullPtrTy, NullPtrTy }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } } @@ -6999,8 +7009,7 @@ public: if (Arg == 0 || Op == OO_Plus) { // operator+(T*, ptrdiff_t) or operator-(T*, ptrdiff_t) // T* operator+(ptrdiff_t, T*); - S.AddBuiltinCandidate(*Ptr, AsymetricParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(*Ptr, AsymetricParamTypes, Args, CandidateSet); } if (Op == OO_Minus) { // ptrdiff_t operator-(T, T); @@ -7009,7 +7018,7 @@ public: QualType ParamTypes[2] = { *Ptr, *Ptr }; S.AddBuiltinCandidate(S.Context.getPointerDiffType(), ParamTypes, - Args, 2, CandidateSet); + Args, CandidateSet); } } } @@ -7057,7 +7066,7 @@ public: QualType Result = isComparison ? S.Context.BoolTy : getUsualArithmeticConversions(Left, Right); - S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet); + S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet); } } @@ -7080,7 +7089,7 @@ public: Result = *Vec2; } - S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet); + S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet); } } } @@ -7112,7 +7121,7 @@ public: QualType Result = (Op == OO_LessLess || Op == OO_GreaterGreater) ? LandR[0] : getUsualArithmeticConversions(Left, Right); - S.AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet); + S.AddBuiltinCandidate(Result, LandR, Args, CandidateSet); } } } @@ -7136,8 +7145,7 @@ public: if (!AddedTypes.insert(S.Context.getCanonicalType(*Enum))) continue; - AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, 2, - CandidateSet); + AddBuiltinAssignmentOperatorCandidates(S, *Enum, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator @@ -7147,8 +7155,7 @@ public: if (!AddedTypes.insert(S.Context.getCanonicalType(*MemPtr))) continue; - AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, 2, - CandidateSet); + AddBuiltinAssignmentOperatorCandidates(S, *MemPtr, Args, CandidateSet); } } } @@ -7188,7 +7195,7 @@ public: S.Context.getLValueReferenceType(*Ptr), isEqualOp ? *Ptr : S.Context.getPointerDiffType(), }; - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/ isEqualOp); bool NeedVolatile = !(*Ptr).isVolatileQualified() && @@ -7197,7 +7204,7 @@ public: // volatile version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); } @@ -7206,7 +7213,7 @@ public: // restrict version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); if (NeedVolatile) { @@ -7216,8 +7223,7 @@ public: S.Context.getCVRQualifiedType(*Ptr, (Qualifiers::Volatile | Qualifiers::Restrict))); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); } } @@ -7238,7 +7244,7 @@ public: }; // non-volatile version - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/true); bool NeedVolatile = !(*Ptr).isVolatileQualified() && @@ -7247,8 +7253,8 @@ public: // volatile version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getVolatileType(*Ptr)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, /*IsAssigmentOperator=*/true); + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, + /*IsAssigmentOperator=*/true); } if (!(*Ptr).isRestrictQualified() && @@ -7256,8 +7262,8 @@ public: // restrict version ParamTypes[0] = S.Context.getLValueReferenceType(S.Context.getRestrictType(*Ptr)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, /*IsAssigmentOperator=*/true); + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, + /*IsAssigmentOperator=*/true); if (NeedVolatile) { // volatile restrict version @@ -7266,9 +7272,8 @@ public: S.Context.getCVRQualifiedType(*Ptr, (Qualifiers::Volatile | Qualifiers::Restrict))); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, /*IsAssigmentOperator=*/true); - + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, + /*IsAssigmentOperator=*/true); } } } @@ -7300,7 +7305,7 @@ public: // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(getArithmeticType(Left)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). @@ -7308,8 +7313,7 @@ public: ParamTypes[0] = S.Context.getVolatileType(getArithmeticType(Left)); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); } } @@ -7328,15 +7332,14 @@ public: ParamTypes[1] = *Vec2; // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(*Vec1); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = S.Context.getVolatileType(*Vec1); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet, + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); } } @@ -7368,14 +7371,13 @@ public: // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = S.Context.getLValueReferenceType(getArithmeticType(Left)); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). ParamTypes[0] = getArithmeticType(Left); ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); - S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, - CandidateSet); + S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, CandidateSet); } } } @@ -7390,13 +7392,13 @@ public: // bool operator||(bool, bool); void addExclaimOverload() { QualType ParamTy = S.Context.BoolTy; - S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet, + S.AddBuiltinCandidate(ParamTy, &ParamTy, Args, CandidateSet, /*IsAssignmentOperator=*/false, /*NumContextualBoolArguments=*/1); } void addAmpAmpOrPipePipeOverload() { QualType ParamTypes[2] = { S.Context.BoolTy, S.Context.BoolTy }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, 2, CandidateSet, + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet, /*IsAssignmentOperator=*/false, /*NumContextualBoolArguments=*/2); } @@ -7424,7 +7426,7 @@ public: QualType ResultTy = S.Context.getLValueReferenceType(PointeeType); // T& operator[](T*, ptrdiff_t) - S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator @@ -7439,7 +7441,7 @@ public: QualType ResultTy = S.Context.getLValueReferenceType(PointeeType); // T& operator[](ptrdiff_t, T*) - S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet); } } @@ -7490,7 +7492,7 @@ public: continue; T = Q1.apply(S.Context, T); QualType ResultTy = S.Context.getLValueReferenceType(T); - S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(ResultTy, ParamTypes, Args, CandidateSet); } } } @@ -7518,7 +7520,7 @@ public: continue; QualType ParamTypes[2] = { *Ptr, *Ptr }; - S.AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(*Ptr, ParamTypes, Args, CandidateSet); } for (BuiltinCandidateTypeSet::iterator @@ -7529,7 +7531,7 @@ public: continue; QualType ParamTypes[2] = { *MemPtr, *MemPtr }; - S.AddBuiltinCandidate(*MemPtr, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(*MemPtr, ParamTypes, Args, CandidateSet); } if (S.getLangOpts().CPlusPlus11) { @@ -7544,7 +7546,7 @@ public: continue; QualType ParamTypes[2] = { *Enum, *Enum }; - S.AddBuiltinCandidate(*Enum, ParamTypes, Args, 2, CandidateSet); + S.AddBuiltinCandidate(*Enum, ParamTypes, Args, CandidateSet); } } } @@ -7561,7 +7563,7 @@ public: void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, - Expr **Args, unsigned NumArgs, + llvm::ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet) { // Find all of the types that the arguments can convert to, but only // if the operator we're looking at has built-in operator candidates @@ -7569,13 +7571,13 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, // candidate types or either arithmetic or enumeral candidate types. Qualifiers VisibleTypeConversionsQuals; VisibleTypeConversionsQuals.addConst(); - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]); bool HasNonRecordCandidateType = false; bool HasArithmeticOrEnumeralCandidateType = false; SmallVector<BuiltinCandidateTypeSet, 2> CandidateTypes; - for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { CandidateTypes.push_back(BuiltinCandidateTypeSet(*this)); CandidateTypes[ArgIdx].AddTypesConvertedFrom(Args[ArgIdx]->getType(), OpLoc, @@ -7596,12 +7598,12 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, // // We can't exit early for !, ||, or &&, since there we have always have // 'bool' overloads. - if (!HasNonRecordCandidateType && + if (!HasNonRecordCandidateType && !(Op == OO_Exclaim || Op == OO_AmpAmp || Op == OO_PipePipe)) return; // Setup an object to manage the common state for building overloads. - BuiltinOperatorOverloadBuilder OpBuilder(*this, Args, NumArgs, + BuiltinOperatorOverloadBuilder OpBuilder(*this, Args, VisibleTypeConversionsQuals, HasArithmeticOrEnumeralCandidateType, CandidateTypes, CandidateSet); @@ -7628,12 +7630,12 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, break; case OO_Plus: // '+' is either unary or binary - if (NumArgs == 1) + if (Args.size() == 1) OpBuilder.addUnaryPlusPointerOverloads(); // Fall through. case OO_Minus: // '-' is either unary or binary - if (NumArgs == 1) { + if (Args.size() == 1) { OpBuilder.addUnaryPlusOrMinusArithmeticOverloads(); } else { OpBuilder.addBinaryPlusOrMinusPointerOverloads(Op); @@ -7642,7 +7644,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, break; case OO_Star: // '*' is either unary or binary - if (NumArgs == 1) + if (Args.size() == 1) OpBuilder.addUnaryStarPointerOverloads(); else OpBuilder.addGenericBinaryArithmeticOverloads(/*isComparison=*/false); @@ -7680,7 +7682,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, break; case OO_Amp: // '&' is either unary or binary - if (NumArgs == 1) + if (Args.size() == 1) // C++ [over.match.oper]p3: // -- For the operator ',', the unary operator '&', or the // operator '->', the built-in candidates set is empty. @@ -8508,13 +8510,35 @@ void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, return; } - case Sema::TDK_NonDeducedMismatch: + case Sema::TDK_NonDeducedMismatch: { // FIXME: Provide a source location to indicate what we couldn't match. + TemplateArgument FirstTA = *Cand->DeductionFailure.getFirstArg(); + TemplateArgument SecondTA = *Cand->DeductionFailure.getSecondArg(); + if (FirstTA.getKind() == TemplateArgument::Template && + SecondTA.getKind() == TemplateArgument::Template) { + TemplateName FirstTN = FirstTA.getAsTemplate(); + TemplateName SecondTN = SecondTA.getAsTemplate(); + if (FirstTN.getKind() == TemplateName::Template && + SecondTN.getKind() == TemplateName::Template) { + if (FirstTN.getAsTemplateDecl()->getName() == + SecondTN.getAsTemplateDecl()->getName()) { + // FIXME: This fixes a bad diagnostic where both templates are named + // the same. This particular case is a bit difficult since: + // 1) It is passed as a string to the diagnostic printer. + // 2) The diagnostic printer only attempts to find a better + // name for types, not decls. + // Ideally, this should folded into the diagnostic printer. + S.Diag(Fn->getLocation(), + diag::note_ovl_candidate_non_deduced_mismatch_qualified) + << FirstTN.getAsTemplateDecl() << SecondTN.getAsTemplateDecl(); + return; + } + } + } S.Diag(Fn->getLocation(), diag::note_ovl_candidate_non_deduced_mismatch) - << *Cand->DeductionFailure.getFirstArg() - << *Cand->DeductionFailure.getSecondArg(); + << FirstTA << SecondTA; return; - + } // TODO: diagnose these individually, then kill off // note_ovl_candidate_bad_deduction, which is uselessly vague. case Sema::TDK_MiscellaneousDeductionFailure: @@ -9109,17 +9133,19 @@ private: = S.DeduceTemplateArguments(FunctionTemplate, &OvlExplicitTemplateArgs, TargetFunctionType, Specialization, - Info)) { + Info, /*InOverloadResolution=*/true)) { // FIXME: make a note of the failed deduction for diagnostics. (void)Result; return false; } - // Template argument deduction ensures that we have an exact match. + // Template argument deduction ensures that we have an exact match or + // compatible pointer-to-function arguments that would be adjusted by ICS. // This function template specicalization works. Specialization = cast<FunctionDecl>(Specialization->getCanonicalDecl()); - assert(TargetFunctionType - == Context.getCanonicalType(Specialization->getType())); + assert(S.isSameOrCompatibleFunctionType( + Context.getCanonicalType(Specialization->getType()), + Context.getCanonicalType(TargetFunctionType))); Matches.push_back(std::make_pair(CurAccessFunPair, Specialization)); return true; } @@ -9141,6 +9167,13 @@ private: if (S.CheckCUDATarget(Caller, FunDecl)) return false; + // If any candidate has a placeholder return type, trigger its deduction + // now. + if (S.getLangOpts().CPlusPlus1y && + FunDecl->getResultType()->isUndeducedType() && + S.DeduceReturnType(FunDecl, SourceExpr->getLocStart(), Complain)) + return false; + QualType ResultTy; if (Context.hasSameUnqualifiedType(TargetFunctionType, FunDecl->getType()) || @@ -9384,7 +9417,8 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, TemplateDeductionInfo Info(ovl->getNameLoc()); if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs, - Specialization, Info)) { + Specialization, Info, + /*InOverloadResolution=*/true)) { // FIXME: make a note of the failed deduction for diagnostics. (void)Result; continue; @@ -9406,6 +9440,11 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, if (FoundResult) *FoundResult = I.getPair(); } + if (Matched && getLangOpts().CPlusPlus1y && + Matched->getResultType()->isUndeducedType() && + DeduceReturnType(Matched, ovl->getExprLoc(), Complain)) + return 0; + return Matched; } @@ -9932,7 +9971,8 @@ static ExprResult FinishOverloadedCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, case OR_Success: { FunctionDecl *FDecl = (*Best)->Function; SemaRef.CheckUnresolvedLookupAccess(ULE, (*Best)->FoundDecl); - SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc()); + if (SemaRef.DiagnoseUseOfDecl(FDecl, ULE->getNameLoc())) + return ExprError(); Fn = SemaRef.FixOverloadedFunctionReference(Fn, (*Best)->FoundDecl, FDecl); return SemaRef.BuildResolvedCallExpr(Fn, FDecl, LParenLoc, Args, NumArgs, RParenLoc, ExecConfig); @@ -10065,6 +10105,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, NumArgs = 2; } + ArrayRef<Expr *> ArgsArray(Args, NumArgs); + if (Input->isTypeDependent()) { if (Fns.empty()) return Owned(new (Context) UnaryOperator(Input, @@ -10079,8 +10121,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, NestedNameSpecifierLoc(), OpNameInfo, /*ADL*/ true, IsOverloaded(Fns), Fns.begin(), Fns.end()); - return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, - llvm::makeArrayRef(Args, NumArgs), + return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy, VK_RValue, OpLoc, false)); @@ -10090,20 +10131,18 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, OverloadCandidateSet CandidateSet(OpLoc); // Add the candidates from the given function set. - AddFunctionCandidates(Fns, llvm::makeArrayRef(Args, NumArgs), CandidateSet, - false); + AddFunctionCandidates(Fns, ArgsArray, CandidateSet, false); // Add operator candidates that are member functions. - AddMemberOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet); + AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); // Add candidates from ADL. - AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, - OpLoc, llvm::makeArrayRef(Args, NumArgs), - /*ExplicitTemplateArgs*/ 0, + AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, OpLoc, + ArgsArray, /*ExplicitTemplateArgs*/ 0, CandidateSet); // Add builtin operator candidates. - AddBuiltinOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet); + AddBuiltinOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -10154,8 +10193,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, Args[0] = Input; CallExpr *TheCall = - new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), - llvm::makeArrayRef(Args, NumArgs), + new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.take(), ArgsArray, ResultTy, VK, OpLoc, false); if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, @@ -10181,8 +10219,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, // This is an erroneous use of an operator which can be overloaded by // a non-member function. Check for non-member operators which were // defined too late to be candidates. - if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc, - llvm::makeArrayRef(Args, NumArgs))) + if (DiagnoseTwoPhaseOperatorLookup(*this, Op, OpLoc, ArgsArray)) // FIXME: Recover by calling the found function. return ExprError(); @@ -10195,8 +10232,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, << UnaryOperator::getOpcodeStr(Opc) << Input->getType() << Input->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, - llvm::makeArrayRef(Args, NumArgs), + CandidateSet.NoteCandidates(*this, OCD_ViableCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); @@ -10206,8 +10242,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, << UnaryOperator::getOpcodeStr(Opc) << getDeletedOrUnavailableSuffix(Best->Function) << Input->getSourceRange(); - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, - llvm::makeArrayRef(Args, NumArgs), + CandidateSet.NoteCandidates(*this, OCD_AllCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc), OpLoc); return ExprError(); } @@ -10315,7 +10350,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, AddFunctionCandidates(Fns, Args, CandidateSet, false); // Add operator candidates that are member functions. - AddMemberOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet); + AddMemberOperatorCandidates(Op, OpLoc, Args, CandidateSet); // Add candidates from ADL. AddArgumentDependentLookupCandidates(OpName, /*Operator*/ true, @@ -10324,7 +10359,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, CandidateSet); // Add builtin operator candidates. - AddBuiltinOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet); + AddBuiltinOperatorCandidates(Op, OpLoc, Args, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -10545,10 +10580,10 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, // Subscript can only be overloaded as a member function. // Add operator candidates that are member functions. - AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet); + AddMemberOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet); // Add builtin operator candidates. - AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet); + AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, CandidateSet); bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -10815,7 +10850,8 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, Method = cast<CXXMethodDecl>(Best->Function); FoundDecl = Best->FoundDecl; CheckUnresolvedMemberAccess(UnresExpr, Best->FoundDecl); - DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc()); + if (DiagnoseUseOfDecl(Best->FoundDecl, UnresExpr->getNameLoc())) + return ExprError(); break; case OR_No_Viable_Function: @@ -10956,7 +10992,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), - Object.get()->Classify(Context), Args, NumArgs, CandidateSet, + Object.get()->Classify(Context), + llvm::makeArrayRef(Args, NumArgs), CandidateSet, /*SuppressUserConversions=*/ false); } @@ -11066,7 +11103,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, Best->Conversions[0].UserDefined.ConversionFunction); CheckMemberOperatorAccess(LParenLoc, Object.get(), 0, Best->FoundDecl); - DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc); + if (DiagnoseUseOfDecl(Best->FoundDecl, LParenLoc)) + return ExprError(); // We selected one of the surrogate functions that converts the // object parameter to a function pointer. Perform the conversion @@ -11248,7 +11286,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) { for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), - 0, 0, CandidateSet, /*SuppressUserConversions=*/false); + None, CandidateSet, /*SuppressUserConversions=*/false); } bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -11363,7 +11401,7 @@ ExprResult Sema::BuildLiteralOperatorCall(LookupResult &R, // Check the argument types. This should almost always be a no-op, except // that array-to-pointer decay is applied to string literals. Expr *ConvArgs[2]; - for (unsigned ArgIdx = 0; ArgIdx != Args.size(); ++ArgIdx) { + for (unsigned ArgIdx = 0, N = Args.size(); ArgIdx != N; ++ArgIdx) { ExprResult InputInit = PerformCopyInitialization( InitializedEntity::InitializeParameter(Context, FD->getParamDecl(ArgIdx)), SourceLocation(), Args[ArgIdx]); @@ -11420,7 +11458,7 @@ Sema::BuildForRangeBeginEndCall(Scope *S, SourceLocation Loc, << RangeLoc << BEF << Range->getType(); return FRS_DiagnosticIssued; } - *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, MultiExprArg(), Loc, 0); + *CallExpr = ActOnCallExpr(S, MemberRef.get(), Loc, None, Loc, 0); if (CallExpr->isInvalid()) { *CallExpr = ExprError(); Diag(Range->getLocStart(), diag::note_in_for_range) |