Added a flag to identify resolved overloaded function references.

llvm-svn: 141171
This commit is contained in:
Abramo Bagnara 2011-10-05 07:56:41 +00:00
parent b50451a188
commit 635ed24e1d
16 changed files with 237 additions and 87 deletions

View File

@ -770,6 +770,7 @@ public:
DeclRefExprBits.HasQualifier = 0;
DeclRefExprBits.HasExplicitTemplateArgs = 0;
DeclRefExprBits.HasFoundDecl = 0;
DeclRefExprBits.HadMultipleCandidates = 0;
computeDependence();
}
@ -923,6 +924,18 @@ public:
return getExplicitTemplateArgs().RAngleLoc;
}
/// \brief Returns true if this expression refers to a function that
/// was resolved from an overloaded set having size greater than 1.
bool hadMultipleCandidates() const {
return DeclRefExprBits.HadMultipleCandidates;
}
/// \brief Sets the flag telling whether this expression refers to
/// a function that was resolved from an overloaded set having size
/// greater than 1.
void setHadMultipleCandidates(bool V = true) {
DeclRefExprBits.HadMultipleCandidates = V;
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == DeclRefExprClass;
}
@ -2021,6 +2034,10 @@ class MemberExpr : public Expr {
/// the MemberNameQualifier structure.
bool HasExplicitTemplateArgumentList : 1;
/// \brief True if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1.
bool HadMultipleCandidates : 1;
/// \brief Retrieve the qualifier that preceded the member name, if any.
MemberNameQualifier *getMemberQualifier() {
assert(HasQualifierOrFoundDecl);
@ -2043,7 +2060,8 @@ public:
base->containsUnexpandedParameterPack()),
Base(base), MemberDecl(memberdecl), MemberLoc(NameInfo.getLoc()),
MemberDNLoc(NameInfo.getInfo()), IsArrow(isarrow),
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false),
HadMultipleCandidates(false) {
assert(memberdecl->getDeclName() == NameInfo.getName());
}
@ -2060,7 +2078,8 @@ public:
base->containsUnexpandedParameterPack()),
Base(base), MemberDecl(memberdecl), MemberLoc(l), MemberDNLoc(),
IsArrow(isarrow),
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {}
HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false),
HadMultipleCandidates(false) {}
static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow,
NestedNameSpecifierLoc QualifierLoc,
@ -2210,7 +2229,19 @@ public:
bool isImplicitAccess() const {
return getBase() && getBase()->isImplicitCXXThis();
}
/// \brief Returns true if this member expression refers to a method that
/// was resolved from an overloaded set having size greater than 1.
bool hadMultipleCandidates() const {
return HadMultipleCandidates;
}
/// \brief Sets the flag telling whether this expression refers to
/// a method that was resolved from an overloaded set having size
/// greater than 1.
void setHadMultipleCandidates(bool V = true) {
HadMultipleCandidates = V;
}
static bool classof(const Stmt *T) {
return T->getStmtClass() == MemberExprClass;
}

View File

