summaryrefslogtreecommitdiffstats
path: root/lib/Parse
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
commit9df1b963a69dc85a271b3791267e994485e0bfe1 (patch)
tree1801e09d50213473238f9ebcb7970549d8e92fa0 /lib/Parse
parent7947bb127629faff4897f04e579d80fd0d7f97f0 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154163 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse')
-rw-r--r--lib/Parse/ParseTemplate.cpp44
1 files changed, 29 insertions, 15 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 91a9d723a6..b7cc862b4d 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/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 {