<div class="gmail_quote">On Wed, May 16, 2012 at 11:51 AM, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com" target="_blank">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 class="h5"><br><div><div>On May 15, 2012, at 6:12 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:</div><br><blockquote type="cite">
Hi,<div><br></div><div>The attached patch allows Clang to recover better from a missing 'typename' keyword in a function template definition:</div><div><br></div><div><div><font face="courier new, monospace"><stdin>:1:29: error: missing 'typename' prior to dependent type name 'T::type'</font></div>


<div><font face="courier new, monospace">template<typename T> void f(T::type) {}</font></div><div><font face="courier new, monospace">                            ^~~~~~~</font></div><div><font face="courier new, monospace">                            typename </font></div>


</div><div><br></div><div>With this patch, we carry on disambiguating past such a situation. If we can't disambiguate the declaration in some other way, the absence of 'typename' is used to infer that we have a variable declaration. I've also extended the disambiguation code to inspect the token immediately after the parameter-declaration-clause to disambiguate (in the above case, the <font face="courier new, monospace">{</font> token is used to disambiguate, and more generally we will also look for an exception-specification, ref-qualifier, cv-qualifier, etc., which cannot appear after a parenthesized initializer in a variable declaration).</div>

<div><br></div><div>Does this seem like a reasonable approach?</div></blockquote><br></div></div></div><div>I like this approach. Just one trivial comment:</div><div><br></div><div><div>+    else if (NextToken().is(tok::amp) || NextToken().is(tok::ampamp) ||</div>
<div>+             NextToken().is(tok::kw_const) ||</div><div>+             NextToken().is(tok::kw_volatile) ||</div><div>+             NextToken().is(tok::kw_throw) ||</div><div>+             NextToken().is(tok::kw_noexcept) ||</div>
<div>+             NextToken().is(tok::l_square) ||</div><div>+             isCXX0XVirtSpecifier(NextToken()) ||</div><div>+             NextToken().is(tok::l_brace) || NextToken().is(tok::kw_try) ||</div><div>+             NextToken().is(tok::equal))</div>
<div><br></div></div>Please cache NextToken() here.</div></blockquote><div><br></div><div>Done. r156963.</div></div>