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
This commit is contained in:
Douglas Gregor 2009-07-22 00:28:09 +00:00
Родитель f59a56e180
Коммит 7551c183e8
3 изменённых файлов: 21 добавлений и 2 удалений

Просмотреть файл

@ -793,7 +793,7 @@ def err_template_arg_not_pointer_to_member_form : Error<
def err_template_arg_extra_parens : Error< def err_template_arg_extra_parens : Error<
"non-type template argument cannot be surrounded by parentheses">; "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< def err_template_spec_needs_header : Error<
"template specialization requires 'template<>'">; "template specialization requires 'template<>'">;
def err_template_spec_needs_template_parameters : Error< 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< def err_template_spec_extra_headers : Error<
"extraneous template parameter list in template specialization or " "extraneous template parameter list in template specialization or "
"out-of-line template definition">; "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< def err_template_spec_decl_out_of_scope_global : Error<
"class template %select{|partial }0specialization of %1 must occur in the " "class template %select{|partial }0specialization of %1 must occur in the "
"global scope">; "global scope">;

Просмотреть файл

@ -17,6 +17,7 @@
#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/NestedNameSpecifier.h"
#include "clang/Parse/DeclSpec.h" #include "clang/Parse/DeclSpec.h"
#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang; using namespace clang;
/// \brief Compute the DeclContext that is associated with the given /// \brief Compute the DeclContext that is associated with the given
@ -48,7 +49,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
if (EnteringContext) { if (EnteringContext) {
// We are entering the context of the nested name specifier, so try to // We are entering the context of the nested name specifier, so try to
// match the nested name specifier to either a primary class template // 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 if (const TemplateSpecializationType *SpecType
= dyn_cast_or_null<TemplateSpecializationType>(NNS->getAsType())) { = dyn_cast_or_null<TemplateSpecializationType>(NNS->getAsType())) {
if (ClassTemplateDecl *ClassTemplate if (ClassTemplateDecl *ClassTemplate
@ -64,6 +65,17 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
// FIXME: Class template partial specializations // 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; return 0;

Просмотреть файл

@ -12,6 +12,7 @@ public:
void f1(size_type) const; void f1(size_type) const;
void f2(size_type) const; void f2(size_type) const;
void f3(size_type) const; void f3(size_type) const;
void f4() ;
T value; T value;
}; };
@ -36,6 +37,9 @@ template<class X, class Y, class Z> // expected-error{{too many template paramet
void X0<X, Y>::f3(size_type) const { void X0<X, Y>::f3(size_type) const {
} }
template<class X, class Y>
void X0<Y, X>::f4() { } // expected-error{{does not refer to}}
// FIXME: error message should probably say, "redefinition of 'X0<T, U>::f0'" // FIXME: error message should probably say, "redefinition of 'X0<T, U>::f0'"
// rather than just "redefinition of 'f0'" // rather than just "redefinition of 'f0'"
template<typename T, typename U> template<typename T, typename U>