diff options
author | Nico Weber <nicolasweber@gmx.de> | 2012-12-14 18:22:38 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2012-12-14 18:22:38 +0000 |
commit | 7aa4a881e6c534b89c39247bbd059729c22ddef3 (patch) | |
tree | 1f842a4a7055ed8a81c2a3c8f49350a71efe1d86 /clang/lib/Parse/ParseTemplate.cpp | |
parent | 9f0b4ec0f5c456179803e2674bade8ee5d1f8677 (diff) | |
download | bcm5719-llvm-7aa4a881e6c534b89c39247bbd059729c22ddef3.tar.gz bcm5719-llvm-7aa4a881e6c534b89c39247bbd059729c22ddef3.zip |
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.
llvm-svn: 170223
Diffstat (limited to 'clang/lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 102 |
1 files changed, 58 insertions, 44 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index f227089acfb..80a3a910cce 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/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. /// |