[cfe-commits] r100729 - in /cfe/trunk: include/clang/AST/TemplateName.h include/clang/Basic/DiagnosticSemaKinds.td lib/AST/TemplateName.cpp lib/Sema/SemaTemplate.cpp test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp test/SemaTemplate/temp_arg_type.cpp

Jeffrey Yasskin jyasskin at google.com
Wed Apr 7 17:03:06 PDT 2010


Author: jyasskin
Date: Wed Apr  7 19:03:06 2010
New Revision: 100729

URL: http://llvm.org/viewvc/llvm-project?rev=100729&view=rev
Log:
When a template (without arguments) is passed as a template type
parameter, explicitly ask the user to give it arguments.  We used to
complain that it wasn't a type and expect the user to figure it out.


Modified:
    cfe/trunk/include/clang/AST/TemplateName.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/TemplateName.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
    cfe/trunk/test/SemaTemplate/temp_arg_type.cpp

Modified: cfe/trunk/include/clang/AST/TemplateName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TemplateName.h?rev=100729&r1=100728&r2=100729&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/TemplateName.h (original)
+++ cfe/trunk/include/clang/AST/TemplateName.h Wed Apr  7 19:03:06 2010
@@ -25,6 +25,7 @@
 namespace clang {
 
 class DependentTemplateName;
+class DiagnosticBuilder;
 class IdentifierInfo;
 class NestedNameSpecifier;
 struct PrintingPolicy;
@@ -173,6 +174,11 @@
   }
 };
 
+/// Insertion operator for diagnostics.  This allows sending TemplateName's
+/// into a diagnostic with <<.
+const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
+                                    TemplateName N);
+
 /// \brief Represents a template name that was expressed as a
 /// qualified name.
 ///

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=100729&r1=100728&r2=100729&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr  7 19:03:06 2010
@@ -1184,6 +1184,8 @@
   "cannot refer to class template %0 without a template argument list">;
 
 // C++ Template Argument Lists
+def err_template_missing_args : Error<
+  "use of class template %0 requires template arguments">;
 def err_template_arg_list_different_arity : Error<
   "%select{too few|too many}0 template arguments for "
   "%select{class template|function template|template template parameter"

Modified: cfe/trunk/lib/AST/TemplateName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TemplateName.cpp?rev=100729&r1=100728&r2=100729&view=diff
==============================================================================
--- cfe/trunk/lib/AST/TemplateName.cpp (original)
+++ cfe/trunk/lib/AST/TemplateName.cpp Wed Apr  7 19:03:06 2010
@@ -15,9 +15,11 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/PrettyPrinter.h"
+#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/LangOptions.h"
 #include "llvm/Support/raw_ostream.h"
 using namespace clang;
+using namespace llvm;
 
 TemplateDecl *TemplateName::getAsTemplateDecl() const {
   if (TemplateDecl *Template = Storage.dyn_cast<TemplateDecl *>())
@@ -64,6 +66,18 @@
   }
 }
 
+const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
+                                           TemplateName N) {
+  std::string NameStr;
+  raw_string_ostream OS(NameStr);
+  LangOptions LO;
+  LO.CPlusPlus = true;
+  LO.Bool = true;
+  N.print(OS, PrintingPolicy(LO));
+  OS.flush();
+  return DB << NameStr;
+}
+
 void TemplateName::dump() const {
   LangOptions LO;  // FIXME!
   LO.CPlusPlus = true;

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=100729&r1=100728&r2=100729&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Apr  7 19:03:06 2010
@@ -1663,11 +1663,25 @@
   const TemplateArgument &Arg = AL.getArgument();
 
   // Check template type parameter.
-  if (Arg.getKind() != TemplateArgument::Type) {
+  switch(Arg.getKind()) {
+  case TemplateArgument::Type:
     // C++ [temp.arg.type]p1:
     //   A template-argument for a template-parameter which is a
     //   type shall be a type-id.
+    break;
+  case TemplateArgument::Template: {
+    // We have a template type parameter but the template argument
+    // is a template without any arguments.
+    SourceRange SR = AL.getSourceRange();
+    TemplateName Name = Arg.getAsTemplate();
+    Diag(SR.getBegin(), diag::err_template_missing_args)
+      << Name << SR;
+    if (TemplateDecl *Decl = Name.getAsTemplateDecl())
+      Diag(Decl->getLocation(), diag::note_template_decl_here);
 
+    return true;
+  }
+  default: {
     // We have a template type parameter but the template argument
     // is not a type.
     SourceRange SR = AL.getSourceRange();
@@ -1676,6 +1690,7 @@
 
     return true;
   }
+  }
 
   if (CheckTemplateArgument(Param, AL.getTypeSourceInfo()))
     return true;

Modified: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp?rev=100729&r1=100728&r2=100729&view=diff
==============================================================================
--- cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp (original)
+++ cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp Wed Apr  7 19:03:06 2010
@@ -32,6 +32,6 @@
 // Test that we don't find the injected class name when parsing base
 // specifiers.
 namespace test2 {
-  template <class T> struct bar {}; // expected-note {{template parameter is declared here}}
-  template <class T> struct foo : bar<foo> {}; // expected-error {{template argument for template type parameter must be a type}}
+  template <class T> struct bar {};
+  template <class T> struct foo : bar<foo> {}; // expected-error {{use of class template foo requires template arguments}} expected-note {{template is declared here}}
 }

Modified: cfe/trunk/test/SemaTemplate/temp_arg_type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_arg_type.cpp?rev=100729&r1=100728&r2=100729&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_arg_type.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_arg_type.cpp Wed Apr  7 19:03:06 2010
@@ -1,16 +1,26 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
-template<typename T> class A; // expected-note 2 {{template parameter is declared here}}
+template<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}}
 
 // [temp.arg.type]p1
 A<0> *a1; // expected-error{{template argument for template type parameter must be a type}}
 
-A<A> *a2; // expected-error{{template argument for template type parameter must be a type}}
+A<A> *a2; // expected-error{{use of class template A requires template arguments}}
 
 A<int> *a3;
 A<int()> *a4; 
 A<int(float)> *a5;
 A<A<int> > *a6;
 
+// Pass an overloaded function template:
+template<typename T> void function_tpl(T);
+A<function_tpl> a7;  // expected-error{{template argument for template type parameter must be a type}}
+
+// Pass a qualified name:
+namespace ns {
+template<typename T> class B {};  // expected-note{{template is declared here}}
+}
+A<ns::B> a8; // expected-error{{use of class template ns::B requires template arguments}}
+
 // [temp.arg.type]p2
 void f() {
   class X { };
@@ -18,7 +28,7 @@
 }
 
 struct { int x; } Unnamed; // expected-note{{unnamed type used in template argument was declared here}}
-A<__typeof__(Unnamed)> *a7; // expected-error{{template argument uses unnamed type}}
+A<__typeof__(Unnamed)> *a9; // expected-error{{template argument uses unnamed type}}
 
 // FIXME: [temp.arg.type]p3. The check doesn't really belong here (it
 // belongs somewhere in the template instantiation section).





More information about the cfe-commits mailing list