@ -809,6 +809,7 @@ private:
SourceRange ParenRange;
unsigned NumArgs : 16;
bool Elidable : 1;
bool HadMultipleCandidates : 1;
bool ZeroInitialization : 1;
unsigned ConstructKind : 2;
Stmt **Args;
@ -818,26 +819,29 @@ protected:
SourceLocation Loc,
CXXConstructorDecl *d, bool elidable,
Expr **args, unsigned numargs,
bool HadMultipleCandidates,
bool ZeroInitialization = false,
ConstructionKind ConstructKind = CK_Complete,
SourceRange ParenRange = SourceRange());
/// \brief Construct an empty C++ construction expression.
CXXConstructExpr(StmtClass SC, EmptyShell Empty)
: Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(0),
ZeroInitialization(0), ConstructKind(0), Args(0) { }
: Expr(SC, Empty), Constructor(0), NumArgs(0), Elidable(0),
HadMultipleCandidates(false), ZeroInitialization(0),
ConstructKind(0), Args(0) { }
public:
/// \brief Construct an empty C++ construction expression.
explicit CXXConstructExpr(EmptyShell Empty)
: Expr(CXXConstructExprClass, Empty), Constructor(0),
NumArgs(0), Elidable(0), ZeroInitialization(0),
ConstructKind(0), Args(0) { }
NumArgs(0), Elidable(0), HadMultipleCandidates(false),
ZeroInitialization(0), ConstructKind(0), Args(0) { }
static CXXConstructExpr *Create(ASTContext &C, QualType T,
SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
bool HadMultipleCandidates,
bool ZeroInitialization = false,
ConstructionKind ConstructKind = CK_Complete,
SourceRange ParenRange = SourceRange());
@ -852,7 +856,12 @@ public:
/// \brief Whether this construction is elidable.
bool isElidable() const { return Elidable; }
void setElidable(bool E) { Elidable = E; }
/// \brief Whether the referred constructor was resolved from
/// an overloaded set having size greater than 1.
bool hadMultipleCandidates() const { return HadMultipleCandidates; }
void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
/// \brief Whether this construction first requires
/// zero-initialization before the initializer is called.
bool requiresZeroInitialization() const { return ZeroInitialization; }
@ -980,6 +989,7 @@ public:
TypeSourceInfo *Type,
Expr **Args,unsigned NumArgs,
SourceRange parenRange,
bool HadMultipleCandidates,
bool ZeroInitialization = false);
explicit CXXTemporaryObjectExpr(EmptyShell Empty)
: CXXConstructExpr(CXXTemporaryObjectExprClass, Empty), Type() { }
@ -1049,8 +1059,11 @@ class CXXNewExpr : public Expr {
// If this is an array allocation, does the usual deallocation
// function for the allocated type want to know the allocated size?
bool UsualArrayDeleteWantsSize : 1;
// Whether the referred constructor (if any) was resolved from an
// overload set having size greater than 1.
bool HadMultipleCandidates : 1;
// The number of placement new arguments.
unsigned NumPlacementArgs : 14;
unsigned NumPlacementArgs : 13;
// The number of constructor arguments. This may be 1 even for non-class
// types; use the pseudo copy constructor.
unsigned NumConstructorArgs : 14;
@ -1086,6 +1099,7 @@ public:
SourceRange TypeIdParens,
Expr *arraySize, CXXConstructorDecl *constructor, bool initializer,
Expr **constructorArgs, unsigned numConsArgs,
bool HadMultipleCandidates,
FunctionDecl *operatorDelete, bool usualArrayDeleteWantsSize,
QualType ty, TypeSourceInfo *AllocatedTypeInfo,
SourceLocation startLoc, SourceLocation endLoc,
@ -1174,6 +1188,11 @@ public:
return cast<Expr>(SubExprs[Array + NumPlacementArgs + i]);
}
/// \brief Whether the new expression refers a constructor that was
/// resolved from an overloaded set having size greater than 1.
bool hadMultipleCandidates() const { return HadMultipleCandidates; }
void setHadMultipleCandidates(bool V) { HadMultipleCandidates = V; }
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;

View File

@ -165,6 +165,7 @@ protected:
unsigned HasQualifier : 1;
unsigned HasExplicitTemplateArgs : 1;
unsigned HasFoundDecl : 1;
unsigned HadMultipleCandidates : 1;
};
class CastExprBitfields {

View File

@ -568,10 +568,12 @@ public:
/// When Kind == SK_ConstructorInitialization or SK_ListConstruction,
/// the constructor to be called.
///
/// Always a FunctionDecl.
/// Always a FunctionDecl, plus a Boolean flag telling if it was
/// selected from an overloaded set having size greater than 1.
/// For conversion decls, the naming class is the source type.
/// For construct decls, the naming class is the target type.
struct {
bool HadMultipleCandidates;
FunctionDecl *Function;
DeclAccessPair FoundDecl;
} Function;

View File

@ -244,7 +244,12 @@ namespace clang {
// a gcc code gen. bug which causes a crash in a test. Putting it here seems
// to work around the crash.
bool EllipsisConversion : 1;
/// HadMultipleCandidates - When this is true, it means that the
/// conversion function was resolved from an overloaded set having
/// size greater than 1.
bool HadMultipleCandidates : 1;
/// After - Represents the standard conversion that occurs after
/// the actual user-defined conversion.
StandardConversionSequence After;

View File

@ -2685,7 +2685,8 @@ public:
/// and sets it as the initializer for the the passed in VarDecl.
bool InitializeVarWithConstructor(VarDecl *VD,
CXXConstructorDecl *Constructor,
MultiExprArg Exprs);
MultiExprArg Exprs,
bool HadMultipleCandidates);
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
/// including handling of its default argument expressions.
@ -2694,16 +2695,16 @@ public:
ExprResult
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, MultiExprArg Exprs,
bool RequiresZeroInit, unsigned ConstructKind,
SourceRange ParenRange);
bool HadMultipleCandidates, bool RequiresZeroInit,
unsigned ConstructKind, SourceRange ParenRange);
// FIXME: Can re remove this and have the above BuildCXXConstructExpr check if
// the constructor can be elidable?
ExprResult
BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg Exprs, bool RequiresZeroInit,
unsigned ConstructKind,
MultiExprArg Exprs, bool HadMultipleCandidates,
bool RequiresZeroInit, unsigned ConstructKind,
SourceRange ParenRange);
/// BuildCXXDefaultArgExpr - Creates a CXXDefaultArgExpr, instantiating
@ -3360,7 +3361,8 @@ public:
TypeSourceInfo *EncodedTypeInfo,
SourceLocation RParenLoc);
ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl,
CXXMethodDecl *Method);
CXXMethodDecl *Method,
bool HadMultipleCandidates);
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation EncodeLoc,

