зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
f59a56e180
Коммит
7551c183e8
|
@ -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>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче