Index: FixIt/fixit-typedef-instead-of-typename-typo.cpp =================================================================== --- /dev/null +++ FixIt/fixit-typedef-instead-of-typename-typo.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -verify %s + +template struct Foo { + // Should not produce error about type since parsing speculatively with fixit applied. + B member; + // Let's just check that other errors get reported. + a +}; +// CHECK: expected-error@-6 {{expected template parameter}} +// CHECK: expected-note@-7 {{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@-6 {{unknown type name 'a'}} +// CHECK: expected-error@-6 {{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 {