<div class="gmail_quote">On Mon, Jul 25, 2011 at 11:13 AM, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div style="word-wrap:break-word"><div><div></div><div class="h5"><br><div><div>On Jul 22, 2011, at 4:19 PM, Kaelyn Uhrain wrote:</div><br><blockquote type="cite">Here's a patch to improve the messages for out-of-line definition errors by including the function's signature along with its name, and in the candidate function notes including the candidates name and signature as namespace qualifiers aren't always apparent at the line of code with the declaration.<br>
<br>The patch is also available for review at <a href="http://codereview.appspot.com/4817047" target="_blank">http://codereview.appspot.com/4817047</a><br>
<br>For example, given a file tmp.cpp containing:<br><br>namespace N2 {<br> struct S1;<br><br> namespace N1 {<br> struct S2 {<br> void func(S1*);<br> };<br><br> struct S1 {};<br> }<br>}<br>void N2::N1::S2::func(S1*) {}<br>
<br>Clang currently reports:<br><br>tmp.cpp:12:18: error: out-of-line definition of 'func' does not match any declaration in 'N2::N1::S2'<br>void N2::N1::S2::func(S1*) {}<br> ~~~~~~~~~~~~^<br><br>Sadly, g++ (version 4.4.3) gives better messages:<br>
<br>tmp.cpp:12: error: prototype for 'void N2::N1::S2::func(N2::N1::S1*)' does not match any in class 'N2::N1::S2'<br>tmp.cpp:6: error: candidate is: void N2::N1::S2::func(N2::S1*)<br><br>With this patch, clang yields:<br>
<br>tmp.cpp:12:18: error: out-of-line definition of 'void func(N2::N1::S1 *)' does not match any<br> declaration in 'N2::N1::S2'<br>void N2::N1::S2::func(S1*) {}<br> ~~~~~~~~~~~~^<br>tmp.cpp:6:11: note: member declaration 'void func(N2::S1 *)' nearly matches<br>
void func(S1*);<br> ^<br></blockquote></div><div><br></div></div></div>I'm not convinced we want to go in this direction. Or general principle for Clang diagnostics has been "show, don't tell", and we'd much rather point out specifically where the mismatch occurs than print out the entire type of the function and force the user to walk through the parameters to find the mismatch. This approach also allows us to add Fix-Its when the mismatch is due to something easily fixed (e.g., missing cv-qualifiers).</div>
</blockquote><div><br>Clang currently only suggests match candidates if there is a slight mismatch such as missing cv-qualifers, but all of the underlying (unqualified) types have to match. My patch just expands that to match cases where the types are different but have the same name--where there are missing/implicit namespace qualifers, which currently will give a totally useless and very baffling message to the user. In the example I gave previously, it says N2::N1::S2::func(S1*) is unmatched but the user will look in the code and see func(S1*) declared in struct N2::N1::S2 with no idea why clang wasn't accepting the message.<br>
<br></div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div style="word-wrap: break-word;"><div><br></div><div>Overload-resolution diagnostics are a good model for what we want here. We don't just print out the types of the arguments and the types of the candidate functions; instead, we only point out the specific problem that caused us to reject each candidate, so users can focus on that parameter/argument pair.</div>
</div></blockquote><div><br><br>
I actually started to save off which parameters were causing the
mismatch so they could be reported, but I could not come up with a way
to mark it without being too ridiculously verbose (especially if more
than one param was a mismatch). And this is also a case where choosing
an appropriate fixit would be problematic since e.g. in the example from my previous email it is unclear whether the definition of func(S1*) should be changed to func(::S1*) or if the first declaration of struct S1 accidentally done at the wrong namespace scope. I'll take a look at the overload-resolution diagnostic to see how it handles this kind of mismatch.<br>
<br>Cheers,<br>Kaelyn<br></div></div><br>