View File

@ -3837,14 +3837,17 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) {
QualType T = Importer.Import(E->getType());
if (T.isNull())
return 0;
return DeclRefExpr::Create(Importer.getToContext(),
Importer.Import(E->getQualifierLoc()),
ToD,
Importer.Import(E->getLocation()),
T, E->getValueKind(),
FoundD,
/*FIXME:TemplateArgs=*/0);
DeclRefExpr *DRE = DeclRefExpr::Create(Importer.getToContext(),
Importer.Import(E->getQualifierLoc()),
ToD,
Importer.Import(E->getLocation()),
T, E->getValueKind(),
FoundD,
/*FIXME:TemplateArgs=*/0);
if (E->hadMultipleCandidates())
DRE->setHadMultipleCandidates(true);
return DRE;
}
Expr *ASTNodeImporter::VisitIntegerLiteral(IntegerLiteral *E) {

View File

@ -49,6 +49,7 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
SourceRange TypeIdParens, Expr *arraySize,
CXXConstructorDecl *constructor, bool initializer,
Expr **constructorArgs, unsigned numConsArgs,
bool HadMultipleCandidates,
FunctionDecl *operatorDelete,
bool usualArrayDeleteWantsSize, QualType ty,
TypeSourceInfo *AllocatedTypeInfo,
@ -61,6 +62,7 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew,
ty->containsUnexpandedParameterPack()),
GlobalNew(globalNew), Initializer(initializer),
UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize),
HadMultipleCandidates(HadMultipleCandidates),
SubExprs(0), OperatorNew(operatorNew),
OperatorDelete(operatorDelete), Constructor(constructor),
AllocatedTypeInfo(AllocatedTypeInfo), TypeIdParens(TypeIdParens),
@ -628,11 +630,13 @@ CXXTemporaryObjectExpr::CXXTemporaryObjectExpr(ASTContext &C,
Expr **Args,
unsigned NumArgs,
SourceRange parenRange,
bool HadMultipleCandidates,
bool ZeroInitialization)
: CXXConstructExpr(C, CXXTemporaryObjectExprClass,
Type->getType().getNonReferenceType(),
Type->getTypeLoc().getBeginLoc(),
Cons, false, Args, NumArgs, ZeroInitialization,
Cons, false, Args, NumArgs,
HadMultipleCandidates, ZeroInitialization,
CXXConstructExpr::CK_Complete, parenRange),
Type(Type) {
}
@ -646,11 +650,13 @@ CXXConstructExpr *CXXConstructExpr::Create(ASTContext &C, QualType T,
SourceLocation Loc,
CXXConstructorDecl *D, bool Elidable,
Expr **Args, unsigned NumArgs,
bool HadMultipleCandidates,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenRange) {
return new (C) CXXConstructExpr(C, CXXConstructExprClass, T, Loc, D,
Elidable, Args, NumArgs, ZeroInitialization,
Elidable, Args, NumArgs,
HadMultipleCandidates, ZeroInitialization,
ConstructKind, ParenRange);
}
@ -658,7 +664,8 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
SourceLocation Loc,
CXXConstructorDecl *D, bool elidable,
Expr **args, unsigned numargs,
bool ZeroInitialization,
bool HadMultipleCandidates,
bool ZeroInitialization,
ConstructionKind ConstructKind,
SourceRange ParenRange)
: Expr(SC, T, VK_RValue, OK_Ordinary,
@ -666,7 +673,8 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T,
T->isInstantiationDependentType(),
T->containsUnexpandedParameterPack()),
Constructor(D), Loc(Loc), ParenRange(ParenRange), NumArgs(numargs),
Elidable(elidable), ZeroInitialization(ZeroInitialization),
Elidable(elidable), HadMultipleCandidates(HadMultipleCandidates),
ZeroInitialization(ZeroInitialization),
ConstructKind(ConstructKind), Args(0)
{
if (NumArgs) {

View File

@ -8874,6 +8874,7 @@ ExprResult
Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor,
MultiExprArg ExprArgs,
bool HadMultipleCandidates,
bool RequiresZeroInit,
unsigned ConstructKind,
SourceRange ParenRange) {
@ -8896,8 +8897,8 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
}
return BuildCXXConstructExpr(ConstructLoc, DeclInitType, Constructor,
Elidable, move(ExprArgs), RequiresZeroInit,
ConstructKind, ParenRange);
Elidable, move(ExprArgs), HadMultipleCandidates,
RequiresZeroInit, ConstructKind, ParenRange);
}
/// BuildCXXConstructExpr - Creates a complete call to a constructor,
@ -8906,6 +8907,7 @@ ExprResult
Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
CXXConstructorDecl *Constructor, bool Elidable,
MultiExprArg ExprArgs,
bool HadMultipleCandidates,
bool RequiresZeroInit,
unsigned ConstructKind,
SourceRange ParenRange) {
@ -8921,20 +8923,21 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
MarkDeclarationReferenced(ConstructLoc, Constructor);
return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
Constructor, Elidable, Exprs, NumExprs,
RequiresZeroInit,
Constructor, Elidable, Exprs, NumExprs,
HadMultipleCandidates, RequiresZeroInit,
static_cast<CXXConstructExpr::ConstructionKind>(ConstructKind),
ParenRange));
}
bool Sema::InitializeVarWithConstructor(VarDecl *VD,
CXXConstructorDecl *Constructor,
MultiExprArg Exprs) {
MultiExprArg Exprs,
bool HadMultipleCandidates) {
// FIXME: Provide the correct paren SourceRange when available.
ExprResult TempResult =
BuildCXXConstructExpr(VD->getLocation(), VD->getType(), Constructor,
move(Exprs), false, CXXConstructExpr::CK_Complete,
SourceRange());
move(Exprs), HadMultipleCandidates, false,
CXXConstructExpr::CK_Complete, SourceRange());
if (TempResult.isInvalid())
return true;

