https://reviews.llvm.org/D77954 caused regressions due to diagnostics in implicit
host device functions.
The implicit host device functions are often functions in system headers forced to be device host by pragmas.
Some of them are valid host device functions that can be emitted in both host and device compilation.
Some of them are valid host functions but invalid device functions. In device compilation they incur
diagnostics. However as long as these diagnostics are deferred and these functions are not emitted
this is fine.
Before D77954, in host device callers, host device candidates are not favored against wrong-sided candidates,
which preserves the overloading resolution result as if the caller and the candidates are host functions.
This makes sure the callee does not cause other issues, e.g. type mismatch, const-ness issues, etc. If the
selected function is a host device function, then it is a viable callee. If the selected function is a host
function, then the caller is not a valid host device function, and it results in a diagnostic but it can be deferred.
The problem is that we have to give host device candidates equal preference with wrong-sided candidates. If
the users really intend to favor host device candidate against wrong-sided candidate, they cannot get the
expected selection.
Ideally we should be able to defer all diagnostics for functions not sure to be emitted. In that case we can
have correct preference. If diagnostics occur due to overloading resolution change, as long as the function
is not emitted, it is fine.
Unfortunately it is not a trivial work to defer all diagnostics. Even deferring only overloading resolution related
diagnostics is not a simple work.
For now, it seems the most feasible workaround is to treat implicit host device function and explicit host
device function differently. Basically in device compilation for implicit host device functions, keep the
old behavior, i.e. give host device candidates and wrong-sided candidates equal preference. For explicit
host device functions, favor host device candidates against wrong-sided candidates.
The rationale is that explicit host device functions are blessed by the user to be valid host device functions,
that is, they should not cause diagnostics in both host and device compilation. If diagnostics occur, user is
able to fix them. However, there is no guarantee that implicit host device function can be compiled in
device compilation, therefore we need to preserve its overloading resolution in device compilation.
Plumbing an optional output argument it through multiple levels of callers as an output argument is rather hard to follow, especially considering that it's not set in all code paths. Perhaps we can turn IsImplicitHDAttr into a separate function and call it from isBetterOverloadCandidate().