aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAbramo Bagnara <abramo.bagnara@gmail.com>2011-10-05 07:56:41 +0000
committerAbramo Bagnara <abramo.bagnara@gmail.com>2011-10-05 07:56:41 +0000
commit7cc58b4c927fca539d43eaa58e00dca95946eb7c (patch)
tree64016485e4eacc7b93f7ffbffbb2b27b9da6d141 /lib
parentb45ae256cfd5ef3ab22b4d715159f978d8120d45 (diff)
Added a flag to identify resolved overloaded function references.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141171 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTImporter.cpp19
-rw-r--r--lib/AST/ExprCXX.cpp16
-rw-r--r--lib/Sema/SemaDeclCXX.cpp17
-rw-r--r--lib/Sema/SemaExprCXX.cpp21
-rw-r--r--lib/Sema/SemaInit.cpp12
-rw-r--r--lib/Sema/SemaOverload.cpp109
-rw-r--r--lib/Sema/TreeTransform.h15
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp13
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp1
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp7
10 files changed, 160 insertions, 70 deletions
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 37299d9633..e50dcbe4b0 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -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) {
diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp
index 95b03ee183..ad5ec8b833 100644
--- a/lib/AST/ExprCXX.cpp
+++ b/lib/AST/ExprCXX.cpp
@@ -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) {
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index bc0383165d..4df525c6f3 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -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;
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 7571f7610c..16d9ae94f2 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -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);
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 145a7ecaba..30abef5d83 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -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);
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 6174bbac73..c968498d00 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -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");
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 99ddd23912..62c6d18b59 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -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());
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index e2a78e9d1e..7653d5f290 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -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)
+