"candidate function template specialization %0">;
def err_ovl_candidate_deleted : Note<
"candidate function has been explicitly %select{made unavailable|deleted}0">;
-def err_ovl_builtin_candidate : Note<"built-in candidate operator %2 (%0, %1)">;
+def err_ovl_builtin_binary_candidate : Note<
+ "built-in candidate operator %0 (%1, %2)">;
+def err_ovl_builtin_unary_candidate : Note<
+ "built-in candidate operator %0 (%1)">;
def err_ovl_no_viable_function_in_init : Error<
"no matching constructor for initialization of %0">;
def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;
void
Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
bool OnlyViable,
- BinaryOperator::Opcode Opc,
+ const char *Opc,
SourceLocation OpLoc) {
OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
LastCand = CandidateSet.end();
Diag(Cand->Surrogate->getLocation(), diag::err_ovl_surrogate_cand)
<< FnType;
} else if (OnlyViable) {
- assert(Cand->Conversions.size() == 2 &&
+ assert(Cand->Conversions.size() <= 2 &&
"builtin-binary-operator-not-binary");
- Diag(OpLoc, diag::err_ovl_builtin_candidate)
- << Cand->BuiltinTypes.ParamTypes[0]
- << Cand->BuiltinTypes.ParamTypes[1]
- << BinaryOperator::getOpcodeStr(Opc);
+ if (Cand->Conversions.size() == 1)
+ Diag(OpLoc, diag::err_ovl_builtin_unary_candidate)
+ << Opc << Cand->BuiltinTypes.ParamTypes[0];
+ else
+ Diag(OpLoc, diag::err_ovl_builtin_binary_candidate)
+ << Opc << Cand->BuiltinTypes.ParamTypes[0]
+ << Cand->BuiltinTypes.ParamTypes[1];
}
else if (!Cand->Viable && !Reported) {
// Non-viability might be due to ambiguous user-defined conversions,
// needed for built-in operators. Report them as well, but only once
// as we have typically many built-in candidates.
- assert(Cand->Conversions.size() == 2 &&
- "builtin-binary-operator-not-binary");
- for (unsigned ArgIdx = 0; ArgIdx < 2; ++ArgIdx) {
+ unsigned NoOperands = Cand->Conversions.size();
+ for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) {
const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx];
if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion ||
ICS.ConversionFunctionSet.empty())
Diag(OpLoc, diag::err_ovl_ambiguous_oper)
<< UnaryOperator::getOpcodeStr(Opc)
<< Input->getSourceRange();
- PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true,
+ UnaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
case OR_Deleted:
assert(Result.isInvalid() &&
"C++ binary operator overloading is missing candidates!");
if (Result.isInvalid())
- PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false, Opc, OpLoc);
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false,
+ BinaryOperator::getOpcodeStr(Opc), OpLoc);
return move(Result);
}
Diag(OpLoc, diag::err_ovl_ambiguous_oper)
<< BinaryOperator::getOpcodeStr(Opc)
<< Args[0]->getSourceRange() << Args[1]->getSourceRange();
- PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true, Opc, OpLoc);
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true,
+ BinaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
case OR_Deleted: