forked from OSchip/llvm-project
Preserve the FoundDecl when performing overload resolution for constructors.
This is in preparation for C++ P0136R1, which switches the model for inheriting constructors over from synthesizing a constructor to finding base class constructors (via using shadow decls) when looking for derived class constructors. llvm-svn: 269231
This commit is contained in:
parent
1455de2171
commit
c2bebe9aca
|
@ -16,6 +16,7 @@
|
|||
#define LLVM_CLANG_AST_EXPRCXX_H
|
||||
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/LambdaCapture.h"
|
||||
#include "clang/AST/TemplateBase.h"
|
||||
|
@ -26,9 +27,6 @@
|
|||
|
||||
namespace clang {
|
||||
|
||||
class CXXConstructorDecl;
|
||||
class CXXDestructorDecl;
|
||||
class CXXMethodDecl;
|
||||
class CXXTemporary;
|
||||
class MSPropertyDecl;
|
||||
class TemplateArgumentListInfo;
|
||||
|
@ -1168,18 +1166,21 @@ private:
|
|||
SourceLocation Loc;
|
||||
SourceRange ParenOrBraceRange;
|
||||
unsigned NumArgs : 16;
|
||||
bool Elidable : 1;
|
||||
bool HadMultipleCandidates : 1;
|
||||
bool ListInitialization : 1;
|
||||
bool StdInitListInitialization : 1;
|
||||
bool ZeroInitialization : 1;
|
||||
unsigned Elidable : 1;
|
||||
unsigned HadMultipleCandidates : 1;
|
||||
unsigned ListInitialization : 1;
|
||||
unsigned StdInitListInitialization : 1;
|
||||
unsigned ZeroInitialization : 1;
|
||||
unsigned ConstructKind : 2;
|
||||
Stmt **Args;
|
||||
|
||||
void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
|
||||
|
||||
protected:
|
||||
CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T,
|
||||
SourceLocation Loc,
|
||||
CXXConstructorDecl *d, bool elidable,
|
||||
NamedDecl *Found, CXXConstructorDecl *Ctor,
|
||||
bool Elidable,
|
||||
ArrayRef<Expr *> Args,
|
||||
bool HadMultipleCandidates,
|
||||
bool ListInitialization,
|
||||
|
@ -1198,15 +1199,13 @@ protected:
|
|||
public:
|
||||
/// \brief Construct an empty C++ construction expression.
|
||||
explicit CXXConstructExpr(EmptyShell Empty)
|
||||
: Expr(CXXConstructExprClass, Empty), Constructor(nullptr),
|
||||
NumArgs(0), Elidable(false), HadMultipleCandidates(false),
|
||||
ListInitialization(false), ZeroInitialization(false),
|
||||
ConstructKind(0), Args(nullptr)
|
||||
{ }
|
||||
: CXXConstructExpr(CXXConstructExprClass, Empty) {}
|
||||
|
||||
static CXXConstructExpr *Create(const ASTContext &C, QualType T,
|
||||
SourceLocation Loc,
|
||||
CXXConstructorDecl *D, bool Elidable,
|
||||
NamedDecl *Found,
|
||||
CXXConstructorDecl *Ctor,
|
||||
bool Elidable,
|
||||
ArrayRef<Expr *> Args,
|
||||
bool HadMultipleCandidates,
|
||||
bool ListInitialization,
|
||||
|
@ -1215,8 +1214,11 @@ public:
|
|||
ConstructionKind ConstructKind,
|
||||
SourceRange ParenOrBraceRange);
|
||||
|
||||
/// \brief Get the declaration that was found by name lookup.
|
||||
NamedDecl *getFoundDecl() const;
|
||||
|
||||
/// \brief Get the constructor that this expression will (ultimately) call.
|
||||
CXXConstructorDecl *getConstructor() const { return Constructor; }
|
||||
void setConstructor(CXXConstructorDecl *C) { Constructor = C; }
|
||||
|
||||
SourceLocation getLocation() const { return Loc; }
|
||||
void setLocation(SourceLocation Loc) { this->Loc = Loc; }
|
||||
|
@ -1382,7 +1384,9 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr {
|
|||
TypeSourceInfo *Type;
|
||||
|
||||
public:
|
||||
CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons,
|
||||
CXXTemporaryObjectExpr(const ASTContext &C,
|
||||
NamedDecl *Found,
|
||||
CXXConstructorDecl *Cons,
|
||||
TypeSourceInfo *Type,
|
||||
ArrayRef<Expr *> Args,
|
||||
SourceRange ParenOrBraceRange,
|
||||
|
|
|
@ -199,6 +199,7 @@ namespace clang {
|
|||
/// conversions are either identity conversions or derived-to-base
|
||||
/// conversions.
|
||||
CXXConstructorDecl *CopyConstructor;
|
||||
DeclAccessPair FoundCopyConstructor;
|
||||
|
||||
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
|
||||
void setToType(unsigned Idx, QualType T) {
|
||||
|
@ -282,7 +283,7 @@ namespace clang {
|
|||
|
||||
/// Represents an ambiguous user-defined conversion sequence.
|
||||
struct AmbiguousConversionSequence {
|
||||
typedef SmallVector<FunctionDecl*, 4> ConversionSet;
|
||||
typedef SmallVector<std::pair<NamedDecl*, FunctionDecl*>, 4> ConversionSet;
|
||||
|
||||
void *FromTypePtr;
|
||||
void *ToTypePtr;
|
||||
|
@ -305,8 +306,8 @@ namespace clang {
|
|||
return *reinterpret_cast<const ConversionSet*>(Buffer);
|
||||
}
|
||||
|
||||
void addConversion(FunctionDecl *D) {
|
||||
conversions().push_back(D);
|
||||
void addConversion(NamedDecl *Found, FunctionDecl *D) {
|
||||
conversions().push_back(std::make_pair(Found, D));
|
||||
}
|
||||
|
||||
typedef ConversionSet::iterator iterator;
|
||||
|
@ -797,6 +798,29 @@ namespace clang {
|
|||
const OverloadCandidate& Cand2,
|
||||
SourceLocation Loc,
|
||||
bool UserDefinedConversion = false);
|
||||
|
||||
struct ConstructorInfo {
|
||||
DeclAccessPair FoundDecl;
|
||||
CXXConstructorDecl *Constructor;
|
||||
FunctionTemplateDecl *ConstructorTmpl;
|
||||
};
|
||||
// FIXME: Add an AddOverloadCandidate / AddTemplateOverloadCandidate overload
|
||||
// that takes one of these.
|
||||
inline ConstructorInfo getConstructorInfo(NamedDecl *ND) {
|
||||
if (isa<UsingDecl>(ND))
|
||||
return ConstructorInfo{};
|
||||
|
||||
// For constructors, the access check is performed against the underlying
|
||||
// declaration, not the found declaration.
|
||||
auto *D = ND->getUnderlyingDecl();
|
||||
ConstructorInfo Info = {DeclAccessPair::make(ND, D->getAccess()), nullptr,
|
||||
nullptr};
|
||||
Info.ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
|
||||
if (Info.ConstructorTmpl)
|
||||
D = Info.ConstructorTmpl->getTemplatedDecl();
|
||||
Info.Constructor = cast<CXXConstructorDecl>(D);
|
||||
return Info;
|
||||
}
|
||||
} // end namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_SEMA_OVERLOAD_H
|
||||
|
|
|
@ -2526,7 +2526,8 @@ public:
|
|||
bool PartialOverloading = false);
|
||||
|
||||
// Emit as a 'note' the specific overload candidate
|
||||
void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType(),
|
||||
void NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn,
|
||||
QualType DestType = QualType(),
|
||||
bool TakingAddress = false);
|
||||
|
||||
// Emit as a series of 'note's all template and non-templates identified by
|
||||
|
@ -4273,6 +4274,7 @@ public:
|
|||
/// \param ConstructKind - a CXXConstructExpr::ConstructionKind
|
||||
ExprResult
|
||||
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
||||
NamedDecl *FoundDecl,
|
||||
CXXConstructorDecl *Constructor, MultiExprArg Exprs,
|
||||
bool HadMultipleCandidates, bool IsListInitialization,
|
||||
bool IsStdInitListInitialization,
|
||||
|
@ -4283,6 +4285,7 @@ public:
|
|||
// the constructor can be elidable?
|
||||
ExprResult
|
||||
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
||||
NamedDecl *FoundDecl,
|
||||
CXXConstructorDecl *Constructor, bool Elidable,
|
||||
MultiExprArg Exprs, bool HadMultipleCandidates,
|
||||
bool IsListInitialization,
|
||||
|
|
|
@ -244,6 +244,10 @@ struct DeductionFailureInfo {
|
|||
/// TODO: In the future, we may need to unify/generalize this with
|
||||
/// OverloadCandidate.
|
||||
struct TemplateSpecCandidate {
|
||||
/// \brief The declaration that was looked up, together with its access.
|
||||
/// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl.
|
||||
DeclAccessPair FoundDecl;
|
||||
|
||||
/// Specialization - The actual specialization that this candidate
|
||||
/// represents. When NULL, this may be a built-in candidate.
|
||||
Decl *Specialization;
|
||||
|
@ -251,7 +255,8 @@ struct TemplateSpecCandidate {
|
|||
/// Template argument deduction info
|
||||
DeductionFailureInfo DeductionFailure;
|
||||
|
||||
void set(Decl *Spec, DeductionFailureInfo Info) {
|
||||
void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) {
|
||||
FoundDecl = Found;
|
||||
Specialization = Spec;
|
||||
DeductionFailure = Info;
|
||||
}
|
||||
|
|
|
@ -5767,9 +5767,14 @@ Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
|||
if (T.isNull())
|
||||
return nullptr;
|
||||
|
||||
NamedDecl *ToFound =
|
||||
dyn_cast<NamedDecl>(Importer.Import(E->getFoundDecl()));
|
||||
if (!ToFound)
|
||||
return nullptr;
|
||||
|
||||
CXXConstructorDecl *ToCCD =
|
||||
dyn_cast<CXXConstructorDecl>(Importer.Import(E->getConstructor()));
|
||||
if (!ToCCD && E->getConstructor())
|
||||
if (!ToCCD)
|
||||
return nullptr;
|
||||
|
||||
SmallVector<Expr *, 6> ToArgs(E->getNumArgs());
|
||||
|
@ -5779,7 +5784,7 @@ Expr *ASTNodeImporter::VisitCXXConstructExpr(CXXConstructExpr *E) {
|
|||
|
||||
return CXXConstructExpr::Create(Importer.getToContext(), T,
|
||||
Importer.Import(E->getLocation()),
|
||||
ToCCD, E->isElidable(),
|
||||
ToFound, ToCCD, E->isElidable(),
|
||||
ToArgs, E->hadMultipleCandidates(),
|
||||
E->isListInitialization(),
|
||||
E->isStdInitListInitialization(),
|
||||
|
|
|
@ -432,6 +432,12 @@ SourceLocation CXXConstructExpr::getLocEnd() const {
|
|||
return End;
|
||||
}
|
||||
|
||||
NamedDecl *CXXConstructExpr::getFoundDecl() const {
|
||||
if (auto *Template = Constructor->getPrimaryTemplate())
|
||||
return Template;
|
||||
return Constructor;
|
||||
}
|
||||
|
||||
SourceRange CXXOperatorCallExpr::getSourceRangeImpl() const {
|
||||
OverloadedOperatorKind Kind = getOperator();
|
||||
if (Kind == OO_PlusPlus || Kind == OO_MinusMinus) {
|
||||
|
@ -717,6 +723,7 @@ CXXBindTemporaryExpr *CXXBindTemporaryExpr::Create(const ASTContext &C,
|
|||
}
|
||||
|
||||
CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C,
|
||||
NamedDecl *Found,
|
||||
CXXConstructorDecl *Cons,
|
||||
TypeSourceInfo *Type,
|
||||
ArrayRef<Expr*> Args,
|
||||
|
@ -728,7 +735,7 @@ CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(const ASTContext &C,
|
|||
: CXXConstructExpr(C, CXXTemporaryObjectExprClass,
|
||||
Type->getType().getNonReferenceType(),
|
||||
Type->getTypeLoc().getBeginLoc(),
|
||||
Cons, false, Args,
|
||||
Found, Cons, false, Args,
|
||||
HadMultipleCandidates,
|
||||
ListInitialization,
|
||||
StdInitListInitialization,
|
||||
|
@ -750,7 +757,9 @@ SourceLocation CXXTemporaryObjectExpr::getLocEnd() const {
|
|||
|
||||
CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T,
|
||||
SourceLocation Loc,
|
||||
CXXConstructorDecl *D, bool Elidable,
|
||||
NamedDecl *Found,
|
||||
CXXConstructorDecl *Ctor,
|
||||
bool Elidable,
|
||||
ArrayRef<Expr*> Args,
|
||||
bool HadMultipleCandidates,
|
||||
bool ListInitialization,
|
||||
|
@ -758,8 +767,8 @@ CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T,
|
|||
bool ZeroInitialization,
|
||||
ConstructionKind ConstructKind,
|
||||
SourceRange ParenOrBraceRange) {
|
||||
return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
|
||||
Elidable, Args,
|
||||
return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc,
|
||||
Found, Ctor, Elidable, Args,
|
||||
HadMultipleCandidates, ListInitialization,
|
||||
StdInitListInitialization,
|
||||
ZeroInitialization, ConstructKind,
|
||||
|
@ -768,8 +777,9 @@ CXXConstructExpr *CXXConstructExpr::Create(const ASTContext &C, QualType T,
|
|||
|
||||
CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
|
||||
QualType T, SourceLocation Loc,
|
||||
CXXConstructorDecl *D, bool elidable,
|
||||
ArrayRef<Expr*> args,
|
||||
NamedDecl *Found, CXXConstructorDecl *Ctor,
|
||||
bool Elidable,
|
||||
ArrayRef<Expr*> Args,
|
||||
bool HadMultipleCandidates,
|
||||
bool ListInitialization,
|
||||
bool StdInitListInitialization,
|
||||
|
@ -780,28 +790,30 @@ CXXConstructExpr::CXXConstructExpr(const ASTContext &C, StmtClass SC,
|
|||
T->isDependentType(), T->isDependentType(),
|
||||
T->isInstantiationDependentType(),
|
||||
T->containsUnexpandedParameterPack()),
|
||||
Constructor(D), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange),
|
||||
NumArgs(args.size()),
|
||||
Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates),
|
||||
Constructor(Ctor), Loc(Loc), ParenOrBraceRange(ParenOrBraceRange),
|
||||
NumArgs(Args.size()),
|
||||
Elidable(Elidable), HadMultipleCandidates(HadMultipleCandidates),
|
||||
ListInitialization(ListInitialization),
|
||||
StdInitListInitialization(StdInitListInitialization),
|
||||
ZeroInitialization(ZeroInitialization),
|
||||
ConstructKind(ConstructKind), Args(nullptr)
|
||||
{
|
||||
assert(declaresSameEntity(Found, Ctor) ||
|
||||
declaresSameEntity(Found, Ctor->getPrimaryTemplate()));
|
||||
if (NumArgs) {
|
||||
Args = new (C) Stmt*[args.size()];
|
||||
this->Args = new (C) Stmt*[Args.size()];
|
||||
|
||||
for (unsigned i = 0; i != args.size(); ++i) {
|
||||
assert(args[i] && "NULL argument in CXXConstructExpr");
|
||||
for (unsigned i = 0; i != Args.size(); ++i) {
|
||||
assert(Args[i] && "NULL argument in CXXConstructExpr");
|
||||
|
||||
if (args[i]->isValueDependent())
|
||||
if (Args[i]->isValueDependent())
|
||||
ExprBits.ValueDependent = true;
|
||||
if (args[i]->isInstantiationDependent())
|
||||
if (Args[i]->isInstantiationDependent())
|
||||
ExprBits.InstantiationDependent = true;
|
||||
if (args[i]->containsUnexpandedParameterPack())
|
||||
if (Args[i]->containsUnexpandedParameterPack())
|
||||
ExprBits.ContainsUnexpandedParameterPack = true;
|
||||
|
||||
Args[i] = args[i];
|
||||
this->Args[i] = Args[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3305,6 +3305,7 @@ CodeGenFunction::GenerateObjCAtomicGetterCopyHelperFunction(
|
|||
|
||||
CXXConstructExpr *TheCXXConstructExpr =
|
||||
CXXConstructExpr::Create(C, Ty, SourceLocation(),
|
||||
CXXConstExpr->getFoundDecl(),
|
||||
CXXConstExpr->getConstructor(),
|
||||
CXXConstExpr->isElidable(),
|
||||
ConstructorArgs,
|
||||
|
|
|
@ -11369,6 +11369,7 @@ static bool hasOneRealArgument(MultiExprArg Args) {
|
|||
|
||||
ExprResult
|
||||
Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
||||
NamedDecl *FoundDecl,
|
||||
CXXConstructorDecl *Constructor,
|
||||
MultiExprArg ExprArgs,
|
||||
bool HadMultipleCandidates,
|
||||
|
@ -11395,7 +11396,8 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
|||
Elidable = SubExpr->isTemporaryObject(Context, Constructor->getParent());
|
||||
}
|
||||
|
||||
return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
|
||||
return BuildCXXConstructExpr(ConstructLoc, DeclInitType,
|
||||
FoundDecl, Constructor,
|
||||
Elidable, ExprArgs, HadMultipleCandidates,
|
||||
IsListInitialization,
|
||||
IsStdInitListInitialization, RequiresZeroInit,
|
||||
|
@ -11406,7 +11408,9 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
|||
/// including handling of its default argument expressions.
|
||||
ExprResult
|
||||
Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
||||
CXXConstructorDecl *Constructor, bool Elidable,
|
||||
NamedDecl *FoundDecl,
|
||||
CXXConstructorDecl *Constructor,
|
||||
bool Elidable,
|
||||
MultiExprArg ExprArgs,
|
||||
bool HadMultipleCandidates,
|
||||
bool IsListInitialization,
|
||||
|
@ -11416,9 +11420,9 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
|||
SourceRange ParenRange) {
|
||||
MarkFunctionReferenced(ConstructLoc, Constructor);
|
||||
return CXXConstructExpr::Create(
|
||||
Context, DeclInitType, ConstructLoc, Constructor, Elidable, ExprArgs,
|
||||
HadMultipleCandidates, IsListInitialization, IsStdInitListInitialization,
|
||||
RequiresZeroInit,
|
||||
Context, DeclInitType, ConstructLoc, FoundDecl, Constructor, Elidable,
|
||||
ExprArgs, HadMultipleCandidates, IsListInitialization,
|
||||
IsStdInitListInitialization, RequiresZeroInit,
|
||||
static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
|
||||
ParenRange);
|
||||
}
|
||||
|
|
|
@ -3077,7 +3077,7 @@ static ExprResult BuildCXXCastArgument(Sema &S,
|
|||
return ExprError();
|
||||
|
||||
ExprResult Result = S.BuildCXXConstructExpr(
|
||||
CastLoc, Ty, cast<CXXConstructorDecl>(Method),
|
||||
CastLoc, Ty, FoundDecl, cast<CXXConstructorDecl>(Method),
|
||||
ConstructorArgs, HadMultipleCandidates,
|
||||
/*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
|
||||
CXXConstructExpr::CK_Complete, SourceRange());
|
||||
|
@ -3228,13 +3228,15 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
|
|||
ConstructorArgs))
|
||||
return ExprError();
|
||||
return BuildCXXConstructExpr(
|
||||
/*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.CopyConstructor,
|
||||
/*FIXME:ConstructLoc*/ SourceLocation(), ToType,
|
||||
SCS.FoundCopyConstructor, SCS.CopyConstructor,
|
||||
ConstructorArgs, /*HadMultipleCandidates*/ false,
|
||||
/*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
|
||||
CXXConstructExpr::CK_Complete, SourceRange());
|
||||
}
|
||||
return BuildCXXConstructExpr(
|
||||
/*FIXME:ConstructLoc*/ SourceLocation(), ToType, SCS.CopyConstructor,
|
||||
/*FIXME:ConstructLoc*/ SourceLocation(), ToType,
|
||||
SCS.FoundCopyConstructor, SCS.CopyConstructor,
|
||||
From, /*HadMultipleCandidates*/ false,
|
||||
/*ListInit*/ false, /*StdInitListInit*/ false, /*ZeroInit*/ false,
|
||||
CXXConstructExpr::CK_Complete, SourceRange());
|
||||
|
|
|
@ -3449,18 +3449,13 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
|
|||
CandidateSet.clear();
|
||||
|
||||
for (NamedDecl *D : Ctors) {
|
||||
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
|
||||
auto Info = getConstructorInfo(D);
|
||||
if (!Info.Constructor)
|
||||
continue;
|
||||
|
||||
bool SuppressUserConversions = false;
|
||||
|
||||
// Find the constructor (which may be a template).
|
||||
CXXConstructorDecl *Constructor = nullptr;
|
||||
FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
|
||||
if (ConstructorTmpl)
|
||||
Constructor = cast<CXXConstructorDecl>(
|
||||
ConstructorTmpl->getTemplatedDecl());
|
||||
else {
|
||||
Constructor = cast<CXXConstructorDecl>(D);
|
||||
|
||||
if (!Info.ConstructorTmpl) {
|
||||
// C++11 [over.best.ics]p4:
|
||||
// ... and the constructor or user-defined conversion function is a
|
||||
// candidate by
|
||||
|
@ -3477,15 +3472,15 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
|
|||
// parameter of a constructor of X.
|
||||
if ((CopyInitializing ||
|
||||
(IsListInit && Args.size() == 1 && isa<InitListExpr>(Args[0]))) &&
|
||||
Constructor->isCopyOrMoveConstructor())
|
||||
Info.Constructor->isCopyOrMoveConstructor())
|
||||
SuppressUserConversions = true;
|
||||
}
|
||||
|
||||
if (!Constructor->isInvalidDecl() &&
|
||||
(AllowExplicit || !Constructor->isExplicit()) &&
|
||||
(!OnlyListConstructors || S.isInitListConstructor(Constructor))) {
|
||||
if (ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
|
||||
if (!Info.Constructor->isInvalidDecl() &&
|
||||
(AllowExplicit || !Info.Constructor->isExplicit()) &&
|
||||
(!OnlyListConstructors || S.isInitListConstructor(Info.Constructor))) {
|
||||
if (Info.ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
|
||||
/*ExplicitArgs*/ nullptr, Args,
|
||||
CandidateSet, SuppressUserConversions);
|
||||
else {
|
||||
|
@ -3497,9 +3492,9 @@ ResolveConstructorOverload(Sema &S, SourceLocation DeclLoc,
|
|||
// are also considered.
|
||||
bool AllowExplicitConv = AllowExplicit && !CopyInitializing &&
|
||||
Args.size() == 1 &&
|
||||
Constructor->isCopyOrMoveConstructor();
|
||||
S.AddOverloadCandidate(Constructor, FoundDecl, Args, CandidateSet,
|
||||
SuppressUserConversions,
|
||||
Info.Constructor->isCopyOrMoveConstructor();
|
||||
S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, Args,
|
||||
CandidateSet, SuppressUserConversions,
|
||||
/*PartialOverloading=*/false,
|
||||
/*AllowExplicit=*/AllowExplicitConv);
|
||||
}
|
||||
|
@ -3991,26 +3986,19 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,
|
|||
CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());
|
||||
|
||||
for (NamedDecl *D : S.LookupConstructors(T1RecordDecl)) {
|
||||
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
|
||||
auto Info = getConstructorInfo(D);
|
||||
if (!Info.Constructor)
|
||||
continue;
|
||||
|
||||
// Find the constructor (which may be a template).
|
||||
CXXConstructorDecl *Constructor = nullptr;
|
||||
FunctionTemplateDecl *ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D);
|
||||
if (ConstructorTmpl)
|
||||
Constructor = cast<CXXConstructorDecl>(
|
||||
ConstructorTmpl->getTemplatedDecl());
|
||||
else
|
||||
Constructor = cast<CXXConstructorDecl>(D);
|
||||
|
||||
if (!Constructor->isInvalidDecl() &&
|
||||
Constructor->isConvertingConstructor(AllowExplicit)) {
|
||||
if (ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
|
||||
if (!Info.Constructor->isInvalidDecl() &&
|
||||
Info.Constructor->isConvertingConstructor(AllowExplicit)) {
|
||||
if (Info.ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
|
||||
/*ExplicitArgs*/ nullptr,
|
||||
Initializer, CandidateSet,
|
||||
/*SuppressUserConversions=*/true);
|
||||
else
|
||||
S.AddOverloadCandidate(Constructor, FoundDecl,
|
||||
S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
|
||||
Initializer, CandidateSet,
|
||||
/*SuppressUserConversions=*/true);
|
||||
}
|
||||
|
@ -4614,27 +4602,19 @@ static void TryUserDefinedConversion(Sema &S,
|
|||
Con = CopyOfCon.begin(), ConEnd = CopyOfCon.end();
|
||||
Con != ConEnd; ++Con) {
|
||||
NamedDecl *D = *Con;
|
||||
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
|
||||
auto Info = getConstructorInfo(D);
|
||||
if (!Info.Constructor)
|
||||
continue;
|
||||
|
||||
// Find the constructor (which may be a template).
|
||||
CXXConstructorDecl *Constructor = nullptr;
|
||||
FunctionTemplateDecl *ConstructorTmpl
|
||||
= dyn_cast<FunctionTemplateDecl>(D);
|
||||
if (ConstructorTmpl)
|
||||
Constructor = cast<CXXConstructorDecl>(
|
||||
ConstructorTmpl->getTemplatedDecl());
|
||||
else
|
||||
Constructor = cast<CXXConstructorDecl>(D);
|
||||
|
||||
if (!Constructor->isInvalidDecl() &&
|
||||
Constructor->isConvertingConstructor(AllowExplicit)) {
|
||||
if (ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
|
||||
if (!Info.Constructor->isInvalidDecl() &&
|
||||
Info.Constructor->isConvertingConstructor(AllowExplicit)) {
|
||||
if (Info.ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
|
||||
/*ExplicitArgs*/ nullptr,
|
||||
Initializer, CandidateSet,
|
||||
/*SuppressUserConversions=*/true);
|
||||
else
|
||||
S.AddOverloadCandidate(Constructor, FoundDecl,
|
||||
S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
|
||||
Initializer, CandidateSet,
|
||||
/*SuppressUserConversions=*/true);
|
||||
}
|
||||
|
@ -5378,38 +5358,33 @@ static void LookupCopyAndMoveConstructors(Sema &S,
|
|||
for (SmallVectorImpl<NamedDecl *>::iterator
|
||||
CI = Ctors.begin(), CE = Ctors.end(); CI != CE; ++CI) {
|
||||
NamedDecl *D = *CI;
|
||||
CXXConstructorDecl *Constructor = nullptr;
|
||||
|
||||
if ((Constructor = dyn_cast<CXXConstructorDecl>(D))) {
|
||||
// Handle copy/moveconstructors, only.
|
||||
if (!Constructor || Constructor->isInvalidDecl() ||
|
||||
!Constructor->isCopyOrMoveConstructor() ||
|
||||
!Constructor->isConvertingConstructor(/*AllowExplicit=*/true))
|
||||
auto Info = getConstructorInfo(D);
|
||||
if (!Info.Constructor)
|
||||
continue;
|
||||
|
||||
DeclAccessPair FoundDecl
|
||||
= DeclAccessPair::make(Constructor, Constructor->getAccess());
|
||||
S.AddOverloadCandidate(Constructor, FoundDecl,
|
||||
if (!Info.ConstructorTmpl) {
|
||||
// Handle copy/move constructors, only.
|
||||
if (Info.Constructor->isInvalidDecl() ||
|
||||
!Info.Constructor->isCopyOrMoveConstructor() ||
|
||||
!Info.Constructor->isConvertingConstructor(/*AllowExplicit=*/true))
|
||||
continue;
|
||||
|
||||
S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
|
||||
CurInitExpr, CandidateSet);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle constructor templates.
|
||||
FunctionTemplateDecl *ConstructorTmpl = cast<FunctionTemplateDecl>(D);
|
||||
if (ConstructorTmpl->isInvalidDecl())
|
||||
if (Info.ConstructorTmpl->isInvalidDecl())
|
||||
continue;
|
||||
|
||||
Constructor = cast<CXXConstructorDecl>(
|
||||
ConstructorTmpl->getTemplatedDecl());
|
||||
if (!Constructor->isConvertingConstructor(/*AllowExplicit=*/true))
|
||||
if (!Info.Constructor->isConvertingConstructor(/*AllowExplicit=*/true))
|
||||
continue;
|
||||
|
||||
// FIXME: Do we need to limit this to copy-constructor-like
|
||||
// candidates?
|
||||
DeclAccessPair FoundDecl
|
||||
= DeclAccessPair::make(ConstructorTmpl, ConstructorTmpl->getAccess());
|
||||
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, nullptr,
|
||||
CurInitExpr, CandidateSet, true);
|
||||
S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
|
||||
nullptr, CurInitExpr, CandidateSet, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5584,7 +5559,8 @@ static ExprResult CopyObject(Sema &S,
|
|||
return ExprError();
|
||||
|
||||
// Actually perform the constructor call.
|
||||
CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable,
|
||||
CurInit = S.BuildCXXConstructExpr(Loc, T, Best->FoundDecl, Constructor,
|
||||
Elidable,
|
||||
ConstructorArgs,
|
||||
HadMultipleCandidates,
|
||||
/*ListInit*/ false,
|
||||
|
@ -5770,9 +5746,10 @@ PerformConstructorInitialization(Sema &S,
|
|||
: Kind.getParenRange();
|
||||
|
||||
CurInit = new (S.Context) CXXTemporaryObjectExpr(
|
||||
S.Context, Constructor, TSInfo, ConstructorArgs, ParenOrBraceRange,
|
||||
HadMultipleCandidates, IsListInitialization,
|
||||
IsStdInitListInitialization, ConstructorInitRequiresZeroInit);
|
||||
S.Context, Step.Function.FoundDecl, Constructor, TSInfo,
|
||||
ConstructorArgs, ParenOrBraceRange, HadMultipleCandidates,
|
||||
IsListInitialization, IsStdInitListInitialization,
|
||||
ConstructorInitRequiresZeroInit);
|
||||
} else {
|
||||
CXXConstructExpr::ConstructionKind ConstructKind =
|
||||
CXXConstructExpr::CK_Complete;
|
||||
|
@ -5797,6 +5774,7 @@ PerformConstructorInitialization(Sema &S,
|
|||
// unconditionally.
|
||||
if (Entity.allowsNRVO())
|
||||
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
|
||||
Step.Function.FoundDecl,
|
||||
Constructor, /*Elidable=*/true,
|
||||
ConstructorArgs,
|
||||
HadMultipleCandidates,
|
||||
|
@ -5807,6 +5785,7 @@ PerformConstructorInitialization(Sema &S,
|
|||
ParenOrBraceRange);
|
||||
else
|
||||
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
|
||||
Step.Function.FoundDecl,
|
||||
Constructor,
|
||||
ConstructorArgs,
|
||||
HadMultipleCandidates,
|
||||
|
@ -6511,7 +6490,8 @@ InitializationSequence::Perform(Sema &S,
|
|||
return ExprError();
|
||||
|
||||
// Build an expression that constructs a temporary.
|
||||
CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor,
|
||||
CurInit = S.BuildCXXConstructExpr(Loc, Step->Type,
|
||||
FoundFn, Constructor,
|
||||
ConstructorArgs,
|
||||
HadMultipleCandidates,
|
||||
/*ListInit*/ false,
|
||||
|
|
|
@ -3196,7 +3196,7 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
|
|||
if (FoundRaw && FoundTemplate) {
|
||||
Diag(R.getNameLoc(), diag::err_ovl_ambiguous_call) << R.getLookupName();
|
||||
for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
|
||||
NoteOverloadCandidate((*I)->getUnderlyingDecl()->getAsFunction());
|
||||
NoteOverloadCandidate(*I, (*I)->getUnderlyingDecl()->getAsFunction());
|
||||
return LOLR_Error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1218,11 +1218,13 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
S.IsDerivedFrom(From->getLocStart(), FromCanon, ToCanon))) {
|
||||
// Turn this into a "standard" conversion sequence, so that it
|
||||
// gets ranked with standard conversion sequences.
|
||||
DeclAccessPair Found = ICS.UserDefined.FoundConversionFunction;
|
||||
ICS.setStandard();
|
||||
ICS.Standard.setAsIdentityConversion();
|
||||
ICS.Standard.setFromType(From->getType());
|
||||
ICS.Standard.setAllToTypes(ToType);
|
||||
ICS.Standard.CopyConstructor = Constructor;
|
||||
ICS.Standard.FoundCopyConstructor = Found;
|
||||
if (ToCanon != FromCanon)
|
||||
ICS.Standard.Second = ICK_Derived_To_Base;
|
||||
}
|
||||
|
@ -1236,7 +1238,7 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
for (OverloadCandidateSet::iterator Cand = Conversions.begin();
|
||||
Cand != Conversions.end(); ++Cand)
|
||||
if (Cand->Viable)
|
||||
ICS.Ambiguous.addConversion(Cand->Function);
|
||||
ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function);
|
||||
break;
|
||||
|
||||
// Fall through.
|
||||
|
@ -3051,39 +3053,26 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType,
|
|||
UserDefinedConversionSequence &User,
|
||||
OverloadCandidateSet &CandidateSet,
|
||||
bool AllowExplicit) {
|
||||
DeclContext::lookup_result R = S.LookupConstructors(To);
|
||||
for (DeclContext::lookup_iterator Con = R.begin(), ConEnd = R.end();
|
||||
Con != ConEnd; ++Con) {
|
||||
NamedDecl *D = *Con;
|
||||
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
|
||||
for (auto *D : S.LookupConstructors(To)) {
|
||||
auto Info = getConstructorInfo(D);
|
||||
if (!Info.Constructor)
|
||||
continue;
|
||||
|
||||
// Find the constructor (which may be a template).
|
||||
CXXConstructorDecl *Constructor = nullptr;
|
||||
FunctionTemplateDecl *ConstructorTmpl
|
||||
= dyn_cast<FunctionTemplateDecl>(D);
|
||||
if (ConstructorTmpl)
|
||||
Constructor
|
||||
= cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl());
|
||||
else
|
||||
Constructor = cast<CXXConstructorDecl>(D);
|
||||
|
||||
bool Usable = !Constructor->isInvalidDecl() &&
|
||||
S.isInitListConstructor(Constructor) &&
|
||||
(AllowExplicit || !Constructor->isExplicit());
|
||||
bool Usable = !Info.Constructor->isInvalidDecl() &&
|
||||
S.isInitListConstructor(Info.Constructor) &&
|
||||
(AllowExplicit || !Info.Constructor->isExplicit());
|
||||
if (Usable) {
|
||||
// If the first argument is (a reference to) the target type,
|
||||
// suppress conversions.
|
||||
bool SuppressUserConversions =
|
||||
isFirstArgumentCompatibleWithType(S.Context, Constructor, ToType);
|
||||
if (ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
|
||||
/*ExplicitArgs*/ nullptr,
|
||||
From, CandidateSet,
|
||||
SuppressUserConversions);
|
||||
bool SuppressUserConversions = isFirstArgumentCompatibleWithType(
|
||||
S.Context, Info.Constructor, ToType);
|
||||
if (Info.ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl,
|
||||
/*ExplicitArgs*/ nullptr, From,
|
||||
CandidateSet, SuppressUserConversions);
|
||||
else
|
||||
S.AddOverloadCandidate(Constructor, FoundDecl,
|
||||
From, CandidateSet,
|
||||
SuppressUserConversions);
|
||||
S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, From,
|
||||
CandidateSet, SuppressUserConversions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3183,27 +3172,17 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
ListInitializing = true;
|
||||
}
|
||||
|
||||
DeclContext::lookup_result R = S.LookupConstructors(ToRecordDecl);
|
||||
for (DeclContext::lookup_iterator Con = R.begin(), ConEnd = R.end();
|
||||
Con != ConEnd; ++Con) {
|
||||
NamedDecl *D = *Con;
|
||||
DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess());
|
||||
for (auto *D : S.LookupConstructors(ToRecordDecl)) {
|
||||
auto Info = getConstructorInfo(D);
|
||||
if (!Info.Constructor)
|
||||
continue;
|
||||
|
||||
// Find the constructor (which may be a template).
|
||||
CXXConstructorDecl *Constructor = nullptr;
|
||||
FunctionTemplateDecl *ConstructorTmpl
|
||||
= dyn_cast<FunctionTemplateDecl>(D);
|
||||
if (ConstructorTmpl)
|
||||
Constructor
|
||||
= cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl());
|
||||
else
|
||||
Constructor = cast<CXXConstructorDecl>(D);
|
||||
|
||||
bool Usable = !Constructor->isInvalidDecl();
|
||||
bool Usable = !Info.Constructor->isInvalidDecl();
|
||||
if (ListInitializing)
|
||||
Usable = Usable && (AllowExplicit || !Constructor->isExplicit());
|
||||
Usable = Usable && (AllowExplicit || !Info.Constructor->isExplicit());
|
||||
else
|
||||
Usable = Usable &&Constructor->isConvertingConstructor(AllowExplicit);
|
||||
Usable = Usable &&
|
||||
Info.Constructor->isConvertingConstructor(AllowExplicit);
|
||||
if (Usable) {
|
||||
bool SuppressUserConversions = !ConstructorsOnly;
|
||||
if (SuppressUserConversions && ListInitializing) {
|
||||
|
@ -3212,18 +3191,18 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
|
|||
// If the first argument is (a reference to) the target type,
|
||||
// suppress conversions.
|
||||
SuppressUserConversions = isFirstArgumentCompatibleWithType(
|
||||
S.Context, Constructor, ToType);
|
||||
S.Context, Info.Constructor, ToType);
|
||||
}
|
||||
}
|
||||
if (ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl,
|
||||
/*ExplicitArgs*/ nullptr,
|
||||
llvm::makeArrayRef(Args, NumArgs),
|
||||
if (Info.ConstructorTmpl)
|
||||
S.AddTemplateOverloadCandidate(
|
||||
Info.ConstructorTmpl, Info.FoundDecl,
|
||||
/*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs),
|
||||
CandidateSet, SuppressUserConversions);
|
||||
else
|
||||
// Allow one user-defined conversion when user specifies a
|
||||
// From->ToType conversion via an static cast (c-style, etc).
|
||||
S.AddOverloadCandidate(Constructor, FoundDecl,
|
||||
S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl,
|
||||
llvm::makeArrayRef(Args, NumArgs),
|
||||
CandidateSet, SuppressUserConversions);
|
||||
}
|
||||
|
@ -4288,7 +4267,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
|
|||
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
|
||||
Cand != CandidateSet.end(); ++Cand)
|
||||
if (Cand->Viable)
|
||||
ICS.Ambiguous.addConversion(Cand->Function);
|
||||
ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function);
|
||||
return true;
|
||||
|
||||
case OR_No_Viable_Function:
|
||||
|
@ -8862,6 +8841,7 @@ enum OverloadCandidateKind {
|
|||
};
|
||||
|
||||
OverloadCandidateKind ClassifyOverloadCandidate(Sema &S,
|
||||
NamedDecl *Found,
|
||||
FunctionDecl *Fn,
|
||||
std::string &Description) {
|
||||
bool isTemplate = false;
|
||||
|
@ -8990,13 +8970,13 @@ bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function,
|
|||
}
|
||||
|
||||
// Notes the location of an overload candidate.
|
||||
void Sema::NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType,
|
||||
bool TakingAddress) {
|
||||
void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn,
|
||||
QualType DestType, bool TakingAddress) {
|
||||
if (TakingAddress && !checkAddressOfCandidateIsAvailable(*this, Fn))
|
||||
return;
|
||||
|
||||
std::string FnDesc;
|
||||
OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Fn, FnDesc);
|
||||
OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Found, Fn, FnDesc);
|
||||
PartialDiagnostic PD = PDiag(diag::note_ovl_candidate)
|
||||
<< (unsigned) K << FnDesc;
|
||||
|
||||
|
@ -9019,11 +8999,11 @@ void Sema::NoteAllOverloadCandidates(Expr *OverloadedExpr, QualType DestType,
|
|||
I != IEnd; ++I) {
|
||||
if (FunctionTemplateDecl *FunTmpl =
|
||||
dyn_cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl()) ) {
|
||||
NoteOverloadCandidate(FunTmpl->getTemplatedDecl(), DestType,
|
||||
NoteOverloadCandidate(*I, FunTmpl->getTemplatedDecl(), DestType,
|
||||
TakingAddress);
|
||||
} else if (FunctionDecl *Fun
|
||||
= dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()) ) {
|
||||
NoteOverloadCandidate(Fun, DestType, TakingAddress);
|
||||
NoteOverloadCandidate(*I, Fun, DestType, TakingAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9047,7 +9027,7 @@ void ImplicitConversionSequence::DiagnoseAmbiguousConversion(
|
|||
if (CandsShown >= 4 && ShowOverloads == Ovl_Best)
|
||||
break;
|
||||
++CandsShown;
|
||||
S.NoteOverloadCandidate(*I);
|
||||
S.NoteOverloadCandidate(I->first, I->second);
|
||||
}
|
||||
if (I != E)
|
||||
S.Diag(SourceLocation(), diag::note_ovl_too_many_candidates) << int(E - I);
|
||||
|
@ -9072,7 +9052,8 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand,
|
|||
}
|
||||
|
||||
std::string FnDesc;
|
||||
OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc);
|
||||
OverloadCandidateKind FnKind =
|
||||
ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc);
|
||||
|
||||
Expr *FromExpr = Conv.Bad.FromExpr;
|
||||
QualType FromTy = Conv.Bad.getFromType();
|
||||
|
@ -9318,7 +9299,8 @@ static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand,
|
|||
}
|
||||
|
||||
/// General arity mismatch diagnosis over a candidate in a candidate set.
|
||||
static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) {
|
||||
static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D,
|
||||
unsigned NumFormalArgs) {
|
||||
assert(isa<FunctionDecl>(D) &&
|
||||
"The templated declaration should at least be a function"
|
||||
" when diagnosing bad template argument deduction due to too many"
|
||||
|
@ -9348,7 +9330,8 @@ static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) {
|
|||
}
|
||||
|
||||
std::string Description;
|
||||
OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description);
|
||||
OverloadCandidateKind FnKind =
|
||||
ClassifyOverloadCandidate(S, Found, Fn, Description);
|
||||
|
||||
if (modeCount == 1 && Fn->getParamDecl(0)->getDeclName())
|
||||
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one)
|
||||
|
@ -9365,7 +9348,7 @@ static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) {
|
|||
static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand,
|
||||
unsigned NumFormalArgs) {
|
||||
if (!CheckArityMismatch(S, Cand, NumFormalArgs))
|
||||
DiagnoseArityMismatch(S, Cand->Function, NumFormalArgs);
|
||||
DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs);
|
||||
}
|
||||
|
||||
static TemplateDecl *getDescribedTemplate(Decl *Templated) {
|
||||
|
@ -9376,7 +9359,7 @@ static TemplateDecl *getDescribedTemplate(Decl *Templated) {
|
|||
}
|
||||
|
||||
/// Diagnose a failed template-argument deduction.
|
||||
static void DiagnoseBadDeduction(Sema &S, Decl *Templated,
|
||||
static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
|
||||
DeductionFailureInfo &DeductionFailure,
|
||||
unsigned NumArgs,
|
||||
bool TakingCandidateAddress) {
|
||||
|
@ -9466,7 +9449,7 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated,
|
|||
|
||||
case Sema::TDK_TooManyArguments:
|
||||
case Sema::TDK_TooFewArguments:
|
||||
DiagnoseArityMismatch(S, Templated, NumArgs);
|
||||
DiagnoseArityMismatch(S, Found, Templated, NumArgs);
|
||||
return;
|
||||
|
||||
case Sema::TDK_InstantiationDepth:
|
||||
|
@ -9596,7 +9579,7 @@ static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand,
|
|||
if (CheckArityMismatch(S, Cand, NumArgs))
|
||||
return;
|
||||
}
|
||||
DiagnoseBadDeduction(S, Cand->Function, // pattern
|
||||
DiagnoseBadDeduction(S, Cand->FoundDecl, Cand->Function, // pattern
|
||||
Cand->DeductionFailure, NumArgs, TakingCandidateAddress);
|
||||
}
|
||||
|
||||
|
@ -9609,7 +9592,8 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) {
|
|||
CalleeTarget = S.IdentifyCUDATarget(Callee);
|
||||
|
||||
std::string FnDesc;
|
||||
OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Callee, FnDesc);
|
||||
OverloadCandidateKind FnKind =
|
||||
ClassifyOverloadCandidate(S, Cand->FoundDecl, Callee, FnDesc);
|
||||
|
||||
S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target)
|
||||
<< (unsigned)FnKind << CalleeTarget << CallerTarget;
|
||||
|
@ -9686,7 +9670,8 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
|
|||
if (Cand->Viable && (Fn->isDeleted() ||
|
||||
S.isFunctionConsideredUnavailable(Fn))) {
|
||||
std::string FnDesc;
|
||||
OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc);
|
||||
OverloadCandidateKind FnKind =
|
||||
ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc);
|
||||
|
||||
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)
|
||||
<< FnKind << FnDesc
|
||||
|
@ -9697,7 +9682,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
|
|||
|
||||
// We don't really have anything else to say about viable candidates.
|
||||
if (Cand->Viable) {
|
||||
S.NoteOverloadCandidate(Fn);
|
||||
S.NoteOverloadCandidate(Cand->FoundDecl, Fn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -9707,7 +9692,8 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
|
|||
return DiagnoseArityMismatch(S, Cand, NumArgs);
|
||||
|
||||
case ovl_fail_bad_deduction:
|
||||
return DiagnoseBadDeduction(S, Cand, NumArgs, TakingCandidateAddress);
|
||||
return DiagnoseBadDeduction(S, Cand, NumArgs,
|
||||
TakingCandidateAddress);
|
||||
|
||||
case ovl_fail_illegal_constructor: {
|
||||
S.Diag(Fn->getLocation(), diag::note_ovl_candidate_illegal_constructor)
|
||||
|
@ -9719,7 +9705,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
|
|||
case ovl_fail_trivial_conversion:
|
||||
case ovl_fail_bad_final_conversion:
|
||||
case ovl_fail_final_conversion_not_exact:
|
||||
return S.NoteOverloadCandidate(Fn);
|
||||
return S.NoteOverloadCandidate(Cand->FoundDecl, Fn);
|
||||
|
||||
case ovl_fail_bad_conversion: {
|
||||
unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0);
|
||||
|
@ -9730,7 +9716,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
|
|||
// FIXME: this currently happens when we're called from SemaInit
|
||||
// when user-conversion overload fails. Figure out how to handle
|
||||
// those conditions and diagnose them well.
|
||||
return S.NoteOverloadCandidate(Fn);
|
||||
return S.NoteOverloadCandidate(Cand->FoundDecl, Fn);
|
||||
}
|
||||
|
||||
case ovl_fail_bad_target:
|
||||
|
@ -9808,8 +9794,8 @@ static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
|
|||
if (ICS.isBad()) break; // all meaningless after first invalid
|
||||
if (!ICS.isAmbiguous()) continue;
|
||||
|
||||
ICS.DiagnoseAmbiguousConversion(S, OpLoc,
|
||||
S.PDiag(diag::note_ambiguous_type_conversion));
|
||||
ICS.DiagnoseAmbiguousConversion(
|
||||
S, OpLoc, S.PDiag(diag::note_ambiguous_type_conversion));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10176,7 +10162,7 @@ struct CompareTemplateSpecCandidatesForDisplay {
|
|||
/// deductions.
|
||||
void TemplateSpecCandidate::NoteDeductionFailure(Sema &S,
|
||||
bool ForTakingAddress) {
|
||||
DiagnoseBadDeduction(S, Specialization, // pattern
|
||||
DiagnoseBadDeduction(S, FoundDecl, Specialization, // pattern
|
||||
DeductionFailure, /*NumArgs=*/0, ForTakingAddress);
|
||||
}
|
||||
|
||||
|
@ -10429,7 +10415,7 @@ private:
|
|||
Info, /*InOverloadResolution=*/true)) {
|
||||
// Make a note of the failed deduction for diagnostics.
|
||||
FailedCandidates.addCandidate()
|
||||
.set(FunctionTemplate->getTemplatedDecl(),
|
||||
.set(CurAccessFunPair, FunctionTemplate->getTemplatedDecl(),
|
||||
MakeDeductionFailureInfo(Context, Result, Info));
|
||||
return false;
|
||||
}
|
||||
|
@ -10595,7 +10581,7 @@ public:
|
|||
if (FunctionDecl *Fun =
|
||||
dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()))
|
||||
if (!functionHasPassObjectSizeParams(Fun))
|
||||
S.NoteOverloadCandidate(Fun, TargetFunctionType,
|
||||
S.NoteOverloadCandidate(*I, Fun, TargetFunctionType,
|
||||
/*TakingAddress=*/true);
|
||||
FailedCandidates.NoteCandidates(S, OvlExpr->getLocStart());
|
||||
}
|
||||
|
@ -10801,7 +10787,7 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
|
|||
// Make a note of the failed deduction for diagnostics.
|
||||
// TODO: Actually use the failed-deduction info?
|
||||
FailedCandidates.addCandidate()
|
||||
.set(FunctionTemplate->getTemplatedDecl(),
|
||||
.set(I.getPair(), FunctionTemplate->getTemplatedDecl(),
|
||||
MakeDeductionFailureInfo(Context, Result, Info));
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -2791,8 +2791,9 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
|
|||
DeduceTemplateArguments(Partial, TemplateArgList, Info)) {
|
||||
// Store the failed-deduction information for use in diagnostics, later.
|
||||
// TODO: Actually use the failed-deduction info?
|
||||
FailedCandidates.addCandidate()
|
||||
.set(Partial, MakeDeductionFailureInfo(Context, Result, Info));
|
||||
FailedCandidates.addCandidate().set(
|
||||
DeclAccessPair::make(Template, AS_public), Partial,
|
||||
MakeDeductionFailureInfo(Context, Result, Info));
|
||||
(void)Result;
|
||||
} else {
|
||||
Matched.push_back(PartialSpecMatchResult());
|
||||
|
@ -6895,11 +6896,12 @@ bool Sema::CheckFunctionTemplateSpecialization(
|
|||
FunctionDecl *Specialization = nullptr;
|
||||
if (TemplateDeductionResult TDK = DeduceTemplateArguments(
|
||||
cast<FunctionTemplateDecl>(FunTmpl->getFirstDecl()),
|
||||
ExplicitTemplateArgs ? &Args : nullptr, FT, Specialization, Info)) {
|
||||
ExplicitTemplateArgs ? &Args : nullptr, FT, Specialization,
|
||||
Info)) {
|
||||
// Template argument deduction failed; record why it failed, so
|
||||
// that we can provide nifty diagnostics.
|
||||
FailedCandidates.addCandidate()
|
||||
.set(FunTmpl->getTemplatedDecl(),
|
||||
FailedCandidates.addCandidate().set(
|
||||
I.getPair(), FunTmpl->getTemplatedDecl(),
|
||||
MakeDeductionFailureInfo(Context, TDK, Info));
|
||||
(void)TDK;
|
||||
continue;
|
||||
|
@ -7925,7 +7927,7 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
|
|||
R, Specialization, Info)) {
|
||||
// Keep track of almost-matches.
|
||||
FailedCandidates.addCandidate()
|
||||
.set(FunTmpl->getTemplatedDecl(),
|
||||
.set(P.getPair(), FunTmpl->getTemplatedDecl(),
|
||||
MakeDeductionFailureInfo(Context, TDK, Info));
|
||||
(void)TDK;
|
||||
continue;
|
||||
|
|
|
@ -2321,8 +2321,9 @@ bool Sema::InstantiateClassTemplateSpecialization(
|
|||
Info)) {
|
||||
// Store the failed-deduction information for use in diagnostics, later.
|
||||
// TODO: Actually use the failed-deduction info?
|
||||
FailedCandidates.addCandidate()
|
||||
.set(Partial, MakeDeductionFailureInfo(Context, Result, Info));
|
||||
FailedCandidates.addCandidate().set(
|
||||
DeclAccessPair::make(Template, AS_public), Partial,
|
||||
MakeDeductionFailureInfo(Context, Result, Info));
|
||||
(void)Result;
|
||||
} else {
|
||||
Matched.push_back(PartialSpecMatchResult());
|
||||
|
|
|
@ -2637,6 +2637,7 @@ public:
|
|||
/// Subclasses may override this routine to provide different behavior.
|
||||
ExprResult RebuildCXXConstructExpr(QualType T,
|
||||
SourceLocation Loc,
|
||||
NamedDecl *Found,
|
||||
CXXConstructorDecl *Constructor,
|
||||
bool IsElidable,
|
||||
MultiExprArg Args,
|
||||
|
@ -2651,7 +2652,8 @@ public:
|
|||
ConvertedArgs))
|
||||
return ExprError();
|
||||
|
||||
return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
|
||||
return getSema().BuildCXXConstructExpr(Loc, T, Found, Constructor,
|
||||
IsElidable,
|
||||
ConvertedArgs,
|
||||
HadMultipleCandidates,
|
||||
ListInitialization,
|
||||
|
@ -9880,6 +9882,11 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
|
|||
if (T.isNull())
|
||||
return ExprError();
|
||||
|
||||
NamedDecl *FoundDecl = cast_or_null<NamedDecl>(
|
||||
getDerived().TransformDecl(E->getLocStart(), E->getFoundDecl()));
|
||||
if (!FoundDecl)
|
||||
return ExprError();
|
||||
|
||||
CXXConstructorDecl *Constructor
|
||||
= cast_or_null<CXXConstructorDecl>(
|
||||
getDerived().TransformDecl(E->getLocStart(),
|
||||
|
@ -9895,6 +9902,7 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
|
|||
|
||||
if (!getDerived().AlwaysRebuild() &&
|
||||
T == E->getType() &&
|
||||
FoundDecl == E->getFoundDecl() &&
|
||||
Constructor == E->getConstructor() &&
|
||||
!ArgumentChanged) {
|
||||
// Mark the constructor as referenced.
|
||||
|
@ -9904,8 +9912,8 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
|
|||
}
|
||||
|
||||
return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
|
||||
Constructor, E->isElidable(),
|
||||
Args,
|
||||
FoundDecl, Constructor,
|
||||
E->isElidable(), Args,
|
||||
E->hadMultipleCandidates(),
|
||||
E->isListInitialization(),
|
||||
E->isStdInitListInitialization(),
|
||||
|
|
Loading…
Reference in New Issue