jkorous-apple created this revision.

https://reviews.llvm.org/D42170

Files:
  Parse/ParseTemplate.cpp
  Parser/typedef-instead-of-typename-typo.hpp
  clang/Basic/DiagnosticParseKinds.td


Index: Parser/typedef-instead-of-typename-typo.hpp
===================================================================
--- /dev/null
+++ Parser/typedef-instead-of-typename-typo.hpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -verify %s
+
+template <typename A, typedef B> struct Foo {
+  a
+}; // CHECK: expected-error{{expected template parameter}} \
+// CHECK: expected-note{{Did you mean to use 'typename'?}} \
+// CHECK: fix-it:{{.*}}:{4:23-4:30}:"typename" \
+// Check that we are speculatively (with fixit applied) trying to parse the 
rest. \
+// CHECK: expected-error{{unknown type name 'a'}} \
+// CHECK: expected-error{{expected member name or ';' after declaration 
specifiers}}
Index: Parse/ParseTemplate.cpp
===================================================================
--- Parse/ParseTemplate.cpp
+++ Parse/ParseTemplate.cpp
@@ -488,6 +488,20 @@
   if (Tok.is(tok::kw_template))
     return ParseTemplateTemplateParameter(Depth, Position);
 
+  // Is there just a typo in the input code? ('typedef' instead of 'typename')
+  if (Tok.is(tok::kw_typedef)) {
+    Diag(Tok.getLocation(), diag::err_expected_template_parameter);
+
+    Diag(Tok.getLocation(), diag::note_meant_to_use_typename)
+        << FixItHint::CreateReplacement(CharSourceRange::getCharRange(
+                                            Tok.getLocation(), 
Tok.getEndLoc()),
+                                        "typename");
+
+    Tok.setKind(tok::kw_typename);
+
+    return ParseTypeParameter(Depth, Position);
+  }
+
   // If it's none of the above, then it must be a parameter declaration.
   // NOTE: This will pick up errors in the closure of the template parameter
   // list (e.g., template < ; Check here to implement >> style closures.
Index: clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/Basic/DiagnosticParseKinds.td
+++ clang/Basic/DiagnosticParseKinds.td
@@ -1162,6 +1162,9 @@
 
 def err_objc_type_args_after_protocols : Error<
   "protocol qualifiers must precede type arguments">;
+
+def note_meant_to_use_typename : Note<
+  "Did you mean to use 'typename'?">;
 }
 
 let CategoryName = "Coroutines Issue" in {


Index: Parser/typedef-instead-of-typename-typo.hpp
===================================================================
--- /dev/null
+++ Parser/typedef-instead-of-typename-typo.hpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -verify %s
+
+template <typename A, typedef B> struct Foo {
+  a
+}; // CHECK: expected-error{{expected template parameter}} \
+// CHECK: expected-note{{Did you mean to use 'typename'?}} \
+// CHECK: fix-it:{{.*}}:{4:23-4:30}:"typename" \
+// Check that we are speculatively (with fixit applied) trying to parse the rest. \
+// CHECK: expected-error{{unknown type name 'a'}} \
+// CHECK: expected-error{{expected member name or ';' after declaration specifiers}}
Index: Parse/ParseTemplate.cpp
===================================================================
--- Parse/ParseTemplate.cpp
+++ Parse/ParseTemplate.cpp
@@ -488,6 +488,20 @@
   if (Tok.is(tok::kw_template))
     return ParseTemplateTemplateParameter(Depth, Position);
 
+  // Is there just a typo in the input code? ('typedef' instead of 'typename')
+  if (Tok.is(tok::kw_typedef)) {
+    Diag(Tok.getLocation(), diag::err_expected_template_parameter);
+
+    Diag(Tok.getLocation(), diag::note_meant_to_use_typename)
+        << FixItHint::CreateReplacement(CharSourceRange::getCharRange(
+                                            Tok.getLocation(), Tok.getEndLoc()),
+                                        "typename");
+
+    Tok.setKind(tok::kw_typename);
+
+    return ParseTypeParameter(Depth, Position);
+  }
+
   // If it's none of the above, then it must be a parameter declaration.
   // NOTE: This will pick up errors in the closure of the template parameter
   // list (e.g., template < ; Check here to implement >> style closures.
Index: clang/Basic/DiagnosticParseKinds.td
===================================================================
--- clang/Basic/DiagnosticParseKinds.td
+++ clang/Basic/DiagnosticParseKinds.td
@@ -1162,6 +1162,9 @@
 
 def err_objc_type_args_after_protocols : Error<
   "protocol qualifiers must precede type arguments">;
+
+def note_meant_to_use_typename : Note<
+  "Did you mean to use 'typename'?">;
 }
 
 let CategoryName = "Coroutines Issue" in {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to