[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