View File

@ -1062,6 +1062,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
bool Init = ConstructorLParen.isValid();
// --- Choosing a constructor ---
CXXConstructorDecl *Constructor = 0;
bool HadMultipleCandidates = false;
Expr **ConsArgs = (Expr**)ConstructorArgs.get();
unsigned NumConsArgs = ConstructorArgs.size();
ASTOwningVector<Expr*> ConvertedConstructorArgs(*this);
@ -1108,6 +1109,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
if (CXXConstructExpr *Construct
= dyn_cast<CXXConstructExpr>(FullInitExpr)) {
Constructor = Construct->getConstructor();
HadMultipleCandidates = Construct->hadMultipleCandidates();
for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(),
AEnd = Construct->arg_end();
A != AEnd; ++A)
@ -1149,7 +1151,9 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
return Owned(new (Context) CXXNewExpr(Context, UseGlobal, OperatorNew,
PlaceArgs, NumPlaceArgs, TypeIdParens,
ArraySize, Constructor, Init,
ConsArgs, NumConsArgs, OperatorDelete,
ConsArgs, NumConsArgs,
HadMultipleCandidates,
OperatorDelete,
UsualArrayDeleteWantsSize,
ResultType, AllocTypeInfo,
StartLoc,
@ -2048,6 +2052,7 @@ static ExprResult BuildCXXCastArgument(Sema &S,
CastKind Kind,
CXXMethodDecl *Method,
DeclAccessPair FoundDecl,
bool HadMultipleCandidates,
Expr *From) {
switch (Kind) {
default: llvm_unreachable("Unhandled cast kind!");
@ -2061,7 +2066,7 @@ static ExprResult BuildCXXCastArgument(Sema &S,
ExprResult Result =
S.BuildCXXConstructExpr(CastLoc, Ty, cast<CXXConstructorDecl>(Method),
move_arg(ConstructorArgs),
move_arg(ConstructorArgs), HadMultipleCandidates,
/*ZeroInit*/ false, CXXConstructExpr::CK_Complete,
SourceRange());
if (Result.isInvalid())
@ -2074,7 +2079,8 @@ static ExprResult BuildCXXCastArgument(Sema &S,
assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
// Create an implicit call expr that calls it.
ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Method);
ExprResult Result = S.BuildCXXMemberCallExpr(From, FoundDecl, Method,
HadMultipleCandidates);
if (Result.isInvalid())
return ExprError();
@ -2145,6 +2151,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
ToType.getNonReferenceType(),
CastKind, cast<CXXMethodDecl>(FD),
ICS.UserDefined.FoundConversionFunction,
ICS.UserDefined.HadMultipleCandidates,
From);
if (CastArg.isInvalid())
@ -2204,6 +2211,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
ToType, SCS.CopyConstructor,
move_arg(ConstructorArgs),
/*HadMultipleCandidates*/ false,
/*ZeroInit*/ false,
CXXConstructExpr::CK_Complete,
SourceRange());
@ -2211,6 +2219,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
return BuildCXXConstructExpr(/*FIXME:ConstructLoc*/SourceLocation(),
ToType, SCS.CopyConstructor,
MultiExprArg(*this, &From, 1),
/*HadMultipleCandidates*/ false,
/*ZeroInit*/ false,
CXXConstructExpr::CK_Complete,
SourceRange());
@ -4520,7 +4529,8 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
}
ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
CXXMethodDecl *Method) {
CXXMethodDecl *Method,
bool HadMultipleCandidates) {
ExprResult Exp = PerformObjectArgumentInitialization(E, /*Qualifier=*/0,
FoundDecl, Method);
if (Exp.isInvalid())
@ -4530,6 +4540,9 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
new (Context) MemberExpr(Exp.take(), /*IsArrow=*/false, Method,
SourceLocation(), Method->getType(),
VK_RValue, OK_Ordinary);
if (HadMultipleCandidates)
ME->setHadMultipleCandidates(true);
QualType ResultType = Method->getResultType();
ExprValueKind VK = Expr::getValueKindForType(ResultType);
ResultType = ResultType.getNonLValueExprType(Context);

View File

@ -4140,6 +4140,8 @@ static ExprResult CopyObject(Sema &S,
&CurInitExpr, 1, CandidateSet, true);
}
bool HadMultipleCandidates = (CandidateSet.size() > 1);
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(S, Loc, Best)) {
case OR_Success:
@ -4217,6 +4219,7 @@ static ExprResult CopyObject(Sema &S,
// Actually perform the constructor call.
CurInit = S.BuildCXXConstructExpr(Loc, T, Constructor, Elidable,
move_arg(ConstructorArgs),
HadMultipleCandidates,
/*ZeroInit*/ false,
CXXConstructExpr::CK_Complete,
SourceRange());
@ -4478,6 +4481,7 @@ InitializationSequence::Perform(Sema &S,
bool IsCopy = false;
FunctionDecl *Fn = Step->Function.Function;
DeclAccessPair FoundFn = Step->Function.FoundDecl;
bool HadMultipleCandidates = Step->Function.HadMultipleCandidates;
bool CreatedObject = false;
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {
// Build a call to the selected constructor.
@ -4496,6 +4500,7 @@ InitializationSequence::Perform(Sema &S,
// Build the an expression that constructs a temporary.
CurInit = S.BuildCXXConstructExpr(Loc, Step->Type, Constructor,
move_arg(ConstructorArgs),
HadMultipleCandidates,
/*ZeroInit*/ false,
CXXConstructExpr::CK_Complete,
SourceRange());
@ -4531,7 +4536,8 @@ InitializationSequence::Perform(Sema &S,
CurInit = move(CurInitExprRes);
// Build the actual call to the conversion function.
CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion);
CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion,
HadMultipleCandidates);
if (CurInit.isInvalid() || !CurInit.get())
return ExprError();
@ -4616,6 +4622,7 @@ InitializationSequence::Perform(Sema &S,
unsigned NumArgs = Args.size();
CXXConstructorDecl *Constructor
= cast<CXXConstructorDecl>(Step->Function.Function);
bool HadMultipleCandidates = Step->Function.HadMultipleCandidates;
// Build a call to the selected constructor.
ASTOwningVector<Expr*> ConstructorArgs(S);
@ -4662,6 +4669,7 @@ InitializationSequence::Perform(Sema &S,
Exprs,
NumExprs,
Kind.getParenRange(),
HadMultipleCandidates,
ConstructorInitRequiresZeroInit));
} else {
CXXConstructExpr::ConstructionKind ConstructKind =
@ -4686,6 +4694,7 @@ InitializationSequence::Perform(Sema &S,
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
Constructor, /*Elidable=*/true,
move_arg(ConstructorArgs),
HadMultipleCandidates,
ConstructorInitRequiresZeroInit,
ConstructKind,
parenRange);
@ -4693,6 +4702,7 @@ InitializationSequence::Perform(Sema &S,
CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
Constructor,
move_arg(ConstructorArgs),
HadMultipleCandidates,
ConstructorInitRequiresZeroInit,
ConstructKind,
parenRange);

View File

@ -37,11 +37,14 @@ using namespace sema;
/// A convenience routine for creating a decayed reference to a
/// function.
static ExprResult
CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn,
CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, bool HadMultipleCandidates,
SourceLocation Loc = SourceLocation(),
const DeclarationNameLoc &LocInfo = DeclarationNameLoc()){
ExprResult E = S.Owned(new (S.Context) DeclRefExpr(Fn, Fn->getType(),
VK_LValue, Loc, LocInfo));
DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, 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();
@ -2496,6 +2499,8 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
}
}
bool HadMultipleCandidates = (CandidateSet.size() > 1);
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(S, From->getLocStart(), Best, true)) {
case OR_Success:
@ -2517,6 +2522,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
User.Before = Best->Conversions[0].Standard;
User.EllipsisConversion = false;
}
User.HadMultipleCandidates = HadMultipleCandidates;
User.ConversionFunction = Constructor;
User.FoundConversionFunction = Best->FoundDecl;
User.After.setAsIdentityConversion();
@ -2534,6 +2540,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
// conversion sequence converts the source type to the
// implicit object parameter of the conversion function.
User.Before = Best->Conversions[0].Standard;
User.HadMultipleCandidates = HadMultipleCandidates;
User.ConversionFunction = Conversion;
User.FoundConversionFunction = Best->FoundDecl;
User.EllipsisConversion = false;
@ -3364,6 +3371,8 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
DeclType, CandidateSet);
}
bool HadMultipleCandidates = (CandidateSet.size() > 1);
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) {
case OR_Success:
@ -3385,6 +3394,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
ICS.setUserDefined();
ICS.UserDefined.Before = Best->Conversions[0].Standard;
ICS.UserDefined.After = Best->FinalConversion;
ICS.UserDefined.HadMultipleCandidates = HadMultipleCandidates;
ICS.UserDefined.ConversionFunction = Best->Function;
ICS.UserDefined.FoundConversionFunction = Best->FoundDecl;
ICS.UserDefined.EllipsisConversion = false;
@ -4050,6 +4060,8 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
const UnresolvedSetImpl *Conversions
= cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
bool HadMultipleCandidates = (Conversions->size() > 1);
for (UnresolvedSetImpl::iterator I = Conversions->begin(),
E = Conversions->end();
I != E;
@ -4094,7 +4106,8 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
return ExprError();
CheckMemberOperatorAccess(From->getExprLoc(), From, 0, Found);
ExprResult Result = BuildCXXMemberCallExpr(From, Found, Conversion);
ExprResult Result = BuildCXXMemberCallExpr(From, Found, Conversion,
HadMultipleCandidates);
if (Result.isInvalid())
return ExprError();
@ -4121,8 +4134,8 @@ Sema::ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *From,
<< T << ConvTy->isEnumeralType() << ConvTy << From->getSourceRange();
}
ExprResult Result = BuildCXXMemberCallExpr(From, Found,
cast<CXXConversionDecl>(Found->getUnderlyingDecl()));
ExprResult Result = BuildCXXMemberCallExpr(From, Found, Conversion,
HadMultipleCandidates);
if (Result.isInvalid())
return ExprError();
@ -4794,6 +4807,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
Candidate.Conversions[0].setUserDefined();
Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
Candidate.Conversions[0].UserDefined.EllipsisConversion = false;
Candidate.Conversions[0].UserDefined.HadMultipleCandidates = false;
Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
Candidate.Conversions[0].UserDefined.FoundConversionFunction = FoundDecl;
Candidate.Conversions[0].UserDefined.After
@ -8621,6 +8635,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
// Add builtin operator candidates.
AddBuiltinOperatorCandidates(Op, OpLoc, &Args[0], NumArgs, CandidateSet);
bool HadMultipleCandidates = (CandidateSet.size() > 1);
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
@ -8665,7 +8681,8 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl);
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl,
HadMultipleCandidates);
if (FnExpr.isInvalid())
return ExprError();
@ -8869,6 +8886,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// Add builtin operator candidates.
AddBuiltinOperatorCandidates(Op, OpLoc, Args, 2, CandidateSet);
bool HadMultipleCandidates = (CandidateSet.size() > 1);
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
@ -8930,7 +8949,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
ResultTy = ResultTy.getNonLValueExprType(Context);
// Build the actual expression node.
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, OpLoc);
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl,
HadMultipleCandidates, OpLoc);
if (FnExpr.isInvalid())
return ExprError();
@ -9080,6 +9100,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// Add builtin operator candidates.
AddBuiltinOperatorCandidates(OO_Subscript, LLoc, Args, 2, CandidateSet);
bool HadMultipleCandidates = (CandidateSet.size() > 1);
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, LLoc, Best)) {
@ -9126,7 +9148,9 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
DeclarationNameLoc LocInfo;
LocInfo.CXXOperatorName.BeginOpNameLoc = LLoc.getRawEncoding();
LocInfo.CXXOperatorName.EndOpNameLoc = RLoc.getRawEncoding();
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl, LLoc, LocInfo);
ExprResult FnExpr = CreateFunctionRefExpr(*this, FnDecl,
HadMultipleCandidates,
LLoc, LocInfo);
if (FnExpr.isInvalid())
return ExprError();
@ -9520,6 +9544,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
}
}
bool HadMultipleCandidates = (CandidateSet.size() > 1);
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, Object.get()->getLocStart(),
@ -9578,7 +9604,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
// Create an implicit member expr to refer to the conversion operator.
// and then call it.
ExprResult Call = BuildCXXMemberCallExpr(Object.get(), Best->FoundDecl, Conv);
ExprResult Call = BuildCXXMemberCallExpr(Object.get(), Best->FoundDecl,
Conv, HadMultipleCandidates);
if (Call.isInvalid())
return ExprError();
@ -9614,7 +9641,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
MethodArgs[ArgIdx + 1] = Args[ArgIdx];
ExprResult NewFn = CreateFunctionRefExpr(*this, Method);
ExprResult NewFn = CreateFunctionRefExpr(*this, Method,
HadMultipleCandidates);
if (NewFn.isInvalid())
return true;
@ -9744,6 +9772,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
0, 0, CandidateSet, /*SuppressUserConversions=*/false);
}
bool HadMultipleCandidates = (CandidateSet.size() > 1);
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, OpLoc, Best)) {
@ -9791,7 +9821,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) {
Base = BaseResult.take();
// Build the operator call.
ExprResult FnExpr = CreateFunctionRefExpr(*this, Method);
ExprResult FnExpr = CreateFunctionRefExpr(*this, Method,
HadMultipleCandidates);
if (FnExpr.isInvalid())
return ExprError();
@ -9894,14 +9925,16 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
TemplateArgs = &TemplateArgsBuffer;
}
return DeclRefExpr::Create(Context,
ULE->getQualifierLoc(),
Fn,
ULE->getNameLoc(),
Fn->getType(),
VK_LValue,
Found.getDecl(),
TemplateArgs);
DeclRefExpr *DRE = DeclRefExpr::Create(Context,
ULE->getQualifierLoc(),
Fn,
ULE->getNameLoc(),
Fn->getType(),
VK_LValue,
Found.getDecl(),
TemplateArgs);
DRE->setHadMultipleCandidates(ULE->getNumDecls() > 1);
return DRE;
}
if (UnresolvedMemberExpr *MemExpr = dyn_cast<UnresolvedMemberExpr>(E)) {
@ -9918,14 +9951,16 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
// implicit member access, rewrite to a simple decl ref.
if (MemExpr->isImplicitAccess()) {
if (cast<CXXMethodDecl>(Fn)->isStatic()) {
return DeclRefExpr::Create(Context,
MemExpr->getQualifierLoc(),
Fn,
MemExpr->getMemberLoc(),
Fn->getType(),
VK_LValue,
Found.getDecl(),
TemplateArgs);
DeclRefExpr *DRE = DeclRefExpr::Create(Context,
MemExpr->getQualifierLoc(),
Fn,
MemExpr->getMemberLoc(),
Fn->getType(),
VK_LValue,
Found.getDecl(),
TemplateArgs);
DRE->setHadMultipleCandidates(MemExpr->getNumDecls() > 1);
return DRE;
} else {
SourceLocation Loc = MemExpr->getMemberLoc();
if (MemExpr->getQualifier())
@ -9947,14 +9982,16 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
type = Context.BoundMemberTy;
}
return MemberExpr::Create(Context, Base,
MemExpr->isArrow(),
MemExpr->getQualifierLoc(),
Fn,
Found,
MemExpr->getMemberNameInfo(),
TemplateArgs,
type, valueKind, OK_Ordinary);
MemberExpr *ME = MemberExpr::Create(Context, Base,
MemExpr->isArrow(),
MemExpr->getQualifierLoc(),
Fn,
Found,
MemExpr->getMemberNameInfo(),
TemplateArgs,
type, valueKind, OK_Ordinary);
ME->setHadMultipleCandidates(true);
return ME;
}
llvm_unreachable("Invalid reference to overloaded function");

View File

@ -2031,13 +2031,14 @@ public:
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
ExprResult RebuildCXXConstructExpr(QualType T,
SourceLocation Loc,
CXXConstructorDecl *Constructor,
bool IsElidable,
MultiExprArg Args,
bool RequiresZeroInit,
SourceLocation Loc,
CXXConstructorDecl *Constructor,
bool IsElidable,
MultiExprArg Args,
bool HadMultipleCandidates,
bool RequiresZeroInit,
CXXConstructExpr::ConstructionKind ConstructKind,
SourceRange ParenRange) {
SourceRange ParenRange) {
ASTOwningVector<Expr*> ConvertedArgs(SemaRef);
if (getSema().CompleteConstructorCall(Constructor, move(Args), Loc,
ConvertedArgs))
@ -2045,6 +2046,7 @@ public:
return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
move_arg(ConvertedArgs),
HadMultipleCandidates,
RequiresZeroInit, ConstructKind,
ParenRange);
}
@ -7345,6 +7347,7 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
Constructor, E->isElidable(),
move_arg(Args),
E->hadMultipleCandidates(),
E->requiresZeroInitialization(),
E->getConstructionKind(),
E->getParenRange());

