Don't print canonical types in overloading-related diagnostics

llvm-svn: 59789
This commit is contained in:
Douglas Gregor 2008-11-21 02:54:28 +00:00
parent 5eee74446d
commit 4fc308bd3b
4 changed files with 32 additions and 10 deletions

View File

@ -1931,8 +1931,8 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {
DK = diag::err_operator_overload_post_inc_must_be_int;
else
DK = diag::err_operator_overload_post_dec_must_be_int;
return Diag(LastParam->getLocation(), DK)
<< Context.getCanonicalType(LastParam->getType()).getAsString();
return Diag(LastParam->getLocation(), DK)
<< LastParam->getType().getAsString();
}
}

View File

@ -2853,9 +2853,28 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
// Normal function
Diag(Cand->Function->getLocation(), diag::err_ovl_candidate);
} else if (Cand->IsSurrogate) {
// Desugar the type of the surrogate down to a function type,
// retaining as many typedefs as possible while still showing
// the function type (and, therefore, its parameter types).
QualType FnType = Cand->Surrogate->getConversionType();
bool isReference = false;
bool isPointer = false;
if (const ReferenceType *FnTypeRef = FnType->getAsReferenceType()) {
FnType = FnTypeRef->getPointeeType();
isReference = true;
}
if (const PointerType *FnTypePtr = FnType->getAsPointerType()) {
FnType = FnTypePtr->getPointeeType();
isPointer = true;
}
// Desugar down to a function type.
FnType = QualType(FnType->getAsFunctionType(), 0);
// Reconstruct the pointer/reference as appropriate.
if (isPointer) FnType = Context.getPointerType(FnType);
if (isReference) FnType = Context.getReferenceType(FnType);
Diag(Cand->Surrogate->getLocation(), diag::err_ovl_surrogate_cand)
<< Context.getCanonicalType(Cand->Surrogate->getConversionType())
.getAsString();
<< FnType.getAsString();
} else {
// FIXME: We need to get the identifier in here
// FIXME: Do we want the error message to point at the
@ -3006,9 +3025,10 @@ Sema::BuildCallToObjectOfClassType(Expr *Object, SourceLocation LParenLoc,
// FIXME: Look in base classes for more conversion operators!
OverloadedFunctionDecl *Conversions
= cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
for (OverloadedFunctionDecl::function_iterator Func
= Conversions->function_begin();
Func != Conversions->function_end(); ++Func) {
for (OverloadedFunctionDecl::function_iterator
Func = Conversions->function_begin(),
FuncEnd = Conversions->function_end();
Func != FuncEnd; ++Func) {
CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func);
// Strip the reference type (if any) and then the pointer type (if

View File

@ -34,6 +34,6 @@ typedef int INT;
typedef float FLOAT;
Y& operator++(Y&);
Y operator++(Y&, INT);
X operator++(X&, FLOAT); // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'float')}}
X operator++(X&, FLOAT); // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'FLOAT')}}
int operator+; // expected-error{{'operator+' cannot be the name of a variable or data member}}

View File

@ -135,11 +135,13 @@ void test_callable(Callable c) {
c(); // expected-error{{no matching function for call to object of type 'struct Callable'; candidates are:}}
}
typedef int& Func1(float, double);
typedef float FLOAT;
typedef int& INTREF;
typedef INTREF Func1(FLOAT, double);
typedef float& Func2(int, double);
struct ConvertToFunc {
operator Func1*(); // expected-note{{conversion candidate of type 'int &(*)(float, double)'}}
operator Func1*(); // expected-note{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}}
operator Func2&(); // expected-note{{conversion candidate of type 'float &(&)(int, double)'}}
void operator()();
};