nikola created this revision.
nikola added a reviewer: rsmith.
nikola added a subscriber: cfe-commits.

Current diagnostic says "expected expression" or "reference to non-static 
member function must be called". This should fix PR13566 and PR18995

http://reviews.llvm.org/D15509

Files:
  lib/Parse/ParseTemplate.cpp
  lib/Parse/RAIIObjectsForParser.h
  test/SemaTemplate/dependent-template-recover.cpp

Index: test/SemaTemplate/dependent-template-recover.cpp
===================================================================
--- test/SemaTemplate/dependent-template-recover.cpp
+++ test/SemaTemplate/dependent-template-recover.cpp
@@ -11,12 +11,35 @@
     T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
     t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
 
-    // FIXME: We can't recover from these yet
-    (*t).f2<N>(); // expected-error{{expected expression}}
-    (*t).f2<0>(); // expected-error{{expected expression}}
+    (*t).f2<N>(); // expected-error{{use 'template' keyword to treat 'f2' as a dependent template name}}
+    (*t).f2<0>(); // expected-error{{use 'template' keyword to treat 'f2' as a dependent template name}}
   }
 };
 
+namespace PR13566 {
+template <typename T>
+struct S
+{
+  template <int N>
+  void foo();
+
+  template <int N>
+  void foo(int);
+};
+
+template <typename T>
+void bar()
+{
+  S<T> s;
+  s.foo<1>(); // expected-error{{use 'template' keyword to treat 'foo' as a dependent template name}}
+  s.foo<1>(0); // expected-error{{use 'template' keyword to treat 'foo' as a dependent template name}}
+}
+
+void instantiate() {
+  bar<int>();
+}
+}
+
 namespace PR9401 {
   // From GCC PR c++/45558
   template <typename S, typename T>
Index: lib/Parse/RAIIObjectsForParser.h
===================================================================
--- lib/Parse/RAIIObjectsForParser.h
+++ lib/Parse/RAIIObjectsForParser.h
@@ -442,6 +442,18 @@
     void skipToEnd();
   };
 
+  /// \brief RAII object that suppresses all diagnostics
+  class SuppressAllDiagnostics {
+    DiagnosticsEngine &Diags;
+    bool OldVal;
+  public:
+    SuppressAllDiagnostics(DiagnosticsEngine &Diags) : Diags(Diags) {
+      OldVal = Diags.getSuppressAllDiagnostics();
+      Diags.setSuppressAllDiagnostics(true);
+    }
+    ~SuppressAllDiagnostics() { Diags.setSuppressAllDiagnostics(OldVal); }
+  };
+
 } // end namespace clang
 
 #endif
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -1209,34 +1209,35 @@
                                 ExprArg.get(), Loc);
 }
 
-/// \brief Determine whether the current tokens can only be parsed as a 
-/// template argument list (starting with the '<') and never as a '<' 
-/// expression.
+/// \brief Determine whether the current tokens (starting with the '<') can be
+/// parsed as a template argument list
 bool Parser::IsTemplateArgumentList(unsigned Skip) {
   struct AlwaysRevertAction : TentativeParsingAction {
     AlwaysRevertAction(Parser &P) : TentativeParsingAction(P) { }
     ~AlwaysRevertAction() { Revert(); }
   } Tentative(*this);
-  
+
   while (Skip) {
     ConsumeToken();
     --Skip;
   }
-  
+
   // '<'
   if (!TryConsumeToken(tok::less))
     return false;
 
   // An empty template argument list.
   if (Tok.is(tok::greater))
     return true;
-  
-  // See whether we have declaration specifiers, which indicate a type.
-  while (isCXXDeclarationSpecifier() == TPResult::True)
-    ConsumeToken();
-  
-  // If we have a '>' or a ',' then this is a template argument list.
-  return Tok.isOneOf(tok::greater, tok::comma);
+
+  SuppressAllDiagnostics S(Diags);
+  GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
+  TemplateArgList TemplateArgs;
+  if (ParseTemplateArgumentList(TemplateArgs))
+    return false;
+
+  // Closing '>'
+  return Tok.is(tok::greater);
 }
 
 /// ParseTemplateArgumentList - Parse a C++ template-argument-list
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to