summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp269
1 files changed, 219 insertions, 50 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 6ec4d1b..44a8f15 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -25,7 +25,6 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
-#include <cstdio>
namespace clang {
@@ -183,51 +182,53 @@ isPointerConversionToVoidPointer(ASTContext& Context) const {
/// DebugPrint - Print this standard conversion sequence to standard
/// error. Useful for debugging overloading issues.
void StandardConversionSequence::DebugPrint() const {
+ llvm::raw_ostream &OS = llvm::errs();
bool PrintedSomething = false;
if (First != ICK_Identity) {
- fprintf(stderr, "%s", GetImplicitConversionName(First));
+ OS << GetImplicitConversionName(First);
PrintedSomething = true;
}
if (Second != ICK_Identity) {
if (PrintedSomething) {
- fprintf(stderr, " -> ");
+ OS << " -> ";
}
- fprintf(stderr, "%s", GetImplicitConversionName(Second));
+ OS << GetImplicitConversionName(Second);
if (CopyConstructor) {
- fprintf(stderr, " (by copy constructor)");
+ OS << " (by copy constructor)";
} else if (DirectBinding) {
- fprintf(stderr, " (direct reference binding)");
+ OS << " (direct reference binding)";
} else if (ReferenceBinding) {
- fprintf(stderr, " (reference binding)");
+ OS << " (reference binding)";
}
PrintedSomething = true;
}
if (Third != ICK_Identity) {
if (PrintedSomething) {
- fprintf(stderr, " -> ");
+ OS << " -> ";
}
- fprintf(stderr, "%s", GetImplicitConversionName(Third));
+ OS << GetImplicitConversionName(Third);
PrintedSomething = true;
}
if (!PrintedSomething) {
- fprintf(stderr, "No conversions required");
+ OS << "No conversions required";
}
}
/// DebugPrint - Print this user-defined conversion sequence to standard
/// error. Useful for debugging overloading issues.
void UserDefinedConversionSequence::DebugPrint() const {
+ llvm::raw_ostream &OS = llvm::errs();
if (Before.First || Before.Second || Before.Third) {
Before.DebugPrint();
- fprintf(stderr, " -> ");
+ OS << " -> ";
}
- fprintf(stderr, "'%s'", ConversionFunction->getNameAsString().c_str());
+ OS << "'" << ConversionFunction->getNameAsString() << "'";
if (After.First || After.Second || After.Third) {
- fprintf(stderr, " -> ");
+ OS << " -> ";
After.DebugPrint();
}
}
@@ -235,27 +236,28 @@ void UserDefinedConversionSequence::DebugPrint() const {
/// DebugPrint - Print this implicit conversion sequence to standard
/// error. Useful for debugging overloading issues.
void ImplicitConversionSequence::DebugPrint() const {
+ llvm::raw_ostream &OS = llvm::errs();
switch (ConversionKind) {
case StandardConversion:
- fprintf(stderr, "Standard conversion: ");
+ OS << "Standard conversion: ";
Standard.DebugPrint();
break;
case UserDefinedConversion:
- fprintf(stderr, "User-defined conversion: ");
+ OS << "User-defined conversion: ";
UserDefined.DebugPrint();
break;
case EllipsisConversion:
- fprintf(stderr, "Ellipsis conversion");
+ OS << "Ellipsis conversion";
break;
case AmbiguousConversion:
- fprintf(stderr, "Ambiguous conversion");
+ OS << "Ambiguous conversion";
break;
case BadConversion:
- fprintf(stderr, "Bad conversion");
+ OS << "Bad conversion";
break;
}
- fprintf(stderr, "\n");
+ OS << "\n";
}
void AmbiguousConversionSequence::construct() {
@@ -1100,7 +1102,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
bool &IncompatibleObjC) {
if (!getLangOptions().ObjC1)
return false;
-
+
// First, we handle all conversions on ObjC object pointer types.
const ObjCObjectPointerType* ToObjCPtr = ToType->getAs<ObjCObjectPointerType>();
const ObjCObjectPointerType *FromObjCPtr =
@@ -1141,8 +1143,23 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
QualType ToPointeeType;
if (const PointerType *ToCPtr = ToType->getAs<PointerType>())
ToPointeeType = ToCPtr->getPointeeType();
- else if (const BlockPointerType *ToBlockPtr = ToType->getAs<BlockPointerType>())
+ else if (const BlockPointerType *ToBlockPtr =
+ ToType->getAs<BlockPointerType>()) {
+ // Objective C++: We're able to convert from a pointer to any object
+ // to a block pointer type.
+ if (FromObjCPtr && FromObjCPtr->isObjCBuiltinType()) {
+ ConvertedType = ToType;
+ return true;
+ }
ToPointeeType = ToBlockPtr->getPointeeType();
+ }
+ else if (FromType->getAs<BlockPointerType>() &&
+ ToObjCPtr && ToObjCPtr->isObjCBuiltinType()) {
+ // Objective C++: We're able to convert from a block pointer type to a
+ // pointer to any object.
+ ConvertedType = ToType;
+ return true;
+ }
else
return false;
@@ -1164,6 +1181,16 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
ConvertedType = ToType;
return true;
}
+ // Allow conversion of pointee being objective-c pointer to another one;
+ // as in I* to id.
+ if (FromPointeeType->getAs<ObjCObjectPointerType>() &&
+ ToPointeeType->getAs<ObjCObjectPointerType>() &&
+ isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType,
+ IncompatibleObjC)) {
+ ConvertedType = ToType;
+ return true;
+ }
+
// If we have pointers to functions or blocks, check whether the only
// differences in the argument and result types are in Objective-C
// pointer conversions. If so, we permit the conversion (but
@@ -1523,9 +1550,9 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
if (CXXRecordDecl *FromRecordDecl
= dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
// Add all of the conversion functions as candidates.
- const UnresolvedSet *Conversions
+ const UnresolvedSetImpl *Conversions
= FromRecordDecl->getVisibleConversionFunctions();
- for (UnresolvedSet::iterator I = Conversions->begin(),
+ for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
NamedDecl *D = *I;
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
@@ -2756,7 +2783,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
if (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon)) {
Candidate.Viable = false;
- Candidate.FailureKind = ovl_fail_bad_conversion;
+ Candidate.FailureKind = ovl_fail_trivial_conversion;
return;
}
@@ -2794,7 +2821,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
case ImplicitConversionSequence::BadConversion:
Candidate.Viable = false;
- Candidate.FailureKind = ovl_fail_bad_conversion;
+ Candidate.FailureKind = ovl_fail_bad_final_conversion;
break;
default:
@@ -2869,6 +2896,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
if (ObjectInit.isBad()) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_fail_bad_conversion;
+ Candidate.Conversions[0] = ObjectInit;
return;
}
@@ -3270,9 +3298,9 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
}
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
- const UnresolvedSet *Conversions
+ const UnresolvedSetImpl *Conversions
= ClassDecl->getVisibleConversionFunctions();
- for (UnresolvedSet::iterator I = Conversions->begin(),
+ for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
// Skip conversion function templates; they don't tell us anything
@@ -3334,10 +3362,10 @@ static Qualifiers CollectVRQualifiers(ASTContext &Context, Expr* ArgExpr) {
}
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
- const UnresolvedSet *Conversions =
+ const UnresolvedSetImpl *Conversions =
ClassDecl->getVisibleConversionFunctions();
- for (UnresolvedSet::iterator I = Conversions->begin(),
+ for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
if (CXXConversionDecl *Conv = dyn_cast<CXXConversionDecl>(*I)) {
QualType CanTy = Context.getCanonicalType(Conv->getConversionType());
@@ -4386,7 +4414,8 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
QualType FromTy = Conv.Bad.getFromType();
QualType ToTy = Conv.Bad.getToType();
- // Do some hand-waving analysis to see if the non-viability is due to a
+ // Do some hand-waving analysis to see if the non-viability is due
+ // to a qualifier mismatch.
CanQualType CFromTy = S.Context.getCanonicalType(FromTy);
CanQualType CToTy = S.Context.getCanonicalType(ToTy);
if (CanQual<ReferenceType> RT = CToTy->getAs<ReferenceType>())
@@ -4436,6 +4465,20 @@ void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, unsigned I) {
return;
}
+ // Diagnose references or pointers to incomplete types differently,
+ // since it's far from impossible that the incompleteness triggered
+ // the failure.
+ QualType TempFromTy = FromTy.getNonReferenceType();
+ if (const PointerType *PTy = TempFromTy->getAs<PointerType>())
+ TempFromTy = PTy->getPointeeType();
+ if (TempFromTy->isIncompleteType()) {
+ S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete)
+ << (unsigned) FnKind << FnDesc
+ << (FromExpr ? FromExpr->getSourceRange() : SourceRange())
+ << FromTy << ToTy << (unsigned) isObjectArgument << I+1;
+ return;
+ }
+
// TODO: specialize more based on the kind of mismatch
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv)
<< (unsigned) FnKind << FnDesc
@@ -4503,6 +4546,8 @@ void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
return DiagnoseArityMismatch(S, Cand, NumArgs);
case ovl_fail_bad_deduction:
+ case ovl_fail_trivial_conversion:
+ case ovl_fail_bad_final_conversion:
return S.NoteOverloadCandidate(Fn);
case ovl_fail_bad_conversion:
@@ -4582,12 +4627,23 @@ void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
}
}
+SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) {
+ if (Cand->Function)
+ return Cand->Function->getLocation();
+ if (Cand->IsSurrogate)
+ return Cand->Surrogate->getLocation();
+ return SourceLocation();
+}
+
struct CompareOverloadCandidatesForDisplay {
Sema &S;
CompareOverloadCandidatesForDisplay(Sema &S) : S(S) {}
bool operator()(const OverloadCandidate *L,
const OverloadCandidate *R) {
+ // Fast-path this check.
+ if (L == R) return false;
+
// Order first by viability.
if (L->Viable) {
if (!R->Viable) return true;
@@ -4600,25 +4656,132 @@ struct CompareOverloadCandidatesForDisplay {
} else if (R->Viable)
return false;
- // Put declared functions first.
- if (L->Function) {
- if (!R->Function) return true;
- return S.SourceMgr.isBeforeInTranslationUnit(L->Function->getLocation(),
- R->Function->getLocation());
- } else if (R->Function) return false;
-
- // Then surrogates.
- if (L->IsSurrogate) {
- if (!R->IsSurrogate) return true;
- return S.SourceMgr.isBeforeInTranslationUnit(L->Surrogate->getLocation(),
- R->Surrogate->getLocation());
- } else if (R->IsSurrogate) return false;
-
- // And builtins just come in a jumble.
- return false;
+ assert(L->Viable == R->Viable);
+
+ // Criteria by which we can sort non-viable candidates:
+ if (!L->Viable) {
+ // 1. Arity mismatches come after other candidates.
+ if (L->FailureKind == ovl_fail_too_many_arguments ||
+ L->FailureKind == ovl_fail_too_few_arguments)
+ return false;
+ if (R->FailureKind == ovl_fail_too_many_arguments ||
+ R->FailureKind == ovl_fail_too_few_arguments)
+ return true;
+
+ // 2. Bad conversions come first and are ordered by the number
+ // of bad conversions and quality of good conversions.
+ if (L->FailureKind == ovl_fail_bad_conversion) {
+ if (R->FailureKind != ovl_fail_bad_conversion)
+ return true;
+
+ // If there's any ordering between the defined conversions...
+ // FIXME: this might not be transitive.
+ assert(L->Conversions.size() == R->Conversions.size());
+
+ int leftBetter = 0;
+ for (unsigned I = 0, E = L->Conversions.size(); I != E; ++I) {
+ switch (S.CompareImplicitConversionSequences(L->Conversions[I],
+ R->Conversions[I])) {
+ case ImplicitConversionSequence::Better:
+ leftBetter++;
+ break;
+
+ case ImplicitConversionSequence::Worse:
+ leftBetter--;
+ break;
+
+ case ImplicitConversionSequence::Indistinguishable:
+ break;
+ }
+ }
+ if (leftBetter > 0) return true;
+ if (leftBetter < 0) return false;
+
+ } else if (R->FailureKind == ovl_fail_bad_conversion)
+ return false;
+
+ // TODO: others?
+ }
+
+ // Sort everything else by location.
+ SourceLocation LLoc = GetLocationForCandidate(L);
+ SourceLocation RLoc = GetLocationForCandidate(R);
+
+ // Put candidates without locations (e.g. builtins) at the end.
+ if (LLoc.isInvalid()) return false;
+ if (RLoc.isInvalid()) return true;
+
+ return S.SourceMgr.isBeforeInTranslationUnit(LLoc, RLoc);
}
};
+/// CompleteNonViableCandidate - Normally, overload resolution only
+/// computes up to the first
+void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand,
+ Expr **Args, unsigned NumArgs) {
+ assert(!Cand->Viable);
+
+ // Don't do anything on failures other than bad conversion.
+ if (Cand->FailureKind != ovl_fail_bad_conversion) return;
+
+ // Skip forward to the first bad conversion.
+ unsigned ConvIdx = 0;
+ unsigned ConvCount = Cand->Conversions.size();
+ while (true) {
+ assert(ConvIdx != ConvCount && "no bad conversion in candidate");
+ ConvIdx++;
+ if (Cand->Conversions[ConvIdx - 1].isBad())
+ break;
+ }
+
+ if (ConvIdx == ConvCount)
+ return;
+
+ // FIXME: these should probably be preserved from the overload
+ // operation somehow.
+ bool SuppressUserConversions = false;
+ bool ForceRValue = false;
+
+ const FunctionProtoType* Proto;
+ unsigned ArgIdx = ConvIdx;
+
+ if (Cand->IsSurrogate) {
+ QualType ConvType
+ = Cand->Surrogate->getConversionType().getNonReferenceType();
+ if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
+ ConvType = ConvPtrType->getPointeeType();
+ Proto = ConvType->getAs<FunctionProtoType>();
+ ArgIdx--;
+ } else if (Cand->Function) {
+ Proto = Cand->Function->getType()->getAs<FunctionProtoType>();
+ if (isa<CXXMethodDecl>(Cand->Function) &&
+ !isa<CXXConstructorDecl>(Cand->Function))
+ ArgIdx--;
+ } else {
+ // Builtin binary operator with a bad first conversion.
+ assert(ConvCount <= 3);
+ for (; ConvIdx != ConvCount; ++ConvIdx)
+ Cand->Conversions[ConvIdx]
+ = S.TryCopyInitialization(Args[ConvIdx],
+ Cand->BuiltinTypes.ParamTypes[ConvIdx],
+ SuppressUserConversions, ForceRValue,
+ /*InOverloadResolution*/ true);
+ return;
+ }
+
+ // Fill in the rest of the conversions.
+ unsigned NumArgsInProto = Proto->getNumArgs();
+ for (; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) {
+ if (ArgIdx < NumArgsInProto)
+ Cand->Conversions[ConvIdx]
+ = S.TryCopyInitialization(Args[ArgIdx], Proto->getArgType(ArgIdx),
+ SuppressUserConversions, ForceRValue,
+ /*InOverloadResolution=*/true);
+ else
+ Cand->Conversions[ConvIdx].setEllipsis();
+ }
+}
+
} // end anonymous namespace
/// PrintOverloadCandidates - When overload resolution fails, prints
@@ -4636,9 +4799,15 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
if (OCD == OCD_AllCandidates) Cands.reserve(CandidateSet.size());
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
LastCand = CandidateSet.end();
- Cand != LastCand; ++Cand)
- if (Cand->Viable || OCD == OCD_AllCandidates)
+ Cand != LastCand; ++Cand) {
+ if (Cand->Viable)
Cands.push_back(Cand);
+ else if (OCD == OCD_AllCandidates) {
+ CompleteNonViableCandidate(*this, Cand, Args, NumArgs);
+ Cands.push_back(Cand);
+ }
+ }
+
std::sort(Cands.begin(), Cands.end(),
CompareOverloadCandidatesForDisplay(*this));
@@ -5909,9 +6078,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// functions for each conversion function declared in an
// accessible base class provided the function is not hidden
// within T by another intervening declaration.
- const UnresolvedSet *Conversions
+ const UnresolvedSetImpl *Conversions
= cast<CXXRecordDecl>(Record->getDecl())->getVisibleConversionFunctions();
- for (UnresolvedSet::iterator I = Conversions->begin(),
+ for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end(); I != E; ++I) {
NamedDecl *D = *I;
CXXRecordDecl *ActingContext = cast<CXXRecordDecl>(D->getDeclContext());
OpenPOWER on IntegriCloud