https://github.com/Veeloxfire created https://github.com/llvm/llvm-project/pull/95726
For the somewhat easy mistake of `template<template A> ...` clang outputs a partially cryptic error This patch changes this to assume the programmer intended `typename` in cases where `template` is illegal, and emit diagnostics (and forward parsing) accordingly This mirrors the behaviour of `typedef` handling, so I feel its a reasonable qol change Apologies if I missed any broken tests. Currently my local setup is messed up and fails on 100-200 tests eroniously, so I did my best to search through the errors and find the ones that needed updating >From 44620330cd5238de549d3d77ddc447cd3bc51e60 Mon Sep 17 00:00:00 2001 From: Veeloxfire <58116051+veeloxf...@users.noreply.github.com> Date: Mon, 17 Jun 2024 01:20:32 +0100 Subject: [PATCH] [clang][Parser] "Better" error messages for invalid template template For the somewhat easy mistake of `template<template A> ...` clang outputs a partially cryptic error Change this to assume the programmer intended `typename` in cases where `template` is illegal, and emit diagnostics (and forward parsing) accordingly This mirrors the behaviour of `typedef` handling --- clang/lib/Parse/ParseTemplate.cpp | 17 +++++++++++++++++ clang/test/CXX/drs/cwg1xx.cpp | 2 ++ clang/test/Parser/cxx-template-decl.cpp | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index a5130f56600e5..e5308d9edac5f 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -787,6 +787,23 @@ NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { assert(Tok.is(tok::kw_template) && "Expected 'template' keyword"); + if (Token ahead = GetLookAheadToken(1); + ahead.isOneOf(tok::identifier, tok::ellipsis, + tok::equal, tok::comma, + tok::greater, tok::greatergreater, tok::greatergreatergreater)) { + // Maybe they intended `typename` instead of `template` (given thats more common) + // Error early, to add a fixit hint + + Diag(ahead.getLocation(), diag::err_expected_less_after) << "template"; + + Diag(Tok.getLocation(), diag::note_meant_to_use_typename) + << FixItHint::CreateReplacement(CharSourceRange::getTokenRange(Tok.getLocation()), + "typename"); + + Tok.setKind(tok::kw_typename); + return ParseTypeParameter(Depth, Position); + } + // Handle the template <...> part. SourceLocation TemplateLoc = ConsumeToken(); SmallVector<NamedDecl*,8> TemplateParams; diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp index e7dddd1ea9278..72b3ff40152d5 100644 --- a/clang/test/CXX/drs/cwg1xx.cpp +++ b/clang/test/CXX/drs/cwg1xx.cpp @@ -1145,8 +1145,10 @@ namespace cwg181 { // cwg181: yes namespace X { template <template X<class T> > struct A { }; // expected-error@-1 +{{}} + // expected-note@-2 {{did you mean to use 'typename'?}} template <template X<class T> > void f(A<X>) { } // expected-error@-1 +{{}} + // expected-note@-2 {{did you mean to use 'typename'?}} } namespace Y { diff --git a/clang/test/Parser/cxx-template-decl.cpp b/clang/test/Parser/cxx-template-decl.cpp index 734438069b9ae..69b9ab012b478 100644 --- a/clang/test/Parser/cxx-template-decl.cpp +++ b/clang/test/Parser/cxx-template-decl.cpp @@ -22,7 +22,7 @@ template<template<int+>> struct x3; // expected-error {{expected ',' or '>' in t cpp14-error {{template template parameter requires 'class' after the parameter list}} \ cpp17-error {{template template parameter requires 'class' or 'typename' after the parameter list}} template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} \ -// expected-error{{extraneous}} +// expected-note{{did you mean to use 'typename'?}} template <template <typename> > struct Err2; // cpp14-error {{template template parameter requires 'class' after the parameter list}} // cpp17-error@-1{{template template parameter requires 'class' or 'typename' after the parameter list}} template <template <typename> Foo> struct Err3; // cpp14-error {{template template parameter requires 'class' after the parameter list}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits