summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp2271
1 files changed, 1451 insertions, 820 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 03ac2d9bb73a..99e7b0811c91 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -12,23 +12,25 @@
//===----------------------------------------------------------------------===//
#include "Sema.h"
-#include "SemaInherit.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeOrdering.h"
+#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include <algorithm>
+#include <cstdio>
namespace clang {
/// GetConversionCategory - Retrieve the implicit conversion
/// category corresponding to the given implicit conversion kind.
-ImplicitConversionCategory
+ImplicitConversionCategory
GetConversionCategory(ImplicitConversionKind Kind) {
static const ImplicitConversionCategory
Category[(int)ICK_Num_Conversion_Kinds] = {
@@ -136,10 +138,9 @@ ImplicitConversionRank StandardConversionSequence::getRank() const {
/// isPointerConversionToBool - Determines whether this conversion is
/// a conversion of a pointer or pointer-to-member to bool. This is
-/// used as part of the ranking of standard conversion sequences
+/// used as part of the ranking of standard conversion sequences
/// (C++ 13.3.3.2p4).
-bool StandardConversionSequence::isPointerConversionToBool() const
-{
+bool StandardConversionSequence::isPointerConversionToBool() const {
QualType FromType = QualType::getFromOpaquePtr(FromTypePtr);
QualType ToType = QualType::getFromOpaquePtr(ToTypePtr);
@@ -159,10 +160,9 @@ bool StandardConversionSequence::isPointerConversionToBool() const
/// conversion is a conversion of a pointer to a void pointer. This is
/// used as part of the ranking of standard conversion sequences (C++
/// 13.3.3.2p4).
-bool
+bool
StandardConversionSequence::
-isPointerConversionToVoidPointer(ASTContext& Context) const
-{
+isPointerConversionToVoidPointer(ASTContext& Context) const {
QualType FromType = QualType::getFromOpaquePtr(FromTypePtr);
QualType ToType = QualType::getFromOpaquePtr(ToTypePtr);
@@ -173,7 +173,7 @@ isPointerConversionToVoidPointer(ASTContext& Context) const
FromType = Context.getArrayDecayedType(FromType);
if (Second == ICK_Pointer_Conversion)
- if (const PointerType* ToPtrType = ToType->getAsPointerType())
+ if (const PointerType* ToPtrType = ToType->getAs<PointerType>())
return ToPtrType->getPointeeType()->isVoidType();
return false;
@@ -260,7 +260,7 @@ void ImplicitConversionSequence::DebugPrint() const {
// same signature (C++ 1.3.10) or if the Old declaration isn't a
// function (or overload set). When it does return false and Old is an
// OverloadedFunctionDecl, MatchedDecl will be set to point to the
-// FunctionDecl that New cannot be overloaded with.
+// FunctionDecl that New cannot be overloaded with.
//
// Example: Given the following input:
//
@@ -269,7 +269,7 @@ void ImplicitConversionSequence::DebugPrint() const {
// int f(int, int); // #3
//
// When we process #1, there is no previous declaration of "f",
-// so IsOverload will not be used.
+// so IsOverload will not be used.
//
// When we process #2, Old is a FunctionDecl for #1. By comparing the
// parameter types, we see that #1 and #2 are overloaded (since they
@@ -283,9 +283,8 @@ void ImplicitConversionSequence::DebugPrint() const {
// signature), IsOverload returns false and MatchedDecl will be set to
// point to the FunctionDecl for #2.
bool
-Sema::IsOverload(FunctionDecl *New, Decl* OldD,
- OverloadedFunctionDecl::function_iterator& MatchedDecl)
-{
+Sema::IsOverload(FunctionDecl *New, Decl* OldD,
+ OverloadedFunctionDecl::function_iterator& MatchedDecl) {
if (OverloadedFunctionDecl* Ovl = dyn_cast<OverloadedFunctionDecl>(OldD)) {
// Is this new function an overload of every function in the
// overload set?
@@ -304,8 +303,8 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
return IsOverload(New, Old->getTemplatedDecl(), MatchedDecl);
else if (FunctionDecl* Old = dyn_cast<FunctionDecl>(OldD)) {
FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
- FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
-
+ FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
+
// C++ [temp.fct]p2:
// A function template can be overloaded with other function templates
// and with normal (non-template) functions.
@@ -340,21 +339,21 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
return true;
// C++ [temp.over.link]p4:
- // The signature of a function template consists of its function
+ // The signature of a function template consists of its function
// signature, its return type and its template parameter list. The names
// of the template parameters are significant only for establishing the
- // relationship between the template parameters and the rest of the
+ // relationship between the template parameters and the rest of the
// signature.
//
// We check the return type and template parameter lists for function
// templates first; the remaining checks follow.
if (NewTemplate &&
- (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
- OldTemplate->getTemplateParameters(),
+ (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
+ OldTemplate->getTemplateParameters(),
false, false, SourceLocation()) ||
OldType->getResultType() != NewType->getResultType()))
return true;
-
+
// If the function is a class member, its signature includes the
// cv-qualifiers (if any) on the function itself.
//
@@ -365,7 +364,7 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
// can be overloaded.
CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
- if (OldMethod && NewMethod &&
+ if (OldMethod && NewMethod &&
!OldMethod->isStatic() && !NewMethod->isStatic() &&
OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers())
return true;
@@ -405,18 +404,25 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
/// permitted.
/// If @p ForceRValue, then overloading is performed as if From was an rvalue,
/// no matter its actual lvalueness.
+/// If @p UserCast, the implicit conversion is being done for a user-specified
+/// cast.
ImplicitConversionSequence
Sema::TryImplicitConversion(Expr* From, QualType ToType,
bool SuppressUserConversions,
- bool AllowExplicit, bool ForceRValue)
-{
+ bool AllowExplicit, bool ForceRValue,
+ bool InOverloadResolution,
+ bool UserCast) {
ImplicitConversionSequence ICS;
- if (IsStandardConversion(From, ToType, ICS.Standard))
+ OverloadCandidateSet Conversions;
+ OverloadingResult UserDefResult = OR_Success;
+ if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard))
ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
else if (getLangOptions().CPlusPlus &&
- IsUserDefinedConversion(From, ToType, ICS.UserDefined,
+ (UserDefResult = IsUserDefinedConversion(From, ToType,
+ ICS.UserDefined,
+ Conversions,
!SuppressUserConversions, AllowExplicit,
- ForceRValue)) {
+ ForceRValue, UserCast)) == OR_Success) {
ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
// C++ [over.ics.user]p4:
// A conversion of an expression of class type to the same class
@@ -425,9 +431,9 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
// given Conversion rank, in spite of the fact that a copy
// constructor (i.e., a user-defined conversion function) is
// called for those cases.
- if (CXXConstructorDecl *Constructor
+ if (CXXConstructorDecl *Constructor
= dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
- QualType FromCanon
+ QualType FromCanon
= Context.getCanonicalType(From->getType().getUnqualifiedType());
QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType();
if (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon)) {
@@ -453,8 +459,15 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
if (SuppressUserConversions &&
ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion)
ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
- } else
+ } else {
ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
+ if (UserDefResult == OR_Ambiguous) {
+ for (OverloadCandidateSet::iterator Cand = Conversions.begin();
+ Cand != Conversions.end(); ++Cand)
+ if (Cand->Viable)
+ ICS.ConversionFunctionSet.push_back(Cand->Function);
+ }
+ }
return ICS;
}
@@ -467,10 +480,10 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
/// contain the standard conversion sequence required to perform this
/// conversion and this routine will return true. Otherwise, this
/// routine will return false and the value of SCS is unspecified.
-bool
-Sema::IsStandardConversion(Expr* From, QualType ToType,
- StandardConversionSequence &SCS)
-{
+bool
+Sema::IsStandardConversion(Expr* From, QualType ToType,
+ bool InOverloadResolution,
+ StandardConversionSequence &SCS) {
QualType FromType = From->getType();
// Standard conversions (C++ [conv])
@@ -481,23 +494,23 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
SCS.CopyConstructor = 0;
// There are no standard conversions for class types in C++, so
- // abort early. When overloading in C, however, we do permit
+ // abort early. When overloading in C, however, we do permit
if (FromType->isRecordType() || ToType->isRecordType()) {
if (getLangOptions().CPlusPlus)
return false;
- // When we're overloading in C, we allow, as standard conversions,
+ // When we're overloading in C, we allow, as standard conversions,
}
// The first conversion can be an lvalue-to-rvalue conversion,
// array-to-pointer conversion, or function-to-pointer conversion
// (C++ 4p1).
- // Lvalue-to-rvalue conversion (C++ 4.1):
+ // Lvalue-to-rvalue conversion (C++ 4.1):
// An lvalue (3.10) of a non-function, non-array type T can be
// converted to an rvalue.
Expr::isLvalueResult argIsLvalue = From->isLvalue(Context);
- if (argIsLvalue == Expr::LV_Valid &&
+ if (argIsLvalue == Expr::LV_Valid &&
!FromType->isFunctionType() && !FromType->isArrayType() &&
Context.getCanonicalType(FromType) != Context.OverloadTy) {
SCS.First = ICK_Lvalue_To_Rvalue;
@@ -509,9 +522,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// FIXME: Doesn't see through to qualifiers behind a typedef!
FromType = FromType.getUnqualifiedType();
- }
- // Array-to-pointer conversion (C++ 4.2)
- else if (FromType->isArrayType()) {
+ } else if (FromType->isArrayType()) {
+ // Array-to-pointer conversion (C++ 4.2)
SCS.First = ICK_Array_To_Pointer;
// An lvalue or rvalue of type "array of N T" or "array of unknown
@@ -532,19 +544,17 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
SCS.ToTypePtr = ToType.getAsOpaquePtr();
return true;
}
- }
- // Function-to-pointer conversion (C++ 4.3).
- else if (FromType->isFunctionType() && argIsLvalue == Expr::LV_Valid) {
+ } else if (FromType->isFunctionType() && argIsLvalue == Expr::LV_Valid) {
+ // Function-to-pointer conversion (C++ 4.3).
SCS.First = ICK_Function_To_Pointer;
// An lvalue of function type T can be converted to an rvalue of
// type "pointer to T." The result is a pointer to the
// function. (C++ 4.3p1).
FromType = Context.getPointerType(FromType);
- }
- // Address of overloaded function (C++ [over.over]).
- else if (FunctionDecl *Fn
+ } else if (FunctionDecl *Fn
= ResolveAddressOfOverloadedFunction(From, ToType, false)) {
+ // Address of overloaded function (C++ [over.over]).
SCS.First = ICK_Function_To_Pointer;
// We were able to resolve the address of the overloaded function,
@@ -566,9 +576,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
Context.getTypeDeclType(M->getParent()).getTypePtr());
} else
FromType = Context.getPointerType(FromType);
- }
- // We don't require any conversions for the first step.
- else {
+ } else {
+ // We don't require any conversions for the first step.
SCS.First = ICK_Identity;
}
@@ -583,79 +592,68 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// The unqualified versions of the types are the same: there's no
// conversion to do.
SCS.Second = ICK_Identity;
- }
- // Integral promotion (C++ 4.5).
- else if (IsIntegralPromotion(From, FromType, ToType)) {
+ } else if (IsIntegralPromotion(From, FromType, ToType)) {
+ // Integral promotion (C++ 4.5).
SCS.Second = ICK_Integral_Promotion;
FromType = ToType.getUnqualifiedType();
- }
- // Floating point promotion (C++ 4.6).
- else if (IsFloatingPointPromotion(FromType, ToType)) {
+ } else if (IsFloatingPointPromotion(FromType, ToType)) {
+ // Floating point promotion (C++ 4.6).
SCS.Second = ICK_Floating_Promotion;
FromType = ToType.getUnqualifiedType();
- }
- // Complex promotion (Clang extension)
- else if (IsComplexPromotion(FromType, ToType)) {
+ } else if (IsComplexPromotion(FromType, ToType)) {
+ // Complex promotion (Clang extension)
SCS.Second = ICK_Complex_Promotion;
FromType = ToType.getUnqualifiedType();
- }
- // Integral conversions (C++ 4.7).
- // FIXME: isIntegralType shouldn't be true for enums in C++.
- else if ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
+ } else if ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
(ToType->isIntegralType() && !ToType->isEnumeralType())) {
+ // Integral conversions (C++ 4.7).
+ // FIXME: isIntegralType shouldn't be true for enums in C++.
SCS.Second = ICK_Integral_Conversion;
FromType = ToType.getUnqualifiedType();
- }
- // Floating point conversions (C++ 4.8).
- else if (FromType->isFloatingType() && ToType->isFloatingType()) {
+ } else if (FromType->isFloatingType() && ToType->isFloatingType()) {
+ // Floating point conversions (C++ 4.8).
SCS.Second = ICK_Floating_Conversion;
FromType = ToType.getUnqualifiedType();
- }
- // Complex conversions (C99 6.3.1.6)
- else if (FromType->isComplexType() && ToType->isComplexType()) {
+ } else if (FromType->isComplexType() && ToType->isComplexType()) {
+ // Complex conversions (C99 6.3.1.6)
SCS.Second = ICK_Complex_Conversion;
FromType = ToType.getUnqualifiedType();
- }
- // Floating-integral conversions (C++ 4.9).
- // FIXME: isIntegralType shouldn't be true for enums in C++.
- else if ((FromType->isFloatingType() &&
- ToType->isIntegralType() && !ToType->isBooleanType() &&
- !ToType->isEnumeralType()) ||
- ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
- ToType->isFloatingType())) {
+ } else if ((FromType->isFloatingType() &&
+ ToType->isIntegralType() && (!ToType->isBooleanType() &&
+ !ToType->isEnumeralType())) ||
+ ((FromType->isIntegralType() || FromType->isEnumeralType()) &&
+ ToType->isFloatingType())) {
+ // Floating-integral conversions (C++ 4.9).
+ // FIXME: isIntegralType shouldn't be true for enums in C++.
SCS.Second = ICK_Floating_Integral;
FromType = ToType.getUnqualifiedType();
- }
- // Complex-real conversions (C99 6.3.1.7)
- else if ((FromType->isComplexType() && ToType->isArithmeticType()) ||
- (ToType->isComplexType() && FromType->isArithmeticType())) {
+ } else if ((FromType->isComplexType() && ToType->isArithmeticType()) ||
+ (ToType->isComplexType() && FromType->isArithmeticType())) {
+ // Complex-real conversions (C99 6.3.1.7)
SCS.Second = ICK_Complex_Real;
FromType = ToType.getUnqualifiedType();
- }
- // Pointer conversions (C++ 4.10).
- else if (IsPointerConversion(From, FromType, ToType, FromType,
- IncompatibleObjC)) {
+ } else if (IsPointerConversion(From, FromType, ToType, InOverloadResolution,
+ FromType, IncompatibleObjC)) {
+ // Pointer conversions (C++ 4.10).
SCS.Second = ICK_Pointer_Conversion;
SCS.IncompatibleObjC = IncompatibleObjC;
- }
- // Pointer to member conversions (4.11).
- else if (IsMemberPointerConversion(From, FromType, ToType, FromType)) {
+ } else if (IsMemberPointerConversion(From, FromType, ToType,
+ InOverloadResolution, FromType)) {
+ // Pointer to member conversions (4.11).
SCS.Second = ICK_Pointer_Member;
- }
- // Boolean conversions (C++ 4.12).
- else if (ToType->isBooleanType() &&
- (FromType->isArithmeticType() ||
- FromType->isEnumeralType() ||
- FromType->isPointerType() ||
- FromType->isBlockPointerType() ||
- FromType->isMemberPointerType() ||
- FromType->isNullPtrType())) {
+ } else if (ToType->isBooleanType() &&
+ (FromType->isArithmeticType() ||
+ FromType->isEnumeralType() ||
+ FromType->isPointerType() ||
+ FromType->isBlockPointerType() ||
+ FromType->isMemberPointerType() ||
+ FromType->isNullPtrType())) {
+ // Boolean conversions (C++ 4.12).
SCS.Second = ICK_Boolean_Conversion;
FromType = Context.BoolTy;
- }
- // Compatible conversions (Clang extension for C function overloading)
- else if (!getLangOptions().CPlusPlus &&
- Context.typesAreCompatible(ToType, FromType)) {
+ } else if (!getLangOptions().CPlusPlus &&
+ Context.typesAreCompatible(ToType, FromType)) {
+ // Compatible conversions (Clang extension for C function overloading)
SCS.Second = ICK_Compatible_Conversion;
} else {
// No second conversion required.
@@ -674,12 +672,12 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
// No conversion required
SCS.Third = ICK_Identity;
- // C++ [over.best.ics]p6:
+ // C++ [over.best.ics]p6:
// [...] Any difference in top-level cv-qualification is
// subsumed by the initialization itself and does not constitute
// a conversion. [...]
CanonFrom = Context.getCanonicalType(FromType);
- CanonTo = Context.getCanonicalType(ToType);
+ CanonTo = Context.getCanonicalType(ToType);
if (CanonFrom.getUnqualifiedType() == CanonTo.getUnqualifiedType() &&
CanonFrom.getCVRQualifiers() != CanonTo.getCVRQualifiers()) {
FromType = ToType;
@@ -700,9 +698,8 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
/// expression From (whose potentially-adjusted type is FromType) to
/// ToType is an integral promotion (C++ 4.5). If so, returns true and
/// sets PromotedType to the promoted type.
-bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
-{
- const BuiltinType *To = ToType->getAsBuiltinType();
+bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
+ const BuiltinType *To = ToType->getAs<BuiltinType>();
// All integers are built-in.
if (!To) {
return false;
@@ -718,7 +715,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
(FromType->isSignedIntegerType() ||
// We can promote any unsigned integer type whose size is
// less than int to an int.
- (!FromType->isSignedIntegerType() &&
+ (!FromType->isSignedIntegerType() &&
Context.getTypeSize(FromType) < Context.getTypeSize(ToType)))) {
return To->getKind() == BuiltinType::Int;
}
@@ -736,7 +733,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
// unsigned.
bool FromIsSigned;
uint64_t FromSize = Context.getTypeSize(FromType);
- if (const EnumType *FromEnumType = FromType->getAsEnumType()) {
+ if (const EnumType *FromEnumType = FromType->getAs<EnumType>()) {
QualType UnderlyingType = FromEnumType->getDecl()->getIntegerType();
FromIsSigned = UnderlyingType->isSignedIntegerType();
} else {
@@ -746,15 +743,15 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
// The types we'll try to promote to, in the appropriate
// order. Try each of these types.
- QualType PromoteTypes[6] = {
- Context.IntTy, Context.UnsignedIntTy,
+ QualType PromoteTypes[6] = {
+ Context.IntTy, Context.UnsignedIntTy,
Context.LongTy, Context.UnsignedLongTy ,
Context.LongLongTy, Context.UnsignedLongLongTy
};
for (int Idx = 0; Idx < 6; ++Idx) {
uint64_t ToSize = Context.getTypeSize(PromoteTypes[Idx]);
if (FromSize < ToSize ||
- (FromSize == ToSize &&
+ (FromSize == ToSize &&
FromIsSigned == PromoteTypes[Idx]->isSignedIntegerType())) {
// We found the type that we can promote to. If this is the
// type we wanted, we have a promotion. Otherwise, no
@@ -782,23 +779,23 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) {
APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned());
ToSize = Context.getTypeSize(ToType);
-
+
// Are we promoting to an int from a bitfield that fits in an int?
if (BitWidth < ToSize ||
(FromType->isSignedIntegerType() && BitWidth <= ToSize)) {
return To->getKind() == BuiltinType::Int;
}
-
+
// Are we promoting to an unsigned int from an unsigned bitfield
// that fits into an unsigned int?
if (FromType->isUnsignedIntegerType() && BitWidth <= ToSize) {
return To->getKind() == BuiltinType::UInt;
}
-
+
return false;
}
}
-
+
// An rvalue of type bool can be converted to an rvalue of type int,
// with false becoming zero and true becoming one (C++ 4.5p4).
if (FromType->isBooleanType() && To->getKind() == BuiltinType::Int) {
@@ -811,12 +808,11 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType)
/// IsFloatingPointPromotion - Determines whether the conversion from
/// FromType to ToType is a floating point promotion (C++ 4.6). If so,
/// returns true and sets PromotedType to the promoted type.
-bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType)
-{
+bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType) {
/// An rvalue of type float can be converted to an rvalue of type
/// double. (C++ 4.6p1).
- if (const BuiltinType *FromBuiltin = FromType->getAsBuiltinType())
- if (const BuiltinType *ToBuiltin = ToType->getAsBuiltinType()) {
+ if (const BuiltinType *FromBuiltin = FromType->getAs<BuiltinType>())
+ if (const BuiltinType *ToBuiltin = ToType->getAs<BuiltinType>()) {
if (FromBuiltin->getKind() == BuiltinType::Float &&
ToBuiltin->getKind() == BuiltinType::Double)
return true;
@@ -840,11 +836,11 @@ bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType)
/// where the conversion between the underlying real types is a
/// floating-point or integral promotion.
bool Sema::IsComplexPromotion(QualType FromType, QualType ToType) {
- const ComplexType *FromComplex = FromType->getAsComplexType();
+ const ComplexType *FromComplex = FromType->getAs<ComplexType>();
if (!FromComplex)
return false;
- const ComplexType *ToComplex = ToType->getAsComplexType();
+ const ComplexType *ToComplex = ToType->getAs<ComplexType>();
if (!ToComplex)
return false;
@@ -859,18 +855,18 @@ bool Sema::IsComplexPromotion(QualType FromType, QualType ToType) {
/// same type qualifiers as FromPtr has on its pointee type. ToType,
/// if non-empty, will be a pointer to ToType that may or may not have
/// the right set of qualifiers on its pointee.
-static QualType
-BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
+static QualType
+BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
QualType ToPointee, QualType ToType,
ASTContext &Context) {
QualType CanonFromPointee = Context.getCanonicalType(FromPtr->getPointeeType());
QualType CanonToPointee = Context.getCanonicalType(ToPointee);
- unsigned Quals = CanonFromPointee.getCVRQualifiers();
-
- // Exact qualifier match -> return the pointer type we're converting to.
- if (CanonToPointee.getCVRQualifiers() == Quals) {
+ Qualifiers Quals = CanonFromPointee.getQualifiers();
+
+ // Exact qualifier match -> return the pointer type we're converting to.
+ if (CanonToPointee.getQualifiers() == Quals) {
// ToType is exactly what we need. Return it.
- if (ToType.getTypePtr())
+ if (!ToType.isNull())
return ToType;
// Build a pointer to ToPointee. It has the right qualifiers
@@ -879,7 +875,22 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
}
// Just build a canonical type that has the right qualifiers.
- return Context.getPointerType(CanonToPointee.getQualifiedType(Quals));
+ return Context.getPointerType(
+ Context.getQualifiedType(CanonToPointee.getUnqualifiedType(), Quals));
+}
+
+static bool isNullPointerConstantForConversion(Expr *Expr,
+ bool InOverloadResolution,
+ ASTContext &Context) {
+ // Handle value-dependent integral null pointer constants correctly.
+ // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903
+ if (Expr->isValueDependent() && !Expr->isTypeDependent() &&
+ Expr->getType()->isIntegralType())
+ return !InOverloadResolution;
+
+ return Expr->isNullPointerConstant(Context,
+ InOverloadResolution? Expr::NPC_ValueDependentIsNotNull
+ : Expr::NPC_ValueDependentIsNull);
}
/// IsPointerConversion - Determines whether the conversion of the
@@ -899,52 +910,54 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
/// set if the conversion is an allowed Objective-C conversion that
/// should result in a warning.
bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
+ bool InOverloadResolution,
QualType& ConvertedType,
- bool &IncompatibleObjC)
-{
+ bool &IncompatibleObjC) {
IncompatibleObjC = false;
if (isObjCPointerConversion(FromType, ToType, ConvertedType, IncompatibleObjC))
return true;
- // Conversion from a null pointer constant to any Objective-C pointer type.
- if (Context.isObjCObjectPointerType(ToType) &&
- From->isNullPointerConstant(Context)) {
+ // Conversion from a null pointer constant to any Objective-C pointer type.
+ if (ToType->isObjCObjectPointerType() &&
+ isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
ConvertedType = ToType;
return true;
}
// Blocks: Block pointers can be converted to void*.
if (FromType->isBlockPointerType() && ToType->isPointerType() &&
- ToType->getAsPointerType()->getPointeeType()->isVoidType()) {
+ ToType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
ConvertedType = ToType;
return true;
}
// Blocks: A null pointer constant can be converted to a block
// pointer type.
- if (ToType->isBlockPointerType() && From->isNullPointerConstant(Context)) {
+ if (ToType->isBlockPointerType() &&
+ isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
ConvertedType = ToType;
return true;
}
// If the left-hand-side is nullptr_t, the right side can be a null
// pointer constant.
- if (ToType->isNullPtrType() && From->isNullPointerConstant(Context)) {
+ if (ToType->isNullPtrType() &&
+ isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
ConvertedType = ToType;
return true;
}
- const PointerType* ToTypePtr = ToType->getAsPointerType();
+ const PointerType* ToTypePtr = ToType->getAs<PointerType>();
if (!ToTypePtr)
return false;
// A null pointer constant can be converted to a pointer type (C++ 4.10p1).
- if (From->isNullPointerConstant(Context)) {
+ if (isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
ConvertedType = ToType;
return true;
}
// Beyond this point, both types need to be pointers.
- const PointerType *FromTypePtr = FromType->getAsPointerType();
+ const PointerType *FromTypePtr = FromType->getAs<PointerType>();
if (!FromTypePtr)
return false;
@@ -955,7 +968,7 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
// can be converted to an rvalue of type "pointer to cv void" (C++
// 4.10p2).
if (FromPointeeType->isObjectType() && ToPointeeType->isVoidType()) {
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
+ ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
ToType, Context);
return true;
@@ -963,16 +976,16 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
// When we're overloading in C, we allow a special kind of pointer
// conversion for compatible-but-not-identical pointee types.
- if (!getLangOptions().CPlusPlus &&
+ if (!getLangOptions().CPlusPlus &&
Context.typesAreCompatible(FromPointeeType, ToPointeeType)) {
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
+ ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
- ToType, Context);
+ ToType, Context);
return true;
}
// C++ [conv.ptr]p3:
- //
+ //
// An rvalue of type "pointer to cv D," where D is a class type,
// can be converted to an rvalue of type "pointer to cv B," where
// B is a base class (clause 10) of D. If B is an inaccessible
@@ -987,7 +1000,7 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
if (getLangOptions().CPlusPlus &&
FromPointeeType->isRecordType() && ToPointeeType->isRecordType() &&
IsDerivedFrom(FromPointeeType, ToPointeeType)) {
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
+ ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
ToType, Context);
return true;
@@ -999,83 +1012,65 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
/// isObjCPointerConversion - Determines whether this is an
/// Objective-C pointer conversion. Subroutine of IsPointerConversion,
/// with the same arguments and return values.
-bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
+bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
QualType& ConvertedType,
bool &IncompatibleObjC) {
if (!getLangOptions().ObjC1)
return false;
- // Conversions with Objective-C's id<...>.
- if ((FromType->isObjCQualifiedIdType() || ToType->isObjCQualifiedIdType()) &&
- ObjCQualifiedIdTypesAreCompatible(ToType, FromType, /*compare=*/false)) {
- ConvertedType = ToType;
- return true;
- }
+ // First, we handle all conversions on ObjC object pointer types.
+ const ObjCObjectPointerType* ToObjCPtr = ToType->getAs<ObjCObjectPointerType>();
+ const ObjCObjectPointerType *FromObjCPtr =
+ FromType->getAs<ObjCObjectPointerType>();
+
+ if (ToObjCPtr && FromObjCPtr) {
+ // Objective C++: We're able to convert between "id" or "Class" and a
+ // pointer to any interface (in both directions).
+ if (ToObjCPtr->isObjCBuiltinType() && FromObjCPtr->isObjCBuiltinType()) {
+ ConvertedType = ToType;
+ return true;
+ }
+ // Conversions with Objective-C's id<...>.
+ if ((FromObjCPtr->isObjCQualifiedIdType() ||
+ ToObjCPtr->isObjCQualifiedIdType()) &&
+ Context.ObjCQualifiedIdTypesAreCompatible(ToType, FromType,
+ /*compare=*/false)) {
+ ConvertedType = ToType;
+ return true;
+ }
+ // Objective C++: We're able to convert from a pointer to an
+ // interface to a pointer to a different interface.
+ if (Context.canAssignObjCInterfaces(ToObjCPtr, FromObjCPtr)) {
+ ConvertedType = ToType;
+ return true;
+ }
- // Beyond this point, both types need to be pointers or block pointers.
+ if (Context.canAssignObjCInterfaces(FromObjCPtr, ToObjCPtr)) {
+ // Okay: this is some kind of implicit downcast of Objective-C
+ // interfaces, which is permitted. However, we're going to
+ // complain about it.
+ IncompatibleObjC = true;
+ ConvertedType = FromType;
+ return true;
+ }
+ }
+ // Beyond this point, both types need to be C pointers or block pointers.
QualType ToPointeeType;
- const PointerType* ToTypePtr = ToType->getAsPointerType();
- if (ToTypePtr)
- ToPointeeType = ToTypePtr->getPointeeType();
- else if (const BlockPointerType *ToBlockPtr = ToType->getAsBlockPointerType())
+ if (const PointerType *ToCPtr = ToType->getAs<PointerType>())
+ ToPointeeType = ToCPtr->getPointeeType();
+ else if (const BlockPointerType *ToBlockPtr = ToType->getAs<BlockPointerType>())
ToPointeeType = ToBlockPtr->getPointeeType();
else
return false;
QualType FromPointeeType;
- const PointerType *FromTypePtr = FromType->getAsPointerType();
- if (FromTypePtr)
- FromPointeeType = FromTypePtr->getPointeeType();
- else if (const BlockPointerType *FromBlockPtr
- = FromType->getAsBlockPointerType())
+ if (const PointerType *FromCPtr = FromType->getAs<PointerType>())
+ FromPointeeType = FromCPtr->getPointeeType();
+ else if (const BlockPointerType *FromBlockPtr = FromType->getAs<BlockPointerType>())
FromPointeeType = FromBlockPtr->getPointeeType();
else
return false;
- // Objective C++: We're able to convert from a pointer to an
- // interface to a pointer to a different interface.
- const ObjCInterfaceType* FromIface = FromPointeeType->getAsObjCInterfaceType();
- const ObjCInterfaceType* ToIface = ToPointeeType->getAsObjCInterfaceType();
- if (FromIface && ToIface &&
- Context.canAssignObjCInterfaces(ToIface, FromIface)) {
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
- ToPointeeType,
- ToType, Context);
- return true;
- }
-
- if (FromIface && ToIface &&
- Context.canAssignObjCInterfaces(FromIface, ToIface)) {
- // Okay: this is some kind of implicit downcast of Objective-C
- // interfaces, which is permitted. However, we're going to
- // complain about it.
- IncompatibleObjC = true;
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
- ToPointeeType,
- ToType, Context);
- return true;
- }
-
- // Objective C++: We're able to convert between "id" and a pointer
- // to any interface (in both directions).
- if ((FromIface && Context.isObjCIdStructType(ToPointeeType))
- || (ToIface && Context.isObjCIdStructType(FromPointeeType))) {
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
- ToPointeeType,
- ToType, Context);
- return true;
- }
-
- // Objective C++: Allow conversions between the Objective-C "id" and
- // "Class", in either direction.
- if ((Context.isObjCIdStructType(FromPointeeType) &&
- Context.isObjCClassStructType(ToPointeeType)) ||
- (Context.isObjCClassStructType(FromPointeeType) &&
- Context.isObjCIdStructType(ToPointeeType))) {
- ConvertedType = ToType;
- return true;
- }
-
// If we have pointers to pointers, recursively check whether this
// is an Objective-C conversion.
if (FromPointeeType->isPointerType() && ToPointeeType->isPointerType() &&
@@ -1086,15 +1081,14 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
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
// complain about it).
- const FunctionProtoType *FromFunctionType
- = FromPointeeType->getAsFunctionProtoType();
+ const FunctionProtoType *FromFunctionType
+ = FromPointeeType->getAs<FunctionProtoType>();
const FunctionProtoType *ToFunctionType
- = ToPointeeType->getAsFunctionProtoType();
+ = ToPointeeType->getAs<FunctionProtoType>();
if (FromFunctionType && ToFunctionType) {
// If the function types are exactly the same, this isn't an
// Objective-C pointer conversion.
@@ -1122,7 +1116,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
// Function types are too different. Abort.
return false;
}
-
+
// Check argument types.
for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
ArgIdx != NumArgs; ++ArgIdx) {
@@ -1155,37 +1149,43 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
/// CheckPointerConversion - Check the pointer conversion from the
/// expression From to the type ToType. This routine checks for
-/// ambiguous (FIXME: or inaccessible) derived-to-base pointer
+/// ambiguous or inaccessible derived-to-base pointer
/// conversions for which IsPointerConversion has already returned
/// true. It returns true and produces a diagnostic if there was an
/// error, or returns false otherwise.
-bool Sema::CheckPointerConversion(Expr *From, QualType ToType) {
+bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
+ CastExpr::CastKind &Kind) {
QualType FromType = From->getType();
- if (const PointerType *FromPtrType = FromType->getAsPointerType())
- if (const PointerType *ToPtrType = ToType->getAsPointerType()) {
+ if (const PointerType *FromPtrType = FromType->getAs<PointerType>())
+ if (const PointerType *ToPtrType = ToType->getAs<PointerType>()) {
QualType FromPointeeType = FromPtrType->getPointeeType(),
ToPointeeType = ToPtrType->getPointeeType();
- // Objective-C++ conversions are always okay.
- // FIXME: We should have a different class of conversions for the
- // Objective-C++ implicit conversions.
- if (Context.isObjCIdStructType(FromPointeeType) ||
- Context.isObjCIdStructType(ToPointeeType) ||
- Context.isObjCClassStructType(FromPointeeType) ||
- Context.isObjCClassStructType(ToPointeeType))
- return false;
-
if (FromPointeeType->isRecordType() &&
ToPointeeType->isRecordType()) {
// We must have a derived-to-base conversion. Check an
// ambiguous or inaccessible conversion.
- return CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType,
- From->getExprLoc(),
- From->getSourceRange());
+ if (CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType,
+ From->getExprLoc(),
+ From->getSourceRange()))
+ return true;
+
+ // The conversion was successful.
+ Kind = CastExpr::CK_DerivedToBase;
}
}
+ if (const ObjCObjectPointerType *FromPtrType =
+ FromType->getAs<ObjCObjectPointerType>())
+ if (const ObjCObjectPointerType *ToPtrType =
+ ToType->getAs<ObjCObjectPointerType>()) {
+ // Objective-C++ conversions are always okay.
+ // FIXME: We should have a different class of conversions for the
+ // Objective-C++ implicit conversions.
+ if (FromPtrType->isObjCBuiltinType() || ToPtrType->isObjCBuiltinType())
+ return false;
+ }
return false;
}
@@ -1195,20 +1195,23 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType) {
/// If so, returns true and places the converted type (that might differ from
/// ToType in its cv-qualifiers at some level) into ConvertedType.
bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
- QualType ToType, QualType &ConvertedType)
-{
- const MemberPointerType *ToTypePtr = ToType->getAsMemberPointerType();
+ QualType ToType,
+ bool InOverloadResolution,
+ QualType &ConvertedType) {
+ const MemberPointerType *ToTypePtr = ToType->getAs<MemberPointerType>();
if (!ToTypePtr)
return false;
// A null pointer constant can be converted to a member pointer (C++ 4.11p1)
- if (From->isNullPointerConstant(Context)) {
+ if (From->isNullPointerConstant(Context,
+ InOverloadResolution? Expr::NPC_ValueDependentIsNotNull
+ : Expr::NPC_ValueDependentIsNull)) {
ConvertedType = ToType;
return true;
}
// Otherwise, both types have to be member pointers.
- const MemberPointerType *FromTypePtr = FromType->getAsMemberPointerType();
+ const MemberPointerType *FromTypePtr = FromType->getAs<MemberPointerType>();
if (!FromTypePtr)
return false;
@@ -1233,13 +1236,20 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType,
/// for which IsMemberPointerConversion has already returned true. It returns
/// true and produces a diagnostic if there was an error, or returns false
/// otherwise.
-bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType) {
+bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType,
+ CastExpr::CastKind &Kind) {
QualType FromType = From->getType();
- const MemberPointerType *FromPtrType = FromType->getAsMemberPointerType();
- if (!FromPtrType)
+ const MemberPointerType *FromPtrType = FromType->getAs<MemberPointerType>();
+ if (!FromPtrType) {
+ // This must be a null pointer to member pointer conversion
+ assert(From->isNullPointerConstant(Context,
+ Expr::NPC_ValueDependentIsNull) &&
+ "Expr must be null pointer constant!");
+ Kind = CastExpr::CK_NullToMemberPointer;
return false;
+ }
- const MemberPointerType *ToPtrType = ToType->getAsMemberPointerType();
+ const MemberPointerType *ToPtrType = ToType->getAs<MemberPointerType>();
assert(ToPtrType && "No member pointer cast has a target type "
"that is not a member pointer.");
@@ -1250,8 +1260,8 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType) {
assert(FromClass->isRecordType() && "Pointer into non-class.");
assert(ToClass->isRecordType() && "Pointer into non-class.");
- BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false,
- /*DetectVirtual=*/true);
+ CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false,
+ /*DetectVirtual=*/true);
bool DerivationOkay = IsDerivedFrom(ToClass, FromClass, Paths);
assert(DerivationOkay &&
"Should not have been called if derivation isn't OK.");
@@ -1279,15 +1289,16 @@ bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType) {
return true;
}
+ // Must be a base to derived member conversion.
+ Kind = CastExpr::CK_BaseToDerivedMemberPointer;
return false;
}
/// IsQualificationConversion - Determines whether the conversion from
/// an rvalue of type FromType to ToType is a qualification conversion
/// (C++ 4.4).
-bool
-Sema::IsQualificationConversion(QualType FromType, QualType ToType)
-{
+bool
+Sema::IsQualificationConversion(QualType FromType, QualType ToType) {
FromType = Context.getCanonicalType(FromType);
ToType = Context.getCanonicalType(ToType);
@@ -1314,16 +1325,16 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType)
// 2,j, and similarly for volatile.
if (!ToType.isAtLeastAsQualifiedAs(FromType))
return false;
-
+
// -- if the cv 1,j and cv 2,j are different, then const is in
// every cv for 0 < k < j.
if (FromType.getCVRQualifiers() != ToType.getCVRQualifiers()
&& !PreviousToQualsIncludeConst)
return false;
-
+
// Keep track of whether all prior cv-qualifiers in the "to" type
// include const.
- PreviousToQualsIncludeConst
+ PreviousToQualsIncludeConst
= PreviousToQualsIncludeConst && ToType.isConstQualified();
}
@@ -1336,6 +1347,18 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType)
FromType.getUnqualifiedType() == ToType.getUnqualifiedType();
}
+/// \brief Given a function template or function, extract the function template
+/// declaration (if any) and the underlying function declaration.
+template<typename T>
+static void GetFunctionAndTemplate(AnyFunctionDecl Orig, T *&Function,
+ FunctionTemplateDecl *&FunctionTemplate) {
+ FunctionTemplate = dyn_cast<FunctionTemplateDecl>(Orig);
+ if (FunctionTemplate)
+ Function = cast<T>(FunctionTemplate->getTemplatedDecl());
+ else
+ Function = cast<T>(Orig);
+}
+
/// Determines whether there is a user-defined conversion sequence
/// (C++ [over.ics.user]) that converts expression From to the type
/// ToType. If such a conversion exists, User will contain the
@@ -1353,14 +1376,17 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType)
///
/// \param ForceRValue true if the expression should be treated as an rvalue
/// for overload resolution.
-bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
+/// \param UserCast true if looking for user defined conversion for a static
+/// cast.
+Sema::OverloadingResult Sema::IsUserDefinedConversion(
+ Expr *From, QualType ToType,
UserDefinedConversionSequence& User,
+ OverloadCandidateSet& CandidateSet,
bool AllowConversionFunctions,
- bool AllowExplicit, bool ForceRValue)
-{
- OverloadCandidateSet CandidateSet;
- if (const RecordType *ToRecordType = ToType->getAsRecordType()) {
- if (CXXRecordDecl *ToRecordDecl
+ bool AllowExplicit, bool ForceRValue,
+ bool UserCast) {
+ if (const RecordType *ToRecordType = ToType->getAs<RecordType>()) {
+ if (CXXRecordDecl *ToRecordDecl
= dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
// C++ [over.match.ctor]p1:
// When objects of class type are direct-initialized (8.5), or
@@ -1370,37 +1396,72 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
// functions are all the converting constructors (12.3.1) of
// that class. The argument list is the expression-list within
// the parentheses of the initializer.
- DeclarationName ConstructorName
+ DeclarationName ConstructorName
= Context.DeclarationNames.getCXXConstructorName(
Context.getCanonicalType(ToType).getUnqualifiedType());
DeclContext::lookup_iterator Con, ConEnd;
- for (llvm::tie(Con, ConEnd)
+ for (llvm::tie(Con, ConEnd)
= ToRecordDecl->lookup(ConstructorName);
Con != ConEnd; ++Con) {
- CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(*Con);
- if (Constructor->isConvertingConstructor())
- AddOverloadCandidate(Constructor, &From, 1, CandidateSet,
- /*SuppressUserConversions=*/true, ForceRValue);
+ // Find the constructor (which may be a template).
+ CXXConstructorDecl *Constructor = 0;
+ FunctionTemplateDecl *ConstructorTmpl
+ = dyn_cast<FunctionTemplateDecl>(*Con);
+ if (ConstructorTmpl)
+ Constructor
+ = cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl());
+ else
+ Constructor = cast<CXXConstructorDecl>(*Con);
+
+ if (!Constructor->isInvalidDecl() &&
+ Constructor->isConvertingConstructor(AllowExplicit)) {
+ if (ConstructorTmpl)
+ AddTemplateOverloadCandidate(ConstructorTmpl, false, 0, 0, &From,
+ 1, CandidateSet,
+ /*SuppressUserConversions=*/!UserCast,
+ ForceRValue);
+ else
+ // Allow one user-defined conversion when user specifies a
+ // From->ToType conversion via an static cast (c-style, etc).
+ AddOverloadCandidate(Constructor, &From, 1, CandidateSet,
+ /*SuppressUserConversions=*/!UserCast,
+ ForceRValue);
+ }
}
}
}
if (!AllowConversionFunctions) {
// Don't allow any conversion functions to enter the overload set.
- } else if (const RecordType *FromRecordType
- = From->getType()->getAsRecordType()) {
- if (CXXRecordDecl *FromRecordDecl
- = dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
+ } else if (RequireCompleteType(From->getLocStart(), From->getType(),
+ PDiag(0)
+ << From->getSourceRange())) {
+ // No conversion functions from incomplete types.
+ } else if (const RecordType *FromRecordType
+ = From->getType()->getAs<RecordType>()) {
+ if (CXXRecordDecl *FromRecordDecl
+ = dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
// Add all of the conversion functions as candidates.
- // FIXME: Look for conversions in base classes!
- OverloadedFunctionDecl *Conversions
- = FromRecordDecl->getConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator Func
+ OverloadedFunctionDecl *Conversions
+ = FromRecordDecl->getVisibleConversionFunctions();
+ for (OverloadedFunctionDecl::function_iterator Func
= Conversions->function_begin();
Func != Conversions->function_end(); ++Func) {
- CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func);
- if (AllowExplicit || !Conv->isExplicit())
- AddConversionCandidate(Conv, From, ToType, CandidateSet);
+ CXXConversionDecl *Conv;
+ FunctionTemplateDecl *ConvTemplate;
+ GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
+ if (ConvTemplate)
+ Conv = dyn_cast<CXXConversionDecl>(ConvTemplate->getTemplatedDecl());
+ else
+ Conv = dyn_cast<CXXConversionDecl>(*Func);
+
+ if (AllowExplicit || !Conv->isExplicit()) {
+ if (ConvTemplate)
+ AddTemplateConversionCandidate(ConvTemplate, From, ToType,
+ CandidateSet);
+ else
+ AddConversionCandidate(Conv, From, ToType, CandidateSet);
+ }
}
}
}
@@ -1409,7 +1470,7 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
switch (BestViableFunction(CandidateSet, From->getLocStart(), Best)) {
case OR_Success:
// Record the standard conversion we used and the conversion function.
- if (CXXConstructorDecl *Constructor
+ if (CXXConstructorDecl *Constructor
= dyn_cast<CXXConstructorDecl>(Best->Function)) {
// C++ [over.ics.user]p1:
// If the user-defined conversion is specified by a
@@ -1422,10 +1483,10 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
User.Before = Best->Conversions[0].Standard;
User.ConversionFunction = Constructor;
User.After.setAsIdentityConversion();
- User.After.FromTypePtr
- = ThisType->getAsPointerType()->getPointeeType().getAsOpaquePtr();
+ User.After.FromTypePtr
+ = ThisType->getAs<PointerType>()->getPointeeType().getAsOpaquePtr();
User.After.ToTypePtr = ToType.getAsOpaquePtr();
- return true;
+ return OR_Success;
} else if (CXXConversionDecl *Conversion
= dyn_cast<CXXConversionDecl>(Best->Function)) {
// C++ [over.ics.user]p1:
@@ -1436,8 +1497,8 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
// implicit object parameter of the conversion function.
User.Before = Best->Conversions[0].Standard;
User.ConversionFunction = Conversion;
-
- // C++ [over.ics.user]p2:
+
+ // C++ [over.ics.user]p2:
// The second standard conversion sequence converts the
// result of the user-defined conversion to the target type
// for the sequence. Since an implicit conversion sequence
@@ -1447,30 +1508,45 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
// user-defined conversion sequence (see 13.3.3 and
// 13.3.3.1).
User.After = Best->FinalConversion;
- return true;
+ return OR_Success;
} else {
assert(false && "Not a constructor or conversion function?");
- return false;
+ return OR_No_Viable_Function;
}
-
+
case OR_No_Viable_Function:
+ return OR_No_Viable_Function;
case OR_Deleted:
// No conversion here! We're done.
- return false;
+ return OR_Deleted;
case OR_Ambiguous:
- // FIXME: See C++ [over.best.ics]p10 for the handling of
- // ambiguous conversion sequences.
- return false;
+ return OR_Ambiguous;
}
- return false;
+ return OR_No_Viable_Function;
+}
+
+bool
+Sema::DiagnoseAmbiguousUserDefinedConversion(Expr *From, QualType ToType) {
+ ImplicitConversionSequence ICS;
+ OverloadCandidateSet CandidateSet;
+ OverloadingResult OvResult =
+ IsUserDefinedConversion(From, ToType, ICS.UserDefined,
+ CandidateSet, true, false, false);
+ if (OvResult != OR_Ambiguous)
+ return false;
+ Diag(From->getSourceRange().getBegin(),
+ diag::err_typecheck_ambiguous_condition)
+ << From->getType() << ToType << From->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
+ return true;
}
/// CompareImplicitConversionSequences - Compare two implicit
/// conversion sequences to determine whether one is better than the
/// other or if they are indistinguishable (C++ 13.3.3.2).
-ImplicitConversionSequence::CompareKind
+ImplicitConversionSequence::CompareKind
Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
const ImplicitConversionSequence& ICS2)
{
@@ -1482,7 +1558,7 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
// -- a user-defined conversion sequence (13.3.3.1.2) is a better
// conversion sequence than an ellipsis conversion sequence
// (13.3.3.1.3).
- //
+ //
if (ICS1.ConversionKind < ICS2.ConversionKind)
return ImplicitConversionSequence::Better;
else if (ICS2.ConversionKind < ICS1.ConversionKind)
@@ -1493,7 +1569,7 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
// following rules apply: (C++ 13.3.3.2p3):
if (ICS1.ConversionKind == ImplicitConversionSequence::StandardConversion)
return CompareStandardConversionSequences(ICS1.Standard, ICS2.Standard);
- else if (ICS1.ConversionKind ==
+ else if (ICS1.ConversionKind ==
ImplicitConversionSequence::UserDefinedConversion) {
// User-defined conversion sequence U1 is a better conversion
// sequence than another user-defined conversion sequence U2 if
@@ -1501,7 +1577,7 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
// constructor and if the second standard conversion sequence of
// U1 is better than the second standard conversion sequence of
// U2 (C++ 13.3.3.2p3).
- if (ICS1.UserDefined.ConversionFunction ==
+ if (ICS1.UserDefined.ConversionFunction ==
ICS2.UserDefined.ConversionFunction)
return CompareStandardConversionSequences(ICS1.UserDefined.After,
ICS2.UserDefined.After);
@@ -1513,7 +1589,7 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
/// CompareStandardConversionSequences - Compare two standard
/// conversion sequences to determine whether one is better than the
/// other or if they are indistinguishable (C++ 13.3.3.2p3).
-ImplicitConversionSequence::CompareKind
+ImplicitConversionSequence::CompareKind
Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
const StandardConversionSequence& SCS2)
{
@@ -1530,13 +1606,13 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
;
else if ((SCS1.Second == ICK_Identity && SCS1.Third == SCS2.Third) ||
(SCS1.Third == ICK_Identity && SCS1.Second == SCS2.Second) ||
- (SCS1.Second == ICK_Identity &&
+ (SCS1.Second == ICK_Identity &&
SCS1.Third == ICK_Identity))
// SCS1 is a proper subsequence of SCS2.
return ImplicitConversionSequence::Better;
else if ((SCS2.Second == ICK_Identity && SCS2.Third == SCS1.Third) ||
(SCS2.Third == ICK_Identity && SCS2.Second == SCS1.Second) ||
- (SCS2.Second == ICK_Identity &&
+ (SCS2.Second == ICK_Identity &&
SCS2.Third == ICK_Identity))
// SCS2 is a proper subsequence of SCS1.
return ImplicitConversionSequence::Worse;
@@ -1553,7 +1629,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// (C++ 13.3.3.2p4): Two conversion sequences with the same rank
// are indistinguishable unless one of the following rules
// applies:
-
+
// A conversion that is not a conversion of a pointer, or
// pointer to member, to bool is better than another conversion
// that is such a conversion.
@@ -1568,9 +1644,9 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// conversion of B* to A* is better than conversion of B* to
// void*, and conversion of A* to void* is better than conversion
// of B* to void*.
- bool SCS1ConvertsToVoid
+ bool SCS1ConvertsToVoid
= SCS1.isPointerConversionToVoidPointer(Context);
- bool SCS2ConvertsToVoid
+ bool SCS2ConvertsToVoid
= SCS2.isPointerConversionToVoidPointer(Context);
if (SCS1ConvertsToVoid != SCS2ConvertsToVoid) {
// Exactly one of the conversion sequences is a conversion to
@@ -1597,10 +1673,10 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
if (SCS2.First == ICK_Array_To_Pointer)
FromType2 = Context.getArrayDecayedType(FromType2);
- QualType FromPointee1
- = FromType1->getAsPointerType()->getPointeeType().getUnqualifiedType();
+ QualType FromPointee1
+ = FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
QualType FromPointee2
- = FromType2->getAsPointerType()->getPointeeType().getUnqualifiedType();
+ = FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
if (IsDerivedFrom(FromPointee2, FromPointee1))
return ImplicitConversionSequence::Better;
@@ -1609,8 +1685,8 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// Objective-C++: If one interface is more specific than the
// other, it is the better one.
- const ObjCInterfaceType* FromIface1 = FromPointee1->getAsObjCInterfaceType();
- const ObjCInterfaceType* FromIface2 = FromPointee2->getAsObjCInterfaceType();
+ const ObjCInterfaceType* FromIface1 = FromPointee1->getAs<ObjCInterfaceType>();
+ const ObjCInterfaceType* FromIface2 = FromPointee2->getAs<ObjCInterfaceType>();
if (FromIface1 && FromIface1) {
if (Context.canAssignObjCInterfaces(FromIface2, FromIface1))
return ImplicitConversionSequence::Better;
@@ -1621,7 +1697,7 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
// Compare based on qualification conversions (C++ 13.3.3.2p3,
// bullet 3).
- if (ImplicitConversionSequence::CompareKind QualCK
+ if (ImplicitConversionSequence::CompareKind QualCK
= CompareQualificationConversions(SCS1, SCS2))
return QualCK;
@@ -1661,11 +1737,10 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
/// CompareQualificationConversions - Compares two standard conversion
/// sequences to determine whether they can be ranked based on their
-/// qualification conversions (C++ 13.3.3.2p3 bullet 3).
-ImplicitConversionSequence::CompareKind
+/// qualification conversions (C++ 13.3.3.2p3 bullet 3).
+ImplicitConversionSequence::CompareKind
Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
- const StandardConversionSequence& SCS2)
-{
+ const StandardConversionSequence& SCS2) {
// C++ 13.3.3.2p3:
// -- S1 and S2 differ only in their qualification conversion and
// yield similar types T1 and T2 (C++ 4.4), respectively, and the
@@ -1688,7 +1763,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
if (T1.getUnqualifiedType() == T2.getUnqualifiedType())
return ImplicitConversionSequence::Indistinguishable;
- ImplicitConversionSequence::CompareKind Result
+ ImplicitConversionSequence::CompareKind Result
= ImplicitConversionSequence::Indistinguishable;
while (UnwrapSimilarPointerTypes(T1, T2)) {
// Within each iteration of the loop, we check the qualifiers to
@@ -1709,7 +1784,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
// Neither has qualifiers that are a subset of the other's
// qualifiers.
return ImplicitConversionSequence::Indistinguishable;
-
+
Result = ImplicitConversionSequence::Better;
} else if (T1.isMoreQualifiedThan(T2)) {
// T2 has fewer qualifiers, so it could be the better sequence.
@@ -1717,7 +1792,7 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
// Neither has qualifiers that are a subset of the other's
// qualifiers.
return ImplicitConversionSequence::Indistinguishable;
-
+
Result = ImplicitConversionSequence::Worse;
} else {
// Qualifiers are disjoint.
@@ -1784,24 +1859,24 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
// interfaces.
// Compare based on pointer conversions.
- if (SCS1.Second == ICK_Pointer_Conversion &&
+ if (SCS1.Second == ICK_Pointer_Conversion &&
SCS2.Second == ICK_Pointer_Conversion &&
/*FIXME: Remove if Objective-C id conversions get their own rank*/
FromType1->isPointerType() && FromType2->isPointerType() &&
ToType1->isPointerType() && ToType2->isPointerType()) {
- QualType FromPointee1
- = FromType1->getAsPointerType()->getPointeeType().getUnqualifiedType();
- QualType ToPointee1
- = ToType1->getAsPointerType()->getPointeeType().getUnqualifiedType();
+ QualType FromPointee1
+ = FromType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
+ QualType ToPointee1
+ = ToType1->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
QualType FromPointee2
- = FromType2->getAsPointerType()->getPointeeType().getUnqualifiedType();
+ = FromType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
QualType ToPointee2
- = ToType2->getAsPointerType()->getPointeeType().getUnqualifiedType();
+ = ToType2->getAs<PointerType>()->getPointeeType().getUnqualifiedType();
- const ObjCInterfaceType* FromIface1 = FromPointee1->getAsObjCInterfaceType();
- const ObjCInterfaceType* FromIface2 = FromPointee2->getAsObjCInterfaceType();
- const ObjCInterfaceType* ToIface1 = ToPointee1->getAsObjCInterfaceType();
- const ObjCInterfaceType* ToIface2 = ToPointee2->getAsObjCInterfaceType();
+ const ObjCInterfaceType* FromIface1 = FromPointee1->getAs<ObjCInterfaceType>();
+ const ObjCInterfaceType* FromIface2 = FromPointee2->getAs<ObjCInterfaceType>();
+ const ObjCInterfaceType* ToIface1 = ToPointee1->getAs<ObjCInterfaceType>();
+ const ObjCInterfaceType* ToIface2 = ToPointee2->getAs<ObjCInterfaceType>();
// -- conversion of C* to B* is better than conversion of C* to A*,
if (FromPointee1 == FromPointee2 && ToPointee1 != ToPointee2) {
@@ -1824,7 +1899,7 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
return ImplicitConversionSequence::Better;
else if (IsDerivedFrom(FromPointee1, FromPointee2))
return ImplicitConversionSequence::Worse;
-
+
if (FromIface1 && FromIface2) {
if (Context.canAssignObjCInterfaces(FromIface1, FromIface2))
return ImplicitConversionSequence::Better;
@@ -1898,17 +1973,25 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
/// a parameter of this type). If @p SuppressUserConversions, then we
/// do not permit any user-defined conversion sequences. If @p ForceRValue,
/// then we treat @p From as an rvalue, even if it is an lvalue.
-ImplicitConversionSequence
-Sema::TryCopyInitialization(Expr *From, QualType ToType,
- bool SuppressUserConversions, bool ForceRValue) {
+ImplicitConversionSequence
+Sema::TryCopyInitialization(Expr *From, QualType ToType,
+ bool SuppressUserConversions, bool ForceRValue,
+ bool InOverloadResolution) {
if (ToType->isReferenceType()) {
ImplicitConversionSequence ICS;
- CheckReferenceInit(From, ToType, &ICS, SuppressUserConversions,
- /*AllowExplicit=*/false, ForceRValue);
+ CheckReferenceInit(From, ToType,
+ /*FIXME:*/From->getLocStart(),
+ SuppressUserConversions,
+ /*AllowExplicit=*/false,
+ ForceRValue,
+ &ICS);
return ICS;
} else {
- return TryImplicitConversion(From, ToType, SuppressUserConversions,
- ForceRValue);
+ return TryImplicitConversion(From, ToType,
+ SuppressUserConversions,
+ /*AllowExplicit=*/false,
+ ForceRValue,
+ InOverloadResolution);
}
}
@@ -1917,32 +2000,37 @@ Sema::TryCopyInitialization(Expr *From, QualType ToType,
/// an error, returns false if the initialization succeeded. Elidable should
/// be true when the copy may be elided (C++ 12.8p15). Overload resolution works
/// differently in C++0x for this case.
-bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType,
+bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType,
const char* Flavor, bool Elidable) {
if (!getLangOptions().CPlusPlus) {
// In C, argument passing is the same as performing an assignment.
QualType FromType = From->getType();
-
+
AssignConvertType ConvTy =
CheckSingleAssignmentConstraints(ToType, From);
if (ConvTy != Compatible &&
CheckTransparentUnionArgumentConstraints(ToType, From) == Compatible)
ConvTy = Compatible;
-
+
return DiagnoseAssignmentResult(ConvTy, From->getLocStart(), ToType,
FromType, From, Flavor);
}
if (ToType->isReferenceType())
- return CheckReferenceInit(From, ToType);
+ return CheckReferenceInit(From, ToType,
+ /*FIXME:*/From->getLocStart(),
+ /*SuppressUserConversions=*/false,
+ /*AllowExplicit=*/false,
+ /*ForceRValue=*/false);
if (!PerformImplicitConversion(From, ToType, Flavor,
/*AllowExplicit=*/false, Elidable))
return false;
-
- return Diag(From->getSourceRange().getBegin(),
- diag::err_typecheck_convert_incompatible)
- << ToType << From->getType() << Flavor << From->getSourceRange();
+ if (!DiagnoseAmbiguousUserDefinedConversion(From, ToType))
+ return Diag(From->getSourceRange().getBegin(),
+ diag::err_typecheck_convert_incompatible)
+ << ToType << From->getType() << Flavor << From->getSourceRange();
+ return true;
}
/// TryObjectArgumentInitialization - Try to initialize the object
@@ -1951,8 +2039,8 @@ bool Sema::PerformCopyInitialization(Expr *&From, QualType ToType,
ImplicitConversionSequence
Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
QualType ClassType = Context.getTypeDeclType(Method->getParent());
- unsigned MethodQuals = Method->getTypeQualifiers();
- QualType ImplicitParamType = ClassType.getQualifiedType(MethodQuals);
+ QualType ImplicitParamType
+ = Context.getCVRQualifiedType(ClassType, Method->getTypeQualifiers());
// Set up the conversion sequence as a "bad" conversion, to allow us
// to exit early.
@@ -1962,7 +2050,7 @@ Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
// We need to have an object of class type.
QualType FromType = From->getType();
- if (const PointerType *PT = FromType->getAsPointerType())
+ if (const PointerType *PT = FromType->getAs<PointerType>())
FromType = PT->getPointeeType();
assert(FromType->isRecordType());
@@ -1971,7 +2059,7 @@ Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
// where X is the class of which the function is a member
// (C++ [over.match.funcs]p4). However, when finding an implicit
// conversion sequence for the argument, we are not allowed to
- // create temporaries or perform user-defined conversions
+ // create temporaries or perform user-defined conversions
// (C++ [over.match.funcs]p5). We perform a simplified version of
// reference binding here, that allows class rvalues to bind to
// non-constant references.
@@ -2009,10 +2097,10 @@ Sema::TryObjectArgumentInitialization(Expr *From, CXXMethodDecl *Method) {
bool
Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) {
QualType FromRecordType, DestType;
- QualType ImplicitParamRecordType =
- Method->getThisType(Context)->getAsPointerType()->getPointeeType();
-
- if (const PointerType *PT = From->getType()->getAsPointerType()) {
+ QualType ImplicitParamRecordType =
+ Method->getThisType(Context)->getAs<PointerType>()->getPointeeType();
+
+ if (const PointerType *PT = From->getType()->getAs<PointerType>()) {
FromRecordType = PT->getPointeeType();
DestType = Method->getThisType(Context);
} else {
@@ -2020,13 +2108,13 @@ Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) {
DestType = ImplicitParamRecordType;
}
- ImplicitConversionSequence ICS
+ ImplicitConversionSequence ICS
= TryObjectArgumentInitialization(From, Method);
if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion)
return Diag(From->getSourceRange().getBegin(),
diag::err_implicit_object_parameter_init)
<< ImplicitParamRecordType << FromRecordType << From->getSourceRange();
-
+
if (ICS.Standard.Second == ICK_Derived_To_Base &&
CheckDerivedToBaseConversion(FromRecordType,
ImplicitParamRecordType,
@@ -2034,14 +2122,20 @@ Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) {
From->getSourceRange()))
return true;
- ImpCastExprToType(From, DestType, /*isLvalue=*/true);
+ ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
+ /*isLvalue=*/true);
return false;
}
/// TryContextuallyConvertToBool - Attempt to contextually convert the
/// expression From to bool (C++0x [conv]p3).
ImplicitConversionSequence Sema::TryContextuallyConvertToBool(Expr *From) {
- return TryImplicitConversion(From, Context.BoolTy, false, true);
+ return TryImplicitConversion(From, Context.BoolTy,
+ // FIXME: Are these flags correct?
+ /*SuppressUserConversions=*/false,
+ /*AllowExplicit=*/true,
+ /*ForceRValue=*/false,
+ /*InOverloadResolution=*/false);
}
/// PerformContextuallyConvertToBool - Perform a contextual conversion
@@ -2050,10 +2144,12 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
ImplicitConversionSequence ICS = TryContextuallyConvertToBool(From);
if (!PerformImplicitConversion(From, Context.BoolTy, ICS, "converting"))
return false;
-
- return Diag(From->getSourceRange().getBegin(),
- diag::err_typecheck_bool_condition)
- << From->getType() << From->getSourceRange();
+
+ if (!DiagnoseAmbiguousUserDefinedConversion(From, Context.BoolTy))
+ return Diag(From->getSourceRange().getBegin(),
+ diag::err_typecheck_bool_condition)
+ << From->getType() << From->getSourceRange();
+ return true;
}
/// AddOverloadCandidate - Adds the given function to the set of
@@ -2063,21 +2159,25 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
/// If @p ForceRValue, treat all arguments as rvalues. This is a slightly
/// hacky way to implement the overloading rules for elidable copy
/// initialization in C++0x (C++0x 12.8p15).
-void
-Sema::AddOverloadCandidate(FunctionDecl *Function,
+///
+/// \para PartialOverloading true if we are performing "partial" overloading
+/// based on an incomplete set of function arguments. This feature is used by
+/// code completion.
+void
+Sema::AddOverloadCandidate(FunctionDecl *Function,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions,
- bool ForceRValue)
-{
- const FunctionProtoType* Proto
- = dyn_cast<FunctionProtoType>(Function->getType()->getAsFunctionType());
+ bool ForceRValue,
+ bool PartialOverloading) {
+ const FunctionProtoType* Proto
+ = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>());
assert(Proto && "Functions without a prototype cannot be overloaded");
- assert(!isa<CXXConversionDecl>(Function) &&
+ assert(!isa<CXXConversionDecl>(Function) &&
"Use AddConversionCandidate for conversion functions");
- assert(!Function->getDescribedFunctionTemplate() &&
+ assert(!Function->getDescribedFunctionTemplate() &&
"Use AddTemplateOverloadCandidate for function templates");
-
+
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) {
if (!isa<CXXConstructorDecl>(Method)) {
// If we get here, it's because we're calling a member function
@@ -2086,7 +2186,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// implicitly. This can happen with a qualified call to a member
// function, e.g., X::f(). We use a NULL object as the implied
// object argument (C++ [over.call.func]p3).
- AddMethodCandidate(Method, 0, Args, NumArgs, CandidateSet,
+ AddMethodCandidate(Method, 0, Args, NumArgs, CandidateSet,
SuppressUserConversions, ForceRValue);
return;
}
@@ -2094,7 +2194,9 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// argument doesn't participate in overload resolution.
}
-
+ if (!CandidateSet.isNewCandidate(Function))
+ return;
+
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
@@ -2108,7 +2210,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// (C++ 13.3.2p2): A candidate function having fewer than m
// parameters is viable only if it has an ellipsis in its parameter
// list (8.3.5).
- if (NumArgs > NumArgsInProto && !Proto->isVariadic()) {
+ if ((NumArgs + (PartialOverloading && NumArgs)) > NumArgsInProto &&
+ !Proto->isVariadic()) {
Candidate.Viable = false;
return;
}
@@ -2119,7 +2222,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// parameter list is truncated on the right, so that there are
// exactly m parameters.
unsigned MinRequiredArgs = Function->getMinRequiredArguments();
- if (NumArgs < MinRequiredArgs) {
+ if (NumArgs < MinRequiredArgs && !PartialOverloading) {
// Not enough arguments.
Candidate.Viable = false;
return;
@@ -2135,19 +2238,38 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
// (13.3.3.1) that converts that argument to the corresponding
// parameter of F.
QualType ParamType = Proto->getArgType(ArgIdx);
- Candidate.Conversions[ArgIdx]
- = TryCopyInitialization(Args[ArgIdx], ParamType,
- SuppressUserConversions, ForceRValue);
- if (Candidate.Conversions[ArgIdx].ConversionKind
+ Candidate.Conversions[ArgIdx]
+ = TryCopyInitialization(Args[ArgIdx], ParamType,
+ SuppressUserConversions, ForceRValue,
+ /*InOverloadResolution=*/true);
+ if (Candidate.Conversions[ArgIdx].ConversionKind
== ImplicitConversionSequence::BadConversion) {
- Candidate.Viable = false;
- break;
+ // 13.3.3.1-p10 If several different sequences of conversions exist that
+ // each convert the argument to the parameter type, the implicit conversion
+ // sequence associated with the parameter is defined to be the unique conversion
+ // sequence designated the ambiguous conversion sequence. For the purpose of
+ // ranking implicit conversion sequences as described in 13.3.3.2, the ambiguous
+ // conversion sequence is treated as a user-defined sequence that is
+ // indistinguishable from any other user-defined conversion sequence
+ if (!Candidate.Conversions[ArgIdx].ConversionFunctionSet.empty()) {
+ Candidate.Conversions[ArgIdx].ConversionKind =
+ ImplicitConversionSequence::UserDefinedConversion;
+ // Set the conversion function to one of them. As due to ambiguity,
+ // they carry the same weight and is needed for overload resolution
+ // later.
+ Candidate.Conversions[ArgIdx].UserDefined.ConversionFunction =
+ Candidate.Conversions[ArgIdx].ConversionFunctionSet[0];
+ }
+ else {
+ Candidate.Viable = false;
+ break;
+ }
}
} else {
// (C++ 13.3.2p2): For the purposes of overload resolution, any
// argument for which there is no corresponding parameter is
// considered to ""match the ellipsis" (C+ 13.3.3.1.3).
- Candidate.Conversions[ArgIdx].ConversionKind
+ Candidate.Conversions[ArgIdx].ConversionKind
= ImplicitConversionSequence::EllipsisConversion;
}
}
@@ -2159,17 +2281,32 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions) {
- for (FunctionSet::const_iterator F = Functions.begin(),
+ for (FunctionSet::const_iterator F = Functions.begin(),
FEnd = Functions.end();
F != FEnd; ++F) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F))
- AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
- SuppressUserConversions);
- else
- AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*F),
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*F)) {
+ if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
+ AddMethodCandidate(cast<CXXMethodDecl>(FD),
+ Args[0], Args + 1, NumArgs - 1,
+ CandidateSet, SuppressUserConversions);
+ else
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ } else {
+ FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*F);
+ if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
+ !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
+ AddMethodTemplateCandidate(FunTmpl,
/*FIXME: explicit args */false, 0, 0,
- Args, NumArgs, CandidateSet,
+ Args[0], Args + 1, NumArgs - 1,
+ CandidateSet,
SuppressUserConversions);
+ else
+ AddTemplateOverloadCandidate(FunTmpl,
+ /*FIXME: explicit args */false, 0, 0,
+ Args, NumArgs, CandidateSet,
+ SuppressUserConversions);
+ }
}
}
@@ -2182,20 +2319,22 @@ void Sema::AddFunctionCandidates(const FunctionSet &Functions,
/// operators. If @p ForceRValue, treat all arguments as rvalues. This is
/// a slightly hacky way to implement the overloading rules for elidable copy
/// initialization in C++0x (C++0x 12.8p15).
-void
+void
Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
- bool SuppressUserConversions, bool ForceRValue)
-{
- const FunctionProtoType* Proto
- = dyn_cast<FunctionProtoType>(Method->getType()->getAsFunctionType());
+ bool SuppressUserConversions, bool ForceRValue) {
+ const FunctionProtoType* Proto
+ = dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>());
assert(Proto && "Methods without a prototype cannot be overloaded");
assert(!isa<CXXConversionDecl>(Method) &&
"Use AddConversionCandidate for conversion functions");
assert(!isa<CXXConstructorDecl>(Method) &&
"Use AddOverloadCandidate for constructors");
+ if (!CandidateSet.isNewCandidate(Method))
+ return;
+
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
@@ -2235,7 +2374,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
// Determine the implicit conversion sequence for the object
// parameter.
Candidate.Conversions[0] = TryObjectArgumentInitialization(Object, Method);
- if (Candidate.Conversions[0].ConversionKind
+ if (Candidate.Conversions[0].ConversionKind
== ImplicitConversionSequence::BadConversion) {
Candidate.Viable = false;
return;
@@ -2251,10 +2390,11 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
// (13.3.3.1) that converts that argument to the corresponding
// parameter of F.
QualType ParamType = Proto->getArgType(ArgIdx);
- Candidate.Conversions[ArgIdx + 1]
- = TryCopyInitialization(Args[ArgIdx], ParamType,
- SuppressUserConversions, ForceRValue);
- if (Candidate.Conversions[ArgIdx + 1].ConversionKind
+ Candidate.Conversions[ArgIdx + 1]
+ = TryCopyInitialization(Args[ArgIdx], ParamType,
+ SuppressUserConversions, ForceRValue,
+ /*InOverloadResolution=*/true);
+ if (Candidate.Conversions[ArgIdx + 1].ConversionKind
== ImplicitConversionSequence::BadConversion) {
Candidate.Viable = false;
break;
@@ -2263,16 +2403,61 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
// (C++ 13.3.2p2): For the purposes of overload resolution, any
// argument for which there is no corresponding parameter is
// considered to ""match the ellipsis" (C+ 13.3.3.1.3).
- Candidate.Conversions[ArgIdx + 1].ConversionKind
+ Candidate.Conversions[ArgIdx + 1].ConversionKind
= ImplicitConversionSequence::EllipsisConversion;
}
}
}
-/// \brief Add a C++ function template as a candidate in the candidate set,
-/// using template argument deduction to produce an appropriate function
-/// template specialization.
-void
+/// \brief Add a C++ member function template as a candidate to the candidate
+/// set, using template argument deduction to produce an appropriate member
+/// function template specialization.
+void
+Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ Expr *Object, Expr **Args, unsigned NumArgs,
+ OverloadCandidateSet& CandidateSet,
+ bool SuppressUserConversions,
+ bool ForceRValue) {
+ if (!CandidateSet.isNewCandidate(MethodTmpl))
+ return;
+
+ // C++ [over.match.funcs]p7:
+ // In each case where a candidate is a function template, candidate
+ // function template specializations are generated using template argument
+ // deduction (14.8.3, 14.8.2). Those candidates are then handled as
+ // candidate functions in the usual way.113) A given name can refer to one
+ // or more function templates and also to a set of overloaded non-template
+ // functions. In such a case, the candidate functions generated from each
+ // function template are combined with the set of non-template candidate
+ // functions.
+ TemplateDeductionInfo Info(Context);
+ FunctionDecl *Specialization = 0;
+ if (TemplateDeductionResult Result
+ = DeduceTemplateArguments(MethodTmpl, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs, NumExplicitTemplateArgs,
+ Args, NumArgs, Specialization, Info)) {
+ // FIXME: Record what happened with template argument deduction, so
+ // that we can give the user a beautiful diagnostic.
+ (void)Result;
+ return;
+ }
+
+ // Add the function template specialization produced by template argument
+ // deduction as a candidate.
+ assert(Specialization && "Missing member function template specialization?");
+ assert(isa<CXXMethodDecl>(Specialization) &&
+ "Specialization is not a member function?");
+ AddMethodCandidate(cast<CXXMethodDecl>(Specialization), Object, Args, NumArgs,
+ CandidateSet, SuppressUserConversions, ForceRValue);
+}
+
+/// \brief Add a C++ function template specialization as a candidate
+/// in the candidate set, using template argument deduction to produce
+/// an appropriate function template specialization.
+void
Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
bool HasExplicitTemplateArgs,
const TemplateArgument *ExplicitTemplateArgs,
@@ -2281,10 +2466,13 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
OverloadCandidateSet& CandidateSet,
bool SuppressUserConversions,
bool ForceRValue) {
+ if (!CandidateSet.isNewCandidate(FunctionTemplate))
+ return;
+
// C++ [over.match.funcs]p7:
- // In each case where a candidate is a function template, candidate
+ // In each case where a candidate is a function template, candidate
// function template specializations are generated using template argument
- // deduction (14.8.3, 14.8.2). Those candidates are then handled as
+ // deduction (14.8.3, 14.8.2). Those candidates are then handled as
// candidate functions in the usual way.113) A given name can refer to one
// or more function templates and also to a set of overloaded non-template
// functions. In such a case, the candidate functions generated from each
@@ -2301,24 +2489,30 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate,
(void)Result;
return;
}
-
+
// Add the function template specialization produced by template argument
// deduction as a candidate.
assert(Specialization && "Missing function template specialization?");
AddOverloadCandidate(Specialization, Args, NumArgs, CandidateSet,
SuppressUserConversions, ForceRValue);
}
-
+
/// AddConversionCandidate - Add a C++ conversion function as a
-/// candidate in the candidate set (C++ [over.match.conv],
+/// candidate in the candidate set (C++ [over.match.conv],
/// C++ [over.match.copy]). From is the expression we're converting from,
-/// and ToType is the type that we're eventually trying to convert to
+/// and ToType is the type that we're eventually trying to convert to
/// (which may or may not be the same type as the type that the
/// conversion function produces).
void
Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
Expr *From, QualType ToType,
OverloadCandidateSet& CandidateSet) {
+ assert(!Conversion->getDescribedFunctionTemplate() &&
+ "Conversion function templates use AddTemplateConversionCandidate");
+
+ if (!CandidateSet.isNewCandidate(Conversion))
+ return;
+
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
@@ -2326,7 +2520,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
Candidate.IsSurrogate = false;
Candidate.IgnoreObjectArgument = false;
Candidate.FinalConversion.setAsIdentityConversion();
- Candidate.FinalConversion.FromTypePtr
+ Candidate.FinalConversion.FromTypePtr
= Conversion->getConversionType().getAsOpaquePtr();
Candidate.FinalConversion.ToTypePtr = ToType.getAsOpaquePtr();
@@ -2335,8 +2529,12 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
Candidate.Viable = true;
Candidate.Conversions.resize(1);
Candidate.Conversions[0] = TryObjectArgumentInitialization(From, Conversion);
-
- if (Candidate.Conversions[0].ConversionKind
+ // Conversion functions to a different type in the base class is visible in
+ // the derived class. So, a derived to base conversion should not participate
+ // in overload resolution.
+ if (Candidate.Conversions[0].Standard.Second == ICK_Derived_To_Base)
+ Candidate.Conversions[0].Standard.Second = ICK_Identity;
+ if (Candidate.Conversions[0].ConversionKind
== ImplicitConversionSequence::BadConversion) {
Candidate.Viable = false;
return;
@@ -2350,18 +2548,24 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
// lvalues/rvalues and the type. Fortunately, we can allocate this
// call on the stack and we don't need its arguments to be
// well-formed.
- DeclRefExpr ConversionRef(Conversion, Conversion->getType(),
+ DeclRefExpr ConversionRef(Conversion, Conversion->getType(),
SourceLocation());
ImplicitCastExpr ConversionFn(Context.getPointerType(Conversion->getType()),
+ CastExpr::CK_Unknown,
&ConversionRef, false);
-
- // Note that it is safe to allocate CallExpr on the stack here because
+
+ // Note that it is safe to allocate CallExpr on the stack here because
// there are 0 arguments (i.e., nothing is allocated using ASTContext's
// allocator).
- CallExpr Call(Context, &ConversionFn, 0, 0,
+ CallExpr Call(Context, &ConversionFn, 0, 0,
Conversion->getConversionType().getNonReferenceType(),
SourceLocation());
- ImplicitConversionSequence ICS = TryCopyInitialization(&Call, ToType, true);
+ ImplicitConversionSequence ICS =
+ TryCopyInitialization(&Call, ToType,
+ /*SuppressUserConversions=*/true,
+ /*ForceRValue=*/false,
+ /*InOverloadResolution=*/false);
+
switch (ICS.ConversionKind) {
case ImplicitConversionSequence::StandardConversion:
Candidate.FinalConversion = ICS.Standard;
@@ -2372,11 +2576,43 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
break;
default:
- assert(false &&
+ assert(false &&
"Can only end up with a standard conversion sequence or failure");
}
}
+/// \brief Adds a conversion function template specialization
+/// candidate to the overload set, using template argument deduction
+/// to deduce the template arguments of the conversion function
+/// template from the type that we are converting to (C++
+/// [temp.deduct.conv]).
+void
+Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate,
+ Expr *From, QualType ToType,
+ OverloadCandidateSet &CandidateSet) {
+ assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) &&
+ "Only conversion function templates permitted here");
+
+ if (!CandidateSet.isNewCandidate(FunctionTemplate))
+ return;
+
+ TemplateDeductionInfo Info(Context);
+ CXXConversionDecl *Specialization = 0;
+ if (TemplateDeductionResult Result
+ = DeduceTemplateArguments(FunctionTemplate, ToType,
+ Specialization, Info)) {
+ // FIXME: Record what happened with template argument deduction, so
+ // that we can give the user a beautiful diagnostic.
+ (void)Result;
+ return;
+ }
+
+ // Add the conversion function template specialization produced by
+ // template argument deduction as a candidate.
+ assert(Specialization && "Missing function template specialization?");
+ AddConversionCandidate(Specialization, From, ToType, CandidateSet);
+}
+
/// AddSurrogateCandidate - Adds a "surrogate" candidate function that
/// converts the given @c Object to a function pointer via the
/// conversion function @c Conversion, and then attempts to call it
@@ -2386,6 +2622,9 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
const FunctionProtoType *Proto,
Expr *Object, Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet) {
+ if (!CandidateSet.isNewCandidate(Conversion))
+ return;
+
CandidateSet.push_back(OverloadCandidate());
OverloadCandidate& Candidate = CandidateSet.back();
Candidate.Function = 0;
@@ -2397,7 +2636,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
// Determine the implicit conversion sequence for the implicit
// object parameter.
- ImplicitConversionSequence ObjectInit
+ ImplicitConversionSequence ObjectInit
= TryObjectArgumentInitialization(Object, Conversion);
if (ObjectInit.ConversionKind == ImplicitConversionSequence::BadConversion) {
Candidate.Viable = false;
@@ -2407,15 +2646,15 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
// The first conversion is actually a user-defined conversion whose
// first conversion is ObjectInit's standard conversion (which is
// effectively a reference binding). Record it as such.
- Candidate.Conversions[0].ConversionKind
+ Candidate.Conversions[0].ConversionKind
= ImplicitConversionSequence::UserDefinedConversion;
Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
- Candidate.Conversions[0].UserDefined.After
+ Candidate.Conversions[0].UserDefined.After
= Candidate.Conversions[0].UserDefined.Before;
Candidate.Conversions[0].UserDefined.After.setAsIdentityConversion();
- // Find the
+ // Find the
unsigned NumArgsInProto = Proto->getNumArgs();
// (C++ 13.3.2p2): A candidate function having fewer than m
@@ -2443,10 +2682,12 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
// (13.3.3.1) that converts that argument to the corresponding
// parameter of F.
QualType ParamType = Proto->getArgType(ArgIdx);
- Candidate.Conversions[ArgIdx + 1]
- = TryCopyInitialization(Args[ArgIdx], ParamType,
- /*SuppressUserConversions=*/false);
- if (Candidate.Conversions[ArgIdx + 1].ConversionKind
+ Candidate.Conversions[ArgIdx + 1]
+ = TryCopyInitialization(Args[ArgIdx], ParamType,
+ /*SuppressUserConversions=*/false,
+ /*ForceRValue=*/false,
+ /*InOverloadResolution=*/false);
+ if (Candidate.Conversions[ArgIdx + 1].ConversionKind
== ImplicitConversionSequence::BadConversion) {
Candidate.Viable = false;
break;
@@ -2455,7 +2696,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
// (C++ 13.3.2p2): For the purposes of overload resolution, any
// argument for which there is no corresponding parameter is
// considered to ""match the ellipsis" (C+ 13.3.3.1.3).
- Candidate.Conversions[ArgIdx + 1].ConversionKind
+ Candidate.Conversions[ArgIdx + 1].ConversionKind
= ImplicitConversionSequence::EllipsisConversion;
}
}
@@ -2469,7 +2710,6 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
SourceRange OpRange) {
-
FunctionSet Functions;
QualType T1 = Args[0]->getType();
@@ -2518,14 +2758,32 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
// result of the qualified lookup of T1::operator@
// (13.3.1.1.1); otherwise, the set of member candidates is
// empty.
- // FIXME: Lookup in base classes, too!
- if (const RecordType *T1Rec = T1->getAsRecordType()) {
- DeclContext::lookup_const_iterator Oper, OperEnd;
- for (llvm::tie(Oper, OperEnd) = T1Rec->getDecl()->lookup(OpName);
- Oper != OperEnd; ++Oper)
- AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Args[0],
- Args+1, NumArgs - 1, CandidateSet,
- /*SuppressUserConversions=*/false);
+ if (const RecordType *T1Rec = T1->getAs<RecordType>()) {
+ // Complete the type if it can be completed. Otherwise, we're done.
+ if (RequireCompleteType(OpLoc, T1, PDiag()))
+ return;
+
+ LookupResult Operators;
+ LookupQualifiedName(Operators, T1Rec->getDecl(), OpName,
+ LookupOrdinaryName, false);
+ for (LookupResult::iterator Oper = Operators.begin(),
+ OperEnd = Operators.end();
+ Oper != OperEnd;
+ ++Oper) {
+ if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Oper)) {
+ AddMethodCandidate(Method, Args[0], Args+1, NumArgs - 1, CandidateSet,
+ /*SuppressUserConversions=*/false);
+ continue;
+ }
+
+ assert(isa<FunctionTemplateDecl>(*Oper) &&
+ isa<CXXMethodDecl>(cast<FunctionTemplateDecl>(*Oper)
+ ->getTemplatedDecl()) &&
+ "Expected a member function template");
+ AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Oper), false, 0, 0,
+ Args[0], Args+1, NumArgs - 1, CandidateSet,
+ /*SuppressUserConversions=*/false);
+ }
}
}
@@ -2537,7 +2795,7 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
/// operator. NumContextualBoolArguments is the number of arguments
/// (at the beginning of the argument list) that will be contextually
/// converted to bool.
-void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
+void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet,
bool IsAssignmentOperator,
@@ -2563,22 +2821,24 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
// -- no temporaries are introduced to hold the left operand, and
// -- no user-defined conversions are applied to the left
// operand to achieve a type match with the left-most
- // parameter of a built-in candidate.
+ // parameter of a built-in candidate.
//
// We block these conversions by turning off user-defined
// conversions, since that is the only way that initialization of
// a reference to a non-class type can occur from something that
// is not of the same type.
if (ArgIdx < NumContextualBoolArguments) {
- assert(ParamTys[ArgIdx] == Context.BoolTy &&
+ assert(ParamTys[ArgIdx] == Context.BoolTy &&
"Contextual conversion to bool requires bool type");
Candidate.Conversions[ArgIdx] = TryContextuallyConvertToBool(Args[ArgIdx]);
} else {
- Candidate.Conversions[ArgIdx]
- = TryCopyInitialization(Args[ArgIdx], ParamTys[ArgIdx],
- ArgIdx == 0 && IsAssignmentOperator);
+ Candidate.Conversions[ArgIdx]
+ = TryCopyInitialization(Args[ArgIdx], ParamTys[ArgIdx],
+ ArgIdx == 0 && IsAssignmentOperator,
+ /*ForceRValue=*/false,
+ /*InOverloadResolution=*/false);
}
- if (Candidate.Conversions[ArgIdx].ConversionKind
+ if (Candidate.Conversions[ArgIdx].ConversionKind
== ImplicitConversionSequence::BadConversion) {
Candidate.Viable = false;
break;
@@ -2606,6 +2866,10 @@ class BuiltinCandidateTypeSet {
/// used in the built-in candidates.
TypeSet EnumerationTypes;
+ /// Sema - The semantic analysis instance where we are building the
+ /// candidate type set.
+ Sema &SemaRef;
+
/// Context - The AST context in which we will build the type sets.
ASTContext &Context;
@@ -2616,7 +2880,8 @@ public:
/// iterator - Iterates through the types that are part of the set.
typedef TypeSet::iterator iterator;
- BuiltinCandidateTypeSet(ASTContext &Context) : Context(Context) { }
+ BuiltinCandidateTypeSet(Sema &SemaRef)
+ : SemaRef(SemaRef), Context(SemaRef.Context) { }
void AddTypesConvertedFrom(QualType Ty, bool AllowUserConversions,
bool AllowExplicitConversions);
@@ -2647,27 +2912,27 @@ public:
/// restrict *", and "int const volatile restrict *" to the set of
/// pointer types. Returns true if the add of @p Ty itself succeeded,
/// false otherwise.
+///
+/// FIXME: what to do about extended qualifiers?
bool
BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty) {
+
// Insert this type.
if (!PointerTypes.insert(Ty))
return false;
- if (const PointerType *PointerTy = Ty->getAsPointerType()) {
- QualType PointeeTy = PointerTy->getPointeeType();
- // FIXME: Optimize this so that we don't keep trying to add the same types.
-
- // FIXME: Do we have to add CVR qualifiers at *all* levels to deal with all
- // pointer conversions that don't cast away constness?
- if (!PointeeTy.isConstQualified())
- AddPointerWithMoreQualifiedTypeVariants
- (Context.getPointerType(PointeeTy.withConst()));
- if (!PointeeTy.isVolatileQualified())
- AddPointerWithMoreQualifiedTypeVariants
- (Context.getPointerType(PointeeTy.withVolatile()));
- if (!PointeeTy.isRestrictQualified())
- AddPointerWithMoreQualifiedTypeVariants
- (Context.getPointerType(PointeeTy.withRestrict()));
+ const PointerType *PointerTy = Ty->getAs<PointerType>();
+ assert(PointerTy && "type was not a pointer type!");
+
+ QualType PointeeTy = PointerTy->getPointeeType();
+ unsigned BaseCVR = PointeeTy.getCVRQualifiers();
+
+ // Iterate through all strict supersets of BaseCVR.
+ for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) {
+ if ((CVR | BaseCVR) != CVR) continue;
+
+ QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
+ PointerTypes.insert(Context.getPointerType(QPointeeTy));
}
return true;
@@ -2680,6 +2945,8 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty) {
/// restrict *", and "int const volatile restrict *" to the set of
/// pointer types. Returns true if the add of @p Ty itself succeeded,
/// false otherwise.
+///
+/// FIXME: what to do about extended qualifiers?
bool
BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
QualType Ty) {
@@ -2687,20 +2954,20 @@ BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
if (!MemberPointerTypes.insert(Ty))
return false;
- if (const MemberPointerType *PointerTy = Ty->getAsMemberPointerType()) {
- QualType PointeeTy = PointerTy->getPointeeType();
- const Type *ClassTy = PointerTy->getClass();
- // FIXME: Optimize this so that we don't keep trying to add the same types.
-
- if (!PointeeTy.isConstQualified())
- AddMemberPointerWithMoreQualifiedTypeVariants
- (Context.getMemberPointerType(PointeeTy.withConst(), ClassTy));
- if (!PointeeTy.isVolatileQualified())
- AddMemberPointerWithMoreQualifiedTypeVariants
- (Context.getMemberPointerType(PointeeTy.withVolatile(), ClassTy));
- if (!PointeeTy.isRestrictQualified())
- AddMemberPointerWithMoreQualifiedTypeVariants
- (Context.getMemberPointerType(PointeeTy.withRestrict(), ClassTy));
+ const MemberPointerType *PointerTy = Ty->getAs<MemberPointerType>();
+ assert(PointerTy && "type was not a member pointer type!");
+
+ QualType PointeeTy = PointerTy->getPointeeType();
+ const Type *ClassTy = PointerTy->getClass();
+
+ // Iterate through all strict supersets of the pointee type's CVR
+ // qualifiers.
+ unsigned BaseCVR = PointeeTy.getCVRQualifiers();
+ for (unsigned CVR = BaseCVR+1; CVR <= Qualifiers::CVRMask; ++CVR) {
+ if ((CVR | BaseCVR) != CVR) continue;
+
+ QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
+ MemberPointerTypes.insert(Context.getMemberPointerType(QPointeeTy, ClassTy));
}
return true;
@@ -2714,7 +2981,7 @@ BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
/// functions of a class type, and AllowExplicitConversions if we
/// should also include the explicit conversion functions of a class
/// type.
-void
+void
BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
bool AllowUserConversions,
bool AllowExplicitConversions) {
@@ -2723,13 +2990,13 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
// Look through reference types; they aren't part of the type of an
// expression for the purposes of conversions.
- if (const ReferenceType *RefTy = Ty->getAsReferenceType())
+ if (const ReferenceType *RefTy = Ty->getAs<ReferenceType>())
Ty = RefTy->getPointeeType();
// We don't care about qualifiers on the type.
Ty = Ty.getUnqualifiedType();
- if (const PointerType *PointerTy = Ty->getAsPointerType()) {
+ if (const PointerType *PointerTy = Ty->getAs<PointerType>()) {
QualType PointeeTy = PointerTy->getPointeeType();
// Insert our type, and its more-qualified variants, into the set
@@ -2739,20 +3006,22 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
// Add 'cv void*' to our set of types.
if (!Ty->isVoidType()) {
- QualType QualVoid
- = Context.VoidTy.getQualifiedType(PointeeTy.getCVRQualifiers());
+ QualType QualVoid
+ = Context.getCVRQualifiedType(Context.VoidTy,
+ PointeeTy.getCVRQualifiers());
AddPointerWithMoreQualifiedTypeVariants(Context.getPointerType(QualVoid));
}
// If this is a pointer to a class type, add pointers to its bases
// (with the same level of cv-qualification as the original
// derived class, of course).
- if (const RecordType *PointeeRec = PointeeTy->getAsRecordType()) {
+ if (const RecordType *PointeeRec = PointeeTy->getAs<RecordType>()) {
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(PointeeRec->getDecl());
for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin();
Base != ClassDecl->bases_end(); ++Base) {
QualType BaseTy = Context.getCanonicalType(Base->getType());
- BaseTy = BaseTy.getQualifiedType(PointeeTy.getCVRQualifiers());
+ BaseTy = Context.getCVRQualifiedType(BaseTy.getUnqualifiedType(),
+ PointeeTy.getCVRQualifiers());
// Add the pointer type, recursively, so that we get all of
// the indirect base classes, too.
@@ -2766,15 +3035,27 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
} else if (Ty->isEnumeralType()) {
EnumerationTypes.insert(Ty);
} else if (AllowUserConversions) {
- if (const RecordType *TyRec = Ty->getAsRecordType()) {
+ if (const RecordType *TyRec = Ty->getAs<RecordType>()) {
+ if (SemaRef.RequireCompleteType(SourceLocation(), Ty, 0)) {
+ // No conversion functions in incomplete types.
+ return;
+ }
+
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
- // FIXME: Visit conversion functions in the base classes, too.
- OverloadedFunctionDecl *Conversions
- = ClassDecl->getConversionFunctions();
- for (OverloadedFunctionDecl::function_iterator Func
+ OverloadedFunctionDecl *Conversions
+ = ClassDecl->getVisibleConversionFunctions();
+ for (OverloadedFunctionDecl::function_iterator Func
= Conversions->function_begin();
Func != Conversions->function_end(); ++Func) {
- CXXConversionDecl *Conv = cast<CXXConversionDecl>(*Func);
+ CXXConversionDecl *Conv;
+ FunctionTemplateDecl *ConvTemplate;
+ GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
+
+ // Skip conversion function templates; they don't tell us anything
+ // about which builtin types we can convert to.
+ if (ConvTemplate)
+ continue;
+
if (AllowExplicitConversions || !Conv->isExplicit())
AddTypesConvertedFrom(Conv->getConversionType(), false, false);
}
@@ -2782,13 +3063,39 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
}
}
+/// \brief Helper function for AddBuiltinOperatorCandidates() that adds
+/// the volatile- and non-volatile-qualified assignment operators for the
+/// given type to the candidate set.
+static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
+ QualType T,
+ Expr **Args,
+ unsigned NumArgs,
+ 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,
+ /*IsAssignmentOperator=*/true);
+
+ if (!S.Context.getCanonicalType(T).isVolatileQualified()) {
+ // volatile T& operator=(volatile T&, T)
+ ParamTypes[0]
+ = S.Context.getLValueReferenceType(S.Context.getVolatileType(T));
+ ParamTypes[1] = T;
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ /*IsAssignmentOperator=*/true);
+ }
+}
+
/// AddBuiltinOperatorCandidates - Add the appropriate built-in
/// operator overloads to the candidate set (C++ [over.built]), based
/// on the operator @p Op and the arguments given. For example, if the
/// operator is a binary '+', this routine might add "int
/// operator+(int, int)" to cover integer addition.
void
-Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
+Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
Expr **Args, unsigned NumArgs,
OverloadCandidateSet& CandidateSet) {
// The set of "promoted arithmetic types", which are the arithmetic
@@ -2798,13 +3105,14 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// FIXME: What about complex?
const unsigned FirstIntegralType = 0;
const unsigned LastIntegralType = 13;
- const unsigned FirstPromotedIntegralType = 7,
+ const unsigned FirstPromotedIntegralType = 7,
LastPromotedIntegralType = 13;
const unsigned FirstPromotedArithmeticType = 7,
LastPromotedArithmeticType = 16;
const unsigned NumArithmeticTypes = 16;
QualType ArithmeticTypes[NumArithmeticTypes] = {
Context.BoolTy, Context.CharTy, Context.WCharTy,
+// FIXME: Context.Char16Ty, Context.Char32Ty,
Context.SignedCharTy, Context.ShortTy,
Context.UnsignedCharTy, Context.UnsignedShortTy,
Context.IntTy, Context.LongTy, Context.LongLongTy,
@@ -2815,7 +3123,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// 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
// that make use of these types.
- BuiltinCandidateTypeSet CandidateTypes(Context);
+ BuiltinCandidateTypeSet CandidateTypes(*this);
if (Op == OO_Less || Op == OO_Greater || Op == OO_LessEqual ||
Op == OO_GreaterEqual || Op == OO_EqualEqual || Op == OO_ExclaimEqual ||
Op == OO_Plus || (Op == OO_Minus && NumArgs == 2) || Op == OO_Equal ||
@@ -2838,7 +3146,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
break;
case OO_Star: // '*' is either unary or binary
- if (NumArgs == 1)
+ if (NumArgs == 1)
goto UnaryStar;
else
goto BinaryStar;
@@ -2883,10 +3191,10 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
//
// VQ T& operator--(VQ T&);
// T operator--(VQ T&, int);
- for (unsigned Arith = (Op == OO_PlusPlus? 0 : 1);
+ for (unsigned Arith = (Op == OO_PlusPlus? 0 : 1);
Arith < NumArithmeticTypes; ++Arith) {
QualType ArithTy = ArithmeticTypes[Arith];
- QualType ParamTypes[2]
+ QualType ParamTypes[2]
= { Context.getLValueReferenceType(ArithTy), Context.IntTy };
// Non-volatile version.
@@ -2896,7 +3204,8 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
AddBuiltinCandidate(ArithTy, ParamTypes, Args, 2, CandidateSet);
// Volatile version
- ParamTypes[0] = Context.getLValueReferenceType(ArithTy.withVolatile());
+ ParamTypes[0]
+ = Context.getLValueReferenceType(Context.getVolatileType(ArithTy));
if (NumArgs == 1)
AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
else
@@ -2916,13 +3225,13 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
Ptr != CandidateTypes.pointer_end(); ++Ptr) {
// Skip pointer types that aren't pointers to object types.
- if (!(*Ptr)->getAsPointerType()->getPointeeType()->isObjectType())
+ if (!(*Ptr)->getAs<PointerType>()->getPointeeType()->isObjectType())
continue;
- QualType ParamTypes[2] = {
- Context.getLValueReferenceType(*Ptr), Context.IntTy
+ QualType ParamTypes[2] = {
+ Context.getLValueReferenceType(*Ptr), Context.IntTy
};
-
+
// Without volatile
if (NumArgs == 1)
AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
@@ -2931,7 +3240,8 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
if (!Context.getCanonicalType(*Ptr).isVolatileQualified()) {
// With volatile
- ParamTypes[0] = Context.getLValueReferenceType((*Ptr).withVolatile());
+ ParamTypes[0]
+ = Context.getLValueReferenceType(Context.getVolatileType(*Ptr));
if (NumArgs == 1)
AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 1, CandidateSet);
else
@@ -2954,8 +3264,8 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
Ptr != CandidateTypes.pointer_end(); ++Ptr) {
QualType ParamTy = *Ptr;
- QualType PointeeTy = ParamTy->getAsPointerType()->getPointeeType();
- AddBuiltinCandidate(Context.getLValueReferenceType(PointeeTy),
+ QualType PointeeTy = ParamTy->getAs<PointerType>()->getPointeeType();
+ AddBuiltinCandidate(Context.getLValueReferenceType(PointeeTy),
&ParamTy, Args, 1, CandidateSet);
}
break;
@@ -2971,7 +3281,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
QualType ParamTy = *Ptr;
AddBuiltinCandidate(ParamTy, &ParamTy, Args, 1, CandidateSet);
}
-
+
// Fall through
UnaryMinus:
@@ -2981,7 +3291,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
//
// T operator+(T);
// T operator-(T);
- for (unsigned Arith = FirstPromotedArithmeticType;
+ for (unsigned Arith = FirstPromotedArithmeticType;
Arith < LastPromotedArithmeticType; ++Arith) {
QualType ArithTy = ArithmeticTypes[Arith];
AddBuiltinCandidate(ArithTy, &ArithTy, Args, 1, CandidateSet);
@@ -2994,7 +3304,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// operator functions of the form
//
// T operator~(T);
- for (unsigned Int = FirstPromotedIntegralType;
+ for (unsigned Int = FirstPromotedIntegralType;
Int < LastPromotedIntegralType; ++Int) {
QualType IntTy = ArithmeticTypes[Int];
AddBuiltinCandidate(IntTy, &IntTy, Args, 1, CandidateSet);
@@ -3017,17 +3327,34 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// operator '->', the built-in candidates set is empty.
break;
+ case OO_EqualEqual:
+ case OO_ExclaimEqual:
+ // C++ [over.match.oper]p16:
+ // For every pointer to member type T, there exist candidate operator
+ // functions of the form
+ //
+ // bool operator==(T,T);
+ // bool operator!=(T,T);
+ for (BuiltinCandidateTypeSet::iterator
+ MemPtr = CandidateTypes.member_pointer_begin(),
+ MemPtrEnd = CandidateTypes.member_pointer_end();
+ MemPtr != MemPtrEnd;
+ ++MemPtr) {
+ QualType ParamTypes[2] = { *MemPtr, *MemPtr };
+ AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet);
+ }
+
+ // Fall through
+
case OO_Less:
case OO_Greater:
case OO_LessEqual:
case OO_GreaterEqual:
- case OO_EqualEqual:
- case OO_ExclaimEqual:
// C++ [over.built]p15:
//
// For every pointer or enumeration type T, there exist
// candidate operator functions of the form
- //
+ //
// bool operator<(T, T);
// bool operator>(T, T);
// bool operator<=(T, T);
@@ -3039,7 +3366,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
QualType ParamTypes[2] = { *Ptr, *Ptr };
AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet);
}
- for (BuiltinCandidateTypeSet::iterator Enum
+ for (BuiltinCandidateTypeSet::iterator Enum
= CandidateTypes.enumeration_begin();
Enum != CandidateTypes.enumeration_end(); ++Enum) {
QualType ParamTypes[2] = { *Enum, *Enum };
@@ -3058,7 +3385,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
//
// For every cv-qualified or cv-unqualified object type T
// there exist candidate operator functions of the form
- //
+ //
// T* operator+(T*, ptrdiff_t);
// T& operator[](T*, ptrdiff_t); [BELOW]
// T* operator-(T*, ptrdiff_t);
@@ -3071,7 +3398,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// exist candidate operator functions of the form
//
// ptrdiff_t operator-(T, T);
- for (BuiltinCandidateTypeSet::iterator Ptr
+ for (BuiltinCandidateTypeSet::iterator Ptr
= CandidateTypes.pointer_begin();
Ptr != CandidateTypes.pointer_end(); ++Ptr) {
QualType ParamTypes[2] = { *Ptr, Context.getPointerDiffType() };
@@ -3126,14 +3453,15 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// where LR is the result of the usual arithmetic conversions
// between types L and R.
// Our candidates ignore the first parameter.
- for (unsigned Left = FirstPromotedArithmeticType;
+ for (unsigned Left = FirstPromotedArithmeticType;
Left < LastPromotedArithmeticType; ++Left) {
- for (unsigned Right = FirstPromotedArithmeticType;
+ for (unsigned Right = FirstPromotedArithmeticType;
Right < LastPromotedArithmeticType; ++Right) {
QualType LandR[2] = { ArithmeticTypes[Left], ArithmeticTypes[Right] };
- QualType Result
- = isComparison? Context.BoolTy
- : UsualArithmeticConversionsType(LandR[0], LandR[1]);
+ QualType Result
+ = isComparison
+ ? Context.BoolTy
+ : Context.UsualArithmeticConversionsType(LandR[0], LandR[1]);
AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
}
}
@@ -3159,14 +3487,14 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
//
// where LR is the result of the usual arithmetic conversions
// between types L and R.
- for (unsigned Left = FirstPromotedIntegralType;
+ for (unsigned Left = FirstPromotedIntegralType;
Left < LastPromotedIntegralType; ++Left) {
- for (unsigned Right = FirstPromotedIntegralType;
+ for (unsigned Right = FirstPromotedIntegralType;
Right < LastPromotedIntegralType; ++Right) {
QualType LandR[2] = { ArithmeticTypes[Left], ArithmeticTypes[Right] };
QualType Result = (Op == OO_LessLess || Op == OO_GreaterGreater)
? LandR[0]
- : UsualArithmeticConversionsType(LandR[0], LandR[1]);
+ : Context.UsualArithmeticConversionsType(LandR[0], LandR[1]);
AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
}
}
@@ -3176,30 +3504,23 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// C++ [over.built]p20:
//
// For every pair (T, VQ), where T is an enumeration or
- // (FIXME:) pointer to member type and VQ is either volatile or
+ // pointer to member type and VQ is either volatile or
// empty, there exist candidate operator functions of the form
//
// VQ T& operator=(VQ T&, T);
- for (BuiltinCandidateTypeSet::iterator Enum
- = CandidateTypes.enumeration_begin();
- Enum != CandidateTypes.enumeration_end(); ++Enum) {
- QualType ParamTypes[2];
-
- // T& operator=(T&, T)
- ParamTypes[0] = Context.getLValueReferenceType(*Enum);
- ParamTypes[1] = *Enum;
- AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
- /*IsAssignmentOperator=*/false);
-
- if (!Context.getCanonicalType(*Enum).isVolatileQualified()) {
- // volatile T& operator=(volatile T&, T)
- ParamTypes[0] = Context.getLValueReferenceType((*Enum).withVolatile());
- ParamTypes[1] = *Enum;
- AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
- /*IsAssignmentOperator=*/false);
- }
- }
- // Fall through.
+ for (BuiltinCandidateTypeSet::iterator
+ Enum = CandidateTypes.enumeration_begin(),
+ EnumEnd = CandidateTypes.enumeration_end();
+ Enum != EnumEnd; ++Enum)
+ AddBuiltinAssignmentOperatorCandidates(*this, *Enum, Args, 2,
+ CandidateSet);
+ for (BuiltinCandidateTypeSet::iterator
+ MemPtr = CandidateTypes.member_pointer_begin(),
+ MemPtrEnd = CandidateTypes.member_pointer_end();
+ MemPtr != MemPtrEnd; ++MemPtr)
+ AddBuiltinAssignmentOperatorCandidates(*this, *MemPtr, Args, 2,
+ CandidateSet);
+ // Fall through.
case OO_PlusEqual:
case OO_MinusEqual:
@@ -3231,7 +3552,8 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
if (!Context.getCanonicalType(*Ptr).isVolatileQualified()) {
// volatile version
- ParamTypes[0] = Context.getLValueReferenceType((*Ptr).withVolatile());
+ ParamTypes[0]
+ = Context.getLValueReferenceType(Context.getVolatileType(*Ptr));
AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
/*IsAssigmentOperator=*/Op == OO_Equal);
}
@@ -3253,7 +3575,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// VQ L& operator+=(VQ L&, R);
// VQ L& operator-=(VQ L&, R);
for (unsigned Left = 0; Left < NumArithmeticTypes; ++Left) {
- for (unsigned Right = FirstPromotedArithmeticType;
+ for (unsigned Right = FirstPromotedArithmeticType;
Right < LastPromotedArithmeticType; ++Right) {
QualType ParamTypes[2];
ParamTypes[1] = ArithmeticTypes[Right];
@@ -3264,7 +3586,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
/*IsAssigmentOperator=*/Op == OO_Equal);
// Add this built-in operator as a candidate (VQ is 'volatile').
- ParamTypes[0] = ArithmeticTypes[Left].withVolatile();
+ ParamTypes[0] = Context.getVolatileType(ArithmeticTypes[Left]);
ParamTypes[0] = Context.getLValueReferenceType(ParamTypes[0]);
AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
/*IsAssigmentOperator=*/Op == OO_Equal);
@@ -3291,7 +3613,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// VQ L& operator^=(VQ L&, R);
// VQ L& operator|=(VQ L&, R);
for (unsigned Left = FirstIntegralType; Left < LastIntegralType; ++Left) {
- for (unsigned Right = FirstPromotedIntegralType;
+ for (unsigned Right = FirstPromotedIntegralType;
Right < LastPromotedIntegralType; ++Right) {
QualType ParamTypes[2];
ParamTypes[1] = ArithmeticTypes[Right];
@@ -3302,7 +3624,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// Add this built-in operator as a candidate (VQ is 'volatile').
ParamTypes[0] = ArithmeticTypes[Left];
- ParamTypes[0].addVolatile();
+ ParamTypes[0] = Context.getVolatileType(ParamTypes[0]);
ParamTypes[0] = Context.getLValueReferenceType(ParamTypes[0]);
AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet);
}
@@ -3314,7 +3636,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
//
// There also exist candidate operator functions of the form
//
- // bool operator!(bool);
+ // bool operator!(bool);
// bool operator&&(bool, bool); [BELOW]
// bool operator||(bool, bool); [BELOW]
QualType ParamTy = Context.BoolTy;
@@ -3345,7 +3667,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
//
// For every cv-qualified or cv-unqualified object type T there
// exist candidate operator functions of the form
- //
+ //
// T* operator+(T*, ptrdiff_t); [ABOVE]
// T& operator[](T*, ptrdiff_t);
// T* operator-(T*, ptrdiff_t); [ABOVE]
@@ -3354,7 +3676,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin();
Ptr != CandidateTypes.pointer_end(); ++Ptr) {
QualType ParamTypes[2] = { *Ptr, Context.getPointerDiffType() };
- QualType PointeeType = (*Ptr)->getAsPointerType()->getPointeeType();
+ QualType PointeeType = (*Ptr)->getAs<PointerType>()->getPointeeType();
QualType ResultTy = Context.getLValueReferenceType(PointeeType);
// T& operator[](T*, ptrdiff_t)
@@ -3368,7 +3690,43 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
break;
case OO_ArrowStar:
- // FIXME: No support for pointer-to-members yet.
+ // C++ [over.built]p11:
+ // For every quintuple (C1, C2, T, CV1, CV2), where C2 is a class type,
+ // C1 is the same type as C2 or is a derived class of C2, T is an object
+ // type or a function type, and CV1 and CV2 are cv-qualifier-seqs,
+ // there exist candidate operator functions of the form
+ // CV12 T& operator->*(CV1 C1*, CV2 T C2::*);
+ // where CV12 is the union of CV1 and CV2.
+ {
+ for (BuiltinCandidateTypeSet::iterator Ptr =
+ CandidateTypes.pointer_begin();
+ Ptr != CandidateTypes.pointer_end(); ++Ptr) {
+ QualType C1Ty = (*Ptr);
+ QualType C1;
+ QualifierCollector Q1;
+ if (const PointerType *PointerTy = C1Ty->getAs<PointerType>()) {
+ C1 = QualType(Q1.strip(PointerTy->getPointeeType()), 0);
+ if (!isa<RecordType>(C1))
+ continue;
+ }
+ for (BuiltinCandidateTypeSet::iterator
+ MemPtr = CandidateTypes.member_pointer_begin(),
+ MemPtrEnd = CandidateTypes.member_pointer_end();
+ MemPtr != MemPtrEnd; ++MemPtr) {
+ const MemberPointerType *mptr = cast<MemberPointerType>(*MemPtr);
+ QualType C2 = QualType(mptr->getClass(), 0);
+ C2 = C2.getUnqualifiedType();
+ if (C1 != C2 && !IsDerivedFrom(C1, C2))
+ break;
+ QualType ParamTypes[2] = { *Ptr, *MemPtr };
+ // build CV12 T&
+ QualType T = mptr->getPointeeType();
+ T = Q1.apply(T);
+ QualType ResultTy = Context.getLValueReferenceType(T);
+ AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
+ }
+ }
+ }
break;
case OO_Conditional:
@@ -3404,12 +3762,18 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
/// given function name (which may also be an operator name) and adds
/// all of the overload candidates found by ADL to the overload
/// candidate set (C++ [basic.lookup.argdep]).
-void
+void
Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
Expr **Args, unsigned NumArgs,
- OverloadCandidateSet& CandidateSet) {
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ OverloadCandidateSet& CandidateSet,
+ bool PartialOverloading) {
FunctionSet Functions;
+ // FIXME: Should we be trafficking in canonical function decls throughout?
+
// Record all of the function candidates that we've already
// added to the overload set, so that we don't add those same
// candidates a second time.
@@ -3422,6 +3786,7 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
Functions.insert(FunTmpl);
}
+ // FIXME: Pass in the explicit template arguments?
ArgumentDependentLookup(Name, Args, NumArgs, Functions);
// Erase all of the candidates we already knew about.
@@ -3440,21 +3805,26 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name,
for (FunctionSet::iterator Func = Functions.begin(),
FuncEnd = Functions.end();
Func != FuncEnd; ++Func) {
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func))
- AddOverloadCandidate(FD, Args, NumArgs, CandidateSet);
- else
- AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),
- /*FIXME: explicit args */false, 0, 0,
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func)) {
+ if (HasExplicitTemplateArgs)
+ continue;
+
+ AddOverloadCandidate(FD, Args, NumArgs, CandidateSet,
+ false, false, PartialOverloading);
+ } else
+ AddTemplateOverloadCandidate(cast<FunctionTemplateDecl>(*Func),
+ HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
Args, NumArgs, CandidateSet);
}
}
/// isBetterOverloadCandidate - Determines whether the first overload
/// candidate is a better candidate than the second (C++ 13.3.3p1).
-bool
+bool
Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
- const OverloadCandidate& Cand2)
-{
+ const OverloadCandidate& Cand2) {
// Define viable functions to be better candidates than non-viable
// functions.
if (!Cand2.Viable)
@@ -3472,10 +3842,10 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
if (Cand1.IgnoreObjectArgument || Cand2.IgnoreObjectArgument)
StartArg = 1;
- // (C++ 13.3.3p1): a viable function F1 is defined to be a better
- // function than another viable function F2 if for all arguments i,
- // ICSi(F1) is not a worse conversion sequence than ICSi(F2), and
- // then...
+ // C++ [over.match.best]p1:
+ // A viable function F1 is defined to be a better function than another
+ // viable function F2 if for all arguments i, ICSi(F1) is not a worse
+ // conversion sequence than ICSi(F2), and then...
unsigned NumArgs = Cand1.Conversions.size();
assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch");
bool HasBetterConversion = false;
@@ -3497,22 +3867,38 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
}
}
+ // -- for some argument j, ICSj(F1) is a better conversion sequence than
+ // ICSj(F2), or, if not that,
if (HasBetterConversion)
return true;
- // FIXME: Several other bullets in (C++ 13.3.3p1) need to be
- // implemented, but they require template support.
+ // - F1 is a non-template function and F2 is a function template
+ // specialization, or, if not that,
+ if (Cand1.Function && !Cand1.Function->getPrimaryTemplate() &&
+ Cand2.Function && Cand2.Function->getPrimaryTemplate())
+ return true;
+
+ // -- F1 and F2 are function template specializations, and the function
+ // template for F1 is more specialized than the template for F2
+ // according to the partial ordering rules described in 14.5.5.2, or,
+ // if not that,
+ if (Cand1.Function && Cand1.Function->getPrimaryTemplate() &&
+ Cand2.Function && Cand2.Function->getPrimaryTemplate())
+ if (FunctionTemplateDecl *BetterTemplate
+ = getMoreSpecializedTemplate(Cand1.Function->getPrimaryTemplate(),
+ Cand2.Function->getPrimaryTemplate(),
+ isa<CXXConversionDecl>(Cand1.Function)? TPOC_Conversion
+ : TPOC_Call))
+ return BetterTemplate == Cand1.Function->getPrimaryTemplate();
- // C++ [over.match.best]p1b4:
- //
// -- the context is an initialization by user-defined conversion
// (see 8.5, 13.3.1.5) and the standard conversion sequence
// from the return type of F1 to the destination type (i.e.,
// the type of the entity being initialized) is a better
// conversion sequence than the standard conversion sequence
// from the return type of F2 to the destination type.
- if (Cand1.Function && Cand2.Function &&
- isa<CXXConversionDecl>(Cand1.Function) &&
+ if (Cand1.Function && Cand2.Function &&
+ isa<CXXConversionDecl>(Cand1.Function) &&
isa<CXXConversionDecl>(Cand2.Function)) {
switch (CompareStandardConversionSequences(Cand1.FinalConversion,
Cand2.FinalConversion)) {
@@ -3533,7 +3919,7 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
return false;
}
-/// \brief Computes the best viable function (C++ 13.3.3)
+/// \brief Computes the best viable function (C++ 13.3.3)
/// within an overload candidate set.
///
/// \param CandidateSet the set of candidate functions.
@@ -3541,15 +3927,14 @@ Sema::isBetterOverloadCandidate(const OverloadCandidate& Cand1,
/// \param Loc the location of the function name (or operator symbol) for
/// which overload resolution occurs.
///
-/// \param Best f overload resolution was successful or found a deleted
+/// \param Best f overload resolution was successful or found a deleted
/// function, Best points to the candidate function found.
///
/// \returns The result of overload resolution.
-Sema::OverloadingResult
+Sema::OverloadingResult
Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
SourceLocation Loc,
- OverloadCandidateSet::iterator& Best)
-{
+ OverloadCandidateSet::iterator& Best) {
// Find the best viable function.
Best = CandidateSet.end();
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
@@ -3568,24 +3953,24 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
// function. If not, we have an ambiguity.
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
Cand != CandidateSet.end(); ++Cand) {
- if (Cand->Viable &&
+ if (Cand->Viable &&
Cand != Best &&
!isBetterOverloadCandidate(*Best, *Cand)) {
Best = CandidateSet.end();
return OR_Ambiguous;
}
}
-
+
// Best is the best viable function.
if (Best->Function &&
- (Best->Function->isDeleted() ||
+ (Best->Function->isDeleted() ||
Best->Function->getAttr<UnavailableAttr>()))
return OR_Deleted;
// C++ [basic.def.odr]p2:
// An overloaded function is used if it is selected by overload resolution
- // when referred to from a potentially-evaluated expression. [Note: this
- // covers calls to named functions (5.2.2), operator overloading
+ // when referred to from a potentially-evaluated expression. [Note: this
+ // covers calls to named functions (5.2.2), operator overloading
// (clause 13), user-defined conversions (12.3.2), allocation function for
// placement new (5.3.4), as well as non-default initialization (8.5).
if (Best->Function)
@@ -3596,12 +3981,14 @@ Sema::BestViableFunction(OverloadCandidateSet& CandidateSet,
/// PrintOverloadCandidates - When overload resolution fails, prints
/// diagnostic messages containing the candidates in the candidate
/// set. If OnlyViable is true, only viable candidates will be printed.
-void
+void
Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
- bool OnlyViable)
-{
+ bool OnlyViable,
+ const char *Opc,
+ SourceLocation OpLoc) {
OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
LastCand = CandidateSet.end();
+ bool Reported = false;
for (; Cand != LastCand; ++Cand) {
if (Cand->Viable || !OnlyViable) {
if (Cand->Function) {
@@ -3610,10 +3997,36 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
// Deleted or "unavailable" function.
Diag(Cand->Function->getLocation(), diag::err_ovl_candidate_deleted)
<< Cand->Function->isDeleted();
+ } else if (FunctionTemplateDecl *FunTmpl
+ = Cand->Function->getPrimaryTemplate()) {
+ // Function template specialization
+ // FIXME: Give a better reason!
+ Diag(Cand->Function->getLocation(), diag::err_ovl_template_candidate)
+ << getTemplateArgumentBindingsText(FunTmpl->getTemplateParameters(),
+ *Cand->Function->getTemplateSpecializationArgs());
} else {
// Normal function
- // FIXME: Give a better reason!
- Diag(Cand->Function->getLocation(), diag::err_ovl_candidate);
+ bool errReported = false;
+ if (!Cand->Viable && Cand->Conversions.size() > 0) {
+ for (int i = Cand->Conversions.size()-1; i >= 0; i--) {
+ const ImplicitConversionSequence &Conversion =
+ Cand->Conversions[i];
+ if ((Conversion.ConversionKind !=
+ ImplicitConversionSequence::BadConversion) ||
+ Conversion.ConversionFunctionSet.size() == 0)
+ continue;
+ Diag(Cand->Function->getLocation(),
+ diag::err_ovl_candidate_not_viable) << (i+1);
+ errReported = true;
+ for (int j = Conversion.ConversionFunctionSet.size()-1;
+ j >= 0; j--) {
+ FunctionDecl *Func = Conversion.ConversionFunctionSet[j];
+ Diag(Func->getLocation(), diag::err_ovl_candidate);
+ }
+ }
+ }
+ if (!errReported)
+ Diag(Cand->Function->getLocation(), diag::err_ovl_candidate);
}
} else if (Cand->IsSurrogate) {
// Desugar the type of the surrogate down to a function type,
@@ -3624,20 +4037,20 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
bool isRValueReference = false;
bool isPointer = false;
if (const LValueReferenceType *FnTypeRef =
- FnType->getAsLValueReferenceType()) {
+ FnType->getAs<LValueReferenceType>()) {
FnType = FnTypeRef->getPointeeType();
isLValueReference = true;
} else if (const RValueReferenceType *FnTypeRef =
- FnType->getAsRValueReferenceType()) {
+ FnType->getAs<RValueReferenceType>()) {
FnType = FnTypeRef->getPointeeType();
isRValueReference = true;
}
- if (const PointerType *FnTypePtr = FnType->getAsPointerType()) {
+ if (const PointerType *FnTypePtr = FnType->getAs<PointerType>()) {
FnType = FnTypePtr->getPointeeType();
isPointer = true;
}
// Desugar down to a function type.
- FnType = QualType(FnType->getAsFunctionType(), 0);
+ FnType = QualType(FnType->getAs<FunctionType>(), 0);
// Reconstruct the pointer/reference as appropriate.
if (isPointer) FnType = Context.getPointerType(FnType);
if (isRValueReference) FnType = Context.getRValueReferenceType(FnType);
@@ -3645,17 +4058,42 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
Diag(Cand->Surrogate->getLocation(), diag::err_ovl_surrogate_cand)
<< FnType;
- } else {
- // 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)
- QualType FnType
- = Context.getFunctionType(Cand->BuiltinTypes.ResultTy,
- Cand->BuiltinTypes.ParamTypes,
- Cand->Conversions.size(),
- false, 0);
-
- Diag(SourceLocation(), diag::err_ovl_builtin_candidate) << FnType;
+ } else if (OnlyViable) {
+ assert(Cand->Conversions.size() <= 2 &&
+ "builtin-binary-operator-not-binary");
+ 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.
+ 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())
+ continue;
+ if (CXXConversionDecl *Func = dyn_cast<CXXConversionDecl>(
+ Cand->Conversions[ArgIdx].ConversionFunctionSet[0])) {
+ QualType FromTy =
+ QualType(
+ static_cast<Type*>(ICS.UserDefined.Before.FromTypePtr),0);
+ Diag(OpLoc,diag::note_ambiguous_type_conversion)
+ << FromTy << Func->getConversionType();
+ }
+ for (unsigned j = 0; j < ICS.ConversionFunctionSet.size(); j++) {
+ FunctionDecl *Func =
+ Cand->Conversions[ArgIdx].ConversionFunctionSet[j];
+ Diag(Func->getLocation(),diag::err_ovl_candidate);
+ }
+ }
+ Reported = true;
}
}
}
@@ -3669,7 +4107,7 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
/// @code
/// int f(double);
/// int f(int);
-///
+///
/// int (*pfd)(double) = f; // selects f(double)
/// @endcode
///
@@ -3681,23 +4119,24 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
bool Complain) {
QualType FunctionType = ToType;
bool IsMember = false;
- if (const PointerType *ToTypePtr = ToType->getAsPointerType())
+ if (const PointerType *ToTypePtr = ToType->getAs<PointerType>())
FunctionType = ToTypePtr->getPointeeType();
- else if (const ReferenceType *ToTypeRef = ToType->getAsReferenceType())
+ else if (const ReferenceType *ToTypeRef = ToType->getAs<ReferenceType>())
FunctionType = ToTypeRef->getPointeeType();
else if (const MemberPointerType *MemTypePtr =
- ToType->getAsMemberPointerType()) {
+ ToType->getAs<MemberPointerType>()) {
FunctionType = MemTypePtr->getPointeeType();
IsMember = true;
}
// We only look at pointers or references to functions.
- if (!FunctionType->isFunctionType())
+ FunctionType = Context.getCanonicalType(FunctionType).getUnqualifiedType();
+ if (!FunctionType->isFunctionType())
return 0;
// Find the actual overloaded function declaration.
OverloadedFunctionDecl *Ovl = 0;
-
+
// C++ [over.over]p1:
// [...] [Note: any redundant set of parentheses surrounding the
// overloaded function name is ignored (5.1). ]
@@ -3712,27 +4151,76 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
}
// Try to dig out the overloaded function.
- if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OvlExpr))
+ FunctionTemplateDecl *FunctionTemplate = 0;
+ if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(OvlExpr)) {
Ovl = dyn_cast<OverloadedFunctionDecl>(DR->getDecl());
+ FunctionTemplate = dyn_cast<FunctionTemplateDecl>(DR->getDecl());
+ } else if (MemberExpr *ME = dyn_cast<MemberExpr>(OvlExpr)) {
+ Ovl = dyn_cast<OverloadedFunctionDecl>(ME->getMemberDecl());
+ FunctionTemplate = dyn_cast<FunctionTemplateDecl>(ME->getMemberDecl());
+ // FIXME: Explicit template arguments
+ }
+ // FIXME: TemplateIdRefExpr?
- // If there's no overloaded function declaration, we're done.
- if (!Ovl)
+ // If there's no overloaded function declaration or function template,
+ // we're done.
+ if (!Ovl && !FunctionTemplate)
return 0;
-
+
+ OverloadIterator Fun;
+ if (Ovl)
+ Fun = Ovl;
+ else
+ Fun = FunctionTemplate;
+
// Look through all of the overloaded functions, searching for one
// whose type matches exactly.
- // FIXME: When templates or using declarations come along, we'll actually
- // have to deal with duplicates, partial ordering, etc. For now, we
- // can just do a simple search.
- FunctionType = Context.getCanonicalType(FunctionType.getUnqualifiedType());
- for (OverloadedFunctionDecl::function_iterator Fun = Ovl->function_begin();
- Fun != Ovl->function_end(); ++Fun) {
+ llvm::SmallPtrSet<FunctionDecl *, 4> Matches;
+ bool FoundNonTemplateFunction = false;
+ for (OverloadIterator FunEnd; Fun != FunEnd; ++Fun) {
// C++ [over.over]p3:
// Non-member functions and static member functions match
// targets of type "pointer-to-function" or "reference-to-function."
// Nonstatic member functions match targets of
// type "pointer-to-member-function."
// Note that according to DR 247, the containing class does not matter.
+
+ if (FunctionTemplateDecl *FunctionTemplate
+ = dyn_cast<FunctionTemplateDecl>(*Fun)) {
+ if (CXXMethodDecl *Method
+ = dyn_cast<CXXMethodDecl>(FunctionTemplate->getTemplatedDecl())) {
+ // Skip non-static function templates when converting to pointer, and
+ // static when converting to member pointer.
+ if (Method->isStatic() == IsMember)
+ continue;
+ } else if (IsMember)
+ continue;
+
+ // C++ [over.over]p2:
+ // If the name is a function template, template argument deduction is
+ // done (14.8.2.2), and if the argument deduction succeeds, the
+ // resulting template argument list is used to generate a single
+ // function template specialization, which is added to the set of
+ // overloaded functions considered.
+ // FIXME: We don't really want to build the specialization here, do we?
+ FunctionDecl *Specialization = 0;
+ TemplateDeductionInfo Info(Context);
+ if (TemplateDeductionResult Result
+ = DeduceTemplateArguments(FunctionTemplate, /*FIXME*/false,
+ /*FIXME:*/0, /*FIXME:*/0,
+ FunctionType, Specialization, Info)) {
+ // FIXME: make a note of the failed deduction for diagnostics.
+ (void)Result;
+ } else {
+ // FIXME: If the match isn't exact, shouldn't we just drop this as
+ // a candidate? Find a testcase before changing the code.
+ assert(FunctionType
+ == Context.getCanonicalType(Specialization->getType()));
+ Matches.insert(
+ cast<FunctionDecl>(Specialization->getCanonicalDecl()));
+ }
+ }
+
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*Fun)) {
// Skip non-static functions when converting to pointer, and static
// when converting to member pointer.
@@ -3742,38 +4230,106 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
continue;
if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Fun)) {
- if (FunctionType == Context.getCanonicalType(FunDecl->getType()))
- return FunDecl;
- } else {
- unsigned DiagID
- = PP.getDiagnostics().getCustomDiagID(Diagnostic::Warning,
- "Clang does not yet support templated conversion functions");
- Diag(From->getLocStart(), DiagID);
+ if (FunctionType == Context.getCanonicalType(FunDecl->getType())) {
+ Matches.insert(cast<FunctionDecl>(Fun->getCanonicalDecl()));
+ FoundNonTemplateFunction = true;
+ }
}
}
+ // If there were 0 or 1 matches, we're done.
+ if (Matches.empty())
+ return 0;
+ else if (Matches.size() == 1)
+ return *Matches.begin();
+
+ // C++ [over.over]p4:
+ // If more than one function is selected, [...]
+ typedef llvm::SmallPtrSet<FunctionDecl *, 4>::iterator MatchIter;
+ if (!FoundNonTemplateFunction) {
+ // [...] and any given function template specialization F1 is
+ // eliminated if the set contains a second function template
+ // specialization whose function template is more specialized
+ // than the function template of F1 according to the partial
+ // ordering rules of 14.5.5.2.
+
+ // The algorithm specified above is quadratic. We instead use a
+ // two-pass algorithm (similar to the one used to identify the
+ // best viable function in an overload set) that identifies the
+ // best function template (if it exists).
+ llvm::SmallVector<FunctionDecl *, 8> TemplateMatches(Matches.begin(),
+ Matches.end());
+ return getMostSpecialized(TemplateMatches.data(), TemplateMatches.size(),
+ TPOC_Other, From->getLocStart(),
+ PDiag(),
+ PDiag(diag::err_addr_ovl_ambiguous)
+ << TemplateMatches[0]->getDeclName(),
+ PDiag(diag::err_ovl_template_candidate));
+ }
+
+ // [...] any function template specializations in the set are
+ // eliminated if the set also contains a non-template function, [...]
+ llvm::SmallVector<FunctionDecl *, 4> RemainingMatches;
+ for (MatchIter M = Matches.begin(), MEnd = Matches.end(); M != MEnd; ++M)
+ if ((*M)->getPrimaryTemplate() == 0)
+ RemainingMatches.push_back(*M);
+
+ // [...] After such eliminations, if any, there shall remain exactly one
+ // selected function.
+ if (RemainingMatches.size() == 1)
+ return RemainingMatches.front();
+
+ // FIXME: We should probably return the same thing that BestViableFunction
+ // returns (even if we issue the diagnostics here).
+ Diag(From->getLocStart(), diag::err_addr_ovl_ambiguous)
+ << RemainingMatches[0]->getDeclName();
+ for (unsigned I = 0, N = RemainingMatches.size(); I != N; ++I)
+ Diag(RemainingMatches[I]->getLocation(), diag::err_ovl_candidate);
return 0;
}
-/// ResolveOverloadedCallFn - Given the call expression that calls Fn
-/// (which eventually refers to the declaration Func) and the call
-/// arguments Args/NumArgs, attempt to resolve the function call down
-/// to a specific function. If overload resolution succeeds, returns
-/// the function declaration produced by overload
-/// resolution. Otherwise, emits diagnostics, deletes all of the
-/// arguments and Fn, and returns NULL.
-FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
- DeclarationName UnqualifiedName,
- bool HasExplicitTemplateArgs,
+/// \brief Add a single candidate to the overload set.
+static void AddOverloadedCallCandidate(Sema &S,
+ AnyFunctionDecl Callee,
+ bool &ArgumentDependentLookup,
+ bool HasExplicitTemplateArgs,
const TemplateArgument *ExplicitTemplateArgs,
- unsigned NumExplicitTemplateArgs,
- SourceLocation LParenLoc,
- Expr **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
- SourceLocation RParenLoc,
- bool &ArgumentDependentLookup) {
- OverloadCandidateSet CandidateSet;
-
+ unsigned NumExplicitTemplateArgs,
+ Expr **Args, unsigned NumArgs,
+ OverloadCandidateSet &CandidateSet,
+ bool PartialOverloading) {
+ if (FunctionDecl *Func = dyn_cast<FunctionDecl>(Callee)) {
+ assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
+ S.AddOverloadCandidate(Func, Args, NumArgs, CandidateSet, false, false,
+ PartialOverloading);
+
+ if (Func->getDeclContext()->isRecord() ||
+ Func->getDeclContext()->isFunctionOrMethod())
+ ArgumentDependentLookup = false;
+ return;
+ }
+
+ FunctionTemplateDecl *FuncTemplate = cast<FunctionTemplateDecl>(Callee);
+ S.AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ Args, NumArgs, CandidateSet);
+
+ if (FuncTemplate->getDeclContext()->isRecord())
+ ArgumentDependentLookup = false;
+}
+
+/// \brief Add the overload candidates named by callee and/or found by argument
+/// dependent lookup to the given overload set.
+void Sema::AddOverloadedCallCandidates(NamedDecl *Callee,
+ DeclarationName &UnqualifiedName,
+ bool &ArgumentDependentLookup,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ Expr **Args, unsigned NumArgs,
+ OverloadCandidateSet &CandidateSet,
+ bool PartialOverloading) {
// Add the functions denoted by Callee to the set of candidate
// functions. While we're doing so, track whether argument-dependent
// lookup still applies, per:
@@ -3783,66 +4339,75 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
// and let Y be the lookup set produced by argument dependent
// lookup (defined as follows). If X contains
//
- // -- a declaration of a class member, or
+ // -- a declaration of a class member, or
//
// -- a block-scope function declaration that is not a
- // using-declaration, or
- //
+ // using-declaration (FIXME: check for using declaration), or
+ //
// -- a declaration that is neither a function or a function
// template
//
- // then Y is empty.
- if (OverloadedFunctionDecl *Ovl
- = dyn_cast_or_null<OverloadedFunctionDecl>(Callee)) {
+ // then Y is empty.
+ if (!Callee) {
+ // Nothing to do.
+ } else if (OverloadedFunctionDecl *Ovl
+ = dyn_cast<OverloadedFunctionDecl>(Callee)) {
for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
FuncEnd = Ovl->function_end();
- Func != FuncEnd; ++Func) {
- DeclContext *Ctx = 0;
- if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(*Func)) {
- if (HasExplicitTemplateArgs)
- continue;
-
- AddOverloadCandidate(FunDecl, Args, NumArgs, CandidateSet);
- Ctx = FunDecl->getDeclContext();
- } else {
- FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(*Func);
- AddTemplateOverloadCandidate(FunTmpl, HasExplicitTemplateArgs,
- ExplicitTemplateArgs,
- NumExplicitTemplateArgs,
- Args, NumArgs, CandidateSet);
- Ctx = FunTmpl->getDeclContext();
- }
-
-
- if (Ctx->isRecord() || Ctx->isFunctionOrMethod())
- ArgumentDependentLookup = false;
- }
- } else if (FunctionDecl *Func = dyn_cast_or_null<FunctionDecl>(Callee)) {
- assert(!HasExplicitTemplateArgs && "Explicit template arguments?");
- AddOverloadCandidate(Func, Args, NumArgs, CandidateSet);
-
- if (Func->getDeclContext()->isRecord() ||
- Func->getDeclContext()->isFunctionOrMethod())
- ArgumentDependentLookup = false;
- } else if (FunctionTemplateDecl *FuncTemplate
- = dyn_cast_or_null<FunctionTemplateDecl>(Callee)) {
- AddTemplateOverloadCandidate(FuncTemplate, HasExplicitTemplateArgs,
- ExplicitTemplateArgs,
- NumExplicitTemplateArgs,
- Args, NumArgs, CandidateSet);
-
- if (FuncTemplate->getDeclContext()->isRecord())
- ArgumentDependentLookup = false;
- }
-
+ Func != FuncEnd; ++Func)
+ AddOverloadedCallCandidate(*this, *Func, ArgumentDependentLookup,
+ HasExplicitTemplateArgs,
+ ExplicitTemplateArgs, NumExplicitTemplateArgs,
+ Args, NumArgs, CandidateSet,
+ PartialOverloading);
+ } else if (isa<FunctionDecl>(Callee) || isa<FunctionTemplateDecl>(Callee))
+ AddOverloadedCallCandidate(*this,
+ AnyFunctionDecl::getFromNamedDecl(Callee),
+ ArgumentDependentLookup,
+ HasExplicitTemplateArgs,
+ ExplicitTemplateArgs, NumExplicitTemplateArgs,
+ Args, NumArgs, CandidateSet,
+ PartialOverloading);
+ // FIXME: assert isa<FunctionDecl> || isa<FunctionTemplateDecl> rather than
+ // checking dynamically.
+
if (Callee)
UnqualifiedName = Callee->getDeclName();
-
- // FIXME: Pass explicit template arguments through for ADL
+
if (ArgumentDependentLookup)
AddArgumentDependentLookupCandidates(UnqualifiedName, Args, NumArgs,
- CandidateSet);
+ HasExplicitTemplateArgs,
+ ExplicitTemplateArgs,
+ NumExplicitTemplateArgs,
+ CandidateSet,
+ PartialOverloading);
+}
+
+/// ResolveOverloadedCallFn - Given the call expression that calls Fn
+/// (which eventually refers to the declaration Func) and the call
+/// arguments Args/NumArgs, attempt to resolve the function call down
+/// to a specific function. If overload resolution succeeds, returns
+/// the function declaration produced by overload
+/// resolution. Otherwise, emits diagnostics, deletes all of the
+/// arguments and Fn, and returns NULL.
+FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
+ DeclarationName UnqualifiedName,
+ bool HasExplicitTemplateArgs,
+ const TemplateArgument *ExplicitTemplateArgs,
+ unsigned NumExplicitTemplateArgs,
+ SourceLocation LParenLoc,
+ Expr **Args, unsigned NumArgs,
+ SourceLocation *CommaLocs,
+ SourceLocation RParenLoc,
+ bool &ArgumentDependentLookup) {
+ OverloadCandidateSet CandidateSet;
+ // Add the functions denoted by Callee to the set of candidate
+ // functions.
+ AddOverloadedCallCandidates(Callee, UnqualifiedName, ArgumentDependentLookup,
+ HasExplicitTemplateArgs, ExplicitTemplateArgs,
+ NumExplicitTemplateArgs, Args, NumArgs,
+ CandidateSet);
OverloadCandidateSet::iterator Best;
switch (BestViableFunction(CandidateSet, Fn->getLocStart(), Best)) {
case OR_Success:
@@ -3897,7 +4462,7 @@ FunctionDecl *Sema::ResolveOverloadedCallFn(Expr *Fn, NamedDecl *Callee,
Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
unsigned OpcIn,
FunctionSet &Functions,
- ExprArg input) {
+ ExprArg input) {
UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
Expr *Input = (Expr *)input.get();
@@ -3907,28 +4472,28 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
Expr *Args[2] = { Input, 0 };
unsigned NumArgs = 1;
-
+
// For post-increment and post-decrement, add the implicit '0' as
// the second argument, so that we know this is a post-increment or
// post-decrement.
if (Opc == UnaryOperator::PostInc || Opc == UnaryOperator::PostDec) {
llvm::APSInt Zero(Context.getTypeSize(Context.IntTy), false);
- Args[1] = new (Context) IntegerLiteral(Zero, Context.IntTy,
+ Args[1] = new (Context) IntegerLiteral(Zero, Context.IntTy,
SourceLocation());
NumArgs = 2;
}
if (Input->isTypeDependent()) {
- OverloadedFunctionDecl *Overloads
+ OverloadedFunctionDecl *Overloads
= OverloadedFunctionDecl::Create(Context, CurContext, OpName);
- for (FunctionSet::iterator Func = Functions.begin(),
+ for (FunctionSet::iterator Func = Functions.begin(),
FuncEnd = Functions.end();
Func != FuncEnd; ++Func)
Overloads->addOverload(*Func);
DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy,
OpLoc, false, false);
-
+
input.release();
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
&Args[0], NumArgs,
@@ -3954,11 +4519,11 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
case OR_Success: {
// We found a built-in operator or an overloaded operator.
FunctionDecl *FnDecl = Best->Function;
-
+
if (FnDecl) {
// We matched an overloaded operator. Build a call to that
// operator.
-
+
// Convert the arguments.
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
if (PerformObjectArgumentInitialization(Input, Method))
@@ -3972,19 +4537,24 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
}
// Determine the result type
- QualType ResultTy
- = FnDecl->getType()->getAsFunctionType()->getResultType();
- ResultTy = ResultTy.getNonReferenceType();
-
+ QualType ResultTy = FnDecl->getResultType().getNonReferenceType();
+
// Build the actual expression node.
Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(),
SourceLocation());
UsualUnaryConversions(FnExpr);
-
+
input.release();
- return Owned(new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
- &Input, 1, ResultTy,
- OpLoc));
+
+ ExprOwningPtr<CallExpr> TheCall(this,
+ new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+ &Input, 1, ResultTy, OpLoc));
+
+ if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(),
+ FnDecl))
+ return ExprError();
+
+ return MaybeBindToTemporary(TheCall.release());
} else {
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
@@ -4006,7 +4576,8 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
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:
@@ -4042,12 +4613,13 @@ Sema::OwningExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc,
///
/// \param LHS Left-hand argument.
/// \param RHS Right-hand argument.
-Sema::OwningExprResult
+Sema::OwningExprResult
Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
- unsigned OpcIn,
+ unsigned OpcIn,
FunctionSet &Functions,
Expr *LHS, Expr *RHS) {
Expr *Args[2] = { LHS, RHS };
+ LHS=RHS=0; //Please use only Args instead of LHS/RHS couple
BinaryOperator::Opcode Opc = static_cast<BinaryOperator::Opcode>(OpcIn);
OverloadedOperatorKind Op = BinaryOperator::getOverloadedOperator(Opc);
@@ -4055,24 +4627,24 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// If either side is type-dependent, create an appropriate dependent
// expression.
- if (LHS->isTypeDependent() || RHS->isTypeDependent()) {
+ if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
// .* cannot be overloaded.
if (Opc == BinaryOperator::PtrMemD)
- return Owned(new (Context) BinaryOperator(LHS, RHS, Opc,
+ return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
Context.DependentTy, OpLoc));
- OverloadedFunctionDecl *Overloads
+ OverloadedFunctionDecl *Overloads
= OverloadedFunctionDecl::Create(Context, CurContext, OpName);
- for (FunctionSet::iterator Func = Functions.begin(),
+ for (FunctionSet::iterator Func = Functions.begin(),
FuncEnd = Functions.end();
Func != FuncEnd; ++Func)
Overloads->addOverload(*Func);
DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads, Context.OverloadTy,
OpLoc, false, false);
-
+
return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn,
- Args, 2,
+ Args, 2,
Context.DependentTy,
OpLoc));
}
@@ -4080,14 +4652,14 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// If this is the .* operator, which is not overloadable, just
// create a built-in binary operator.
if (Opc == BinaryOperator::PtrMemD)
- return CreateBuiltinBinOp(OpLoc, Opc, LHS, RHS);
+ return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
// If this is one of the assignment operators, we only perform
// overload resolution if the left-hand side is a class or
// enumeration type (C++ [expr.ass]p3).
if (Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign &&
- !LHS->getType()->isOverloadableType())
- return CreateBuiltinBinOp(OpLoc, Opc, LHS, RHS);
+ !Args[0]->getType()->isOverloadableType())
+ return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
// Build an empty overload set.
OverloadCandidateSet CandidateSet;
@@ -4114,39 +4686,46 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// Convert the arguments.
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
- if (PerformObjectArgumentInitialization(LHS, Method) ||
- PerformCopyInitialization(RHS, FnDecl->getParamDecl(0)->getType(),
+ if (PerformObjectArgumentInitialization(Args[0], Method) ||
+ PerformCopyInitialization(Args[1], FnDecl->getParamDecl(0)->getType(),
"passing"))
return ExprError();
} else {
// Convert the arguments.
- if (PerformCopyInitialization(LHS, FnDecl->getParamDecl(0)->getType(),
+ if (PerformCopyInitialization(Args[0], FnDecl->getParamDecl(0)->getType(),
"passing") ||
- PerformCopyInitialization(RHS, FnDecl->getParamDecl(1)->getType(),
+ PerformCopyInitialization(Args[1], FnDecl->getParamDecl(1)->getType(),
"passing"))
return ExprError();
}
// Determine the result type
QualType ResultTy
- = FnDecl->getType()->getAsFunctionType()->getResultType();
+ = FnDecl->getType()->getAs<FunctionType>()->getResultType();
ResultTy = ResultTy.getNonReferenceType();
// Build the actual expression node.
Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(),
- SourceLocation());
+ OpLoc);
UsualUnaryConversions(FnExpr);
- return Owned(new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
- Args, 2, ResultTy,
- OpLoc));
+ ExprOwningPtr<CXXOperatorCallExpr>
+ TheCall(this, new (Context) CXXOperatorCallExpr(Context, Op, FnExpr,
+ Args, 2, ResultTy,
+ OpLoc));
+
+ if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall.get(),
+ FnDecl))
+ return ExprError();
+
+ return MaybeBindToTemporary(TheCall.release());
} else {
// We matched a built-in operator. Convert the arguments, then
// break out so that we will build the appropriate built-in
// operator node.
- if (PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0],
+ if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
Best->Conversions[0], "passing") ||
- PerformImplicitConversion(RHS, Best->BuiltinTypes.ParamTypes[1],
+ PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
Best->Conversions[1], "passing"))
return ExprError();
@@ -4154,40 +4733,55 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
}
}
- case OR_No_Viable_Function:
+ case OR_No_Viable_Function: {
+ // C++ [over.match.oper]p9:
+ // If the operator is the operator , [...] and there are no
+ // viable functions, then the operator is assumed to be the
+ // built-in operator and interpreted according to clause 5.
+ if (Opc == BinaryOperator::Comma)
+ break;
+
// For class as left operand for assignment or compound assigment operator
// do not fall through to handling in built-in, but report that no overloaded
// assignment operator found
- if (LHS->getType()->isRecordType() && Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) {
+ OwningExprResult Result = ExprError();
+ if (Args[0]->getType()->isRecordType() &&
+ Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) {
Diag(OpLoc, diag::err_ovl_no_viable_oper)
<< BinaryOperator::getOpcodeStr(Opc)
- << LHS->getSourceRange() << RHS->getSourceRange();
- return ExprError();
+ << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+ } else {
+ // No viable function; try to create a built-in operation, which will
+ // produce an error. Then, show the non-viable candidates.
+ Result = CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
}
- // No viable function; fall through to handling this as a
- // built-in operator, which will produce an error message for us.
- break;
+ assert(Result.isInvalid() &&
+ "C++ binary operator overloading is missing candidates!");
+ if (Result.isInvalid())
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false,
+ BinaryOperator::getOpcodeStr(Opc), OpLoc);
+ return move(Result);
+ }
case OR_Ambiguous:
Diag(OpLoc, diag::err_ovl_ambiguous_oper)
<< BinaryOperator::getOpcodeStr(Opc)
- << LHS->getSourceRange() << RHS->getSourceRange();
- PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
+ << Args[0]->getSourceRange() << Args[1]->getSourceRange();
+ PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true,
+ BinaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
case OR_Deleted:
Diag(OpLoc, diag::err_ovl_deleted_oper)
<< Best->Function->isDeleted()
<< BinaryOperator::getOpcodeStr(Opc)
- << LHS->getSourceRange() << RHS->getSourceRange();
+ << Args[0]->getSourceRange() << Args[1]->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
return ExprError();
}
- // Either we found no viable overloaded operator or we matched a
- // built-in operator. In either case, try to build a built-in
- // operation.
- return CreateBuiltinBinOp(OpLoc, Opc, LHS, RHS);
+ // We matched a built-in operator; build it.
+ return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
}
/// BuildCallToMemberFunction - Build a call to a member
@@ -4198,8 +4792,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
/// expression refers to a member function or an overloaded member
/// function.
Sema::ExprResult
-Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
- SourceLocation LParenLoc, Expr **Args,
+Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
+ SourceLocation LParenLoc, Expr **Args,
unsigned NumArgs, SourceLocation *CommaLocs,
SourceLocation RParenLoc) {
// Dig out the member expression. This holds both the object
@@ -4215,17 +4809,25 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
Expr *ObjectArg = MemExpr->getBase();
CXXMethodDecl *Method = 0;
- if (OverloadedFunctionDecl *Ovl
- = dyn_cast<OverloadedFunctionDecl>(MemExpr->getMemberDecl())) {
+ if (isa<OverloadedFunctionDecl>(MemExpr->getMemberDecl()) ||
+ isa<FunctionTemplateDecl>(MemExpr->getMemberDecl())) {
// Add overload candidates
OverloadCandidateSet CandidateSet;
- for (OverloadedFunctionDecl::function_iterator Func = Ovl->function_begin(),
- FuncEnd = Ovl->function_end();
+ DeclarationName DeclName = MemExpr->getMemberDecl()->getDeclName();
+
+ for (OverloadIterator Func(MemExpr->getMemberDecl()), FuncEnd;
Func != FuncEnd; ++Func) {
- assert(isa<CXXMethodDecl>(*Func) && "Function is not a method");
- Method = cast<CXXMethodDecl>(*Func);
- AddMethodCandidate(Method, ObjectArg, Args, NumArgs, CandidateSet,
- /*SuppressUserConversions=*/false);
+ if ((Method = dyn_cast<CXXMethodDecl>(*Func)))
+ AddMethodCandidate(Method, ObjectArg, Args, NumArgs, CandidateSet,
+ /*SuppressUserConversions=*/false);
+ else
+ AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(*Func),
+ MemExpr->hasExplicitTemplateArgumentList(),
+ MemExpr->getTemplateArgs(),
+ MemExpr->getNumTemplateArgs(),
+ ObjectArg, Args, NumArgs,
+ CandidateSet,
+ /*SuppressUsedConversions=*/false);
}
OverloadCandidateSet::iterator Best;
@@ -4235,26 +4837,26 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
break;
case OR_No_Viable_Function:
- Diag(MemExpr->getSourceRange().getBegin(),
+ Diag(MemExpr->getSourceRange().getBegin(),
diag::err_ovl_no_viable_member_function_in_call)
- << Ovl->getDeclName() << MemExprE->getSourceRange();
+ << DeclName << MemExprE->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
// FIXME: Leaking incoming expressions!
return true;
case OR_Ambiguous:
- Diag(MemExpr->getSourceRange().getBegin(),
+ Diag(MemExpr->getSourceRange().getBegin(),
diag::err_ovl_ambiguous_member_call)
- << Ovl->getDeclName() << MemExprE->getSourceRange();
+ << DeclName << MemExprE->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
// FIXME: Leaking incoming expressions!
return true;
case OR_Deleted:
- Diag(MemExpr->getSourceRange().getBegin(),
+ Diag(MemExpr->getSourceRange().getBegin(),
diag::err_ovl_deleted_member_call)
<< Best->Function->isDeleted()
- << Ovl->getDeclName() << MemExprE->getSourceRange();
+ << DeclName << MemExprE->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
// FIXME: Leaking incoming expressions!
return true;
@@ -4266,43 +4868,51 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
}
assert(Method && "Member call to something that isn't a method?");
- ExprOwningPtr<CXXMemberCallExpr>
+ ExprOwningPtr<CXXMemberCallExpr>
TheCall(this, new (Context) CXXMemberCallExpr(Context, MemExpr, Args,
- NumArgs,
+ NumArgs,
Method->getResultType().getNonReferenceType(),
RParenLoc));
+ // Check for a valid return type.
+ if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(),
+ TheCall.get(), Method))
+ return true;
+
// Convert the object argument (for a non-static member function call).
- if (!Method->isStatic() &&
+ if (!Method->isStatic() &&
PerformObjectArgumentInitialization(ObjectArg, Method))
return true;
MemExpr->setBase(ObjectArg);
// Convert the rest of the arguments
const FunctionProtoType *Proto = cast<FunctionProtoType>(Method->getType());
- if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
+ if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs,
RParenLoc))
return true;
- return CheckFunctionCall(Method, TheCall.take()).release();
+ if (CheckFunctionCall(Method, TheCall.get()))
+ return true;
+
+ return MaybeBindToTemporary(TheCall.release()).release();
}
/// BuildCallToObjectOfClassType - Build a call to an object of class
/// type (C++ [over.call.object]), which can end up invoking an
/// overloaded function call operator (@c operator()) or performing a
/// user-defined conversion on the object argument.
-Sema::ExprResult
-Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
+Sema::ExprResult
+Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
- SourceLocation *CommaLocs,
+ SourceLocation *CommaLocs,
SourceLocation RParenLoc) {
assert(Object->getType()->isRecordType() && "Requires object type argument");
- const RecordType *Record = Object->getType()->getAsRecordType();
-
+ const RecordType *Record = Object->getType()->getAs<RecordType>();
+
// C++ [over.call.object]p1:
// If the primary-expression E in the function call syntax
- // evaluates to a class object of type “cv T”, then the set of
+ // evaluates to a class object of type "cv T", then the set of
// candidate functions includes at least the function call
// operators of T. The function call operators of T are obtained by
// ordinary lookup of the name operator() in the context of
@@ -4312,7 +4922,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
DeclContext::lookup_const_iterator Oper, OperEnd;
for (llvm::tie(Oper, OperEnd) = Record->getDecl()->lookup(OpName);
Oper != OperEnd; ++Oper)
- AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs,
+ AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Object, Args, NumArgs,
CandidateSet, /*SuppressUserConversions=*/false);
// C++ [over.call.object]p2:
@@ -4332,24 +4942,33 @@ 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.
- //
- // FIXME: Look in base classes for more conversion operators!
- OverloadedFunctionDecl *Conversions
- = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
- 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
- // any) to get down to what might be a function type.
- QualType ConvType = Conv->getConversionType().getNonReferenceType();
- if (const PointerType *ConvPtrType = ConvType->getAsPointerType())
- ConvType = ConvPtrType->getPointeeType();
+ if (!RequireCompleteType(SourceLocation(), Object->getType(), 0)) {
+ // FIXME: Look in base classes for more conversion operators!
+ OverloadedFunctionDecl *Conversions
+ = cast<CXXRecordDecl>(Record->getDecl())->getConversionFunctions();
+ for (OverloadedFunctionDecl::function_iterator
+ Func = Conversions->function_begin(),
+ FuncEnd = Conversions->function_end();
+ Func != FuncEnd; ++Func) {
+ CXXConversionDecl *Conv;
+ FunctionTemplateDecl *ConvTemplate;
+ GetFunctionAndTemplate(*Func, Conv, ConvTemplate);
+
+ // Skip over templated conversion functions; they aren't
+ // surrogates.
+ if (ConvTemplate)
+ continue;
+
+ // Strip the reference type (if any) and then the pointer type (if
+ // any) to get down to what might be a function type.
+ QualType ConvType = Conv->getConversionType().getNonReferenceType();
+ if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>())
+ ConvType = ConvPtrType->getPointeeType();
- if (const FunctionProtoType *Proto = ConvType->getAsFunctionProtoType())
- AddSurrogateCandidate(Conv, Proto, Object, Args, NumArgs, CandidateSet);
+ if (const FunctionProtoType *Proto = ConvType->getAs<FunctionProtoType>())
+ AddSurrogateCandidate(Conv, Proto, Object, Args, NumArgs, CandidateSet);
+ }
}
// Perform overload resolution.
@@ -4361,7 +4980,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
break;
case OR_No_Viable_Function:
- Diag(Object->getSourceRange().getBegin(),
+ Diag(Object->getSourceRange().getBegin(),
diag::err_ovl_no_viable_object_call)
<< Object->getType() << Object->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
@@ -4381,7 +5000,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
<< Object->getType() << Object->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
break;
- }
+ }
if (Best == CandidateSet.end()) {
// We had an error; delete all of the subexpressions and return
@@ -4395,18 +5014,20 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
if (Best->Function == 0) {
// Since there is no function declaration, this is one of the
// surrogate candidates. Dig out the conversion function.
- CXXConversionDecl *Conv
+ CXXConversionDecl *Conv
= cast<CXXConversionDecl>(
Best->Conversions[0].UserDefined.ConversionFunction);
// We selected one of the surrogate functions that converts the
// object parameter to a function pointer. Perform the conversion
// on the object argument, then let ActOnCallExpr finish the job.
- // FIXME: Represent the user-defined conversion in the AST!
- ImpCastExprToType(Object,
- Conv->getConversionType().getNonReferenceType(),
- Conv->getConversionType()->isLValueReferenceType());
- return ActOnCallExpr(S, ExprArg(*this, Object), LParenLoc,
+
+ // Create an implicit member expr to refer to the conversion operator.
+ // and then call it.
+ CXXMemberCallExpr *CE =
+ BuildCXXMemberCallExpr(Object, Conv);
+
+ return ActOnCallExpr(S, ExprArg(*this, CE), LParenLoc,
MultiExprArg(*this, (ExprTy**)Args, NumArgs),
CommaLocs, RParenLoc).release();
}
@@ -4415,7 +5036,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
// that calls this method, using Object for the implicit object
// parameter and passing along the remaining arguments.
CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
- const FunctionProtoType *Proto = Method->getType()->getAsFunctionProtoType();
+ const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>();
unsigned NumArgsInProto = Proto->getNumArgs();
unsigned NumArgsToCheck = NumArgs;
@@ -4433,20 +5054,24 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
MethodArgs[0] = Object;
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
MethodArgs[ArgIdx + 1] = Args[ArgIdx];
-
- Expr *NewFn = new (Context) DeclRefExpr(Method, Method->getType(),
+
+ Expr *NewFn = new (Context) DeclRefExpr(Method, Method->getType(),
SourceLocation());
UsualUnaryConversions(NewFn);
// Once we've built TheCall, all of the expressions are properly
// owned.
QualType ResultTy = Method->getResultType().getNonReferenceType();
- ExprOwningPtr<CXXOperatorCallExpr>
- TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
+ ExprOwningPtr<CXXOperatorCallExpr>
+ TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn,
MethodArgs, NumArgs + 1,
ResultTy, RParenLoc));
delete [] MethodArgs;
+ if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall.get(),
+ Method))
+ return true;
+
// We may have default arguments. If so, we need to allocate more
// slots in the call for them.
if (NumArgs < NumArgsInProto)
@@ -4466,12 +5091,12 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
Expr *Arg;
if (i < NumArgs) {
Arg = Args[i];
-
+
// Pass the argument.
QualType ProtoArgType = Proto->getArgType(i);
IsError |= PerformCopyInitialization(Arg, ProtoArgType, "passing");
} else {
- Arg = new (Context) CXXDefaultArgExpr(Method->getParamDecl(i));
+ Arg = CXXDefaultArgExpr::Create(Context, Method->getParamDecl(i));
}
TheCall->setArg(i + 1, Arg);
@@ -4489,37 +5114,38 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
if (IsError) return true;
- return CheckFunctionCall(Method, TheCall.take()).release();
+ if (CheckFunctionCall(Method, TheCall.get()))
+ return true;
+
+ return MaybeBindToTemporary(TheCall.release()).release();
}
/// BuildOverloadedArrowExpr - Build a call to an overloaded @c operator->
-/// (if one exists), where @c Base is an expression of class type and
+/// (if one exists), where @c Base is an expression of class type and
/// @c Member is the name of the member we're trying to find.
-Action::ExprResult
-Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
- SourceLocation MemberLoc,
- IdentifierInfo &Member) {
+Sema::OwningExprResult
+Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
+ Expr *Base = static_cast<Expr *>(BaseIn.get());
assert(Base->getType()->isRecordType() && "left-hand side must have class type");
-
+
// C++ [over.ref]p1:
//
// [...] An expression x->m is interpreted as (x.operator->())->m
// for a class object x of type T if T::operator->() exists and if
// the operator is selected as the best match function by the
// overload resolution mechanism (13.3).
- // FIXME: look in base classes.
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(OO_Arrow);
OverloadCandidateSet CandidateSet;
- const RecordType *BaseRecord = Base->getType()->getAsRecordType();
-
- DeclContext::lookup_const_iterator Oper, OperEnd;
- for (llvm::tie(Oper, OperEnd)
- = BaseRecord->getDecl()->lookup(OpName); Oper != OperEnd; ++Oper)
+ const RecordType *BaseRecord = Base->getType()->getAs<RecordType>();
+
+ LookupResult R;
+ LookupQualifiedName(R, BaseRecord->getDecl(), OpName, LookupOrdinaryName);
+
+ for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
+ Oper != OperEnd; ++Oper)
AddMethodCandidate(cast<CXXMethodDecl>(*Oper), Base, 0, 0, CandidateSet,
/*SuppressUserConversions=*/false);
- ExprOwningPtr<Expr> BasePtr(this, Base);
-
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (BestViableFunction(CandidateSet, OpLoc, Best)) {
@@ -4530,44 +5156,49 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc,
case OR_No_Viable_Function:
if (CandidateSet.empty())
Diag(OpLoc, diag::err_typecheck_member_reference_arrow)
- << BasePtr->getType() << BasePtr->getSourceRange();
+ << Base->getType() << Base->getSourceRange();
else
Diag(OpLoc, diag::err_ovl_no_viable_oper)
- << "operator->" << BasePtr->getSourceRange();
+ << "operator->" << Base->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
- return true;
+ return ExprError();
case OR_Ambiguous:
Diag(OpLoc, diag::err_ovl_ambiguous_oper)
- << "operator->" << BasePtr->getSourceRange();
+ << "->" << Base->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
- return true;
+ return ExprError();
case OR_Deleted:
Diag(OpLoc, diag::err_ovl_deleted_oper)
<< Best->Function->isDeleted()
- << "operator->" << BasePtr->getSourceRange();
+ << "->" << Base->getSourceRange();
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
- return true;
+ return ExprError();
}
// Convert the object parameter.
CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
if (PerformObjectArgumentInitialization(Base, Method))
- return true;
+ return ExprError();
// No concerns about early exits now.
- BasePtr.take();
+ BaseIn.release();
// Build the operator call.
Expr *FnExpr = new (Context) DeclRefExpr(Method, Method->getType(),
SourceLocation());
UsualUnaryConversions(FnExpr);
- Base = new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr, &Base, 1,
- Method->getResultType().getNonReferenceType(),
- OpLoc);
- return ActOnMemberReferenceExpr(S, ExprArg(*this, Base), OpLoc, tok::arrow,
- MemberLoc, Member, DeclPtrTy()).release();
+
+ QualType ResultTy = Method->getResultType().getNonReferenceType();
+ ExprOwningPtr<CXXOperatorCallExpr>
+ TheCall(this, new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr,
+ &Base, 1, ResultTy, OpLoc));
+
+ if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall.get(),
+ Method))
+ return ExprError();
+ return move(TheCall);
}
/// FixOverloadedFunctionReference - E is an expression that refers to
@@ -4580,14 +5211,13 @@ void Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
FixOverloadedFunctionReference(PE->getSubExpr(), Fn);
E->setType(PE->getSubExpr()->getType());
} else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) {
- assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
+ assert(UnOp->getOpcode() == UnaryOperator::AddrOf &&
"Can only take the address of an overloaded function");
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) {
if (Method->isStatic()) {
// Do nothing: static member functions aren't any different
// from non-member functions.
- }
- else if (QualifiedDeclRefExpr *DRE
+ } else if (QualifiedDeclRefExpr *DRE
= dyn_cast<QualifiedDeclRefExpr>(UnOp->getSubExpr())) {
// We have taken the address of a pointer to member
// function. Perform the computation here so that we get the
@@ -4596,7 +5226,7 @@ void Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
DRE->setType(Fn->getType());
QualType ClassType
= Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext()));
- E->setType(Context.getMemberPointerType(Fn->getType(),
+ E->setType(Context.getMemberPointerType(Fn->getType(),
ClassType.getTypePtr()));
return;
}
@@ -4604,8 +5234,9 @@ void Sema::FixOverloadedFunctionReference(Expr *E, FunctionDecl *Fn) {
FixOverloadedFunctionReference(UnOp->getSubExpr(), Fn);
E->setType(Context.getPointerType(UnOp->getSubExpr()->getType()));
} else if (DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
- assert(isa<OverloadedFunctionDecl>(DR->getDecl()) &&
- "Expected overloaded function");
+ assert((isa<OverloadedFunctionDecl>(DR->getDecl()) ||
+ isa<FunctionTemplateDecl>(DR->getDecl())) &&
+ "Expected overloaded function or function template");
DR->setDecl(Fn);
E->setType(Fn->getType());
} else if (MemberExpr *MemExpr = dyn_cast<MemberExpr>(E)) {