[cfe-commits] r170223 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseObjc.cpp lib/Parse/ParseTemplate.cpp test/Parser/objcxx11-protocol-in-template.mm
Nico Weber
nicolasweber at gmx.de
Fri Dec 14 10:22:38 PST 2012
Author: nico
Date: Fri Dec 14 12:22:38 2012
New Revision: 170223
URL: http://llvm.org/viewvc/llvm-project?rev=170223&view=rev
Log:
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.
Added:
cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=170223&r1=170222&r2=170223&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Dec 14 12:22:38 2012
@@ -2166,6 +2166,8 @@
// C++ 14.3: Template arguments [temp.arg]
typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList;
+ bool ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
+ bool ConsumeLastToken);
bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
SourceLocation TemplateNameLoc,
const CXXScopeSpec &SS,
Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=170223&r1=170222&r2=170223&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Fri Dec 14 12:22:38 2012
@@ -1200,12 +1200,8 @@
}
// Consume the '>'.
- if (Tok.isNot(tok::greater)) {
- Diag(Tok, diag::err_expected_greater);
+ if (ParseGreaterThanInTemplateList(EndLoc, /*ConsumeLastToken=*/true))
return true;
- }
-
- EndLoc = ConsumeToken();
// Convert the list of protocols identifiers into a list of protocol decls.
Actions.FindProtocolDeclaration(WarnOnDeclarations,
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=170223&r1=170222&r2=170223&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Fri Dec 14 12:22:38 2012
@@ -665,52 +665,17 @@
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 @@
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.
///
Added: cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm?rev=170223&view=auto
==============================================================================
--- cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm (added)
+++ cfe/trunk/test/Parser/objcxx11-protocol-in-template.mm Fri Dec 14 12:22:38 2012
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+template<class T> class vector {};
+ at protocol P @end
+
+#if __cplusplus >= 201103L
+ // expected-no-diagnostics
+#else
+ // expected-error at 14{{a space is required between consecutive right angle brackets}}
+ // expected-error at 15{{a space is required between consecutive right angle brackets}}
+#endif
+
+vector<id<P>> v;
+vector<vector<id<P>>> v2;
More information about the cfe-commits
mailing list