blob: 013af8a8f624fe5fada17c4e7598c586fe542ba0 [file] [log] [blame]
//===--- SemaOverload.cpp - C++ Overloading ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file provides Sema routines for C++ overloading.
//
//===----------------------------------------------------------------------===//
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/TypeOrdering.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
namespace clang {
using namespace sema;
/// A convenience routine for creating a decayed reference to a
/// function.
static ExprResult
CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, bool HadMultipleCandidates,
SourceLocation Loc = SourceLocation(),
const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(),
VK_LValue, Loc, LocInfo);
if (HadMultipleCandidates)
DRE->setHadMultipleCandidates(true);
ExprResult E = S.Owned(DRE);
E = S.DefaultFunctionArrayConversion(E.take());
if (E.isInvalid())
return ExprError();
return move(E);
}
static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
bool InOverloadResolution,
StandardConversionSequence &SCS,
bool CStyle,
bool AllowObjCWritebackConversion);
static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From,
QualType &ToType,
bool InOverloadResolution,
StandardConversionSequence &SCS,
bool CStyle);
static OverloadingResult
IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
UserDefinedConversionSequence& User,
OverloadCandidateSet& Conversions,
bool AllowExplicit);
static ImplicitConversionSequence::CompareKind
CompareStandardConversionSequences(Sema &S,
const StandardConversionSequence& SCS1,
const StandardConversionSequence& SCS2);
static ImplicitConversionSequence::CompareKind
CompareQualificationConversions(Sema &S,
const StandardConversionSequence& SCS1,
const StandardConversionSequence& SCS2);
static ImplicitConversionSequence::CompareKind
CompareDerivedToBaseConversions(Sema &S,
const StandardConversionSequence& SCS1,
const StandardConversionSequence& SCS2);
/// GetConversionCategory - Retrieve the implicit conversion
/// category corresponding to the given implicit conversion kind.
ImplicitConversionCategory
GetConversionCategory(ImplicitConversionKind Kind) {
static const ImplicitConversionCategory
Category[(int)ICK_Num_Conversion_Kinds] = {
ICC_Identity,
ICC_Lvalue_Transformation,
ICC_Lvalue_Transformation,
ICC_Lvalue_Transformation,
ICC_Identity,
ICC_Qualification_Adjustment,
ICC_Promotion,
ICC_Promotion,
ICC_Promotion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion,
ICC_Conversion
};
return Category[(int)Kind];
}
/// GetConversionRank - Retrieve the implicit conversion rank
/// corresponding to the given implicit conversion kind.
ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind) {
static const ImplicitConversionRank
Rank[(int)ICK_Num_Conversion_Kinds] = {
ICR_Exact_Match,
ICR_Exact_Match,
ICR_Exact_Match,
ICR_Exact_Match,
ICR_Exact_Match,
ICR_Exact_Match,
ICR_Promotion,
ICR_Promotion,
ICR_Promotion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Complex_Real_Conversion,
ICR_Conversion,
ICR_Conversion,
ICR_Writeback_Conversion
};
return Rank[(int)Kind];
}
/// GetImplicitConversionName - Return the name of this kind of
/// implicit conversion.
const char* GetImplicitConversionName(ImplicitConversionKind Kind) {
static const char* const Name[(int)ICK_Num_Conversion_Kinds] = {
"No conversion",
"Lvalue-to-rvalue",
"Array-to-pointer",
"Function-to-pointer",
"Noreturn adjustment",
"Qualification",
"Integral promotion",
"Floating point promotion",
"Complex promotion",
"Integral conversion",
"Floating conversion",
"Complex conversion",
"Floating-integral conversion",
"Pointer conversion",
"Pointer-to-member conversion",
"Boolean conversion",
"Compatible-types conversion",
"Derived-to-base conversion",
"Vector conversion",
"Vector splat",
"Complex-real conversion",
"Block Pointer conversion",
"Transparent Union Conversion"
"Writeback conversion"
};
return Name[Kind];
}
/// StandardConversionSequence - Set the standard conversion
/// sequence to the identity conversion.
void StandardConversionSequence::setAsIdentityConversion() {
First = ICK_Identity;
Second = ICK_Identity;
Third = ICK_Identity;
DeprecatedStringLiteralToCharPtr = false;
QualificationIncludesObjCLifetime = false;
ReferenceBinding = false;
DirectBinding = false;
IsLvalueReference = true;
BindsToFunctionLvalue = false;
BindsToRvalue = false;
BindsImplicitObjectArgumentWithoutRefQualifier = false;
ObjCLifetimeConversionBinding = false;
CopyConstructor = 0;
}
/// getRank - Retrieve the rank of this standard conversion sequence
/// (C++ 13.3.3.1.1p3). The rank is the largest rank of each of the
/// implicit conversions.
ImplicitConversionRank StandardConversionSequence::getRank() const {
ImplicitConversionRank Rank = ICR_Exact_Match;
if (GetConversionRank(First) > Rank)
Rank = GetConversionRank(First);
if (GetConversionRank(Second) > Rank)
Rank = GetConversionRank(Second);
if (GetConversionRank(Third) > Rank)
Rank = GetConversionRank(Third);
return Rank;
}
/// 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
/// (C++ 13.3.3.2p4).
bool StandardConversionSequence::isPointerConversionToBool() const {
// Note that FromType has not necessarily been transformed by the
// array-to-pointer or function-to-pointer implicit conversions, so
// check for their presence as well as checking whether FromType is
// a pointer.
if (getToType(1)->isBooleanType() &&
(getFromType()->isPointerType() ||
getFromType()->isObjCObjectPointerType() ||
getFromType()->isBlockPointerType() ||
getFromType()->isNullPtrType() ||
First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer))
return true;
return false;
}
/// isPointerConversionToVoidPointer - Determines whether this
/// 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
StandardConversionSequence::
isPointerConversionToVoidPointer(ASTContext& Context) const {
QualType FromType = getFromType();
QualType ToType = getToType(1);
// Note that FromType has not necessarily been transformed by the
// array-to-pointer implicit conversion, so check for its presence
// and redo the conversion to get a pointer.
if (First == ICK_Array_To_Pointer)
FromType = Context.getArrayDecayedType(FromType);
if (Second == ICK_Pointer_Conversion && FromType->isAnyPointerType())
if (const PointerType* ToPtrType = ToType->getAs<PointerType>())
return ToPtrType->getPointeeType()->isVoidType();
return false;
}
/// Skip any implicit casts which could be either part of a narrowing conversion
/// or after one in an implicit conversion.
static const Expr *IgnoreNarrowingConversion(const Expr *Converted) {
while (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Converted)) {
switch (ICE->getCastKind()) {
case CK_NoOp:
case CK_IntegralCast:
case CK_IntegralToBoolean:
case CK_IntegralToFloating:
case CK_FloatingToIntegral:
case CK_FloatingToBoolean:
case CK_FloatingCast:
Converted = ICE->getSubExpr();
continue;
default:
return Converted;
}
}
return Converted;
}
/// Check if this standard conversion sequence represents a narrowing
/// conversion, according to C++11 [dcl.init.list]p7.
///
/// \param Ctx The AST context.
/// \param Converted The result of applying this standard conversion sequence.
/// \param ConstantValue If this is an NK_Constant_Narrowing conversion, the
/// value of the expression prior to the narrowing conversion.
/// \param ConstantType If this is an NK_Constant_Narrowing conversion, the
/// type of the expression prior to the narrowing conversion.
NarrowingKind
StandardConversionSequence::getNarrowingKind(ASTContext &Ctx,
const Expr *Converted,
APValue &ConstantValue,
QualType &ConstantType) const {
assert(Ctx.getLangOpts().CPlusPlus && "narrowing check outside C++");
// C++11 [dcl.init.list]p7:
// A narrowing conversion is an implicit conversion ...
QualType FromType = getToType(0);
QualType ToType = getToType(1);
switch (Second) {
// -- from a floating-point type to an integer type, or
//
// -- from an integer type or unscoped enumeration type to a floating-point
// type, except where the source is a constant expression and the actual
// value after conversion will fit into the target type and will produce
// the original value when converted back to the original type, or
case ICK_Floating_Integral:
if (FromType->isRealFloatingType() && ToType->isIntegralType(Ctx)) {
return NK_Type_Narrowing;
} else if (FromType->isIntegralType(Ctx) && ToType->isRealFloatingType()) {
llvm::APSInt IntConstantValue;
const Expr *Initializer = IgnoreNarrowingConversion(Converted);
if (Initializer &&
Initializer->isIntegerConstantExpr(IntConstantValue, Ctx)) {
// Convert the integer to the floating type.
llvm::APFloat Result(Ctx.getFloatTypeSemantics(ToType));
Result.convertFromAPInt(IntConstantValue, IntConstantValue.isSigned(),
llvm::APFloat::rmNearestTiesToEven);
// And back.
llvm::APSInt ConvertedValue = IntConstantValue;
bool ignored;
Result.convertToInteger(ConvertedValue,
llvm::APFloat::rmTowardZero, &ignored);
// If the resulting value is different, this was a narrowing conversion.
if (IntConstantValue != ConvertedValue) {
ConstantValue = APValue(IntConstantValue);
ConstantType = Initializer->getType();
return NK_Constant_Narrowing;
}
} else {
// Variables are always narrowings.
return NK_Variable_Narrowing;
}
}
return NK_Not_Narrowing;
// -- from long double to double or float, or from double to float, except
// where the source is a constant expression and the actual value after
// conversion is within the range of values that can be represented (even
// if it cannot be represented exactly), or
case ICK_Floating_Conversion:
if (FromType->isRealFloatingType() && ToType->isRealFloatingType() &&
Ctx.getFloatingTypeOrder(FromType, ToType) == 1) {
// FromType is larger than ToType.
const Expr *Initializer = IgnoreNarrowingConversion(Converted);
if (Initializer->isCXX11ConstantExpr(Ctx, &ConstantValue)) {
// Constant!
assert(ConstantValue.isFloat());
llvm::APFloat FloatVal = ConstantValue.getFloat();
// Convert the source value into the target type.
bool ignored;
llvm::APFloat::opStatus ConvertStatus = FloatVal.convert(
Ctx.getFloatTypeSemantics(ToType),
llvm::APFloat::rmNearestTiesToEven, &ignored);
// If there was no overflow, the source value is within the range of
// values that can be represented.
if (ConvertStatus & llvm::APFloat::opOverflow) {
ConstantType = Initializer->getType();
return NK_Constant_Narrowing;
}
} else {
return NK_Variable_Narrowing;
}
}
return NK_Not_Narrowing;
// -- from an integer type or unscoped enumeration type to an integer type
// that cannot represent all the values of the original type, except where
// the source is a constant expression and the actual value after
// conversion will fit into the target type and will produce the original
// value when converted back to the original type.
case ICK_Boolean_Conversion: // Bools are integers too.
if (!FromType->isIntegralOrUnscopedEnumerationType()) {
// Boolean conversions can be from pointers and pointers to members
// [conv.bool], and those aren't considered narrowing conversions.
return NK_Not_Narrowing;
} // Otherwise, fall through to the integral case.
case ICK_Integral_Conversion: {
assert(FromType->isIntegralOrUnscopedEnumerationType());
assert(ToType->isIntegralOrUnscopedEnumerationType());
const bool FromSigned = FromType->isSignedIntegerOrEnumerationType();
const unsigned FromWidth = Ctx.getIntWidth(FromType);
const bool ToSigned = ToType->isSignedIntegerOrEnumerationType();
const unsigned ToWidth = Ctx.getIntWidth(ToType);
if (FromWidth > ToWidth ||
(FromWidth == ToWidth && FromSigned != ToSigned) ||
(FromSigned && !ToSigned)) {
// Not all values of FromType can be represented in ToType.
llvm::APSInt InitializerValue;
const Expr *Initializer = IgnoreNarrowingConversion(Converted);
if (!Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) {
// Such conversions on variables are always narrowing.
return NK_Variable_Narrowing;
}
bool Narrowing = false;
if (FromWidth < ToWidth) {
// Negative -> unsigned is narrowing. Otherwise, more bits is never
// narrowing.
if (InitializerValue.isSigned() && InitializerValue.isNegative())
Narrowing = true;
} else {
// Add a bit to the InitializerValue so we don't have to worry about
// signed vs. unsigned comparisons.
InitializerValue = InitializerValue.extend(
InitializerValue.getBitWidth() + 1);
// Convert the initializer to and from the target width and signed-ness.
llvm::APSInt ConvertedValue = InitializerValue;
ConvertedValue = ConvertedValue.trunc(ToWidth);
ConvertedValue.setIsSigned(ToSigned);
ConvertedValue = ConvertedValue.extend(InitializerValue.getBitWidth());
ConvertedValue.setIsSigned(InitializerValue.isSigned());
// If the result is different, this was a narrowing conversion.
if (ConvertedValue != InitializerValue)
Narrowing = true;
}
if (Narrowing) {
ConstantType = Initializer->getType();
ConstantValue = APValue(InitializerValue);
return NK_Constant_Narrowing;
}
}
return NK_Not_Narrowing;
}
default:
// Other kinds of conversions are not narrowings.
return NK_Not_Narrowing;
}
}
/// DebugPrint - Print this standard conversion sequence to standard
/// error. Useful for debugging overloading issues.
void StandardConversionSequence::DebugPrint() const {
raw_ostream &OS = llvm::errs();
bool PrintedSomething = false;
if (First != ICK_Identity) {
OS << GetImplicitConversionName(First);
PrintedSomething = true;
}
if (Second != ICK_Identity) {
if (PrintedSomething) {
OS << " -> ";
}
OS << GetImplicitConversionName(Second);
if (CopyConstructor) {
OS << " (by copy constructor)";
} else if (DirectBinding) {
OS << " (direct reference binding)";
} else if (ReferenceBinding) {
OS << " (reference binding)";
}
PrintedSomething = true;
}
if (Third != ICK_Identity) {
if (PrintedSomething) {
OS << " -> ";
}
OS << GetImplicitConversionName(Third);
PrintedSomething = true;
}
if (!PrintedSomething) {
OS << "No conversions required";
}
}
/// DebugPrint - Print this user-defined conversion sequence to standard
/// error. Useful for debugging overloading issues.
void UserDefinedConversionSequence::DebugPrint() const {
raw_ostream &OS = llvm::errs();
if (Before.First || Before.Second || Before.Third) {
Before.DebugPrint();
OS << " -> ";
}
if (ConversionFunction)
OS << '\'' << *ConversionFunction << '\'';
else
OS << "aggregate initialization";
if (After.First || After.Second || After.Third) {
OS << " -> ";
After.DebugPrint();
}
}
/// DebugPrint - Print this implicit conversion sequence to standard
/// error. Useful for debugging overloading issues.
void ImplicitConversionSequence::DebugPrint() const {
raw_ostream &OS = llvm::errs();
switch (ConversionKind) {
case StandardConversion:
OS << "Standard conversion: ";
Standard.DebugPrint();
break;
case UserDefinedConversion:
OS << "User-defined conversion: ";
UserDefined.DebugPrint();
break;
case EllipsisConversion:
OS << "Ellipsis conversion";
break;
case AmbiguousConversion:
OS << "Ambiguous conversion";
break;
case BadConversion:
OS << "Bad conversion";
break;
}
OS << "\n";
}
void AmbiguousConversionSequence::construct() {
new (&conversions()) ConversionSet();
}
void AmbiguousConversionSequence::destruct() {
conversions().~ConversionSet();
}
void
AmbiguousConversionSequence::copyFrom(const AmbiguousConversionSequence &O) {
FromTypePtr = O.FromTypePtr;
ToTypePtr = O.ToTypePtr;
new (&conversions()) ConversionSet(O.conversions());
}
namespace {
// Structure used by OverloadCandidate::DeductionFailureInfo to store
// template parameter and template argument information.
struct DFIParamWithArguments {
TemplateParameter Param;
TemplateArgument FirstArg;
TemplateArgument SecondArg;
};
}
/// \brief Convert from Sema's representation of template deduction information
/// to the form used in overload-candidate information.
OverloadCandidate::DeductionFailureInfo
static MakeDeductionFailureInfo(ASTContext &Context,
Sema::TemplateDeductionResult TDK,
TemplateDeductionInfo &Info) {
OverloadCandidate::DeductionFailureInfo Result;
Result.Result = static_cast<unsigned>(TDK);
Result.HasDiagnostic = false;
Result.Data = 0;
switch (TDK) {
case Sema::TDK_Success:
case Sema::TDK_InstantiationDepth:
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
break;
case Sema::TDK_Incomplete:
case Sema::TDK_InvalidExplicitArguments:
Result.Data = Info.Param.getOpaqueValue();
break;
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified: {
// FIXME: Should allocate from normal heap so that we can free this later.
DFIParamWithArguments *Saved = new (Context) DFIParamWithArguments;
Saved->Param = Info.Param;
Saved->FirstArg = Info.FirstArg;
Saved->SecondArg = Info.SecondArg;
Result.Data = Saved;
break;
}
case Sema::TDK_SubstitutionFailure:
Result.Data = Info.take();
if (Info.hasSFINAEDiagnostic()) {
PartialDiagnosticAt *Diag = new (Result.Diagnostic) PartialDiagnosticAt(
SourceLocation(), PartialDiagnostic::NullDiagnostic());
Info.takeSFINAEDiagnostic(*Diag);
Result.HasDiagnostic = true;
}
break;
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
return Result;
}
void OverloadCandidate::DeductionFailureInfo::Destroy() {
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
case Sema::TDK_Success:
case Sema::TDK_InstantiationDepth:
case Sema::TDK_Incomplete:
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
case Sema::TDK_InvalidExplicitArguments:
break;
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified:
// FIXME: Destroy the data?
Data = 0;
break;
case Sema::TDK_SubstitutionFailure:
// FIXME: Destroy the template argument list?
Data = 0;
if (PartialDiagnosticAt *Diag = getSFINAEDiagnostic()) {
Diag->~PartialDiagnosticAt();
HasDiagnostic = false;
}
break;
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
}
PartialDiagnosticAt *
OverloadCandidate::DeductionFailureInfo::getSFINAEDiagnostic() {
if (HasDiagnostic)
return static_cast<PartialDiagnosticAt*>(static_cast<void*>(Diagnostic));
return 0;
}
TemplateParameter
OverloadCandidate::DeductionFailureInfo::getTemplateParameter() {
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
case Sema::TDK_Success:
case Sema::TDK_InstantiationDepth:
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
case Sema::TDK_SubstitutionFailure:
return TemplateParameter();
case Sema::TDK_Incomplete:
case Sema::TDK_InvalidExplicitArguments:
return TemplateParameter::getFromOpaqueValue(Data);
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified:
return static_cast<DFIParamWithArguments*>(Data)->Param;
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
return TemplateParameter();
}
TemplateArgumentList *
OverloadCandidate::DeductionFailureInfo::getTemplateArgumentList() {
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
case Sema::TDK_Success:
case Sema::TDK_InstantiationDepth:
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
case Sema::TDK_Incomplete:
case Sema::TDK_InvalidExplicitArguments:
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified:
return 0;
case Sema::TDK_SubstitutionFailure:
return static_cast<TemplateArgumentList*>(Data);
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
return 0;
}
const TemplateArgument *OverloadCandidate::DeductionFailureInfo::getFirstArg() {
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
case Sema::TDK_Success:
case Sema::TDK_InstantiationDepth:
case Sema::TDK_Incomplete:
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
case Sema::TDK_InvalidExplicitArguments:
case Sema::TDK_SubstitutionFailure:
return 0;
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified:
return &static_cast<DFIParamWithArguments*>(Data)->FirstArg;
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
return 0;
}
const TemplateArgument *
OverloadCandidate::DeductionFailureInfo::getSecondArg() {
switch (static_cast<Sema::TemplateDeductionResult>(Result)) {
case Sema::TDK_Success:
case Sema::TDK_InstantiationDepth:
case Sema::TDK_Incomplete:
case Sema::TDK_TooManyArguments:
case Sema::TDK_TooFewArguments:
case Sema::TDK_InvalidExplicitArguments:
case Sema::TDK_SubstitutionFailure:
return 0;
case Sema::TDK_Inconsistent:
case Sema::TDK_Underqualified:
return &static_cast<DFIParamWithArguments*>(Data)->SecondArg;
// Unhandled
case Sema::TDK_NonDeducedMismatch:
case Sema::TDK_FailedOverloadResolution:
break;
}
return 0;
}
void OverloadCandidateSet::clear() {
for (iterator i = begin(), e = end(); i != e; ++i)
for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii)
i->Conversions[ii].~ImplicitConversionSequence();
NumInlineSequences = 0;
Candidates.clear();
Functions.clear();
}
namespace {
class UnbridgedCastsSet {
struct Entry {
Expr **Addr;
Expr *Saved;
};
SmallVector<Entry, 2> Entries;
public:
void save(Sema &S, Expr *&E) {
assert(E->hasPlaceholderType(BuiltinType::ARCUnbridgedCast));
Entry entry = { &E, E };
Entries.push_back(entry);
E = S.stripARCUnbridgedCast(E);
}
void restore() {
for (SmallVectorImpl<Entry>::iterator
i = Entries.begin(), e = Entries.end(); i != e; ++i)
*i->Addr = i->Saved;
}
};
}
/// checkPlaceholderForOverload - Do any interesting placeholder-like
/// preprocessing on the given expression.
///
/// \param unbridgedCasts a collection to which to add unbridged casts;
/// without this, they will be immediately diagnosed as errors
///
/// Return true on unrecoverable error.
static bool checkPlaceholderForOverload(Sema &S, Expr *&E,
UnbridgedCastsSet *unbridgedCasts = 0) {
if (const BuiltinType *placeholder = E->getType()->getAsPlaceholderType()) {
// We can't handle overloaded expressions here because overload
// resolution might reasonably tweak them.
if (placeholder->getKind() == BuiltinType::Overload) return false;
// If the context potentially accepts unbridged ARC casts, strip
// the unbridged cast and add it to the collection for later restoration.
if (placeholder->getKind() == BuiltinType::ARCUnbridgedCast &&
unbridgedCasts) {
unbridgedCasts->save(S, E);
return false;
}
// Go ahead and check everything else.
ExprResult result = S.CheckPlaceholderExpr(E);
if (result.isInvalid())
return true;
E = result.take();
return false;
}
// Nothing to do.
return false;
}
/// checkArgPlaceholdersForOverload - Check a set of call operands for
/// placeholders.
static bool checkArgPlaceholdersForOverload(Sema &S, Expr **args,
unsigned numArgs,
UnbridgedCastsSet &unbridged) {
for (unsigned i = 0; i != numArgs; ++i)
if (checkPlaceholderForOverload(S, args[i], &unbridged))
return true;
return false;
}
// IsOverload - Determine whether the given New declaration is an
// overload of the declarations in Old. This routine returns false if
// New and Old cannot be overloaded, e.g., if New has the same
// signature as some function in Old (C++ 1.3.10) or if the Old
// declarations aren't functions (or function templates) at all. When
// it does return false, MatchedDecl will point to the decl that New
// cannot be overloaded with. This decl may be a UsingShadowDecl on
// top of the underlying declaration.
//
// Example: Given the following input:
//
// void f(int, float); // #1
// void f(int, int); // #2
// int f(int, int); // #3
//
// When we process #1, there is no previous declaration of "f",
// so IsOverload will not be used.
//
// When we process #2, Old contains only the FunctionDecl for #1. By
// comparing the parameter types, we see that #1 and #2 are overloaded
// (since they have different signatures), so this routine returns
// false; MatchedDecl is unchanged.
//
// When we process #3, Old is an overload set containing #1 and #2. We
// compare the signatures of #3 to #1 (they're overloaded, so we do
// nothing) and then #3 to #2. Since the signatures of #3 and #2 are
// identical (return types of functions are not part of the
// signature), IsOverload returns false and MatchedDecl will be set to
// point to the FunctionDecl for #2.
//
// 'NewIsUsingShadowDecl' indicates that 'New' is being introduced
// into a class by a using declaration. The rules for whether to hide
// shadow declarations ignore some properties which otherwise figure
// into a function template's signature.
Sema::OverloadKind
Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
NamedDecl *&Match, bool NewIsUsingDecl) {
for (LookupResult::iterator I = Old.begin(), E = Old.end();
I != E; ++I) {
NamedDecl *OldD = *I;
bool OldIsUsingDecl = false;
if (isa<UsingShadowDecl>(OldD)) {
OldIsUsingDecl = true;
// We can always introduce two using declarations into the same
// context, even if they have identical signatures.
if (NewIsUsingDecl) continue;
OldD = cast<UsingShadowDecl>(OldD)->getTargetDecl();
}
// If either declaration was introduced by a using declaration,
// we'll need to use slightly different rules for matching.
// Essentially, these rules are the normal rules, except that
// function templates hide function templates with different
// return types or template parameter lists.
bool UseMemberUsingDeclRules =
(OldIsUsingDecl || NewIsUsingDecl) && CurContext->isRecord();
if (FunctionTemplateDecl *OldT = dyn_cast<FunctionTemplateDecl>(OldD)) {
if (!IsOverload(New, OldT->getTemplatedDecl(), UseMemberUsingDeclRules)) {
if (UseMemberUsingDeclRules && OldIsUsingDecl) {
HideUsingShadowDecl(S, cast<UsingShadowDecl>(*I));
continue;
}
Match = *I;
return Ovl_Match;
}
} else if (FunctionDecl *OldF = dyn_cast<FunctionDecl>(OldD)) {
if (!IsOverload(New, OldF, UseMemberUsingDeclRules)) {
if (UseMemberUsingDeclRules && OldIsUsingDecl) {
HideUsingShadowDecl(S, cast<UsingShadowDecl>(*I));
continue;
}
Match = *I;
return Ovl_Match;
}
} else if (isa<UsingDecl>(OldD)) {
// We can overload with these, which can show up when doing
// redeclaration checks for UsingDecls.
assert(Old.getLookupKind() == LookupUsingDeclName);
} else if (isa<TagDecl>(OldD)) {
// We can always overload with tags by hiding them.
} else if (isa<UnresolvedUsingValueDecl>(OldD)) {
// Optimistically assume that an unresolved using decl will
// overload; if it doesn't, we'll have to diagnose during
// template instantiation.
} else {
// (C++ 13p1):
// Only function declarations can be overloaded; object and type
// declarations cannot be overloaded.
Match = *I;
return Ovl_NonFunction;
}
}
return Ovl_Overload;
}
bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old,
bool UseUsingDeclRules) {
// If both of the functions are extern "C", then they are not
// overloads.
if (Old->isExternC() && New->isExternC())
return false;
FunctionTemplateDecl *OldTemplate = Old->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.
if ((OldTemplate == 0) != (NewTemplate == 0))
return true;
// Is the function New an overload of the function Old?
QualType OldQType = Context.getCanonicalType(Old->getType());
QualType NewQType = Context.getCanonicalType(New->getType());
// Compare the signatures (C++ 1.3.10) of the two functions to
// determine whether they are overloads. If we find any mismatch
// in the signature, they are overloads.
// If either of these functions is a K&R-style function (no
// prototype), then we consider them to have matching signatures.
if (isa<FunctionNoProtoType>(OldQType.getTypePtr()) ||
isa<FunctionNoProtoType>(NewQType.getTypePtr()))
return false;
const FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
const FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
// The signature of a function includes the types of its
// parameters (C++ 1.3.10), which includes the presence or absence
// of the ellipsis; see C++ DR 357).
if (OldQType != NewQType &&
(OldType->getNumArgs() != NewType->getNumArgs() ||
OldType->isVariadic() != NewType->isVariadic() ||
!FunctionArgTypesAreEqual(OldType, NewType)))
return true;
// C++ [temp.over.link]p4:
// 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
// signature.
//
// We check the return type and template parameter lists for function
// templates first; the remaining checks follow.
//
// However, we don't consider either of these when deciding whether
// a member introduced by a shadow declaration is hidden.
if (!UseUsingDeclRules && NewTemplate &&
(!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
OldTemplate->getTemplateParameters(),
false, TPL_TemplateMatch) ||
OldType->getResultType() != NewType->getResultType()))
return true;
// If the function is a class member, its signature includes the
// cv-qualifiers (if any) and ref-qualifier (if any) on the function itself.
//
// As part of this, also check whether one of the member functions
// is static, in which case they are not overloads (C++
// 13.1p2). While not part of the definition of the signature,
// this check is important to determine whether these functions
// can be overloaded.
CXXMethodDecl* OldMethod = dyn_cast<CXXMethodDecl>(Old);
CXXMethodDecl* NewMethod = dyn_cast<CXXMethodDecl>(New);
if (OldMethod && NewMethod &&
!OldMethod->isStatic() && !NewMethod->isStatic() &&
(OldMethod->getTypeQualifiers() != NewMethod->getTypeQualifiers() ||
OldMethod->getRefQualifier() != NewMethod->getRefQualifier())) {
if (!UseUsingDeclRules &&
OldMethod->getRefQualifier() != NewMethod->getRefQualifier() &&
(OldMethod->getRefQualifier() == RQ_None ||
NewMethod->getRefQualifier() == RQ_None)) {
// C++0x [over.load]p2:
// - Member function declarations with the same name and the same
// parameter-type-list as well as member function template
// declarations with the same name, the same parameter-type-list, and
// the same template parameter lists cannot be overloaded if any of
// them, but not all, have a ref-qualifier (8.3.5).
Diag(NewMethod->getLocation(), diag::err_ref_qualifier_overload)
<< NewMethod->getRefQualifier() << OldMethod->getRefQualifier();
Diag(OldMethod->getLocation(), diag::note_previous_declaration);
}
return true;
}
// The signatures match; this is not an overload.
return false;
}
/// \brief Checks availability of the function depending on the current
/// function context. Inside an unavailable function, unavailability is ignored.
///
/// \returns true if \arg FD is unavailable and current context is inside
/// an available function, false otherwise.
bool Sema::isFunctionConsideredUnavailable(FunctionDecl *FD) {
return FD->isUnavailable() && !cast<Decl>(CurContext)->isUnavailable();
}
/// \brief Tries a user-defined conversion from From to ToType.
///
/// Produces an implicit conversion sequence for when a standard conversion
/// is not an option. See TryImplicitConversion for more information.
static ImplicitConversionSequence
TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
bool SuppressUserConversions,
bool AllowExplicit,
bool InOverloadResolution,
bool CStyle,
bool AllowObjCWritebackConversion) {
ImplicitConversionSequence ICS;
if (SuppressUserConversions) {
// We're not in the case above, so there is no conversion that
// we can perform.
ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
return ICS;
}
// Attempt user-defined conversion.
OverloadCandidateSet Conversions(From->getExprLoc());
OverloadingResult UserDefResult
= IsUserDefinedConversion(S, From, ToType, ICS.UserDefined, Conversions,
AllowExplicit);
if (UserDefResult == OR_Success) {
ICS.setUserDefined();
// C++ [over.ics.user]p4:
// A conversion of an expression of class type to the same class
// type is given Exact Match rank, and a conversion of an
// expression of class type to a base class of that type is
// 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
= dyn_cast<CXXConstructorDecl>(ICS.UserDefined.ConversionFunction)) {
QualType FromCanon
= S.Context.getCanonicalType(From->getType().getUnqualifiedType());
QualType ToCanon
= S.Context.getCanonicalType(ToType).getUnqualifiedType();
if (Constructor->isCopyConstructor() &&
(FromCanon == ToCanon || S.IsDerivedFrom(FromCanon, ToCanon))) {
// Turn this into a "standard" conversion sequence, so that it
// gets ranked with standard conversion sequences.
ICS.setStandard();
ICS.Standard.setAsIdentityConversion();
ICS.Standard.setFromType(From->getType());
ICS.Standard.setAllToTypes(ToType);
ICS.Standard.CopyConstructor = Constructor;
if (ToCanon != FromCanon)
ICS.Standard.Second = ICK_Derived_To_Base;
}
}
// C++ [over.best.ics]p4:
// However, when considering the argument of a user-defined
// conversion function that is a candidate by 13.3.1.3 when
// invoked for the copying of the temporary in the second step
// of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or
// 13.3.1.6 in all cases, only standard conversion sequences and
// ellipsis conversion sequences are allowed.
if (SuppressUserConversions && ICS.isUserDefined()) {
ICS.setBad(BadConversionSequence::suppressed_user, From, ToType);
}
} else if (UserDefResult == OR_Ambiguous && !SuppressUserConversions) {
ICS.setAmbiguous();
ICS.Ambiguous.setFromType(From->getType());
ICS.Ambiguous.setToType(ToType);
for (OverloadCandidateSet::iterator Cand = Conversions.begin();
Cand != Conversions.end(); ++Cand)
if (Cand->Viable)
ICS.Ambiguous.addConversion(Cand->Function);
} else {
ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
}
return ICS;
}
/// TryImplicitConversion - Attempt to perform an implicit conversion
/// from the given expression (Expr) to the given type (ToType). This
/// function returns an implicit conversion sequence that can be used
/// to perform the initialization. Given
///
/// void f(float f);
/// void g(int i) { f(i); }
///
/// this routine would produce an implicit conversion sequence to
/// describe the initialization of f from i, which will be a standard
/// conversion sequence containing an lvalue-to-rvalue conversion (C++
/// 4.1) followed by a floating-integral conversion (C++ 4.9).
//
/// Note that this routine only determines how the conversion can be
/// performed; it does not actually perform the conversion. As such,
/// it will not produce any diagnostics if no conversion is available,
/// but will instead return an implicit conversion sequence of kind
/// "BadConversion".
///
/// If @p SuppressUserConversions, then user-defined conversions are
/// not permitted.
/// If @p AllowExplicit, then explicit user-defined conversions are
/// permitted.
///
/// \param AllowObjCWritebackConversion Whether we allow the Objective-C
/// writeback conversion, which allows __autoreleasing id* parameters to
/// be initialized with __strong id* or __weak id* arguments.
static ImplicitConversionSequence
TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
bool SuppressUserConversions,
bool AllowExplicit,
bool InOverloadResolution,
bool CStyle,
bool AllowObjCWritebackConversion) {
ImplicitConversionSequence ICS;
if (IsStandardConversion(S, From, ToType, InOverloadResolution,
ICS.Standard, CStyle, AllowObjCWritebackConversion)){
ICS.setStandard();
return ICS;
}
if (!S.getLangOpts().CPlusPlus) {
ICS.setBad(BadConversionSequence::no_conversion, From, ToType);
return ICS;
}
// C++ [over.ics.user]p4:
// A conversion of an expression of class type to the same class
// type is given Exact Match rank, and a conversion of an
// expression of class type to a base class of that type is
// given Conversion rank, in spite of the fact that a copy/move
// constructor (i.e., a user-defined conversion function) is
// called for those cases.
QualType FromType = From->getType();
if (ToType->getAs<RecordType>() && FromType->getAs<RecordType>() &&
(S.Context.hasSameUnqualifiedType(FromType, ToType) ||
S.IsDerivedFrom(FromType, ToType))) {
ICS.setStandard();
ICS.Standard.setAsIdentityConversion();
ICS.Standard.setFromType(FromType);
ICS.Standard.setAllToTypes(ToType);
// We don't actually check at this point whether there is a valid
// copy/move constructor, since overloading just assumes that it
// exists. When we actually perform initialization, we'll find the
// appropriate constructor to copy the returned object, if needed.
ICS.Standard.CopyConstructor = 0;
// Determine whether this is considered a derived-to-base conversion.
if (!S.Context.hasSameUnqualifiedType(FromType, ToType))
ICS.Standard.Second = ICK_Derived_To_Base;
return ICS;
}
return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions,
AllowExplicit, InOverloadResolution, CStyle,
AllowObjCWritebackConversion);
}
ImplicitConversionSequence
Sema::TryImplicitConversion(Expr *From, QualType ToType,
bool SuppressUserConversions,
bool AllowExplicit,
bool InOverloadResolution,
bool CStyle,
bool AllowObjCWritebackConversion) {
return clang::TryImplicitConversion(*this, From, ToType,
SuppressUserConversions, AllowExplicit,
InOverloadResolution, CStyle,
AllowObjCWritebackConversion);
}
/// PerformImplicitConversion - Perform an implicit conversion of the
/// expression From to the type ToType. Returns the
/// converted expression. Flavor is the kind of conversion we're
/// performing, used in the error message. If @p AllowExplicit,
/// explicit user-defined conversions are permitted.
ExprResult
Sema::PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action, bool AllowExplicit) {
ImplicitConversionSequence ICS;
return PerformImplicitConversion(From, ToType, Action, AllowExplicit, ICS);
}
ExprResult
Sema::PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action, bool AllowExplicit,
ImplicitConversionSequence& ICS) {
if (checkPlaceholderForOverload(*this, From))
return ExprError();
// Objective-C ARC: Determine whether we will allow the writeback conversion.
bool AllowObjCWritebackConversion
= getLangOpts().ObjCAutoRefCount &&
(Action == AA_Passing || Action == AA_Sending);
ICS = clang::TryImplicitConversion(*this, From, ToType,
/*SuppressUserConversions=*/false,
AllowExplicit,
/*InOverloadResolution=*/false,
/*CStyle=*/false,
AllowObjCWritebackConversion);
return PerformImplicitConversion(From, ToType, ICS, Action);
}
/// \brief Determine whether the conversion from FromType to ToType is a valid
/// conversion that strips "noreturn" off the nested function type.
bool Sema::IsNoReturnConversion(QualType FromType, QualType ToType,
QualType &ResultTy) {
if (Context.hasSameUnqualifiedType(FromType, ToType))
return false;
// Permit the conversion F(t __attribute__((noreturn))) -> F(t)
// where F adds one of the following at most once:
// - a pointer
// - a member pointer
// - a block pointer
CanQualType CanTo = Context.getCanonicalType(ToType);
CanQualType CanFrom = Context.getCanonicalType(FromType);
Type::TypeClass TyClass = CanTo->getTypeClass();
if (TyClass != CanFrom->getTypeClass()) return false;
if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto) {
if (TyClass == Type::Pointer) {
CanTo = CanTo.getAs<PointerType>()->getPointeeType();
CanFrom = CanFrom.getAs<PointerType>()->getPointeeType();
} else if (TyClass == Type::BlockPointer) {
CanTo = CanTo.getAs<BlockPointerType>()->getPointeeType();
CanFrom = CanFrom.getAs<BlockPointerType>()->getPointeeType();
} else if (TyClass == Type::MemberPointer) {
CanTo = CanTo.getAs<MemberPointerType>()->getPointeeType();
CanFrom = CanFrom.getAs<MemberPointerType>()->getPointeeType();
} else {
return false;
}
TyClass = CanTo->getTypeClass();
if (TyClass != CanFrom->getTypeClass()) return false;
if (TyClass != Type::FunctionProto && TyClass != Type::FunctionNoProto)
return false;
}
const FunctionType *FromFn = cast<FunctionType>(CanFrom);
FunctionType::ExtInfo EInfo = FromFn->getExtInfo();
if (!EInfo.getNoReturn()) return false;
FromFn = Context.adjustFunctionType(FromFn, EInfo.withNoReturn(false));
assert(QualType(FromFn, 0).isCanonical());
if (QualType(FromFn, 0) != CanTo) return false;
ResultTy = ToType;
return true;
}
/// \brief Determine whether the conversion from FromType to ToType is a valid
/// vector conversion.
///
/// \param ICK Will be set to the vector conversion kind, if this is a vector
/// conversion.
static bool IsVectorConversion(ASTContext &Context, QualType FromType,
QualType ToType, ImplicitConversionKind &ICK) {
// We need at least one of these types to be a vector type to have a vector
// conversion.
if (!ToType->isVectorType() && !FromType->isVectorType())
return false;
// Identical types require no conversions.
if (Context.hasSameUnqualifiedType(FromType, ToType))
return false;
// There are no conversions between extended vector types, only identity.
if (ToType->isExtVectorType()) {
// There are no conversions between extended vector types other than the
// identity conversion.
if (FromType->isExtVectorType())
return false;
// Vector splat from any arithmetic type to a vector.
if (FromType->isArithmeticType()) {
ICK = ICK_Vector_Splat;
return true;
}
}
// We can perform the conversion between vector types in the following cases:
// 1)vector types are equivalent AltiVec and GCC vector types
// 2)lax vector conversions are permitted and the vector types are of the
// same size
if (ToType->isVectorType() && FromType->isVectorType()) {
if (Context.areCompatibleVectorTypes(FromType, ToType) ||
(Context.getLangOpts().LaxVectorConversions &&
(Context.getTypeSize(FromType) == Context.getTypeSize(ToType)))) {
ICK = ICK_Vector_Conversion;
return true;
}
}
return false;
}
static bool tryAtomicConversion(Sema &S, Expr *From, QualType ToType,
bool InOverloadResolution,
StandardConversionSequence &SCS,
bool CStyle);
/// IsStandardConversion - Determines whether there is a standard
/// conversion sequence (C++ [conv], C++ [over.ics.scs]) from the
/// expression From to the type ToType. Standard conversion sequences
/// only consider non-class types; for conversions that involve class
/// types, use TryImplicitConversion. If a conversion exists, SCS will
/// 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.
static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
bool InOverloadResolution,
StandardConversionSequence &SCS,
bool CStyle,
bool AllowObjCWritebackConversion) {
QualType FromType = From->getType();
// Standard conversions (C++ [conv])
SCS.setAsIdentityConversion();
SCS.DeprecatedStringLiteralToCharPtr = false;
SCS.IncompatibleObjC = false;
SCS.setFromType(FromType);
SCS.CopyConstructor = 0;
// There are no standard conversions for class types in C++, so
// abort early. When overloading in C, however, we do permit
if (FromType->isRecordType() || ToType->isRecordType()) {
if (S.getLangOpts().CPlusPlus)
return false;
// 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).
if (FromType == S.Context.OverloadTy) {
DeclAccessPair AccessPair;
if (FunctionDecl *Fn
= S.ResolveAddressOfOverloadedFunction(From, ToType, false,
AccessPair)) {
// We were able to resolve the address of the overloaded function,
// so we can convert to the type of that function.
FromType = Fn->getType();
// we can sometimes resolve &foo<int> regardless of ToType, so check
// if the type matches (identity) or we are converting to bool
if (!S.Context.hasSameUnqualifiedType(
S.ExtractUnqualifiedFunctionType(ToType), FromType)) {
QualType resultTy;
// if the function type matches except for [[noreturn]], it's ok
if (!S.IsNoReturnConversion(FromType,
S.ExtractUnqualifiedFunctionType(ToType), resultTy))
// otherwise, only a boolean conversion is standard
if (!ToType->isBooleanType())
return false;
}
// Check if the "from" expression is taking the address of an overloaded
// function and recompute the FromType accordingly. Take advantage of the
// fact that non-static member functions *must* have such an address-of
// expression.
CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn);
if (Method && !Method->isStatic()) {
assert(isa<UnaryOperator>(From->IgnoreParens()) &&
"Non-unary operator on non-static member address");
assert(cast<UnaryOperator>(From->IgnoreParens())->getOpcode()
== UO_AddrOf &&
"Non-address-of operator on non-static member address");
const Type *ClassType
= S.Context.getTypeDeclType(Method->getParent()).getTypePtr();
FromType = S.Context.getMemberPointerType(FromType, ClassType);
} else if (isa<UnaryOperator>(From->IgnoreParens())) {
assert(cast<UnaryOperator>(From->IgnoreParens())->getOpcode() ==
UO_AddrOf &&
"Non-address-of operator for overloaded function expression");
FromType = S.Context.getPointerType(FromType);
}
// Check that we've computed the proper type after overload resolution.
assert(S.Context.hasSameType(
FromType,
S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType()));
} else {
return false;
}
}
// Lvalue-to-rvalue conversion (C++11 4.1):
// A glvalue (3.10) of a non-function, non-array type T can
// be converted to a prvalue.
bool argIsLValue = From->isGLValue();
if (argIsLValue &&
!FromType->isFunctionType() && !FromType->isArrayType() &&
S.Context.getCanonicalType(FromType) != S.Context.OverloadTy) {
SCS.First = ICK_Lvalue_To_Rvalue;
// C11 6.3.2.1p2:
// ... if the lvalue has atomic type, the value has the non-atomic version
// of the type of the lvalue ...
if (const AtomicType *Atomic = FromType->getAs<AtomicType>())
FromType = Atomic->getValueType();
// If T is a non-class type, the type of the rvalue is the
// cv-unqualified version of T. Otherwise, the type of the rvalue
// is T (C++ 4.1p1). C++ can't get here with class types; in C, we
// just strip the qualifiers because they don't matter.
FromType = FromType.getUnqualifiedType();
} 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
// bound of T" can be converted to an rvalue of type "pointer to
// T" (C++ 4.2p1).
FromType = S.Context.getArrayDecayedType(FromType);
if (S.IsStringLiteralToNonConstPointerConversion(From, ToType)) {
// This conversion is deprecated. (C++ D.4).
SCS.DeprecatedStringLiteralToCharPtr = true;
// For the purpose of ranking in overload resolution
// (13.3.3.1.1), this conversion is considered an
// array-to-pointer conversion followed by a qualification
// conversion (4.4). (C++ 4.2p2)
SCS.Second = ICK_Identity;
SCS.Third = ICK_Qualification;
SCS.QualificationIncludesObjCLifetime = false;
SCS.setAllToTypes(FromType);
return true;
}
} else if (FromType->isFunctionType() && argIsLValue) {
// 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 = S.Context.getPointerType(FromType);
} else {
// We don't require any conversions for the first step.
SCS.First = ICK_Identity;
}
SCS.setToType(0, FromType);
// The second conversion can be an integral promotion, floating
// point promotion, integral conversion, floating point conversion,
// floating-integral conversion, pointer conversion,
// pointer-to-member conversion, or boolean conversion (C++ 4p1).
// For overloading in C, this can also be a "compatible-type"
// conversion.
bool IncompatibleObjC = false;
ImplicitConversionKind SecondICK = ICK_Identity;
if (S.Context.hasSameUnqualifiedType(FromType, ToType)) {
// The unqualified versions of the types are the same: there's no
// conversion to do.
SCS.Second = ICK_Identity;
} else if (S.IsIntegralPromotion(From, FromType, ToType)) {
// Integral promotion (C++ 4.5).
SCS.Second = ICK_Integral_Promotion;
FromType = ToType.getUnqualifiedType();
} else if (S.IsFloatingPointPromotion(FromType, ToType)) {
// Floating point promotion (C++ 4.6).
SCS.Second = ICK_Floating_Promotion;
FromType = ToType.getUnqualifiedType();
} else if (S.IsComplexPromotion(FromType, ToType)) {
// Complex promotion (Clang extension)
SCS.Second = ICK_Complex_Promotion;
FromType = ToType.getUnqualifiedType();
} else if (ToType->isBooleanType() &&
(FromType->isArithmeticType() ||
FromType->isAnyPointerType() ||
FromType->isBlockPointerType() ||
FromType->isMemberPointerType() ||
FromType->isNullPtrType())) {
// Boolean conversions (C++ 4.12).
SCS.Second = ICK_Boolean_Conversion;
FromType = S.Context.BoolTy;
} else if (FromType->isIntegralOrUnscopedEnumerationType() &&
ToType->isIntegralType(S.Context)) {
// Integral conversions (C++ 4.7).
SCS.Second = ICK_Integral_Conversion;
FromType = ToType.getUnqualifiedType();
} else if (FromType->isAnyComplexType() && ToType->isComplexType()) {
// Complex conversions (C99 6.3.1.6)
SCS.Second = ICK_Complex_Conversion;
FromType = ToType.getUnqualifiedType();
} else if ((FromType->isAnyComplexType() && ToType->isArithmeticType()) ||
(ToType->isAnyComplexType() && FromType->isArithmeticType())) {
// Complex-real conversions (C99 6.3.1.7)
SCS.Second = ICK_Complex_Real;
FromType = ToType.getUnqualifiedType();
} else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) {
// Floating point conversions (C++ 4.8).
SCS.Second = ICK_Floating_Conversion;
FromType = ToType.getUnqualifiedType();
} else if ((FromType->isRealFloatingType() &&
ToType->isIntegralType(S.Context)) ||
(FromType->isIntegralOrUnscopedEnumerationType() &&
ToType->isRealFloatingType())) {
// Floating-integral conversions (C++ 4.9).
SCS.Second = ICK_Floating_Integral;
FromType = ToType.getUnqualifiedType();
} else if (S.IsBlockPointerConversion(FromType, ToType, FromType)) {
SCS.Second = ICK_Block_Pointer_Conversion;
} else if (AllowObjCWritebackConversion &&
S.isObjCWritebackConversion(FromType, ToType, FromType)) {
SCS.Second = ICK_Writeback_Conversion;
} else if (S.IsPointerConversion(From, FromType, ToType, InOverloadResolution,
FromType, IncompatibleObjC)) {
// Pointer conversions (C++ 4.10).
SCS.Second = ICK_Pointer_Conversion;
SCS.IncompatibleObjC = IncompatibleObjC;
FromType = FromType.getUnqualifiedType();
} else if (S.IsMemberPointerConversion(From, FromType, ToType,
InOverloadResolution, FromType)) {
// Pointer to member conversions (4.11).
SCS.Second = ICK_Pointer_Member;
} else if (IsVectorConversion(S.Context, FromType, ToType, SecondICK)) {
SCS.Second = SecondICK;
FromType = ToType.getUnqualifiedType();
} else if (!S.getLangOpts().CPlusPlus &&
S.Context.typesAreCompatible(ToType, FromType)) {
// Compatible conversions (Clang extension for C function overloading)
SCS.Second = ICK_Compatible_Conversion;
FromType = ToType.getUnqualifiedType();
} else if (S.IsNoReturnConversion(FromType, ToType, FromType)) {
// Treat a conversion that strips "noreturn" as an identity conversion.
SCS.Second = ICK_NoReturn_Adjustment;
} else if (IsTransparentUnionStandardConversion(S, From, ToType,
InOverloadResolution,
SCS, CStyle)) {
SCS.Second = ICK_TransparentUnionConversion;
FromType = ToType;
} else if (tryAtomicConversion(S, From, ToType, InOverloadResolution, SCS,
CStyle)) {
// tryAtomicConversion has updated the standard conversion sequence
// appropriately.
return true;
} else {
// No second conversion required.
SCS.Second = ICK_Identity;
}
SCS.setToType(1, FromType);
QualType CanonFrom;
QualType CanonTo;
// The third conversion can be a qualification conversion (C++ 4p1).
bool ObjCLifetimeConversion;
if (S.IsQualificationConversion(FromType, ToType, CStyle,
ObjCLifetimeConversion)) {
SCS.Third = ICK_Qualification;
SCS.QualificationIncludesObjCLifetime = ObjCLifetimeConversion;
FromType = ToType;
CanonFrom = S.Context.getCanonicalType(FromType);
CanonTo = S.Context.getCanonicalType(ToType);
} else {
// No conversion required
SCS.Third = ICK_Identity;
// 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 = S.Context.getCanonicalType(FromType);
CanonTo = S.Context.getCanonicalType(ToType);
if (CanonFrom.getLocalUnqualifiedType()
== CanonTo.getLocalUnqualifiedType() &&
(CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers()
|| CanonFrom.getObjCGCAttr() != CanonTo.getObjCGCAttr()
|| CanonFrom.getObjCLifetime() != CanonTo.getObjCLifetime())) {
FromType = ToType;
CanonFrom = CanonTo;
}
}
SCS.setToType(2, FromType);
// If we have not converted the argument type to the parameter type,
// this is a bad conversion sequence.
if (CanonFrom != CanonTo)
return false;
return true;
}
static bool
IsTransparentUnionStandardConversion(Sema &S, Expr* From,
QualType &ToType,
bool InOverloadResolution,
StandardConversionSequence &SCS,
bool CStyle) {
const RecordType *UT = ToType->getAsUnionType();
if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
return false;
// The field to initialize within the transparent union.
RecordDecl *UD = UT->getDecl();
// It's compatible if the expression matches any of the fields.
for (RecordDecl::field_iterator it = UD->field_begin(),
itend = UD->field_end();
it != itend; ++it) {
if (IsStandardConversion(S, From, it->getType(), InOverloadResolution, SCS,
CStyle, /*ObjCWritebackConversion=*/false)) {
ToType = it->getType();
return true;
}
}
return false;
}
/// IsIntegralPromotion - Determines whether the conversion from the
/// 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->getAs<BuiltinType>();
// All integers are built-in.
if (!To) {
return false;
}
// An rvalue of type char, signed char, unsigned char, short int, or
// unsigned short int can be converted to an rvalue of type int if
// int can represent all the values of the source type; otherwise,
// the source rvalue can be converted to an rvalue of type unsigned
// int (C++ 4.5p1).
if (FromType->isPromotableIntegerType() && !FromType->isBooleanType() &&
!FromType->isEnumeralType()) {
if (// We can promote any signed, promotable integer type to an int
(FromType->isSignedIntegerType() ||
// We can promote any unsigned integer type whose size is
// less than int to an int.
(!FromType->isSignedIntegerType() &&
Context.getTypeSize(FromType) < Context.getTypeSize(ToType)))) {
return To->getKind() == BuiltinType::Int;
}
return To->getKind() == BuiltinType::UInt;
}
// C++0x [conv.prom]p3:
// A prvalue of an unscoped enumeration type whose underlying type is not
// fixed (7.2) can be converted to an rvalue a prvalue of the first of the
// following types that can represent all the values of the enumeration
// (i.e., the values in the range bmin to bmax as described in 7.2): int,
// unsigned int, long int, unsigned long int, long long int, or unsigned
// long long int. If none of the types in that list can represent all the
// values of the enumeration, an rvalue a prvalue of an unscoped enumeration
// type can be converted to an rvalue a prvalue of the extended integer type
// with lowest integer conversion rank (4.13) greater than the rank of long
// long in which all the values of the enumeration can be represented. If
// there are two such extended types, the signed one is chosen.
if (const EnumType *FromEnumType = FromType->getAs<EnumType>()) {
// C++0x 7.2p9: Note that this implicit enum to int conversion is not
// provided for a scoped enumeration.
if (FromEnumType->getDecl()->isScoped())
return false;
// We have already pre-calculated the promotion type, so this is trivial.
if (ToType->isIntegerType() &&
!RequireCompleteType(From->getLocStart(), FromType, 0))
return Context.hasSameUnqualifiedType(ToType,
FromEnumType->getDecl()->getPromotionType());
}
// C++0x [conv.prom]p2:
// A prvalue of type char16_t, char32_t, or wchar_t (3.9.1) can be converted
// to an rvalue a prvalue of the first of the following types that can
// represent all the values of its underlying type: int, unsigned int,
// long int, unsigned long int, long long int, or unsigned long long int.
// If none of the types in that list can represent all the values of its
// underlying type, an rvalue a prvalue of type char16_t, char32_t,
// or wchar_t can be converted to an rvalue a prvalue of its underlying
// type.
if (FromType->isAnyCharacterType() && !FromType->isCharType() &&
ToType->isIntegerType()) {
// Determine whether the type we're converting from is signed or
// unsigned.
bool FromIsSigned = FromType->isSignedIntegerType();
uint64_t FromSize = Context.getTypeSize(FromType);
// The types we'll try to promote to, in the appropriate
// order. Try each of these types.
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 &&
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
// promotion.
return Context.hasSameUnqualifiedType(ToType, PromoteTypes[Idx]);
}
}
}
// An rvalue for an integral bit-field (9.6) can be converted to an
// rvalue of type int if int can represent all the values of the
// bit-field; otherwise, it can be converted to unsigned int if
// unsigned int can represent all the values of the bit-field. If
// the bit-field is larger yet, no integral promotion applies to
// it. If the bit-field has an enumerated type, it is treated as any
// other value of that type for promotion purposes (C++ 4.5p3).
// FIXME: We should delay checking of bit-fields until we actually perform the
// conversion.
using llvm::APSInt;
if (From)
if (FieldDecl *MemberDecl = From->getBitField()) {
APSInt BitWidth;
if (FromType->isIntegralType(Context) &&
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) {
return true;
}
return false;
}
/// 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) {
if (const BuiltinType *FromBuiltin = FromType->getAs<BuiltinType>())
if (const BuiltinType *ToBuiltin = ToType->getAs<BuiltinType>()) {
/// An rvalue of type float can be converted to an rvalue of type
/// double. (C++ 4.6p1).
if (FromBuiltin->getKind() == BuiltinType::Float &&
ToBuiltin->getKind() == BuiltinType::Double)
return true;
// C99 6.3.1.5p1:
// When a float is promoted to double or long double, or a
// double is promoted to long double [...].
if (!getLangOpts().CPlusPlus &&
(FromBuiltin->getKind() == BuiltinType::Float ||
FromBuiltin->getKind() == BuiltinType::Double) &&
(ToBuiltin->getKind() == BuiltinType::LongDouble))
return true;
// Half can be promoted to float.
if (FromBuiltin->getKind() == BuiltinType::Half &&
ToBuiltin->getKind() == BuiltinType::Float)
return true;
}
return false;
}
/// \brief Determine if a conversion is a complex promotion.
///
/// A complex promotion is defined as a complex -> complex conversion
/// 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->getAs<ComplexType>();
if (!FromComplex)
return false;
const ComplexType *ToComplex = ToType->getAs<ComplexType>();
if (!ToComplex)
return false;
return IsFloatingPointPromotion(FromComplex->getElementType(),
ToComplex->getElementType()) ||
IsIntegralPromotion(0, FromComplex->getElementType(),
ToComplex->getElementType());
}
/// BuildSimilarlyQualifiedPointerType - In a pointer conversion from
/// the pointer type FromPtr to a pointer to type ToPointee, with the
/// 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 Type *FromPtr,
QualType ToPointee, QualType ToType,
ASTContext &Context,
bool StripObjCLifetime = false) {
assert((FromPtr->getTypeClass() == Type::Pointer ||
FromPtr->getTypeClass() == Type::ObjCObjectPointer) &&
"Invalid similarly-qualified pointer type");
/// Conversions to 'id' subsume cv-qualifier conversions.
if (ToType->isObjCIdType() || ToType->isObjCQualifiedIdType())
return ToType.getUnqualifiedType();
QualType CanonFromPointee
= Context.getCanonicalType(FromPtr->getPointeeType());
QualType CanonToPointee = Context.getCanonicalType(ToPointee);
Qualifiers Quals = CanonFromPointee.getQualifiers();
if (StripObjCLifetime)
Quals.removeObjCLifetime();
// Exact qualifier match -> return the pointer type we're converting to.
if (CanonToPointee.getLocalQualifiers() == Quals) {
// ToType is exactly what we need. Return it.
if (!ToType.isNull())
return ToType.getUnqualifiedType();
// Build a pointer to ToPointee. It has the right qualifiers
// already.
if (isa<ObjCObjectPointerType>(ToType))
return Context.getObjCObjectPointerType(ToPointee);
return Context.getPointerType(ToPointee);
}
// Just build a canonical type that has the right qualifiers.
QualType QualifiedCanonToPointee
= Context.getQualifiedType(CanonToPointee.getLocalUnqualifiedType(), Quals);
if (isa<ObjCObjectPointerType>(ToType))
return Context.getObjCObjectPointerType(QualifiedCanonToPointee);
return Context.getPointerType(QualifiedCanonToPointee);
}
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()->isIntegerType() && !Expr->getType()->isEnumeralType())
return !InOverloadResolution;
return Expr->isNullPointerConstant(Context,
InOverloadResolution? Expr::NPC_ValueDependentIsNotNull
: Expr::NPC_ValueDependentIsNull);
}
/// IsPointerConversion - Determines whether the conversion of the
/// expression From, which has the (possibly adjusted) type FromType,
/// can be converted to the type ToType via a pointer conversion (C++
/// 4.10). If so, returns true and places the converted type (that
/// might differ from ToType in its cv-qualifiers at some level) into
/// ConvertedType.
///
/// This routine also supports conversions to and from block pointers
/// and conversions with Objective-C's 'id', 'id<protocols...>', and
/// pointers to interfaces. FIXME: Once we've determined the
/// appropriate overloading rules for Objective-C, we may want to
/// split the Objective-C checks into a different routine; however,
/// GCC seems to consider all of these conversions to be pointer
/// conversions, so for now they live here. IncompatibleObjC will be
/// 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) {
IncompatibleObjC = false;
if (isObjCPointerConversion(FromType, ToType, ConvertedType,
IncompatibleObjC))
return true;
// 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->getAs<PointerType>()->getPointeeType()->isVoidType()) {
ConvertedType = ToType;
return true;
}
// Blocks: A null pointer constant can be converted to a block
// pointer type.
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() &&
isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
ConvertedType = ToType;
return true;
}
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 (isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
ConvertedType = ToType;
return true;
}
// Beyond this point, both types need to be pointers
// , including objective-c pointers.
QualType ToPointeeType = ToTypePtr->getPointeeType();
if (FromType->isObjCObjectPointerType() && ToPointeeType->isVoidType() &&
!getLangOpts().ObjCAutoRefCount) {
ConvertedType = BuildSimilarlyQualifiedPointerType(
FromType->getAs<ObjCObjectPointerType>(),
ToPointeeType,
ToType, Context);
return true;
}
const PointerType *FromTypePtr = FromType->getAs<PointerType>();
if (!FromTypePtr)
return false;
QualType FromPointeeType = FromTypePtr->getPointeeType();
// If the unqualified pointee types are the same, this can't be a
// pointer conversion, so don't do all of the work below.
if (Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType))
return false;
// An rvalue of type "pointer to cv T," where T is an object type,
// can be converted to an rvalue of type "pointer to cv void" (C++
// 4.10p2).
if (FromPointeeType->isIncompleteOrObjectType() &&
ToPointeeType->isVoidType()) {
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
ToType, Context,
/*StripObjCLifetime=*/true);
return true;
}
// MSVC allows implicit function to void* type conversion.
if (getLangOpts().MicrosoftExt && FromPointeeType->isFunctionType() &&
ToPointeeType->isVoidType()) {
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
ToType, Context);
return true;
}
// When we're overloading in C, we allow a special kind of pointer
// conversion for compatible-but-not-identical pointee types.
if (!getLangOpts().CPlusPlus &&
Context.typesAreCompatible(FromPointeeType, ToPointeeType)) {
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
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
// (clause 11) or ambiguous (10.2) base class of D, a program that
// necessitates this conversion is ill-formed. The result of the
// conversion is a pointer to the base class sub-object of the
// derived class object. The null pointer value is converted to
// the null pointer value of the destination type.
//
// Note that we do not check for ambiguity or inaccessibility
// here. That is handled by CheckPointerConversion.
if (getLangOpts().CPlusPlus &&
FromPointeeType->isRecordType() && ToPointeeType->isRecordType() &&
!Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType) &&
!RequireCompleteType(From->getLocStart(), FromPointeeType, 0) &&
IsDerivedFrom(FromPointeeType, ToPointeeType)) {
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
ToType, Context);
return true;
}
if (FromPointeeType->isVectorType() && ToPointeeType->isVectorType() &&
Context.areCompatibleVectorTypes(FromPointeeType, ToPointeeType)) {
ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
ToPointeeType,
ToType, Context);
return true;
}
return false;
}
/// \brief Adopt the given qualifiers for the given type.
static QualType AdoptQualifiers(ASTContext &Context, QualType T, Qualifiers Qs){
Qualifiers TQs = T.getQualifiers();
// Check whether qualifiers already match.
if (TQs == Qs)
return T;
if (Qs.compatiblyIncludes(TQs))
return Context.getQualifiedType(T, Qs);
return Context.getQualifiedType(T.getUnqualifiedType(), Qs);
}
/// 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,
QualType& ConvertedType,
bool &IncompatibleObjC) {
if (!getLangOpts().ObjC1)
return false;
// The set of qualifiers on the type we're converting from.
Qualifiers FromQualifiers = FromType.getQualifiers();
// 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) {
// If the pointee types are the same (ignoring qualifications),
// then this is not a pointer conversion.
if (Context.hasSameUnqualifiedType(ToObjCPtr->getPointeeType(),
FromObjCPtr->getPointeeType()))
return false;
// Check for compatible
// 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 = AdoptQualifiers(Context, ToType, FromQualifiers);
return true;
}
// Conversions with Objective-C's id<...>.
if ((FromObjCPtr->isObjCQualifiedIdType() ||
ToObjCPtr->isObjCQualifiedIdType()) &&
Context.ObjCQualifiedIdTypesAreCompatible(ToType, FromType,
/*compare=*/false)) {
ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers);
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)) {
const ObjCInterfaceType* LHS = ToObjCPtr->getInterfaceType();
const ObjCInterfaceType* RHS = FromObjCPtr->getInterfaceType();
if (getLangOpts().CPlusPlus && LHS && RHS &&
!ToObjCPtr->getPointeeType().isAtLeastAsQualifiedAs(
FromObjCPtr->getPointeeType()))
return false;
ConvertedType = BuildSimilarlyQualifiedPointerType(FromObjCPtr,
ToObjCPtr->getPointeeType(),
ToType, Context);
ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers);
return true;
}
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 = BuildSimilarlyQualifiedPointerType(FromObjCPtr,
ToObjCPtr->getPointeeType(),
ToType, Context);
ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers);
return true;
}
}
// Beyond this point, both types need to be C pointers or block pointers.
QualType ToPointeeType;
if (const PointerType *ToCPtr = ToType->getAs<PointerType>())
ToPointeeType = ToCPtr->getPointeeType();
else if (const BlockPointerType *ToBlockPtr =
ToType->getAs<BlockPointerType>()) {
// Objective C++: We're able to convert from a pointer to any object
// to a block pointer type.
if (FromObjCPtr && FromObjCPtr->isObjCBuiltinType()) {
ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers);
return true;
}
ToPointeeType = ToBlockPtr->getPointeeType();
}
else if (FromType->getAs<BlockPointerType>() &&
ToObjCPtr && ToObjCPtr->isObjCBuiltinType()) {
// Objective C++: We're able to convert from a block pointer type to a
// pointer to any object.
ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers);
return true;
}
else
return false;
QualType FromPointeeType;
if (const PointerType *FromCPtr = FromType->getAs<PointerType>())
FromPointeeType = FromCPtr->getPointeeType();
else if (const BlockPointerType *FromBlockPtr =
FromType->getAs<BlockPointerType>())
FromPointeeType = FromBlockPtr->getPointeeType();
else
return false;
// If we have pointers to pointers, recursively check whether this
// is an Objective-C conversion.
if (FromPointeeType->isPointerType() && ToPointeeType->isPointerType() &&
isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType,
IncompatibleObjC)) {
// We always complain about this conversion.
IncompatibleObjC = true;
ConvertedType = Context.getPointerType(ConvertedType);
ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers);
return true;
}
// Allow conversion of pointee being objective-c pointer to another one;
// as in I* to id.
if (FromPointeeType->getAs<ObjCObjectPointerType>() &&
ToPointeeType->getAs<ObjCObjectPointerType>() &&
isObjCPointerConversion(FromPointeeType, ToPointeeType, ConvertedType,
IncompatibleObjC)) {
ConvertedType = Context.getPointerType(ConvertedType);
ConvertedType = AdoptQualifiers(Context, ConvertedType, FromQualifiers);
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->getAs<FunctionProtoType>();
const FunctionProtoType *ToFunctionType
= ToPointeeType->getAs<FunctionProtoType>();
if (FromFunctionType && ToFunctionType) {
// If the function types are exactly the same, this isn't an
// Objective-C pointer conversion.
if (Context.getCanonicalType(FromPointeeType)
== Context.getCanonicalType(ToPointeeType))
return false;
// Perform the quick checks that will tell us whether these
// function types are obviously different.
if (FromFunctionType->getNumArgs() != ToFunctionType->getNumArgs() ||
FromFunctionType->isVariadic() != ToFunctionType->isVariadic() ||
FromFunctionType->getTypeQuals() != ToFunctionType->getTypeQuals())
return false;
bool HasObjCConversion = false;
if (Context.getCanonicalType(FromFunctionType->getResultType())
== Context.getCanonicalType(ToFunctionType->getResultType())) {
// Okay, the types match exactly. Nothing to do.
} else if (isObjCPointerConversion(FromFunctionType->getResultType(),
ToFunctionType->getResultType(),
ConvertedType, IncompatibleObjC)) {
// Okay, we have an Objective-C pointer conversion.
HasObjCConversion = true;
} else {
// Function types are too different. Abort.
return false;
}
// Check argument types.
for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
ArgIdx != NumArgs; ++ArgIdx) {
QualType FromArgType = FromFunctionType->getArgType(ArgIdx);
QualType ToArgType = ToFunctionType->getArgType(ArgIdx);
if (Context.getCanonicalType(FromArgType)
== Context.getCanonicalType(ToArgType)) {
// Okay, the types match exactly. Nothing to do.
} else if (isObjCPointerConversion(FromArgType, ToArgType,
ConvertedType, IncompatibleObjC)) {
// Okay, we have an Objective-C pointer conversion.
HasObjCConversion = true;
} else {
// Argument types are too different. Abort.
return false;
}
}
if (HasObjCConversion) {
// We had an Objective-C conversion. Allow this pointer
// conversion, but complain about it.
ConvertedType = AdoptQualifiers(Context, ToType, FromQualifiers);
IncompatibleObjC = true;
return true;
}
}
return false;
}
/// \brief Determine whether this is an Objective-C writeback conversion,
/// used for parameter passing when performing automatic reference counting.
///
/// \param FromType The type we're converting form.
///
/// \param ToType The type we're converting to.
///
/// \param ConvertedType The type that will be produced after applying
/// this conversion.
bool Sema::isObjCWritebackConversion(QualType FromType, QualType ToType,
QualType &ConvertedType) {
if (!getLangOpts().ObjCAutoRefCount ||
Context.hasSameUnqualifiedType(FromType, ToType))
return false;
// Parameter must be a pointer to __autoreleasing (with no other qualifiers).
QualType ToPointee;
if (const PointerType *ToPointer = ToType->getAs<PointerType>())
ToPointee = ToPointer->getPointeeType();
else
return false;
Qualifiers ToQuals = ToPointee.getQualifiers();
if (!ToPointee->isObjCLifetimeType() ||
ToQuals.getObjCLifetime() != Qualifiers::OCL_Autoreleasing ||
!ToQuals.withoutObjCLifetime().empty())
return false;
// Argument must be a pointer to __strong to __weak.
QualType FromPointee;
if (const PointerType *FromPointer = FromType->getAs<PointerType>())
FromPointee = FromPointer->getPointeeType();
else
return false;
Qualifiers FromQuals = FromPointee.getQualifiers();
if (!FromPointee->isObjCLifetimeType() ||
(FromQuals.getObjCLifetime() != Qualifiers::OCL_Strong &&
FromQuals.getObjCLifetime() != Qualifiers::OCL_Weak))
return false;
// Make sure that we have compatible qualifiers.
FromQuals.setObjCLifetime(Qualifiers::OCL_Autoreleasing);
if (!ToQuals.compatiblyIncludes(FromQuals))
return false;
// Remove qualifiers from the pointee type we're converting from; they
// aren't used in the compatibility check belong, and we'll be adding back
// qualifiers (with __autoreleasing) if the compatibility check succeeds.
FromPointee = FromPointee.getUnqualifiedType();
// The unqualified form of the pointee types must be compatible.
ToPointee = ToPointee.getUnqualifiedType();
bool IncompatibleObjC;
if (Context.typesAreCompatible(FromPointee, ToPointee))
FromPointee = ToPointee;
else if (!isObjCPointerConversion(FromPointee, ToPointee, FromPointee,
IncompatibleObjC))
return false;
/// \brief Construct the type we're converting to, which is a pointer to
/// __autoreleasing pointee.
FromPointee = Context.getQualifiedType(FromPointee, FromQuals);
ConvertedType = Context.getPointerType(FromPointee);
return true;
}
bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType,
QualType& ConvertedType) {
QualType ToPointeeType;
if (const BlockPointerType *ToBlockPtr =
ToType->getAs<BlockPointerType>())
ToPointeeType = ToBlockPtr->getPointeeType();
else
return false;
QualType FromPointeeType;
if (const BlockPointerType *FromBlockPtr =
FromType->getAs<BlockPointerType>())
FromPointeeType = FromBlockPtr->getPointeeType();
else
return false;
// We have pointer to blocks, check whether the only
// differences in the argument and result types are in Objective-C
// pointer conversions. If so, we permit the conversion.
const FunctionProtoType *FromFunctionType
= FromPointeeType->getAs<FunctionProtoType>();
const FunctionProtoType *ToFunctionType
= ToPointeeType->getAs<FunctionProtoType>();
if (!FromFunctionType || !ToFunctionType)
return false;
if (Context.hasSameType(FromPointeeType, ToPointeeType))
return true;
// Perform the quick checks that will tell us whether these
// function types are obviously different.
if (FromFunctionType->getNumArgs() != ToFunctionType->getNumArgs() ||
FromFunctionType->isVariadic() != ToFunctionType->isVariadic())
return false;
FunctionType::ExtInfo FromEInfo = FromFunctionType->getExtInfo();
FunctionType::ExtInfo ToEInfo = ToFunctionType->getExtInfo();
if (FromEInfo != ToEInfo)
return false;
bool IncompatibleObjC = false;
if (Context.hasSameType(FromFunctionType->getResultType(),
ToFunctionType->getResultType())) {
// Okay, the types match exactly. Nothing to do.
} else {
QualType RHS = FromFunctionType->getResultType();
QualType LHS = ToFunctionType->getResultType();
if ((!getLangOpts().CPlusPlus || !RHS->isRecordType()) &&
!RHS.hasQualifiers() && LHS.hasQualifiers())
LHS = LHS.getUnqualifiedType();
if (Context.hasSameType(RHS,LHS)) {
// OK exact match.
} else if (isObjCPointerConversion(RHS, LHS,
ConvertedType, IncompatibleObjC)) {
if (IncompatibleObjC)
return false;
// Okay, we have an Objective-C pointer conversion.
}
else
return false;
}
// Check argument types.
for (unsigned ArgIdx = 0, NumArgs = FromFunctionType->getNumArgs();
ArgIdx != NumArgs; ++ArgIdx) {
IncompatibleObjC = false;
QualType FromArgType = FromFunctionType->getArgType(ArgIdx);
QualType ToArgType = ToFunctionType->getArgType(ArgIdx);
if (Context.hasSameType(FromArgType, ToArgType)) {
// Okay, the types match exactly. Nothing to do.
} else if (isObjCPointerConversion(ToArgType, FromArgType,
ConvertedType, IncompatibleObjC)) {
if (IncompatibleObjC)
return false;
// Okay, we have an Objective-C pointer conversion.
} else
// Argument types are too different. Abort.
return false;
}
if (LangOpts.ObjCAutoRefCount &&
!Context.FunctionTypesMatchOnNSConsumedAttrs(FromFunctionType,
ToFunctionType))
return false;
ConvertedType = ToType;
return true;
}
enum {
ft_default,
ft_different_class,
ft_parameter_arity,
ft_parameter_mismatch,
ft_return_type,
ft_qualifer_mismatch
};
/// HandleFunctionTypeMismatch - Gives diagnostic information for differeing
/// function types. Catches different number of parameter, mismatch in
/// parameter types, and different return types.
void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
QualType FromType, QualType ToType) {
// If either type is not valid, include no extra info.
if (FromType.isNull() || ToType.isNull()) {
PDiag << ft_default;
return;
}
// Get the function type from the pointers.
if (FromType->isMemberPointerType() && ToType->isMemberPointerType()) {
const MemberPointerType *FromMember = FromType->getAs<MemberPointerType>(),
*ToMember = ToType->getAs<MemberPointerType>();
if (FromMember->getClass() != ToMember->getClass()) {
PDiag << ft_different_class << QualType(ToMember->getClass(), 0)
<< QualType(FromMember->getClass(), 0);
return;
}
FromType = FromMember->getPointeeType();
ToType = ToMember->getPointeeType();
}
if (FromType->isPointerType())
FromType = FromType->getPointeeType();
if (ToType->isPointerType())
ToType = ToType->getPointeeType();
// Remove references.
FromType = FromType.getNonReferenceType();
ToType = ToType.getNonReferenceType();
// Don't print extra info for non-specialized template functions.
if (FromType->isInstantiationDependentType() &&
!FromType->getAs<TemplateSpecializationType>()) {
PDiag << ft_default;
return;
}
// No extra info for same types.
if (Context.hasSameType(FromType, ToType)) {
PDiag << ft_default;
return;
}
const FunctionProtoType *FromFunction = FromType->getAs<FunctionProtoType>(),
*ToFunction = ToType->getAs<FunctionProtoType>();
// Both types need to be function types.
if (!FromFunction || !ToFunction) {
PDiag << ft_default;
return;
}
if (FromFunction->getNumArgs() != ToFunction->getNumArgs()) {
PDiag << ft_parameter_arity << ToFunction->getNumArgs()
<< FromFunction->getNumArgs();
return;
}
// Handle different parameter types.
unsigned ArgPos;
if (!FunctionArgTypesAreEqual(FromFunction, ToFunction, &ArgPos)) {
PDiag << ft_parameter_mismatch << ArgPos + 1
<< ToFunction->getArgType(ArgPos)
<< FromFunction->getArgType(ArgPos);
return;
}
// Handle different return type.
if (!Context.hasSameType(FromFunction->getResultType(),
ToFunction->getResultType())) {
PDiag << ft_return_type << ToFunction->getResultType()
<< FromFunction->getResultType();
return;
}
unsigned FromQuals = FromFunction->getTypeQuals(),
ToQuals = ToFunction->getTypeQuals();
if (FromQuals != ToQuals) {
PDiag << ft_qualifer_mismatch << ToQuals << FromQuals;
return;
}
// Unable to find a difference, so add no extra info.
PDiag << ft_default;
}
/// FunctionArgTypesAreEqual - This routine checks two function proto types
/// for equality of their argument types. Caller has already checked that
/// they have same number of arguments. This routine assumes that Objective-C
/// pointer types which only differ in their protocol qualifiers are equal.
/// If the parameters are different, ArgPos will have the the parameter index
/// of the first different parameter.
bool Sema::FunctionArgTypesAreEqual(const FunctionProtoType *OldType,
const FunctionProtoType *NewType,
unsigned *ArgPos) {
if (!getLangOpts().ObjC1) {
for (FunctionProtoType::arg_type_iterator O = OldType->arg_type_begin(),
N = NewType->arg_type_begin(),
E = OldType->arg_type_end(); O && (O != E); ++O, ++N) {
if (!Context.hasSameType(*O, *N)) {
if (ArgPos) *ArgPos = O - OldType->arg_type_begin();
return false;
}
}
return true;
}
for (FunctionProtoType::arg_type_iterator O = OldType->arg_type_begin(),
N = NewType->arg_type_begin(),
E = OldType->arg_type_end(); O && (O != E); ++O, ++N) {
QualType ToType = (*O);
QualType FromType = (*N);
if (!Context.hasSameType(ToType, FromType)) {
if (const PointerType *PTTo = ToType->getAs<PointerType>()) {
if (const PointerType *PTFr = FromType->getAs<PointerType>())
if ((PTTo->getPointeeType()->isObjCQualifiedIdType() &&
PTFr->getPointeeType()->isObjCQualifiedIdType()) ||
(PTTo->getPointeeType()->isObjCQualifiedClassType() &&
PTFr->getPointeeType()->isObjCQualifiedClassType()))
continue;
}
else if (const ObjCObjectPointerType *PTTo =
ToType->getAs<ObjCObjectPointerType>()) {
if (const ObjCObjectPointerType *PTFr =
FromType->getAs<ObjCObjectPointerType>())
if (Context.hasSameUnqualifiedType(
PTTo->getObjectType()->getBaseType(),
PTFr->getObjectType()->getBaseType()))
continue;
}
if (ArgPos) *ArgPos = O - OldType->arg_type_begin();
return false;
}
}
return true;
}
/// CheckPointerConversion - Check the pointer conversion from the
/// expression From to the type ToType. This routine checks for
/// 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,
CastKind &Kind,
CXXCastPath& BasePath,
bool IgnoreBaseAccess) {
QualType FromType = From->getType();
bool IsCStyleOrFunctionalCast = IgnoreBaseAccess;
Kind = CK_BitCast;
if (!IsCStyleOrFunctionalCast &&
Context.hasSameUnqualifiedType(From->getType(), Context.BoolTy) &&
From->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull))
DiagRuntimeBehavior(From->getExprLoc(), From,