<div dir="ltr">I never heard "class specifier" outside of compilerese either…</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Dec 9, 2016 at 2:47 PM, Reid Kleckner via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: rnk<br>
Date: Fri Dec 9 13:47:58 2016<br>
New Revision: 289259<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=289259&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=289259&view=rev</a><br>
Log:<br>
Improve error message when referencing a non-tag type with a tag<br>
<br>
Other compilers accept invalid code here that we reject, and we need a<br>
better error message to try to convince users that the code is really<br>
incorrect. Consider:<br>
class Foo {<br>
typedef MyIterHelper<Foo> iterator;<br>
friend class iterator;<br>
};<br>
<br>
Previously our wording was "elaborated type refers to a typedef".<br>
"elaborated type" isn't widely known terminology, so the new diagnostic<br>
says "typedef 'iterator' cannot be referenced with class specifier".<br>
<br>
Reviewers: rsmith<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D25216" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D25216</a><br>
<br>
Modified:<br>
cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp<br>
cfe/trunk/lib/Sema/<wbr>TreeTransform.h<br>
cfe/trunk/test/CXX/basic/<wbr>basic.lookup/basic.lookup.<wbr>elab/p2.cpp<br>
cfe/trunk/test/CXX/dcl.dcl/<wbr>dcl.spec/dcl.type/dcl.type.<wbr>elab/p2-0x.cpp<br>
cfe/trunk/test/CXX/drs/dr2xx.<wbr>cpp<br>
cfe/trunk/test/CXX/drs/dr4xx.<wbr>cpp<br>
cfe/trunk/test/CXX/temp/temp.<wbr>decls/temp.friend/p1.cpp<br>
cfe/trunk/test/CXX/temp/temp.<wbr>spec/no-body.cpp<br>
cfe/trunk/test/SemaCXX/PR8755.<wbr>cpp<br>
cfe/trunk/test/SemaCXX/using-<wbr>decl-templates.cpp<br>
cfe/trunk/test/SemaTemplate/<wbr>template-id-expr.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/<wbr>DiagnosticSemaKinds.td?rev=<wbr>289259&r1=289258&r2=289259&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/<wbr>DiagnosticSemaKinds.td Fri Dec 9 13:47:58 2016<br>
@@ -4564,10 +4564,15 @@ def err_redefinition_different_<wbr>typedef :<br>
"%select{typedef|type alias|type alias template}0 "<br>
"redefinition with different types%diff{ ($ vs $)|}1,2">;<br>
def err_tag_reference_non_tag : Error<<br>
- "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template|a template template argument}0">;<br>
+ "%select{non-struct type|non-class type|non-union type|non-enum "<br>
+ "type|typedef|type alias|template|type alias template|template "<br>
+ "template argument}1 %0 cannot be referenced with a "<br>
+ "%select{struct|interface|<wbr>union|class|enum}2 specifier">;<br>
def err_tag_reference_conflict : Error<<br>
- "implicit declaration introduced by elaborated type conflicts with "<br>
- "%select{a declaration|a typedef|a type alias|a template}0 of the same name">;<br>
+ "implicit declaration introduced by elaborated type conflicts with a "<br>
+ "%select{non-struct type|non-class type|non-union type|non-enum "<br>
+ "type|typedef|type alias|template|type alias template|template "<br>
+ "template argument}0 of the same name">;<br>
def err_dependent_tag_decl : Error<<br>
"%select{declaration|<wbr>definition}0 of "<br>
"%select{struct|interface|<wbr>union|class|enum}1 in a dependent scope">;<br>
<br>
Modified: cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Sema.h?rev=289259&<wbr>r1=289258&r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/include/clang/Sema/<wbr>Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/<wbr>Sema.h Fri Dec 9 13:47:58 2016<br>
@@ -1976,7 +1976,10 @@ public:<br>
/// Common ways to introduce type names without a tag for use in diagnostics.<br>
/// Keep in sync with err_tag_reference_non_tag.<br>
enum NonTagKind {<br>
- NTK_Unknown,<br>
+ NTK_NonStruct,<br>
+ NTK_NonClass,<br>
+ NTK_NonUnion,<br>
+ NTK_NonEnum,<br>
NTK_Typedef,<br>
NTK_TypeAlias,<br>
NTK_Template,<br>
@@ -1986,7 +1989,7 @@ public:<br>
<br>
/// Given a non-tag type declaration, returns an enum useful for indicating<br>
/// what kind of non-tag type this is.<br>
- NonTagKind getNonTagTypeDeclKind(const Decl *D);<br>
+ NonTagKind getNonTagTypeDeclKind(const Decl *D, TagTypeKind TTK);<br>
<br>
bool isAcceptableTagRedeclaration(<wbr>const TagDecl *Previous,<br>
TagTypeKind NewTag, bool isDefinition,<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDecl.cpp?rev=289259&r1=<wbr>289258&r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp Fri Dec 9 13:47:58 2016<br>
@@ -12430,7 +12430,8 @@ static bool isClassCompatTagKind(TagType<br>
return Tag == TTK_Struct || Tag == TTK_Class || Tag == TTK_Interface;<br>
}<br>
<br>
-Sema::NonTagKind Sema::getNonTagTypeDeclKind(<wbr>const Decl *PrevDecl) {<br>
+Sema::NonTagKind Sema::getNonTagTypeDeclKind(<wbr>const Decl *PrevDecl,<br>
+ TagTypeKind TTK) {<br>
if (isa<TypedefDecl>(PrevDecl))<br>
return NTK_Typedef;<br>
else if (isa<TypeAliasDecl>(PrevDecl))<br>
@@ -12441,7 +12442,17 @@ Sema::NonTagKind Sema::getNonTagTypeDecl<br>
return NTK_TypeAliasTemplate;<br>
else if (isa<TemplateTemplateParmDecl><wbr>(PrevDecl))<br>
return NTK_TemplateTemplateArgument;<br>
- return NTK_Unknown;<br>
+ switch (TTK) {<br>
+ case TTK_Struct:<br>
+ case TTK_Interface:<br>
+ case TTK_Class:<br>
+ return getLangOpts().CPlusPlus ? NTK_NonClass : NTK_NonStruct;<br>
+ case TTK_Union:<br>
+ return NTK_NonUnion;<br>
+ case TTK_Enum:<br>
+ return NTK_NonEnum;<br>
+ }<br>
+ llvm_unreachable("invalid TTK");<br>
}<br>
<br>
/// \brief Determine whether a tag with a given kind is acceptable<br>
@@ -13224,8 +13235,9 @@ Decl *Sema::ActOnTag(Scope *S, unsigned<br>
// (non-redeclaration) lookup.<br>
if ((TUK == TUK_Reference || TUK == TUK_Friend) &&<br>
!Previous.isForRedeclaration()<wbr>) {<br>
- NonTagKind NTK = getNonTagTypeDeclKind(<wbr>PrevDecl);<br>
- Diag(NameLoc, diag::err_tag_reference_non_<wbr>tag) << NTK;<br>
+ NonTagKind NTK = getNonTagTypeDeclKind(<wbr>PrevDecl, Kind);<br>
+ Diag(NameLoc, diag::err_tag_reference_non_<wbr>tag) << PrevDecl << NTK<br>
+ << Kind;<br>
Diag(PrevDecl->getLocation(), diag::note_declared_at);<br>
Invalid = true;<br>
<br>
@@ -13236,7 +13248,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned<br>
<br>
// Diagnose implicit declarations introduced by elaborated types.<br>
} else if (TUK == TUK_Reference || TUK == TUK_Friend) {<br>
- NonTagKind NTK = getNonTagTypeDeclKind(<wbr>PrevDecl);<br>
+ NonTagKind NTK = getNonTagTypeDeclKind(<wbr>PrevDecl, Kind);<br>
Diag(NameLoc, diag::err_tag_reference_<wbr>conflict) << NTK;<br>
Diag(PrevDecl->getLocation(), diag::note_previous_decl) << PrevDecl;<br>
Invalid = true;<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp?rev=289259&<wbr>r1=289258&r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp Fri Dec 9 13:47:58 2016<br>
@@ -2489,7 +2489,8 @@ TypeResult Sema::ActOnTagTemplateIdType(<br>
// If the identifier resolves to a typedef-name or the simple-template-id<br>
// resolves to an alias template specialization, the<br>
// elaborated-type-specifier is ill-formed.<br>
- Diag(TemplateLoc, diag::err_tag_reference_non_<wbr>tag) << NTK_TypeAliasTemplate;<br>
+ Diag(TemplateLoc, diag::err_tag_reference_non_<wbr>tag)<br>
+ << TAT << NTK_TypeAliasTemplate << TagKind;<br>
Diag(TAT->getLocation(), diag::note_declared_at);<br>
}<br>
<br>
@@ -7508,8 +7509,8 @@ Sema::<wbr>ActOnExplicitInstantiation(<wbr>Scope *<br>
ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(<wbr>TD);<br>
<br>
if (!ClassTemplate) {<br>
- NonTagKind NTK = getNonTagTypeDeclKind(TD);<br>
- Diag(TemplateNameLoc, diag::err_tag_reference_non_<wbr>tag) << NTK;<br>
+ NonTagKind NTK = getNonTagTypeDeclKind(TD, Kind);<br>
+ Diag(TemplateNameLoc, diag::err_tag_reference_non_<wbr>tag) << TD << NTK << Kind;<br>
Diag(TD->getLocation(), diag::note_previous_use);<br>
return true;<br>
}<br>
<br>
Modified: cfe/trunk/lib/Sema/<wbr>TreeTransform.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>TreeTransform.h?rev=289259&r1=<wbr>289258&r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/<wbr>TreeTransform.h (original)<br>
+++ cfe/trunk/lib/Sema/<wbr>TreeTransform.h Fri Dec 9 13:47:58 2016<br>
@@ -1013,8 +1013,9 @@ public:<br>
case LookupResult::FoundOverloaded:<br>
case LookupResult::<wbr>FoundUnresolvedValue: {<br>
NamedDecl *SomeDecl = Result.getRepresentativeDecl()<wbr>;<br>
- Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(<wbr>SomeDecl);<br>
- SemaRef.Diag(IdLoc, diag::err_tag_reference_non_<wbr>tag) << NTK;<br>
+ Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(<wbr>SomeDecl, Kind);<br>
+ SemaRef.Diag(IdLoc, diag::err_tag_reference_non_<wbr>tag) << SomeDecl<br>
+ << NTK << Kind;<br>
SemaRef.Diag(SomeDecl-><wbr>getLocation(), diag::note_declared_at);<br>
break;<br>
}<br>
@@ -5706,7 +5707,8 @@ TreeTransform<Derived>::<wbr>TransformElabora<br>
Template.getAsTemplateDecl())) {<br>
SemaRef.Diag(TL.<wbr>getNamedTypeLoc().getBeginLoc(<wbr>),<br>
diag::err_tag_reference_non_<wbr>tag)<br>
- << Sema::NTK_TypeAliasTemplate;<br>
+ << TAT << Sema::NTK_TypeAliasTemplate<br>
+ << ElaboratedType::<wbr>getTagTypeKindForKeyword(T-><wbr>getKeyword());<br>
SemaRef.Diag(TAT->getLocation(<wbr>), diag::note_declared_at);<br>
}<br>
}<br>
<br>
Modified: cfe/trunk/test/CXX/basic/<wbr>basic.lookup/basic.lookup.<wbr>elab/p2.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>basic/basic.lookup/basic.<wbr>lookup.elab/p2.cpp?rev=289259&<wbr>r1=289258&r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/basic/<wbr>basic.lookup/basic.lookup.<wbr>elab/p2.cpp (original)<br>
+++ cfe/trunk/test/CXX/basic/<wbr>basic.lookup/basic.lookup.<wbr>elab/p2.cpp Fri Dec 9 13:47:58 2016<br>
@@ -9,7 +9,7 @@ namespace test0 {<br>
typedef int A; // expected-note {{declared here}}<br>
<br>
int test() {<br>
- struct A a; // expected-error {{elaborated type refers to a typedef}}<br>
+ struct A a; // expected-error {{typedef 'A' cannot be referenced with a struct specifier}}<br>
return a.foo;<br>
}<br>
}<br>
@@ -18,7 +18,7 @@ namespace test0 {<br>
template <class> class A; // expected-note {{declared here}}<br>
<br>
int test() {<br>
- struct A a; // expected-error {{elaborated type refers to a template}}<br>
+ struct A a; // expected-error {{template 'A' cannot be referenced with a struct specifier}}<br>
return a.foo;<br>
}<br>
}<br>
<br>
Modified: cfe/trunk/test/CXX/dcl.dcl/<wbr>dcl.spec/dcl.type/dcl.type.<wbr>elab/p2-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>dcl.dcl/dcl.spec/dcl.type/dcl.<wbr>type.elab/p2-0x.cpp?rev=<wbr>289259&r1=289258&r2=289259&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/dcl.dcl/<wbr>dcl.spec/dcl.type/dcl.type.<wbr>elab/p2-0x.cpp (original)<br>
+++ cfe/trunk/test/CXX/dcl.dcl/<wbr>dcl.spec/dcl.type/dcl.type.<wbr>elab/p2-0x.cpp Fri Dec 9 13:47:58 2016<br>
@@ -2,18 +2,18 @@<br>
<br>
struct A { typedef int type; };<br>
template<typename T> using X = A; // expected-note {{declared here}}<br>
-struct X<int>* p2; // expected-error {{elaborated type refers to a type alias template}}<br>
+struct X<int>* p2; // expected-error {{type alias template 'X' cannot be referenced with a struct specifier}}<br>
<br>
<br>
template<typename T> using Id = T; // expected-note {{declared here}}<br>
template<template<typename> class F><br>
struct Y {<br>
- struct F<int> i; // expected-error {{elaborated type refers to a type alias template}}<br>
+ struct F<int> i; // expected-error {{type alias template 'Id' cannot be referenced with a struct specifier}}<br>
typename F<A>::type j; // ok<br>
<br>
// FIXME: don't produce the diagnostic both for the definition and the instantiation.<br>
template<typename T> using U = F<char>; // expected-note 2{{declared here}}<br>
- struct Y<F>::template U<char> k; // expected-error 2{{elaborated type refers to a type alias template}}<br>
+ struct Y<F>::template U<char> k; // expected-error 2{{type alias template 'U' cannot be referenced with a struct specifier}}<br>
typename Y<F>::template U<char> l; // ok<br>
};<br>
template struct Y<Id>; // expected-note {{requested here}}<br>
<br>
Modified: cfe/trunk/test/CXX/drs/dr2xx.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr2xx.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>drs/dr2xx.cpp?rev=289259&r1=<wbr>289258&r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/drs/dr2xx.<wbr>cpp (original)<br>
+++ cfe/trunk/test/CXX/drs/dr2xx.<wbr>cpp Fri Dec 9 13:47:58 2016<br>
@@ -620,7 +620,7 @@ namespace dr254 { // dr254: yes<br>
template<typename T> struct A {<br>
typedef typename T::type type; // ok even if this is a typedef-name, because<br>
// it's not an elaborated-type-specifier<br>
- typedef struct T::type foo; // expected-error {{elaborated type refers to a typedef}}<br>
+ typedef struct T::type foo; // expected-error {{typedef 'type' cannot be referenced with a struct specifier}}<br>
};<br>
struct B { struct type {}; };<br>
struct C { typedef struct {} type; }; // expected-note {{here}}<br>
@@ -1048,8 +1048,8 @@ namespace dr298 { // dr298: yes<br>
C::type i3;<br>
<br>
struct A a;<br>
- struct B b; // expected-error {{refers to a typedef}}<br>
- struct C c; // expected-error {{refers to a typedef}}<br>
+ struct B b; // expected-error {{typedef 'B' cannot be referenced with a struct specifier}}<br>
+ struct C c; // expected-error {{typedef 'C' cannot be referenced with a struct specifier}}<br>
<br>
B::B() {} // expected-error {{requires a type specifier}}<br>
B::A() {} // ok<br>
<br>
Modified: cfe/trunk/test/CXX/drs/dr4xx.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>drs/dr4xx.cpp?rev=289259&r1=<wbr>289258&r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/drs/dr4xx.<wbr>cpp (original)<br>
+++ cfe/trunk/test/CXX/drs/dr4xx.<wbr>cpp Fri Dec 9 13:47:58 2016<br>
@@ -90,7 +90,7 @@ namespace dr407 { // dr407: 3.8<br>
struct S *p;<br>
{<br>
typedef struct S S; // expected-note {{here}}<br>
- struct S *p; // expected-error {{refers to a typedef}}<br>
+ struct S *p; // expected-error {{typedef 'S' cannot be referenced with a struct specifier}}<br>
}<br>
}<br>
struct S {};<br>
<br>
Modified: cfe/trunk/test/CXX/temp/temp.<wbr>decls/temp.friend/p1.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p1.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>temp/temp.decls/temp.friend/<wbr>p1.cpp?rev=289259&r1=289258&<wbr>r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/temp/temp.<wbr>decls/temp.friend/p1.cpp (original)<br>
+++ cfe/trunk/test/CXX/temp/temp.<wbr>decls/temp.friend/p1.cpp Fri Dec 9 13:47:58 2016<br>
@@ -174,7 +174,7 @@ namespace test7 {<br>
<br>
// This shouldn't crash.<br>
template <class T> class D {<br>
- friend class A; // expected-error {{elaborated type refers to a template}}<br>
+ friend class A; // expected-error {{template 'A' cannot be referenced with a class specifier}}<br>
};<br>
template class D<int>;<br>
}<br>
<br>
Modified: cfe/trunk/test/CXX/temp/temp.<wbr>spec/no-body.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/no-body.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/CXX/<wbr>temp/temp.spec/no-body.cpp?<wbr>rev=289259&r1=289258&r2=<wbr>289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/CXX/temp/temp.<wbr>spec/no-body.cpp (original)<br>
+++ cfe/trunk/test/CXX/temp/temp.<wbr>spec/no-body.cpp Fri Dec 9 13:47:58 2016<br>
@@ -43,7 +43,7 @@ namespace good { // Only good in C++98/0<br>
<br>
namespace unsupported {<br>
#ifndef FIXING<br>
- template struct y; // expected-error {{elaborated type refers to a template}}<br>
+ template struct y; // expected-error {{template 'y' cannot be referenced with a struct specifier}}<br>
#endif<br>
}<br>
<br>
<br>
Modified: cfe/trunk/test/SemaCXX/PR8755.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/PR8755.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/PR8755.cpp?rev=289259&<wbr>r1=289258&r2=289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/PR8755.<wbr>cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/PR8755.<wbr>cpp Fri Dec 9 13:47:58 2016<br>
@@ -7,7 +7,7 @@ struct A {<br>
<br>
template <typename T><br>
void f() {<br>
- class A <T> ::iterator foo; // expected-error{{elaborated type refers to a typedef}}<br>
+ class A <T> ::iterator foo; // expected-error{{typedef 'iterator' cannot be referenced with a class specifier}}<br>
}<br>
<br>
void g() {<br>
<br>
Modified: cfe/trunk/test/SemaCXX/using-<wbr>decl-templates.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/using-decl-templates.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/using-decl-templates.<wbr>cpp?rev=289259&r1=289258&r2=<wbr>289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/using-<wbr>decl-templates.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/using-<wbr>decl-templates.cpp Fri Dec 9 13:47:58 2016<br>
@@ -90,7 +90,7 @@ namespace aliastemplateinst {<br>
template<typename T> struct A { };<br>
template<typename T> using APtr = A<T*>; // expected-note{{previous use is here}}<br>
<br>
- template struct APtr<int>; // expected-error{{elaborated type refers to a type alias template}}<br>
+ template struct APtr<int>; // expected-error{{type alias template 'APtr' cannot be referenced with a struct specifier}}<br>
}<br>
<br>
namespace DontDiagnoseInvalidTest {<br>
<br>
Modified: cfe/trunk/test/SemaTemplate/<wbr>template-id-expr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/template-id-expr.cpp?rev=289259&r1=289258&r2=289259&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaTemplate/template-id-expr.<wbr>cpp?rev=289259&r1=289258&r2=<wbr>289259&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaTemplate/<wbr>template-id-expr.cpp (original)<br>
+++ cfe/trunk/test/SemaTemplate/<wbr>template-id-expr.cpp Fri Dec 9 13:47:58 2016<br>
@@ -100,5 +100,5 @@ template void f5<0>(); // expected-note<br>
class C {};<br>
template <template <typename> class D> // expected-note{{previous use is here}}<br>
class E {<br>
- template class D<C>; // expected-error {{elaborated type refers to a template template argument}}<br>
+ template class D<C>; // expected-error {{template template argument 'D' cannot be referenced with a class specifier}}<br>
};<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>