Improve on reporting ambiguity involving built-in candidates.

I still don't like it but it is improvement over what we had.

llvm-svn: 83603
This commit is contained in:
Fariborz Jahanian 2009-10-09 00:13:15 +00:00
parent 3059924bdd
commit 29f9d39568
3 changed files with 13 additions and 12 deletions

View File

@ -778,7 +778,7 @@ def err_ovl_template_candidate : Note<
"candidate function template specialization %0">; "candidate function template specialization %0">;
def err_ovl_candidate_deleted : Note< def err_ovl_candidate_deleted : Note<
"candidate function has been explicitly %select{made unavailable|deleted}0">; "candidate function has been explicitly %select{made unavailable|deleted}0">;
def err_ovl_builtin_candidate : Note<"built-in candidate function %0">; def err_ovl_builtin_candidate : Note<"built-in candidate function %0 for operator '%1'">;
def err_ovl_no_viable_function_in_init : Error< def err_ovl_no_viable_function_in_init : Error<
"no matching constructor for initialization of %0">; "no matching constructor for initialization of %0">;
def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">; def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">;

View File

@ -906,7 +906,9 @@ public:
SourceLocation Loc, SourceLocation Loc,
OverloadCandidateSet::iterator& Best); OverloadCandidateSet::iterator& Best);
void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, void PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
bool OnlyViable); bool OnlyViable,
BinaryOperator::Opcode Opc=(BinaryOperator::Opcode)0,
SourceLocation Loc=SourceLocation());
FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType, FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
bool Complain); bool Complain);

View File

@ -3690,11 +3690,12 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
Ptr != CandidateTypes.pointer_end(); ++Ptr) { Ptr != CandidateTypes.pointer_end(); ++Ptr) {
QualType C1Ty = (*Ptr); QualType C1Ty = (*Ptr);
QualType C1; QualType C1;
unsigned CV1;
if (const PointerType *PointerTy = C1Ty->getAs<PointerType>()) { if (const PointerType *PointerTy = C1Ty->getAs<PointerType>()) {
C1 = PointerTy->getPointeeType(); C1 = PointerTy->getPointeeType().getUnqualifiedType();
C1 = C1.getUnqualifiedType();
if (!isa<RecordType>(C1)) if (!isa<RecordType>(C1))
continue; continue;
CV1 = PointerTy->getPointeeType().getCVRQualifiers();
} }
for (BuiltinCandidateTypeSet::iterator for (BuiltinCandidateTypeSet::iterator
MemPtr = CandidateTypes.member_pointer_begin(), MemPtr = CandidateTypes.member_pointer_begin(),
@ -3708,7 +3709,6 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
QualType ParamTypes[2] = { *Ptr, *MemPtr }; QualType ParamTypes[2] = { *Ptr, *MemPtr };
// build CV12 T& // build CV12 T&
QualType T = mptr->getPointeeType(); QualType T = mptr->getPointeeType();
unsigned CV1 = (*Ptr).getCVRQualifiers();
unsigned CV2 = T.getCVRQualifiers(); unsigned CV2 = T.getCVRQualifiers();
T = Context.getCVRQualifiedType(T, (CV1 | CV2)); T = Context.getCVRQualifiedType(T, (CV1 | CV2));
QualType ResultTy = Context.getLValueReferenceType(T); QualType ResultTy = Context.getLValueReferenceType(T);
@ -3972,7 +3972,9 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
/// set. If OnlyViable is true, only viable candidates will be printed. /// set. If OnlyViable is true, only viable candidates will be printed.
void void
Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet, Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
bool OnlyViable) { bool OnlyViable,
BinaryOperator::Opcode Opc,
SourceLocation OpLoc) {
OverloadCandidateSet::iterator Cand = CandidateSet.begin(), OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
LastCand = CandidateSet.end(); LastCand = CandidateSet.end();
for (; Cand != LastCand; ++Cand) { for (; Cand != LastCand; ++Cand) {
@ -4045,17 +4047,14 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
Diag(Cand->Surrogate->getLocation(), diag::err_ovl_surrogate_cand) Diag(Cand->Surrogate->getLocation(), diag::err_ovl_surrogate_cand)
<< FnType; << FnType;
} else if (OnlyViable) { } else if (OnlyViable) {
// FIXME: We need to get the identifier in here
// FIXME: Do we want the error message to point at the operator?
// (built-ins won't have a location)
// FIXME: can we get some kind of stable location for this?
QualType FnType QualType FnType
= Context.getFunctionType(Cand->BuiltinTypes.ResultTy, = Context.getFunctionType(Cand->BuiltinTypes.ResultTy,
Cand->BuiltinTypes.ParamTypes, Cand->BuiltinTypes.ParamTypes,
Cand->Conversions.size(), Cand->Conversions.size(),
false, 0); false, 0);
Diag(SourceLocation(), diag::err_ovl_builtin_candidate) << FnType; Diag(OpLoc, diag::err_ovl_builtin_candidate) << FnType <<
BinaryOperator::getOpcodeStr(Opc);
} }
} }
} }
@ -4714,7 +4713,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
Diag(OpLoc, diag::err_ovl_ambiguous_oper) Diag(OpLoc, diag::err_ovl_ambiguous_oper)
<< BinaryOperator::getOpcodeStr(Opc) << BinaryOperator::getOpcodeStr(Opc)
<< Args[0]->getSourceRange() << Args[1]->getSourceRange(); << Args[0]->getSourceRange() << Args[1]->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true, Opc, OpLoc);
return ExprError(); return ExprError();
case OR_Deleted: case OR_Deleted: