summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-03-27 00:56:56 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-03-27 00:56:56 +0000
commitefd009de1c1ff206d32aa2b9db96bfc6a25d5256 (patch)
tree30b4983961c7c0fb9ca5880a780421029e595a43 /clang/lib
parent551662bf5da58dc040eaafe5fa9417c28bf868fe (diff)
downloadbcm5719-llvm-efd009de1c1ff206d32aa2b9db96bfc6a25d5256.tar.gz
bcm5719-llvm-efd009de1c1ff206d32aa2b9db96bfc6a25d5256.zip
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. llvm-svn: 153488
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 24386d08ba6..75abcae2828 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3379,7 +3379,42 @@ bool Parser::isConstructorDeclarator() {
// 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;
+
+ default:
+ IsConstructor = true;
+ break;
+ }
+ }
+
TPA.Revert();
return IsConstructor;
}
OpenPOWER on IntegriCloud