<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 13 October 2017 at 02:02, Vassil Vassilev <span dir="ltr"><<a href="mailto:v.g.vassilev@gmail.com" target="_blank">v.g.vassilev@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 13/10/17 00:17, slycelote wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Consider the following:<br>
<br>
<br>
template<typename T><br>
struct C; // d1<br>
<br>
template<typename T><br>
class D {<br>
     static void f() {}<br>
<br>
     template<typename><br>
     friend struct C; // d2<br>
};<br>
<br>
template<typename T><br>
struct C { }; // d3<br>
<br>
int main() { }<br>
<br>
<br>
Here there are 3 declarations corresponding to class template C (marked<br>
as d1, d2 and d3).<br>
<br>
In clang 3.9 getCanonicalDecl() for all 3 of them returns d1. Starting<br>
from clang 4.0, d2->getCanonicalDecl() == d2. As far as I can tell, this<br>
is caused by commit 291753 [1].<br>
</blockquote></span>
  That was intentional because keeping friend declarations in the redecl chain confuses the template instantiator. That's visible especially with modules.<span class=""><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Is this intended? It looks to me, that, for example,<br>
clang::declaresSameEntity(d1, d2) [2] will return a wrong result.<br>
</blockquote></span>
  Richard, would it be feasible to not add the fiend decl to the redecl chain but to still rewire it to the 'right' canonical decl. That way getMostRecentDecl() won't return d2 (in some cases) and declaresSameEntity(d1,d2) will return true?</blockquote><div><br></div><div>This would pretty badly break some of our invariants (eg, that walking over PreviousDecl edges and then from the first decl to the MostRecentDecl will eventually return you to the declaration where you started, all declarations of an entity have the same semantic DeclContext, all declarations have equivalent template parameter lists, ...). This would bring back some of the problems we fixed when we removed these declarations from the redecl chain (though, granted, not all of the, because walking the redeclaration chain starting from somewhere other than the depedent-context friend would never take you to the dependent-context friend).</div><div><br></div><div>And I don't see much benefit. Any correct code looking at a dependent friend already needs to cope with the possibility that it has not been wired into the redeclaration chain (because some portion of the friend declaration itself might be dependent). Given that, it seems much simpler to say that *no* friends in dependent contexts are wired into a redeclaration chain.</div><div><br></div><div>That said, I can imagine that some (particularly, tooling) users of Clang might want a best-effort "what is this friend declaration redeclaring, if you happen to know?" query. And as it happens, we do work that out while we're initially parsing the friend declaration, so I don't see a problem with storing it and later making it available to such uses, but not as the canonical / previous declaration (or anywhere that suggests it's reliable and not merely best-effort).</div></div></div></div>