From: Douglas Gregor Date: Wed, 22 Jul 2009 00:28:09 +0000 (+0000) Subject: Complain if we're entering the context of a dependent nested-name-specifier but X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7551c183e8d788b5254e9c6f8bd8d719cea47da8;p=clang Complain if we're entering the context of a dependent nested-name-specifier but cannot match that nested-name-specifier to a class template or class template partial specialization. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76704 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index f225b7e808..5a8ffb1bb7 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -793,7 +793,7 @@ def err_template_arg_not_pointer_to_member_form : Error< def err_template_arg_extra_parens : Error< "non-type template argument cannot be surrounded by parentheses">; -// C++ class template specialization +// C++ class template specializations and out-of-line definitions def err_template_spec_needs_header : Error< "template specialization requires 'template<>'">; def err_template_spec_needs_template_parameters : Error< @@ -802,6 +802,9 @@ def err_template_spec_needs_template_parameters : Error< def err_template_spec_extra_headers : Error< "extraneous template parameter list in template specialization or " "out-of-line template definition">; +def err_template_qualified_declarator_no_match : Error< + "nested name specifier '%0' for declaration does not refer to a class " + "template or class template partial specialization">; def err_template_spec_decl_out_of_scope_global : Error< "class template %select{|partial }0specialization of %1 must occur in the " "global scope">; diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 7db0da4553..cf73725e7f 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -17,6 +17,7 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/Parse/DeclSpec.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/raw_ostream.h" using namespace clang; /// \brief Compute the DeclContext that is associated with the given @@ -48,7 +49,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS, if (EnteringContext) { // We are entering the context of the nested name specifier, so try to // match the nested name specifier to either a primary class template - // or a class template partial specialization + // or a class template partial specialization. if (const TemplateSpecializationType *SpecType = dyn_cast_or_null(NNS->getAsType())) { if (ClassTemplateDecl *ClassTemplate @@ -64,6 +65,17 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS, // FIXME: Class template partial specializations } } + + std::string NNSString; + { + llvm::raw_string_ostream OS(NNSString); + NNS->print(OS, Context.PrintingPolicy); + } + + // FIXME: Allow us to pass a nested-name-specifier to Diag? + Diag(SS.getRange().getBegin(), + diag::err_template_qualified_declarator_no_match) + << NNSString << SS.getRange(); } return 0; diff --git a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp index 6979b4135c..c1da8a1f48 100644 --- a/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp +++ b/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp @@ -12,6 +12,7 @@ public: void f1(size_type) const; void f2(size_type) const; void f3(size_type) const; + void f4() ; T value; }; @@ -36,6 +37,9 @@ template // expected-error{{too many template paramet void X0::f3(size_type) const { } +template +void X0::f4() { } // expected-error{{does not refer to}} + // FIXME: error message should probably say, "redefinition of 'X0::f0'" // rather than just "redefinition of 'f0'" template