[PATCH] D13854: Template class: emit better diagnostic in case of missing template argument list

Davide Italiano via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 18 20:43:56 PDT 2015


davide created this revision.
davide added a reviewer: rsmith.
davide added a subscriber: cfe-commits.
davide set the repository for this revision to rL LLVM.

Richard, this implements what you proposed in https://llvm.org/bugs/show_bug.cgi?id=25223 , hopefully in the correct way.
This is what we emit now:

template.cpp:7:3: error: missing template argument list for class template 'X'
T X::foo(void)
  ^
  X<T, Q>
template.cpp:2:7: note: 'X' declared here
class X {
      ^
1 error generated.


I will tackle the case where we emit a terrible diagnostic for ambigous lookup separately.



Repository:
  rL LLVM

http://reviews.llvm.org/D13854

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaCXXScopeSpec.cpp
  test/SemaTemplate/temp_arg_lookup.cpp

Index: test/SemaTemplate/temp_arg_lookup.cpp
===================================================================
--- test/SemaTemplate/temp_arg_lookup.cpp
+++ test/SemaTemplate/temp_arg_lookup.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T, class Q>
+class X { // expected-note{{declared here}}
+  T foo(void);
+};
+
+template<class T, class Q>
+T X::foo(void)  // expected-error{{missing template argument list for class template}}}
+{
+  return 0;
+}
Index: lib/Sema/SemaCXXScopeSpec.cpp
===================================================================
--- lib/Sema/SemaCXXScopeSpec.cpp
+++ lib/Sema/SemaCXXScopeSpec.cpp
@@ -771,9 +771,29 @@
   }
 
   if (!Found.empty()) {
-    if (TypeDecl *TD = Found.getAsSingle<TypeDecl>())
+    if (ClassTemplateDecl *CTD = Found.getAsSingle<ClassTemplateDecl>()) {
+      TemplateParameterList *TPL = CTD->getTemplateParameters();
+      assert(TPL && "NULL template parameter list");
+      std::string FixString = Identifier.getName();
+      FixString += "<";
+      bool FirstArg = true;
+      for (NamedDecl *TemplArg : *TPL) {
+        if (FirstArg)
+          FirstArg = false;
+        else
+          FixString += ", ";
+        FixString += TemplArg->getName();
+      }
+      FixString += ">";
+      Diag(IdentifierLoc, diag::err_missing_argument_list) << &Identifier
+          << FixItHint::CreateReplacement(IdentifierLoc, FixString);
+      if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
+        Diag(ND->getLocation(), diag::note_entity_declared_at) << &Identifier;
+    }
+    else if (TypeDecl *TD = Found.getAsSingle<TypeDecl>()) {
       Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
           << QualType(TD->getTypeForDecl(), 0) << getLangOpts().CPlusPlus;
+    }
     else {
       Diag(IdentifierLoc, diag::err_expected_class_or_namespace)
           << &Identifier << getLangOpts().CPlusPlus;
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5831,6 +5831,8 @@
   
 def err_expected_class_or_namespace : Error<"%0 is not a class"
   "%select{ or namespace|, namespace, or enumeration}1">;
+def err_missing_argument_list : Error<"missing template argument list for "
+  "class template %0">;
 def err_invalid_declarator_scope : Error<"cannot define or redeclare %0 here "
   "because namespace %1 does not enclose namespace %2">;
 def err_invalid_declarator_global_scope : Error<


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13854.37716.patch
Type: text/x-patch
Size: 2577 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151019/a70515a4/attachment-0001.bin>


More information about the cfe-commits mailing list