summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseTemplate.cpp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2012-04-06 05:26:43 +0000
committerDavid Blaikie <dblaikie@gmail.com>2012-04-06 05:26:43 +0000
commitcbd8125a6ad27fd769894cf04a5dc89df3a59d58 (patch)
tree092c8369f56a0f26f8c3d85a8436ebc970afb421 /clang/lib/Parse/ParseTemplate.cpp
parent2b4aeca74e6f2403340482cda9f096b3254df4cd (diff)
downloadbcm5719-llvm-cbd8125a6ad27fd769894cf04a5dc89df3a59d58.tar.gz
bcm5719-llvm-cbd8125a6ad27fd769894cf04a5dc89df3a59d58.zip
Restrict fixit for missing 'class' in template template parameters.
Based on Doug's feedback to r153887 this omits the FixIt if the following token isn't syntactically valid for the context. (not a comma, '...', identifier, '>', or '>>') There's a bunch of work to handle the '>>' case, but it makes for a much more pleasant diagnostic in this case. llvm-svn: 154163
Diffstat (limited to 'clang/lib/Parse/ParseTemplate.cpp')
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp44
1 files changed, 29 insertions, 15 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 91a9d723a6c..b7cc862b4da 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -312,11 +312,15 @@ bool Parser::ParseTemplateParameters(unsigned Depth,
if (Tok.is(tok::greater))
RAngleLoc = ConsumeToken();
else if (ParseTemplateParameterList(Depth, TemplateParams)) {
- if (!Tok.is(tok::greater)) {
+ if (Tok.is(tok::greatergreater)) {
+ Tok.setKind(tok::greater);
+ Tok.setLocation(Tok.getLocation().getLocWithOffset(1));
+ } else if (Tok.is(tok::greater))
+ RAngleLoc = ConsumeToken();
+ else {
Diag(Tok.getLocation(), diag::err_expected_greater);
return true;
}
- RAngleLoc = ConsumeToken();
}
return false;
}
@@ -339,13 +343,13 @@ Parser::ParseTemplateParameterList(unsigned Depth,
} else {
// If we failed to parse a template parameter, skip until we find
// a comma or closing brace.
- SkipUntil(tok::comma, tok::greater, true, true);
+ SkipUntil(tok::comma, tok::greater, tok::greatergreater, true, true);
}
// Did we find a comma or the end of the template parmeter list?
if (Tok.is(tok::comma)) {
ConsumeToken();
- } else if (Tok.is(tok::greater)) {
+ } else if (Tok.is(tok::greater) || Tok.is(tok::greatergreater)) {
// Don't consume this... that's done by template parser.
break;
} else {
@@ -490,7 +494,7 @@ Decl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
ParamName = Tok.getIdentifierInfo();
NameLoc = ConsumeToken();
} else if (Tok.is(tok::equal) || Tok.is(tok::comma) ||
- Tok.is(tok::greater)) {
+ Tok.is(tok::greater) || Tok.is(tok::greatergreater)) {
// Unnamed template parameter. Don't have to do anything here, just
// don't consume this token.
} else {
@@ -539,15 +543,24 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
}
// Generate a meaningful error if the user forgot to put class before the
- // identifier, comma, or greater.
- if (Tok.is(tok::kw_typename) || Tok.is(tok::kw_struct)) {
- Diag(Tok.getLocation(), diag::err_expected_class_on_template_template_param)
- << FixItHint::CreateReplacement(Tok.getLocation(), "class");
- ConsumeToken();
- } else if (!Tok.is(tok::kw_class))
- Diag(Tok.getLocation(), diag::err_expected_class_on_template_template_param)
- << FixItHint::CreateInsertion(Tok.getLocation(), "class ");
- else
+ // identifier, comma, or greater. Provide a fixit if the identifier, comma,
+ // or greater appear immediately or after 'typename' or 'struct'. In the
+ // latter case, replace the keyword with 'class'.
+ if (!Tok.is(tok::kw_class)) {
+ bool Replace = Tok.is(tok::kw_typename) || Tok.is(tok::kw_struct);
+ const Token& Next = Replace ? NextToken() : Tok;
+ if (Next.is(tok::identifier) || Next.is(tok::comma) ||
+ Next.is(tok::greater) || Next.is(tok::greatergreater) ||
+ Next.is(tok::ellipsis))
+ Diag(Tok.getLocation(), diag::err_class_on_template_template_param)
+ << (Replace ? FixItHint::CreateReplacement(Tok.getLocation(), "class")
+ : FixItHint::CreateInsertion(Tok.getLocation(), "class "));
+ else
+ Diag(Tok.getLocation(), diag::err_class_on_template_template_param);
+
+ if (Replace)
+ ConsumeToken();
+ } else
ConsumeToken();
// Parse the ellipsis, if given.
@@ -567,7 +580,8 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
if (Tok.is(tok::identifier)) {
ParamName = Tok.getIdentifierInfo();
NameLoc = ConsumeToken();
- } else if (Tok.is(tok::equal) || Tok.is(tok::comma) || Tok.is(tok::greater)) {
+ } else if (Tok.is(tok::equal) || Tok.is(tok::comma) ||
+ Tok.is(tok::greater) || Tok.is(tok::greatergreater)) {
// Unnamed template parameter. Don't have to do anything here, just
// don't consume this token.
} else {
OpenPOWER on IntegriCloud