aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseTemplate.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2012-12-14 18:22:38 +0000
committerNico Weber <nicolasweber@gmx.de>2012-12-14 18:22:38 +0000
commitb707a4762fcc47c12b5f487856ba0781c9399295 (patch)
tree8752b8f33e5d7f413097e61e03854c26fab18d8b /lib/Parse/ParseTemplate.cpp
parente72f4d93ed44e00e1b1433768f0515b9c4f38562 (diff)
Don't require a space between the two ">" in "vector<id<protocol>>" in objc++11.
C++11 allowed writing "vector<vector<int>>" without a space between the two ">". This change allows this for protocols in template lists too in -std=c++11 mode, and improves the diagnostic in c++98 mode. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@170223 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r--lib/Parse/ParseTemplate.cpp102
1 files changed, 58 insertions, 44 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index f227089acf..80a3a910cc 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -665,52 +665,17 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
DefaultArg.take());
}
-/// \brief Parses a template-id that after the template name has
-/// already been parsed.
-///
-/// This routine takes care of parsing the enclosed template argument
-/// list ('<' template-parameter-list [opt] '>') and placing the
-/// results into a form that can be transferred to semantic analysis.
+/// \brief Parses a '>' at the end of a template list.
///
-/// \param Template the template declaration produced by isTemplateName
-///
-/// \param TemplateNameLoc the source location of the template name
+/// If this function encounters '>>', '>>>', '>=', or '>>=', it tries
+/// to determine if these tokens were supposed to be a '>' followed by
+/// '>', '>>', '>=', or '>='. It emits an appropriate diagnostic if necessary.
///
-/// \param SS if non-NULL, the nested-name-specifier preceding the
-/// template name.
+/// \param RAngleLoc the location of the consumed '>'.
///
-/// \param ConsumeLastToken if true, then we will consume the last
-/// token that forms the template-id. Otherwise, we will leave the
-/// last token in the stream (e.g., so that it can be replaced with an
-/// annotation token).
-bool
-Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
- SourceLocation TemplateNameLoc,
- const CXXScopeSpec &SS,
- bool ConsumeLastToken,
- SourceLocation &LAngleLoc,
- TemplateArgList &TemplateArgs,
- SourceLocation &RAngleLoc) {
- assert(Tok.is(tok::less) && "Must have already parsed the template-name");
-
- // Consume the '<'.
- LAngleLoc = ConsumeToken();
-
- // Parse the optional template-argument-list.
- bool Invalid = false;
- {
- GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
- if (Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater))
- Invalid = ParseTemplateArgumentList(TemplateArgs);
-
- if (Invalid) {
- // Try to find the closing '>'.
- SkipUntil(tok::greater, true, !ConsumeLastToken);
-
- return true;
- }
- }
-
+/// \param ConsumeLastToken if true, the '>' is not consumed.
+bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
+ bool ConsumeLastToken) {
// What will be left once we've consumed the '>'.
tok::TokenKind RemainingToken;
const char *ReplacementStr = "> >";
@@ -809,10 +774,59 @@ Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
Tok.setLength(1);
Tok.setLocation(RAngleLoc);
}
-
return false;
}
+
+/// \brief Parses a template-id that after the template name has
+/// already been parsed.
+///
+/// This routine takes care of parsing the enclosed template argument
+/// list ('<' template-parameter-list [opt] '>') and placing the
+/// results into a form that can be transferred to semantic analysis.
+///
+/// \param Template the template declaration produced by isTemplateName
+///
+/// \param TemplateNameLoc the source location of the template name
+///
+/// \param SS if non-NULL, the nested-name-specifier preceding the
+/// template name.
+///
+/// \param ConsumeLastToken if true, then we will consume the last
+/// token that forms the template-id. Otherwise, we will leave the
+/// last token in the stream (e.g., so that it can be replaced with an
+/// annotation token).
+bool
+Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
+ SourceLocation TemplateNameLoc,
+ const CXXScopeSpec &SS,
+ bool ConsumeLastToken,
+ SourceLocation &LAngleLoc,
+ TemplateArgList &TemplateArgs,
+ SourceLocation &RAngleLoc) {
+ assert(Tok.is(tok::less) && "Must have already parsed the template-name");
+
+ // Consume the '<'.
+ LAngleLoc = ConsumeToken();
+
+ // Parse the optional template-argument-list.
+ bool Invalid = false;
+ {
+ GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
+ if (Tok.isNot(tok::greater) && Tok.isNot(tok::greatergreater))
+ Invalid = ParseTemplateArgumentList(TemplateArgs);
+
+ if (Invalid) {
+ // Try to find the closing '>'.
+ SkipUntil(tok::greater, true, !ConsumeLastToken);
+
+ return true;
+ }
+ }
+
+ return ParseGreaterThanInTemplateList(RAngleLoc, ConsumeLastToken);
+}
+
/// \brief Replace the tokens that form a simple-template-id with an
/// annotation token containing the complete template-id.
///