View File

@ -327,6 +327,7 @@ void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
E->DeclRefExprBits.HasQualifier = Record[Idx++];
E->DeclRefExprBits.HasFoundDecl = Record[Idx++];
E->DeclRefExprBits.HasExplicitTemplateArgs = Record[Idx++];
E->DeclRefExprBits.HadMultipleCandidates = Record[Idx++];
unsigned NumTemplateArgs = 0;
if (E->hasExplicitTemplateArgs())
NumTemplateArgs = Record[Idx++];
@ -986,7 +987,8 @@ void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
E->setArg(I, Reader.ReadSubExpr());
E->setConstructor(ReadDeclAs<CXXConstructorDecl>(Record, Idx));
E->setLocation(ReadSourceLocation(Record, Idx));
E->setElidable(Record[Idx++]);
E->setElidable(Record[Idx++]);
E->setHadMultipleCandidates(Record[Idx++]);
E->setRequiresZeroInitialization(Record[Idx++]);
E->setConstructionKind((CXXConstructExpr::ConstructionKind)Record[Idx++]);
E->ParenRange = ReadSourceRange(Record, Idx);
@ -1090,6 +1092,7 @@ void ASTStmtReader::VisitCXXNewExpr(CXXNewExpr *E) {
E->Initializer = Record[Idx++];
E->UsualArrayDeleteWantsSize = Record[Idx++];
bool isArray = Record[Idx++];
E->setHadMultipleCandidates(Record[Idx++]);
unsigned NumPlacementArgs = Record[Idx++];
unsigned NumCtorArgs = Record[Idx++];
E->setOperatorNew(ReadDeclAs<FunctionDecl>(Record, Idx));
@ -1549,7 +1552,7 @@ Stmt *ASTReader::ReadStmtFromStream(Module &F) {
/*HasFoundDecl=*/Record[ASTStmtReader::NumExprFields + 1],
/*HasExplicitTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2],
/*NumTemplateArgs=*/Record[ASTStmtReader::NumExprFields + 2] ?
Record[ASTStmtReader::NumExprFields + 3] : 0);
Record[ASTStmtReader::NumExprFields + 4] : 0);
break;
case EXPR_INTEGER_LITERAL:
@ -1623,7 +1626,9 @@ Stmt *ASTReader::ReadStmtFromStream(Module &F) {
for (unsigned i = 0; i != NumTemplateArgs; ++i)
ArgInfo.addArgument(ReadTemplateArgumentLoc(F, Record, Idx));
}
bool HadMultipleCandidates = Record[Idx++];
NamedDecl *FoundD = ReadDeclAs<NamedDecl>(F, Record, Idx);
AccessSpecifier AS = (AccessSpecifier)Record[Idx++];
DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS);
@ -1642,6 +1647,8 @@ Stmt *ASTReader::ReadStmtFromStream(Module &F) {
HasExplicitTemplateArgs ? &ArgInfo : 0, T, VK, OK);
ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc,
MemberD->getDeclName(), Record, Idx);
if (HadMultipleCandidates)
cast<MemberExpr>(S)->setHadMultipleCandidates(true);
break;
}

