[cfe-commits] r153488 - in /cfe/trunk: lib/Parse/ParseDecl.cpp test/Parser/cxx-class.cpp test/SemaCXX/copy-assignment.cpp
Eli Friedman
eli.friedman at gmail.com
Mon Mar 26 18:18:24 PDT 2012
On Mon, Mar 26, 2012 at 5:56 PM, Richard Smith
<richard-llvm at metafoo.co.uk> wrote:
> Author: rsmith
> Date: Mon Mar 26 19:56:56 2012
> New Revision: 153488
>
> URL: http://llvm.org/viewvc/llvm-project?rev=153488&view=rev
> Log:
> When we see 'Class(X' or 'Class::Class(X' and we suspect that it names a
> constructor, but X is not a known typename, check whether the tokens could
> possibly match the syntax of a declarator before concluding that it isn't
> a constructor. If it's definitely ill-formed, assume it is a constructor.
>
> Empirical evidence suggests that this pattern is much more often a
> constructor with a typoed (or not-yet-declared) type name than any of the
> other possibilities, so the extra cost of the check is not expected to be
> problematic.
>
> Modified:
> cfe/trunk/lib/Parse/ParseDecl.cpp
> cfe/trunk/test/Parser/cxx-class.cpp
> cfe/trunk/test/SemaCXX/copy-assignment.cpp
>
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=153488&r1=153487&r2=153488&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Mar 26 19:56:56 2012
> @@ -3379,7 +3379,42 @@
> // Check whether the next token(s) are part of a declaration
> // specifier, in which case we have the start of a parameter and,
> // therefore, we know that this is a constructor.
> - bool IsConstructor = isDeclarationSpecifier();
> + bool IsConstructor = false;
> + if (isDeclarationSpecifier())
> + IsConstructor = true;
> + else if (Tok.is(tok::identifier) ||
> + (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::identifier))) {
> + // We've seen "C ( X" or "C ( X::Y", but "X" / "X::Y" is not a type.
> + // This might be a parenthesized member name, but is more likely to
> + // be a constructor declaration with an invalid argument type. Keep
> + // looking.
> + if (Tok.is(tok::annot_cxxscope))
> + ConsumeToken();
> + ConsumeToken();
> +
> + // If this is not a constructor, we must be parsing a declarator,
> + // which must have one of the following syntactic forms:
> + switch (Tok.getKind()) {
> + case tok::l_paren:
> + // C(X ( int));
> + case tok::l_square:
> + // C(X [ 5]);
> + // C(X [ [attribute]]);
> + case tok::coloncolon:
> + // C(X :: Y);
> + // C(X :: *p);
> + case tok::r_paren:
> + // C(X )
> + // Assume this isn't a constructor, rather than assuming it's a
> + // constructor with an unnamed parameter of an ill-formed type.
> + break;
I really don't like adding new lists of tokens like this... can you at
least leave a note pointing here from the place which actually handles
this grammar?
-Eli
More information about the cfe-commits
mailing list