[clang] [Clang][RFC] Bypass TAD during overload resolution if a perfect match exists (PR #133426)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 31 22:57:05 PDT 2025
================
@@ -10933,27 +11096,100 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc,
// -fgpu-exclude-wrong-side-overloads is off. When
// -fgpu-exclude-wrong-side-overloads is on, all candidates are compared
// uniformly in isBetterOverloadCandidate.
- if (S.getLangOpts().CUDA && !S.getLangOpts().GPUExcludeWrongSideOverloads) {
- const FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true);
- bool ContainsSameSideCandidate =
- llvm::any_of(Candidates, [&](OverloadCandidate *Cand) {
- // Check viable function only.
- return Cand->Viable && Cand->Function &&
- S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
- SemaCUDA::CFP_SameSide;
- });
- if (ContainsSameSideCandidate) {
- auto IsWrongSideCandidate = [&](OverloadCandidate *Cand) {
- // Check viable function only to avoid unnecessary data copying/moving.
+ if (!S.getLangOpts().CUDA || S.getLangOpts().GPUExcludeWrongSideOverloads)
+ return;
+ const FunctionDecl *Caller = S.getCurFunctionDecl(/*AllowLambda=*/true);
+
+ bool ContainsSameSideCandidate =
+ llvm::any_of(Candidates, [&](const OverloadCandidate *Cand) {
+ // Check viable function only.
return Cand->Viable && Cand->Function &&
S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
- SemaCUDA::CFP_WrongSide;
- };
- llvm::erase_if(Candidates, IsWrongSideCandidate);
+ SemaCUDA::CFP_SameSide;
+ });
+
+ if (!ContainsSameSideCandidate)
+ return;
+
+ auto IsWrongSideCandidate = [&](const OverloadCandidate *Cand) {
+ // Check viable function only to avoid unnecessary data copying/moving.
+ return Cand->Viable && Cand->Function &&
+ S.CUDA().IdentifyPreference(Caller, Cand->Function) ==
+ SemaCUDA::CFP_WrongSide;
+ };
+ llvm::erase_if(Candidates, IsWrongSideCandidate);
+}
+
+/// Computes the best viable function (C++ 13.3.3)
+/// within an overload candidate set.
+///
+/// \param Loc The location of the function name (or operator symbol) for
+/// which overload resolution occurs.
+///
+/// \param Best If overload resolution was successful or found a deleted
+/// function, \p Best points to the candidate function found.
+///
+/// \returns The result of overload resolution.
+OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S,
+ SourceLocation Loc,
+ iterator &Best) {
+
+ assert(shouldDeferTemplateArgumentDeduction(S.getLangOpts()) ||
+ DeferredCandidates.empty() &&
+ "Unexpected deferred template candidate");
+
+ bool TwoPhaseResolution = !DeferredCandidates.empty();
+
+ if (TwoPhaseResolution) {
+
+ PerfectViableFunction(S, Loc, Best);
+ if (Best != end())
+ return ResultForBestCandidate(Best);
+
+ InjectNonDeducedTemplateCandidates(S);
+ }
+
+ return BestViableFunctionImpl(S, Loc, Best);
+}
+
+void OverloadCandidateSet::PerfectViableFunction(
+ Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best) {
+
+ Best = end();
+ for (auto It = begin(); It != end(); ++It) {
+ if (It->isPerfectMatch(S.getASTContext())) {
----------------
zyn0217 wrote:
maybe
```cpp
if (!It->isPerfectMatch(S.getASTContext()))
continue;
```
to reduce the curley nesting.
https://github.com/llvm/llvm-project/pull/133426
More information about the cfe-commits
mailing list