diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-05-11 20:37:46 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-05-11 20:37:46 +0000 |
commit | c2bebe9acab26b5af209f11b3ee978966feab491 (patch) | |
tree | 3573c6b429a7cf0bf311f648650ce49743c6a741 /clang/lib/Sema/SemaOverload.cpp | |
parent | 1455de2171e8829f75935f11b254f404417c260c (diff) | |
download | bcm5719-llvm-c2bebe9acab26b5af209f11b3ee978966feab491.tar.gz bcm5719-llvm-c2bebe9acab26b5af209f11b3ee978966feab491.zip |
Preserve the FoundDecl when performing overload resolution for constructors.
This is in preparation for C++ P0136R1, which switches the model for inheriting
constructors over from synthesizing a constructor to finding base class
constructors (via using shadow decls) when looking for derived class
constructors.
llvm-svn: 269231
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 146 |
1 files changed, 66 insertions, 80 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 415eda02ec6..1c41487f5a4 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1218,11 +1218,13 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, S.IsDerivedFrom(From->getLocStart(), FromCanon, ToCanon))) { // Turn this into a "standard" conversion sequence, so that it // gets ranked with standard conversion sequences. + DeclAccessPair Found = ICS.UserDefined.FoundConversionFunction; ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.setFromType(From->getType()); ICS.Standard.setAllToTypes(ToType); ICS.Standard.CopyConstructor = Constructor; + ICS.Standard.FoundCopyConstructor = Found; if (ToCanon != FromCanon) ICS.Standard.Second = ICK_Derived_To_Base; } @@ -1236,7 +1238,7 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, for (OverloadCandidateSet::iterator Cand = Conversions.begin(); Cand != Conversions.end(); ++Cand) if (Cand->Viable) - ICS.Ambiguous.addConversion(Cand->Function); + ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function); break; // Fall through. @@ -3051,39 +3053,26 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, UserDefinedConversionSequence &User, OverloadCandidateSet &CandidateSet, bool AllowExplicit) { - DeclContext::lookup_result R = S.LookupConstructors(To); - for (DeclContext::lookup_iterator Con = R.begin(), ConEnd = R.end(); - Con != ConEnd; ++Con) { - NamedDecl *D = *Con; - DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); - - // Find the constructor (which may be a template). - CXXConstructorDecl *Constructor = nullptr; - FunctionTemplateDecl *ConstructorTmpl - = dyn_cast<FunctionTemplateDecl>(D); - if (ConstructorTmpl) - Constructor - = cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl()); - else - Constructor = cast<CXXConstructorDecl>(D); + for (auto *D : S.LookupConstructors(To)) { + auto Info = getConstructorInfo(D); + if (!Info.Constructor) + continue; - bool Usable = !Constructor->isInvalidDecl() && - S.isInitListConstructor(Constructor) && - (AllowExplicit || !Constructor->isExplicit()); + bool Usable = !Info.Constructor->isInvalidDecl() && + S.isInitListConstructor(Info.Constructor) && + (AllowExplicit || !Info.Constructor->isExplicit()); if (Usable) { // If the first argument is (a reference to) the target type, // suppress conversions. - bool SuppressUserConversions = - isFirstArgumentCompatibleWithType(S.Context, Constructor, ToType); - if (ConstructorTmpl) - S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, - /*ExplicitArgs*/ nullptr, - From, CandidateSet, - SuppressUserConversions); + bool SuppressUserConversions = isFirstArgumentCompatibleWithType( + S.Context, Info.Constructor, ToType); + if (Info.ConstructorTmpl) + S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, + /*ExplicitArgs*/ nullptr, From, + CandidateSet, SuppressUserConversions); else - S.AddOverloadCandidate(Constructor, FoundDecl, - From, CandidateSet, - SuppressUserConversions); + S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, From, + CandidateSet, SuppressUserConversions); } } @@ -3183,27 +3172,17 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, ListInitializing = true; } - DeclContext::lookup_result R = S.LookupConstructors(ToRecordDecl); - for (DeclContext::lookup_iterator Con = R.begin(), ConEnd = R.end(); - Con != ConEnd; ++Con) { - NamedDecl *D = *Con; - DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); - - // Find the constructor (which may be a template). - CXXConstructorDecl *Constructor = nullptr; - FunctionTemplateDecl *ConstructorTmpl - = dyn_cast<FunctionTemplateDecl>(D); - if (ConstructorTmpl) - Constructor - = cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl()); - else - Constructor = cast<CXXConstructorDecl>(D); + for (auto *D : S.LookupConstructors(ToRecordDecl)) { + auto Info = getConstructorInfo(D); + if (!Info.Constructor) + continue; - bool Usable = !Constructor->isInvalidDecl(); + bool Usable = !Info.Constructor->isInvalidDecl(); if (ListInitializing) - Usable = Usable && (AllowExplicit || !Constructor->isExplicit()); + Usable = Usable && (AllowExplicit || !Info.Constructor->isExplicit()); else - Usable = Usable &&Constructor->isConvertingConstructor(AllowExplicit); + Usable = Usable && + Info.Constructor->isConvertingConstructor(AllowExplicit); if (Usable) { bool SuppressUserConversions = !ConstructorsOnly; if (SuppressUserConversions && ListInitializing) { @@ -3212,18 +3191,18 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, // If the first argument is (a reference to) the target type, // suppress conversions. SuppressUserConversions = isFirstArgumentCompatibleWithType( - S.Context, Constructor, ToType); + S.Context, Info.Constructor, ToType); } } - if (ConstructorTmpl) - S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, - /*ExplicitArgs*/ nullptr, - llvm::makeArrayRef(Args, NumArgs), - CandidateSet, SuppressUserConversions); + if (Info.ConstructorTmpl) + S.AddTemplateOverloadCandidate( + Info.ConstructorTmpl, Info.FoundDecl, + /*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs), + CandidateSet, SuppressUserConversions); else // Allow one user-defined conversion when user specifies a // From->ToType conversion via an static cast (c-style, etc). - S.AddOverloadCandidate(Constructor, FoundDecl, + S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, llvm::makeArrayRef(Args, NumArgs), CandidateSet, SuppressUserConversions); } @@ -4288,7 +4267,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(); Cand != CandidateSet.end(); ++Cand) if (Cand->Viable) - ICS.Ambiguous.addConversion(Cand->Function); + ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function); return true; case OR_No_Viable_Function: @@ -8862,6 +8841,7 @@ enum OverloadCandidateKind { }; OverloadCandidateKind ClassifyOverloadCandidate(Sema &S, + NamedDecl *Found, FunctionDecl *Fn, std::string &Description) { bool isTemplate = false; @@ -8990,13 +8970,13 @@ bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, } // Notes the location of an overload candidate. -void Sema::NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType, - bool TakingAddress) { +void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, + QualType DestType, bool TakingAddress) { if (TakingAddress && !checkAddressOfCandidateIsAvailable(*this, Fn)) return; std::string FnDesc; - OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Fn, FnDesc); + OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Found, Fn, FnDesc); PartialDiagnostic PD = PDiag(diag::note_ovl_candidate) << (unsigned) K << FnDesc; @@ -9019,11 +8999,11 @@ void Sema::NoteAllOverloadCandidates(Expr *OverloadedExpr, QualType DestType, I != IEnd; ++I) { if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl()) ) { - NoteOverloadCandidate(FunTmpl->getTemplatedDecl(), DestType, + NoteOverloadCandidate(*I, FunTmpl->getTemplatedDecl(), DestType, TakingAddress); } else if (FunctionDecl *Fun = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()) ) { - NoteOverloadCandidate(Fun, DestType, TakingAddress); + NoteOverloadCandidate(*I, Fun, DestType, TakingAddress); } } } @@ -9047,7 +9027,7 @@ void ImplicitConversionSequence::DiagnoseAmbiguousConversion( if (CandsShown >= 4 && ShowOverloads == Ovl_Best) break; ++CandsShown; - S.NoteOverloadCandidate(*I); + S.NoteOverloadCandidate(I->first, I->second); } if (I != E) S.Diag(SourceLocation(), diag::note_ovl_too_many_candidates) << int(E - I); @@ -9072,7 +9052,8 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, } std::string FnDesc; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc); + OverloadCandidateKind FnKind = + ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); Expr *FromExpr = Conv.Bad.FromExpr; QualType FromTy = Conv.Bad.getFromType(); @@ -9318,7 +9299,8 @@ static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, } /// General arity mismatch diagnosis over a candidate in a candidate set. -static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) { +static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, + unsigned NumFormalArgs) { assert(isa<FunctionDecl>(D) && "The templated declaration should at least be a function" " when diagnosing bad template argument deduction due to too many" @@ -9348,7 +9330,8 @@ static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) { } std::string Description; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description); + OverloadCandidateKind FnKind = + ClassifyOverloadCandidate(S, Found, Fn, Description); if (modeCount == 1 && Fn->getParamDecl(0)->getDeclName()) S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one) @@ -9365,7 +9348,7 @@ static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) { static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumFormalArgs) { if (!CheckArityMismatch(S, Cand, NumFormalArgs)) - DiagnoseArityMismatch(S, Cand->Function, NumFormalArgs); + DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs); } static TemplateDecl *getDescribedTemplate(Decl *Templated) { @@ -9376,7 +9359,7 @@ static TemplateDecl *getDescribedTemplate(Decl *Templated) { } /// Diagnose a failed template-argument deduction. -static void DiagnoseBadDeduction(Sema &S, Decl *Templated, +static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, DeductionFailureInfo &DeductionFailure, unsigned NumArgs, bool TakingCandidateAddress) { @@ -9466,7 +9449,7 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated, case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: - DiagnoseArityMismatch(S, Templated, NumArgs); + DiagnoseArityMismatch(S, Found, Templated, NumArgs); return; case Sema::TDK_InstantiationDepth: @@ -9596,7 +9579,7 @@ static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, if (CheckArityMismatch(S, Cand, NumArgs)) return; } - DiagnoseBadDeduction(S, Cand->Function, // pattern + DiagnoseBadDeduction(S, Cand->FoundDecl, Cand->Function, // pattern Cand->DeductionFailure, NumArgs, TakingCandidateAddress); } @@ -9609,7 +9592,8 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { CalleeTarget = S.IdentifyCUDATarget(Callee); std::string FnDesc; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Callee, FnDesc); + OverloadCandidateKind FnKind = + ClassifyOverloadCandidate(S, Cand->FoundDecl, Callee, FnDesc); S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target) << (unsigned)FnKind << CalleeTarget << CallerTarget; @@ -9686,7 +9670,8 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, if (Cand->Viable && (Fn->isDeleted() || S.isFunctionConsideredUnavailable(Fn))) { std::string FnDesc; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc); + OverloadCandidateKind FnKind = + ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted) << FnKind << FnDesc @@ -9697,7 +9682,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, // We don't really have anything else to say about viable candidates. if (Cand->Viable) { - S.NoteOverloadCandidate(Fn); + S.NoteOverloadCandidate(Cand->FoundDecl, Fn); return; } @@ -9707,7 +9692,8 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, return DiagnoseArityMismatch(S, Cand, NumArgs); case ovl_fail_bad_deduction: - return DiagnoseBadDeduction(S, Cand, NumArgs, TakingCandidateAddress); + return DiagnoseBadDeduction(S, Cand, NumArgs, + TakingCandidateAddress); case ovl_fail_illegal_constructor: { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_illegal_constructor) @@ -9719,7 +9705,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, case ovl_fail_trivial_conversion: case ovl_fail_bad_final_conversion: case ovl_fail_final_conversion_not_exact: - return S.NoteOverloadCandidate(Fn); + return S.NoteOverloadCandidate(Cand->FoundDecl, Fn); case ovl_fail_bad_conversion: { unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0); @@ -9730,7 +9716,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, // FIXME: this currently happens when we're called from SemaInit // when user-conversion overload fails. Figure out how to handle // those conditions and diagnose them well. - return S.NoteOverloadCandidate(Fn); + return S.NoteOverloadCandidate(Cand->FoundDecl, Fn); } case ovl_fail_bad_target: @@ -9808,8 +9794,8 @@ static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, if (ICS.isBad()) break; // all meaningless after first invalid if (!ICS.isAmbiguous()) continue; - ICS.DiagnoseAmbiguousConversion(S, OpLoc, - S.PDiag(diag::note_ambiguous_type_conversion)); + ICS.DiagnoseAmbiguousConversion( + S, OpLoc, S.PDiag(diag::note_ambiguous_type_conversion)); } } @@ -10176,7 +10162,7 @@ struct CompareTemplateSpecCandidatesForDisplay { /// deductions. void TemplateSpecCandidate::NoteDeductionFailure(Sema &S, bool ForTakingAddress) { - DiagnoseBadDeduction(S, Specialization, // pattern + DiagnoseBadDeduction(S, FoundDecl, Specialization, // pattern DeductionFailure, /*NumArgs=*/0, ForTakingAddress); } @@ -10429,7 +10415,7 @@ private: Info, /*InOverloadResolution=*/true)) { // Make a note of the failed deduction for diagnostics. FailedCandidates.addCandidate() - .set(FunctionTemplate->getTemplatedDecl(), + .set(CurAccessFunPair, FunctionTemplate->getTemplatedDecl(), MakeDeductionFailureInfo(Context, Result, Info)); return false; } @@ -10595,7 +10581,7 @@ public: if (FunctionDecl *Fun = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl())) if (!functionHasPassObjectSizeParams(Fun)) - S.NoteOverloadCandidate(Fun, TargetFunctionType, + S.NoteOverloadCandidate(*I, Fun, TargetFunctionType, /*TakingAddress=*/true); FailedCandidates.NoteCandidates(S, OvlExpr->getLocStart()); } @@ -10801,7 +10787,7 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, // Make a note of the failed deduction for diagnostics. // TODO: Actually use the failed-deduction info? FailedCandidates.addCandidate() - .set(FunctionTemplate->getTemplatedDecl(), + .set(I.getPair(), FunctionTemplate->getTemplatedDecl(), MakeDeductionFailureInfo(Context, Result, Info)); continue; } |