<div class="gmail_quote">On Thu, Apr 19, 2012 at 4:54 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com">dblaikie@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div></div><div class="h5">On Thu, Apr 19, 2012 at 4:17 PM, Kaelyn Uhrain <<a href="mailto:rikka@google.com">rikka@google.com</a>> wrote:<br>
> Author: rikka<br>
> Date: Thu Apr 19 18:17:45 2012<br>
> New Revision: 155163<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=155163&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=155163&view=rev</a><br>
> Log:<br>
> In Parser::isCXXDeclarationSpecifier, consider a non-type identifier<br>
> followed by an identifier as declaration specificer (except for ObjC).<br>
> This allows e.g. an out-of-line C++ member function definitions to be<br>
> recognized as functions and not as variable declarations if the type<br>
> name for the first parameter is not recognized as a type--say, when there<br>
> is a function name shadowing an enum type name and the parameter is<br>
> missing the "enum" keyword needed to distinguish the two.<br>
><br>
> Note that returning TPResult::Error() instead of TPResult::True()<br>
> appears to have the same end result, while TPResult::Ambiguous()<br>
> results in a crash.<br>
><br>
> Modified:<br>
>    cfe/trunk/lib/Parse/ParseTentative.cpp<br>
>    cfe/trunk/test/FixIt/fixit.cpp<br>
><br>
> Modified: cfe/trunk/lib/Parse/ParseTentative.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=155163&r1=155162&r2=155163&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=155163&r1=155162&r2=155163&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/lib/Parse/ParseTentative.cpp (original)<br>
> +++ cfe/trunk/lib/Parse/ParseTentative.cpp Thu Apr 19 18:17:45 2012<br>
> @@ -931,8 +931,12 @@<br>
>     // recurse to handle whatever we get.<br>
>     if (TryAnnotateTypeOrScopeToken())<br>
>       return TPResult::Error();<br>
> -    if (Tok.is(tok::identifier))<br>
> -      return TPResult::False();<br>
> +    if (Tok.is(tok::identifier)) {<br>
> +      const Token &Next = NextToken();<br>
> +      bool NotObjC = !(getLangOpts().ObjC1 || getLangOpts().ObjC2);<br>
> +      return (NotObjC && Next.is(tok::identifier)) ?<br>
> +          TPResult::True() : TPResult::False();<br>
> +    }<br>
>     return isCXXDeclarationSpecifier(BracedCastResult);<br>
><br>
>   case tok::coloncolon: {    // ::foo::bar<br>
><br>
> Modified: cfe/trunk/test/FixIt/fixit.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=155163&r1=155162&r2=155163&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=155163&r1=155162&r2=155163&view=diff</a><br>

> ==============================================================================<br>
> --- cfe/trunk/test/FixIt/fixit.cpp (original)<br>
> +++ cfe/trunk/test/FixIt/fixit.cpp Thu Apr 19 18:17:45 2012<br>
> @@ -204,3 +204,15 @@<br>
>          template<typename> typename Bar, // expected-error {{template template parameter requires 'class' after the parameter list}}<br>
>          template<typename> struct Baz> // expected-error {{template template parameter requires 'class' after the parameter list}}<br>
>  void func();<br>
> +<br>
> +<br>
> +namespace ShadowedTagType {<br>
> +class Foo {<br>
> + public:<br>
> +  enum Bar { X, Y };<br>
> +  void SetBar(Bar bar);<br>
> +  Bar Bar();<br>
> + private:<br>
> +  Bar bar_; // expected-error {{must use 'enum' tag to refer to type 'Bar' in this scope}}<br>
> +};<br>
> +void Foo::SetBar(Bar bar) { bar_ = bar; } // expected-error {{must use 'enum' tag to refer to type 'Bar' in this scope}}<br>
<br>
</div></div>I assume "void Foo::SetBar(Bar) { }" still confuses clang into<br>
thinking this is a variable definition?<br>
</blockquote></div><br><div>That is correct, since it is a bit harder to detect (especially if the return type is not void or if there is more than one parameter).</div>