mirror of https://github.com/microsoft/clang.git
Diagnose attempts to explicitly instantiate a template at class scope. Previously Clang would simply ignore the 'template' keyword in this case.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@294639 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
05157f019a
commit
7bf80c8d8f
|
@ -2459,9 +2459,10 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
|||
if (Tok.is(tok::kw_template)) {
|
||||
assert(!TemplateInfo.TemplateParams &&
|
||||
"Nested template improperly parsed?");
|
||||
ObjCDeclContextSwitch ObjCDC(*this);
|
||||
SourceLocation DeclEnd;
|
||||
return DeclGroupPtrTy::make(
|
||||
DeclGroupRef(ParseDeclarationStartingWithTemplate(
|
||||
DeclGroupRef(ParseTemplateDeclarationOrSpecialization(
|
||||
Declarator::MemberContext, DeclEnd, AS, AccessAttrs)));
|
||||
}
|
||||
|
||||
|
|
|
@ -238,3 +238,13 @@ struct t2 : base<int,
|
|||
// expected-error@-1 {{expected '{' after base class list}}
|
||||
|
||||
}
|
||||
|
||||
namespace class_scope_instantiation {
|
||||
struct A {
|
||||
template<typename T> void f(T);
|
||||
template void f<int>(int); // expected-error {{expected '<' after 'template'}}
|
||||
template void f(float); // expected-error {{expected '<' after 'template'}}
|
||||
extern template // expected-error {{expected member name or ';'}}
|
||||
void f(double);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// RUN: not %clang_cc1 %s -fsyntax-only 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: error: expected member name or ';' after declaration specifiers
|
||||
// CHECK: error: expected '<' after 'template'
|
||||
// CHECK: error: expected '}'
|
||||
// CHECK: note: to match this '{'
|
||||
// CHECK: error: expected ';' after class
|
||||
|
|
|
@ -17,8 +17,7 @@ class A {
|
|||
template<typename T> CONST float right<float,T> = 5; // expected-error {{member 'right' declared as a template}}
|
||||
template<> static CONST int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}}
|
||||
template<> static CONST float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}}
|
||||
template static CONST int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \
|
||||
// expected-error {{explicit specialization of 'right' in class scope}}
|
||||
template static CONST int right<int,int>; // expected-error {{expected '<' after 'template'}}
|
||||
};
|
||||
|
||||
namespace out_of_line {
|
||||
|
@ -166,8 +165,7 @@ namespace constexpred {
|
|||
template<typename T> constexpr float right<float,T> = 5; // expected-error {{non-static data member cannot be constexpr; did you intend to make it static?}}
|
||||
template<> static constexpr int right<int,int> = 7; // expected-error {{explicit specialization of 'right' in class scope}}
|
||||
template<> static constexpr float right<float,int>; // expected-error {{explicit specialization of 'right' in class scope}}
|
||||
template static constexpr int right<int,int>; // expected-error {{template specialization requires 'template<>'}} \
|
||||
// expected-error {{explicit specialization of 'right' in class scope}}
|
||||
template static constexpr int right<int,int>; // expected-error {{expected '<' after 'template'}}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -103,8 +103,8 @@ namespace PR7622 {
|
|||
// Test that we do not crash.
|
||||
class TC1 {
|
||||
class TC2 {
|
||||
template // FIXME: error here.
|
||||
void foo() { }
|
||||
template
|
||||
void foo() { } // expected-error{{expected '<' after 'template'}}
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -98,7 +98,11 @@ void f5() {
|
|||
template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}}
|
||||
|
||||
class C {};
|
||||
template <template <typename> class D> // expected-note{{previous use is here}}
|
||||
template <template <typename> class D>
|
||||
class E {
|
||||
template class D<C>; // expected-error {{template template argument 'D' cannot be referenced with a class specifier}}
|
||||
template class D<C>; // expected-error {{expected '<' after 'template'}}
|
||||
template<> class D<C>; // expected-error {{cannot specialize a template template parameter}}
|
||||
friend class D<C>; // expected-error {{type alias template 'D' cannot be referenced with a class specifier}}
|
||||
};
|
||||
template<typename T> using D = int; // expected-note {{declared here}} expected-warning {{extension}}
|
||||
E<D> ed; // expected-note {{instantiation of}}
|
||||
|
|
Loading…
Reference in New Issue