Fix PR18792 - Bad diagnostic messages for std::enable_if_t uses
This patch improves the diagnostic messages for overloads disabled with
enable_if, in particular those where the failing typename enable_if<...>::type
lookup happens during the instantiation of an alias template like
std::enable_if_t.
Previously the diagnostic note for an overload disabled with std::enable_if_t
(or a similar alias template) only contained the location of the typename
enable_if<...>::type lookup and did not contain the location of the disabled
function overload, which could be quite annoying when you had many overloads.
This patch makes clang generate a note with the name and location of the
outermost alias template in the SFINAE context in which the enable_if<...>::type
lookup failed. Typically this location will be inside the source range for the
function template declaration, i.e. exactly where we want it. In the rare
circumstances where this is not the case, see e.g. the new test case with the
FIXME in overload-candidates.cpp, the implementation makes sure that the
diagnostic is placed at the disabled overload.
I'm not certain whether using the "disabled by %0" message even for template
aliases whose names don't start with "enable" or "disable" is optimal, but I'm
pretty sure that in the vast majority of cases the generated message should
be quite understandable and certainly better than the one generated when
not using the enable_if logic. Though, if someone has a good idea for the
wording, it would be easy to use a different message for such aliases.
This patch also improves the source range highlighting for regular enable_if
uses and always prints out the fully qualified name of the enable_if template
(as was requested by a FIXME in SemaOverload.cpp).
Rather than essentially duplicating the implementation in the body, how about an English description, "Indicates whether another source range is the same as, or contained within, this range."
Also, the implementation doesn't appear to be correct; < on SourceLocations does not in general give source order (though it happens to if the locations are within the same FileID). Use SourceManager::isBeforeInTranslationUnit for this check (and it shouldn't be a member of SourceRange to avoid layering problems).
Maybe this should be a SourceManager member function?