]> granicus.if.org Git - clang/commitdiff
Fix a tentative-parse error with unqualified template ids in cast expressions.
authorJohn McCall <rjmccall@apple.com>
Fri, 30 Apr 2010 03:11:01 +0000 (03:11 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 30 Apr 2010 03:11:01 +0000 (03:11 +0000)
Also resolve a long-working FIXME in the test case I modified.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102688 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseTentative.cpp
test/Parser/cxx-casting.cpp

index 516a9a620b62c0fda6101d2cab48ce97942b932e..a6c6d3f9453596a214405365b62f53a4d3a53639 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/ParseDiagnostic.h"
+#include "clang/Parse/Template.h"
 using namespace clang;
 
 /// isCXXDeclarationStatement - C++-specialized function that disambiguates
@@ -761,6 +762,17 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() {
   case tok::kw___vector:
     return TPResult::True();
 
+  case tok::annot_template_id: {
+    TemplateIdAnnotation *TemplateId
+      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
+    if (TemplateId->Kind != TNK_Type_template)
+      return TPResult::False();
+    CXXScopeSpec SS;
+    AnnotateTemplateIdTokenAsType(&SS);
+    assert(Tok.is(tok::annot_typename));
+    goto case_typename;
+  }
+
   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())
@@ -801,6 +813,7 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() {
   case tok::kw_double:
   case tok::kw_void:
   case tok::annot_typename:
+  case_typename:
     if (NextToken().is(tok::l_paren))
       return TPResult::Ambiguous();
 
index c8b4716aa356cddde4f7faf8b1685cf8dbcb3fca..98d962ad0998f8dba99a893fad51d8989f4e6159 100644 (file)
@@ -5,8 +5,6 @@ char *const_cast_test(const char *var)
   return const_cast<char*>(var);
 }
 
-#if 0
-// FIXME: Uncomment when C++ is supported more.
 struct A {
   virtual ~A() {}
 };
@@ -18,7 +16,6 @@ struct B *dynamic_cast_test(struct A *a)
 {
   return dynamic_cast<struct B*>(a);
 }
-#endif
 
 char *reinterpret_cast_test()
 {
@@ -34,3 +31,9 @@ char postfix_expr_test()
 {
   return reinterpret_cast<char*>(0xdeadbeef)[0];
 }
+
+// This was being incorrectly tentatively parsed.
+namespace test1 {
+  template <class T> class A {};
+  void foo() { A<int>(*(A<int>*)0); }
+}