<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>