forked from OSchip/llvm-project
Diagnose attempts to write a templated data member, from Stepan
Dyatkovskiy! Fixes PR10896. llvm-svn: 140250
This commit is contained in:
parent
bc9ba30158
commit
7c26c04ba9
|
@ -1947,6 +1947,9 @@ def err_template_template_parm_no_parms : Error<
|
|||
def err_template_variable : Error<"variable %0 declared as a template">;
|
||||
def err_template_variable_noparams : Error<
|
||||
"extraneous 'template<>' in declaration of variable %0">;
|
||||
def err_template_member : Error<"member %0 declared as a template">;
|
||||
def err_template_member_noparams : Error<
|
||||
"extraneous 'template<>' in declaration of member %0">;
|
||||
def err_template_tag_noparams : Error<
|
||||
"extraneous 'template<>' in declaration of %0 %1">;
|
||||
def err_template_decl_ref : Error<
|
||||
|
|
|
@ -1121,6 +1121,30 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
|
|||
if (isInstField) {
|
||||
CXXScopeSpec &SS = D.getCXXScopeSpec();
|
||||
|
||||
// FIXME: Check that the name is an identifier!
|
||||
IdentifierInfo *II = Name.getAsIdentifierInfo();
|
||||
|
||||
// Member field could not be with "template" keyword.
|
||||
// So TemplateParameterLists should be empty in this case.
|
||||
if (TemplateParameterLists.size()) {
|
||||
TemplateParameterList* TemplateParams = TemplateParameterLists.get()[0];
|
||||
if (TemplateParams->size()) {
|
||||
// There is no such thing as a member field template.
|
||||
Diag(D.getIdentifierLoc(), diag::err_template_member)
|
||||
<< II
|
||||
<< SourceRange(TemplateParams->getTemplateLoc(),
|
||||
TemplateParams->getRAngleLoc());
|
||||
} else {
|
||||
// There is an extraneous 'template<>' for this member.
|
||||
Diag(TemplateParams->getTemplateLoc(),
|
||||
diag::err_template_member_noparams)
|
||||
<< II
|
||||
<< SourceRange(TemplateParams->getTemplateLoc(),
|
||||
TemplateParams->getRAngleLoc());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (SS.isSet() && !SS.isInvalid()) {
|
||||
// The user provided a superfluous scope specifier inside a class
|
||||
// definition:
|
||||
|
@ -1138,9 +1162,7 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
|
|||
|
||||
SS.clear();
|
||||
}
|
||||
|
||||
// FIXME: Check for template parameters!
|
||||
// FIXME: Check that the name is an identifier!
|
||||
|
||||
Member = HandleField(S, cast<CXXRecordDecl>(CurContext), Loc, D, BitWidth,
|
||||
HasDeferredInit, AS);
|
||||
assert(Member && "HandleField never returns null");
|
||||
|
|
|
@ -125,4 +125,20 @@ X2<int>::Inner<X2_arg> x2i1;
|
|||
X2<float> x2a; // expected-note{{instantiation}}
|
||||
X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
|
||||
|
||||
namespace PR10896 {
|
||||
template<typename TN>
|
||||
class Foo {
|
||||
|
||||
public:
|
||||
void foo() {}
|
||||
private:
|
||||
|
||||
template<typename T>
|
||||
T SomeField; // expected-error {{member 'SomeField' declared as a template}}
|
||||
};
|
||||
|
||||
void g() {
|
||||
Foo<int> f;
|
||||
f.foo();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue