[cfe-commits] r91734 - in /cfe/trunk: lib/Parse/ParseTentative.cpp lib/Parse/Parser.cpp test/Parser/cxx-ambig-paren-expr.cpp test/SemaTemplate/metafun-apply.cpp

John McCall rjmccall at apple.com
Fri Dec 18 16:35:18 PST 2009


Author: rjmccall
Date: Fri Dec 18 18:35:18 2009
New Revision: 91734

URL: http://llvm.org/viewvc/llvm-project?rev=91734&view=rev
Log:
Teach TryAnnotateTypeOrScopeToken to deal with already-annotated
scope specifiers.  Fix a tentative parsing bug that came up in LLVM.
Incidentally fixes some random FIXMEs in an existing testcase.


Modified:
    cfe/trunk/lib/Parse/ParseTentative.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp
    cfe/trunk/test/SemaTemplate/metafun-apply.cpp

Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=91734&r1=91733&r2=91734&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Fri Dec 18 18:35:18 2009
@@ -680,10 +680,10 @@
     // Otherwise, not a typename.
     return TPResult::False();
 
-  case tok::coloncolon:   // ::foo::bar
-      if (NextToken().is(tok::kw_new) ||    // ::new
-          NextToken().is(tok::kw_delete))   // ::delete
-        return TPResult::False();
+  case tok::coloncolon:     // ::foo::bar
+    if (NextToken().is(tok::kw_new) ||    // ::new
+        NextToken().is(tok::kw_delete))   // ::delete
+      return TPResult::False();
 
     // Annotate typenames and C++ scope specifiers.  If we get one, just
     // recurse to handle whatever we get.
@@ -750,6 +750,12 @@
   case tok::kw___forceinline:
     return TPResult::True();
 
+  case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
+    // We've already annotated a scope; try to annotate a type.
+    if (!(TryAnnotateTypeOrScopeToken() && Tok.is(tok::annot_typename)))
+      return TPResult::False();
+    // If that succeeded, fallthrough into the generic simple-type-id case.
+
     // The ambiguity resides in a simple-type-specifier/typename-specifier
     // followed by a '('. The '(' could either be the start of:
     //

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=91734&r1=91733&r2=91734&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Fri Dec 18 18:35:18 2009
@@ -880,7 +880,7 @@
 /// as the current tokens, so only call it in contexts where these are invalid.
 bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) {
   assert((Tok.is(tok::identifier) || Tok.is(tok::coloncolon)
-          || Tok.is(tok::kw_typename)) &&
+          || Tok.is(tok::kw_typename) || Tok.is(tok::annot_cxxscope)) &&
          "Cannot be a type or scope token!");
 
   if (Tok.is(tok::kw_typename)) {
@@ -935,6 +935,9 @@
     return true;
   }
 
+  // Remembers whether the token was originally a scope annotation.
+  bool wasScopeAnnotation = Tok.is(tok::annot_cxxscope);
+
   CXXScopeSpec SS;
   if (getLang().CPlusPlus)
     ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext);
@@ -1017,9 +1020,11 @@
   Tok.setAnnotationValue(SS.getScopeRep());
   Tok.setAnnotationRange(SS.getRange());
 
-  // In case the tokens were cached, have Preprocessor replace them with the
-  // annotation token.
-  PP.AnnotateCachedTokens(Tok);
+  // In case the tokens were cached, have Preprocessor replace them
+  // with the annotation token.  We don't need to do this if we've
+  // just reverted back to the state we were in before being called.
+  if (!wasScopeAnnotation)
+    PP.AnnotateCachedTokens(Tok);
   return true;
 }
 

Modified: cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp?rev=91734&r1=91733&r2=91734&view=diff

==============================================================================
--- cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp (original)
+++ cfe/trunk/test/Parser/cxx-ambig-paren-expr.cpp Fri Dec 18 18:35:18 2009
@@ -24,3 +24,43 @@
   // FIXME: Special case: "++" is postfix here, not prefix
   // (S())++;
 }
+
+// Make sure we do tentative parsing correctly in conditions.
+typedef int type;
+struct rec { rec(int); };
+
+namespace ns {
+  typedef int type;
+  struct rec { rec(int); };
+}
+
+struct cls {
+  typedef int type;
+  struct rec { rec(int); };
+};
+
+struct result {
+  template <class T> result(T);
+  bool check();
+};
+
+void test(int i) {
+  if (result((cls::type) i).check())
+    return;
+
+  if (result((ns::type) i).check())
+    return;
+
+  if (result((::type) i).check())
+    return;
+
+  if (result((cls::rec) i).check())
+    return;
+
+  if (result((ns::rec) i).check())
+    return;
+
+  if (result((::rec) i).check())
+    return;
+}
+

Modified: cfe/trunk/test/SemaTemplate/metafun-apply.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/metafun-apply.cpp?rev=91734&r1=91733&r2=91734&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/metafun-apply.cpp (original)
+++ cfe/trunk/test/SemaTemplate/metafun-apply.cpp Fri Dec 18 18:35:18 2009
@@ -32,11 +32,9 @@
 apply1<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}}
 
 void test() {
-  apply1<add_reference, void>::type t; // expected-note{{in instantiation of template class 'struct apply1<struct add_reference, void>' requested here}} \
-  // FIXME: expected-error{{unexpected type name 'type': expected expression}}
+  apply1<add_reference, void>::type t; // expected-note{{in instantiation of template class 'struct apply1<struct add_reference, void>' requested here}}
 
-  apply1<bogus, int>::type t2; // expected-note{{in instantiation of template class 'struct apply1<struct bogus, int>' requested here}} \
-  // FIXME: expected-error{{unexpected type name 'type': expected expression}}
+  apply1<bogus, int>::type t2; // expected-note{{in instantiation of template class 'struct apply1<struct bogus, int>' requested here}}
 }
 
 





More information about the cfe-commits mailing list