[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