View File

@ -1538,6 +1538,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HasQualifier
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //GetDeclFound
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //ExplicitTemplateArgs
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); //HadMultipleCandidates
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclRef
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Location
DeclRefExprAbbrev = Stream.EmitAbbrev(Abv);

View File

@ -265,6 +265,7 @@ void ASTStmtWriter::VisitDeclRefExpr(DeclRefExpr *E) {
Record.push_back(E->hasQualifier());
Record.push_back(E->getDecl() != E->getFoundDecl());
Record.push_back(E->hasExplicitTemplateArgs());
Record.push_back(E->hadMultipleCandidates());
if (E->hasExplicitTemplateArgs()) {
unsigned NumTemplateArgs = E->getNumTemplateArgs();
@ -457,7 +458,9 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) {
for (unsigned i=0; i != NumTemplateArgs; ++i)
Writer.AddTemplateArgumentLoc(E->getTemplateArgs()[i], Record);
}
Record.push_back(E->hadMultipleCandidates());
DeclAccessPair FoundDecl = E->getFoundDecl();
Writer.AddDeclRef(FoundDecl.getDecl(), Record);
Record.push_back(FoundDecl.getAccess());
@ -958,6 +961,7 @@ void ASTStmtWriter::VisitCXXConstructExpr(CXXConstructExpr *E) {
Writer.AddDeclRef(E->getConstructor(), Record);
Writer.AddSourceLocation(E->getLocation(), Record);
Record.push_back(E->isElidable());
Record.push_back(E->hadMultipleCandidates());
Record.push_back(E->requiresZeroInitialization());
Record.push_back(E->getConstructionKind()); // FIXME: stable encoding
Writer.AddSourceRange(E->getParenRange(), Record);
@ -1077,6 +1081,7 @@ void ASTStmtWriter::VisitCXXNewExpr(CXXNewExpr *E) {
Record.push_back(E->hasInitializer());
Record.push_back(E->doesUsualArrayDeleteWantSize());
Record.push_back(E->isArray());
Record.push_back(E->hadMultipleCandidates());
Record.push_back(E->getNumPlacementArgs());
Record.push_back(E->getNumConstructorArgs());
Writer.AddDeclRef(E->getOperatorNew(), Record);