diff options
author | Abramo Bagnara <abramo.bagnara@gmail.com> | 2011-10-05 07:56:41 +0000 |
---|---|---|
committer | Abramo Bagnara <abramo.bagnara@gmail.com> | 2011-10-05 07:56:41 +0000 |
commit | 7cc58b4c927fca539d43eaa58e00dca95946eb7c (patch) | |
tree | 64016485e4eacc7b93f7ffbffbb2b27b9da6d141 /lib | |
parent | b45ae256cfd5ef3ab22b4d715159f978d8120d45 (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.cpp | 19 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 109 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 15 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 13 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 1 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 7 |
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) + |