[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-12-09 Thread Reid Kleckner via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL289259: Improve error message when referencing a non-tag 
type with a tag (authored by rnk).

Changed prior to commit:
  https://reviews.llvm.org/D25216?vs=80903=80927#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D25216

Files:
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/lib/Sema/SemaTemplate.cpp
  cfe/trunk/lib/Sema/TreeTransform.h
  cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
  cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
  cfe/trunk/test/CXX/drs/dr2xx.cpp
  cfe/trunk/test/CXX/drs/dr4xx.cpp
  cfe/trunk/test/CXX/temp/temp.decls/temp.friend/p1.cpp
  cfe/trunk/test/CXX/temp/temp.spec/no-body.cpp
  cfe/trunk/test/SemaCXX/PR8755.cpp
  cfe/trunk/test/SemaCXX/using-decl-templates.cpp
  cfe/trunk/test/SemaTemplate/template-id-expr.cpp

Index: cfe/trunk/include/clang/Sema/Sema.h
===
--- cfe/trunk/include/clang/Sema/Sema.h
+++ cfe/trunk/include/clang/Sema/Sema.h
@@ -1976,7 +1976,10 @@
   /// Common ways to introduce type names without a tag for use in diagnostics.
   /// Keep in sync with err_tag_reference_non_tag.
   enum NonTagKind {
-NTK_Unknown,
+NTK_NonStruct,
+NTK_NonClass,
+NTK_NonUnion,
+NTK_NonEnum,
 NTK_Typedef,
 NTK_TypeAlias,
 NTK_Template,
@@ -1986,7 +1989,7 @@
 
   /// Given a non-tag type declaration, returns an enum useful for indicating
   /// what kind of non-tag type this is.
-  NonTagKind getNonTagTypeDeclKind(const Decl *D);
+  NonTagKind getNonTagTypeDeclKind(const Decl *D, TagTypeKind TTK);
 
   bool isAcceptableTagRedeclaration(const TagDecl *Previous,
 TagTypeKind NewTag, bool isDefinition,
Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4564,10 +4564,15 @@
   "%select{typedef|type alias|type alias template}0 "
   "redefinition with different types%diff{ ($ vs $)|}1,2">;
 def err_tag_reference_non_tag : Error<
-  "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">;
+  "%select{non-struct type|non-class type|non-union type|non-enum "
+  "type|typedef|type alias|template|type alias template|template "
+  "template argument}1 %0 cannot be referenced with a "
+  "%select{struct|interface|union|class|enum}2 specifier">;
 def err_tag_reference_conflict : Error<
-  "implicit declaration introduced by elaborated type conflicts with "
-  "%select{a declaration|a typedef|a type alias|a template}0 of the same name">;
+  "implicit declaration introduced by elaborated type conflicts with a "
+  "%select{non-struct type|non-class type|non-union type|non-enum "
+  "type|typedef|type alias|template|type alias template|template "
+  "template argument}0 of the same name">;
 def err_dependent_tag_decl : Error<
   "%select{declaration|definition}0 of "
   "%select{struct|interface|union|class|enum}1 in a dependent scope">;
Index: cfe/trunk/test/SemaTemplate/template-id-expr.cpp
===
--- cfe/trunk/test/SemaTemplate/template-id-expr.cpp
+++ cfe/trunk/test/SemaTemplate/template-id-expr.cpp
@@ -100,5 +100,5 @@
 class C {};
 template  class D>  // expected-note{{previous use is here}}
 class E {
-  template class D;  // expected-error {{elaborated type refers to a template template argument}}
+  template class D;  // expected-error {{template template argument 'D' cannot be referenced with a class specifier}}
 };
Index: cfe/trunk/test/SemaCXX/PR8755.cpp
===
--- cfe/trunk/test/SemaCXX/PR8755.cpp
+++ cfe/trunk/test/SemaCXX/PR8755.cpp
@@ -7,7 +7,7 @@
 
 template 
 void f() {
-  class A  ::iterator foo;  // expected-error{{elaborated type refers to a typedef}}
+  class A  ::iterator foo;  // expected-error{{typedef 'iterator' cannot be referenced with a class specifier}}
 }
 
 void g() {
Index: cfe/trunk/test/SemaCXX/using-decl-templates.cpp
===
--- cfe/trunk/test/SemaCXX/using-decl-templates.cpp
+++ cfe/trunk/test/SemaCXX/using-decl-templates.cpp
@@ -90,7 +90,7 @@
   template struct A { };
   template using APtr = A; // expected-note{{previous use is here}}
 
-  template struct APtr; // expected-error{{elaborated type refers to a type alias template}}
+  template struct APtr; // expected-error{{type alias template 'APtr' cannot be referenced with a struct specifier}}
 }
 
 namespace DontDiagnoseInvalidTest {
Index: cfe/trunk/test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp

[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-12-09 Thread Richard Smith via Phabricator via cfe-commits
rsmith accepted this revision.
rsmith added a comment.
This revision is now accepted and ready to land.

Thanks!


https://reviews.llvm.org/D25216



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-12-09 Thread Reid Kleckner via Phabricator via cfe-commits
rnk updated this revision to Diff 80903.
rnk added a comment.

- new wording


https://reviews.llvm.org/D25216

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/TreeTransform.h
  test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/temp/temp.decls/temp.friend/p1.cpp
  test/CXX/temp/temp.spec/no-body.cpp
  test/SemaCXX/PR8755.cpp
  test/SemaCXX/using-decl-templates.cpp
  test/SemaTemplate/template-id-expr.cpp

Index: test/SemaTemplate/template-id-expr.cpp
===
--- test/SemaTemplate/template-id-expr.cpp
+++ test/SemaTemplate/template-id-expr.cpp
@@ -100,5 +100,5 @@
 class C {};
 template  class D>  // expected-note{{previous use is here}}
 class E {
-  template class D;  // expected-error {{elaborated type refers to a template template argument}}
+  template class D;  // expected-error {{template template argument 'D' cannot be referenced with a class specifier}}
 };
Index: test/SemaCXX/using-decl-templates.cpp
===
--- test/SemaCXX/using-decl-templates.cpp
+++ test/SemaCXX/using-decl-templates.cpp
@@ -90,7 +90,7 @@
   template struct A { };
   template using APtr = A; // expected-note{{previous use is here}}
 
-  template struct APtr; // expected-error{{elaborated type refers to a type alias template}}
+  template struct APtr; // expected-error{{type alias template 'APtr' cannot be referenced with a struct specifier}}
 }
 
 namespace DontDiagnoseInvalidTest {
Index: test/SemaCXX/PR8755.cpp
===
--- test/SemaCXX/PR8755.cpp
+++ test/SemaCXX/PR8755.cpp
@@ -7,7 +7,7 @@
 
 template 
 void f() {
-  class A  ::iterator foo;  // expected-error{{elaborated type refers to a typedef}}
+  class A  ::iterator foo;  // expected-error{{typedef 'iterator' cannot be referenced with a class specifier}}
 }
 
 void g() {
Index: test/CXX/temp/temp.spec/no-body.cpp
===
--- test/CXX/temp/temp.spec/no-body.cpp
+++ test/CXX/temp/temp.spec/no-body.cpp
@@ -43,7 +43,7 @@
 
 namespace unsupported {
 #ifndef FIXING
- template struct y; // expected-error {{elaborated type refers to a template}}
+ template struct y; // expected-error {{template 'y' cannot be referenced with a struct specifier}}
 #endif
 }
 
Index: test/CXX/temp/temp.decls/temp.friend/p1.cpp
===
--- test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -174,7 +174,7 @@
 
   // This shouldn't crash.
   template  class D {
-friend class A; // expected-error {{elaborated type refers to a template}}
+friend class A; // expected-error {{template 'A' cannot be referenced with a class specifier}}
   };
   template class D;
 }
Index: test/CXX/drs/dr4xx.cpp
===
--- test/CXX/drs/dr4xx.cpp
+++ test/CXX/drs/dr4xx.cpp
@@ -90,7 +90,7 @@
 struct S *p;
 {
   typedef struct S S; // expected-note {{here}}
-  struct S *p; // expected-error {{refers to a typedef}}
+  struct S *p; // expected-error {{typedef 'S' cannot be referenced with a struct specifier}}
 }
   }
   struct S {};
Index: test/CXX/drs/dr2xx.cpp
===
--- test/CXX/drs/dr2xx.cpp
+++ test/CXX/drs/dr2xx.cpp
@@ -620,7 +620,7 @@
   template struct A {
 typedef typename T::type type; // ok even if this is a typedef-name, because
// it's not an elaborated-type-specifier
-typedef struct T::type foo; // expected-error {{elaborated type refers to a typedef}}
+typedef struct T::type foo; // expected-error {{typedef 'type' cannot be referenced with a struct specifier}}
   };
   struct B { struct type {}; };
   struct C { typedef struct {} type; }; // expected-note {{here}}
@@ -1048,8 +1048,8 @@
   C::type i3;
 
   struct A a;
-  struct B b; // expected-error {{refers to a typedef}}
-  struct C c; // expected-error {{refers to a typedef}}
+  struct B b; // expected-error {{typedef 'B' cannot be referenced with a struct specifier}}
+  struct C c; // expected-error {{typedef 'C' cannot be referenced with a struct specifier}}
 
   B::B() {} // expected-error {{requires a type specifier}}
   B::A() {} // ok
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
===
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
@@ -2,18 +2,18 @@
 
 struct A { typedef int type; };
 template using X = A; // expected-note {{declared 

[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-11-30 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:4556-4558
+  "%0 is a %select{non-tag type|typedef|type alias|template|type alias "
+  "template|template template argument}1 that cannot be referenced with a "
+  "%select{struct|interface|union|class|enum}2 tag">;

rsmith wrote:
> "tag" is C terminology that C++ doesn't share;  "specifier" would be correct 
> in both languages.
> 
> Also, this wording suggests that *some* templates / template template 
> arguments / ... can be referenced by, say, a `struct` specifier. How about:
> 
>   %select{non-struct type|non-class type|non-union type|non-enum 
> type|typedef|type alias|template|[...]}1 %0 cannot be referenced with 
> %select{struct|interface|union|class|enum}2 specifier
> 
> (where we use "non-enum type" when the tag is `enum`, "non-union type" when 
> the tag is `union`, and otherwise use "non-struct type" in C and "non-class 
> type" in C++)?
OK, sounds good.


https://reviews.llvm.org/D25216



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-11-30 Thread Richard Smith via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: include/clang/Basic/DiagnosticSemaKinds.td:4556-4558
+  "%0 is a %select{non-tag type|typedef|type alias|template|type alias "
+  "template|template template argument}1 that cannot be referenced with a "
+  "%select{struct|interface|union|class|enum}2 tag">;

"tag" is C terminology that C++ doesn't share;  "specifier" would be correct in 
both languages.

Also, this wording suggests that *some* templates / template template arguments 
/ ... can be referenced by, say, a `struct` specifier. How about:

  %select{non-struct type|non-class type|non-union type|non-enum 
type|typedef|type alias|template|[...]}1 %0 cannot be referenced with 
%select{struct|interface|union|class|enum}2 specifier

(where we use "non-enum type" when the tag is `enum`, "non-union type" when the 
tag is `union`, and otherwise use "non-struct type" in C and "non-class type" 
in C++)?


https://reviews.llvm.org/D25216



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-11-30 Thread Bob Haarman via Phabricator via cfe-commits
inglorion added a comment.

I like it. I'll give others a little time to respond, but if no objections are 
raised and nobody else accepts first, I'll accept it tomorrow.


https://reviews.llvm.org/D25216



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-11-30 Thread Reid Kleckner via Phabricator via cfe-commits
rnk updated this revision to Diff 79805.
rnk added a comment.

- rebase


https://reviews.llvm.org/D25216

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/TreeTransform.h
  test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/temp/temp.decls/temp.friend/p1.cpp
  test/CXX/temp/temp.spec/no-body.cpp
  test/SemaCXX/PR8755.cpp
  test/SemaCXX/using-decl-templates.cpp
  test/SemaTemplate/template-id-expr.cpp

Index: test/SemaTemplate/template-id-expr.cpp
===
--- test/SemaTemplate/template-id-expr.cpp
+++ test/SemaTemplate/template-id-expr.cpp
@@ -100,5 +100,5 @@
 class C {};
 template  class D>  // expected-note{{previous use is here}}
 class E {
-  template class D;  // expected-error {{elaborated type refers to a template template argument}}
+  template class D;  // expected-error {{'D' is a template template argument that cannot be referenced with a class tag}}
 };
Index: test/SemaCXX/using-decl-templates.cpp
===
--- test/SemaCXX/using-decl-templates.cpp
+++ test/SemaCXX/using-decl-templates.cpp
@@ -90,7 +90,7 @@
   template struct A { };
   template using APtr = A; // expected-note{{previous use is here}}
 
-  template struct APtr; // expected-error{{elaborated type refers to a type alias template}}
+  template struct APtr; // expected-error{{'APtr' is a type alias template that cannot be referenced with a struct tag}}
 }
 
 namespace DontDiagnoseInvalidTest {
Index: test/SemaCXX/PR8755.cpp
===
--- test/SemaCXX/PR8755.cpp
+++ test/SemaCXX/PR8755.cpp
@@ -7,7 +7,7 @@
 
 template 
 void f() {
-  class A  ::iterator foo;  // expected-error{{elaborated type refers to a typedef}}
+  class A  ::iterator foo;  // expected-error{{'iterator' is a typedef that cannot be referenced with a class tag}}
 }
 
 void g() {
Index: test/CXX/temp/temp.spec/no-body.cpp
===
--- test/CXX/temp/temp.spec/no-body.cpp
+++ test/CXX/temp/temp.spec/no-body.cpp
@@ -43,7 +43,7 @@
 
 namespace unsupported {
 #ifndef FIXING
- template struct y; // expected-error {{elaborated type refers to a template}}
+ template struct y; // expected-error {{'y' is a template that cannot be referenced with a struct tag}}
 #endif
 }
 
Index: test/CXX/temp/temp.decls/temp.friend/p1.cpp
===
--- test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -174,7 +174,7 @@
 
   // This shouldn't crash.
   template  class D {
-friend class A; // expected-error {{elaborated type refers to a template}}
+friend class A; // expected-error {{'A' is a template that cannot be referenced with a class tag}}
   };
   template class D;
 }
Index: test/CXX/drs/dr4xx.cpp
===
--- test/CXX/drs/dr4xx.cpp
+++ test/CXX/drs/dr4xx.cpp
@@ -90,7 +90,7 @@
 struct S *p;
 {
   typedef struct S S; // expected-note {{here}}
-  struct S *p; // expected-error {{refers to a typedef}}
+  struct S *p; // expected-error {{'S' is a typedef}}
 }
   }
   struct S {};
Index: test/CXX/drs/dr2xx.cpp
===
--- test/CXX/drs/dr2xx.cpp
+++ test/CXX/drs/dr2xx.cpp
@@ -620,7 +620,7 @@
   template struct A {
 typedef typename T::type type; // ok even if this is a typedef-name, because
// it's not an elaborated-type-specifier
-typedef struct T::type foo; // expected-error {{elaborated type refers to a typedef}}
+typedef struct T::type foo; // expected-error {{'type' is a typedef that cannot be referenced with a struct tag}}
   };
   struct B { struct type {}; };
   struct C { typedef struct {} type; }; // expected-note {{here}}
@@ -1037,8 +1037,8 @@
   C::type i3;
 
   struct A a;
-  struct B b; // expected-error {{refers to a typedef}}
-  struct C c; // expected-error {{refers to a typedef}}
+  struct B b; // expected-error {{'B' is a typedef}}
+  struct C c; // expected-error {{'C' is a typedef}}
 
   B::B() {} // expected-error {{requires a type specifier}}
   B::A() {} // ok
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
===
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
@@ -2,18 +2,18 @@
 
 struct A { typedef int type; };
 template using X = A; // expected-note {{declared here}}
-struct X* p2; // expected-error {{elaborated type refers to a type alias template}}
+struct X* p2; // expected-error {{'X' 

[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-11-30 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

Ping, found this in my tree. Maybe you weren't that excited about the wording 
change.


https://reviews.llvm.org/D25216



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D25216: Improve error message when referencing a non-tag type with a tag

2016-10-03 Thread Reid Kleckner via cfe-commits
rnk created this revision.
rnk added a reviewer: rsmith.
rnk added a subscriber: cfe-commits.

Other compilers accept invalid code here that we reject, and we need a
better error message to try to convince users that the code is really
incorrect. Consider:

  class Foo {
typedef MyIterHelper iterator;
friend class iterator;
  };

Previously our wording was "elaborated type refers to a typedef".
"elaborated type" isn't widely known terminology, so the new diagnostic
tries to talk about tag types.


https://reviews.llvm.org/D25216

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/TreeTransform.h
  test/CXX/basic/basic.lookup/basic.lookup.elab/p2.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp
  test/CXX/drs/dr2xx.cpp
  test/CXX/drs/dr4xx.cpp
  test/CXX/temp/temp.decls/temp.friend/p1.cpp
  test/CXX/temp/temp.spec/no-body.cpp
  test/SemaCXX/PR8755.cpp
  test/SemaCXX/using-decl-templates.cpp
  test/SemaTemplate/template-id-expr.cpp

Index: test/SemaTemplate/template-id-expr.cpp
===
--- test/SemaTemplate/template-id-expr.cpp
+++ test/SemaTemplate/template-id-expr.cpp
@@ -100,5 +100,5 @@
 class C {};
 template  class D>  // expected-note{{previous use is here}}
 class E {
-  template class D;  // expected-error {{elaborated type refers to a template template argument}}
+  template class D;  // expected-error {{'D' is a template template argument that cannot be referenced with a class tag}}
 };
Index: test/SemaCXX/using-decl-templates.cpp
===
--- test/SemaCXX/using-decl-templates.cpp
+++ test/SemaCXX/using-decl-templates.cpp
@@ -90,5 +90,5 @@
   template struct A { };
   template using APtr = A; // expected-note{{previous use is here}}
 
-  template struct APtr; // expected-error{{elaborated type refers to a type alias template}}
+  template struct APtr; // expected-error{{'APtr' is a type alias template that cannot be referenced with a struct tag}}
 }
Index: test/SemaCXX/PR8755.cpp
===
--- test/SemaCXX/PR8755.cpp
+++ test/SemaCXX/PR8755.cpp
@@ -7,7 +7,7 @@
 
 template 
 void f() {
-  class A  ::iterator foo;  // expected-error{{elaborated type refers to a typedef}}
+  class A  ::iterator foo;  // expected-error{{'iterator' is a typedef that cannot be referenced with a class tag}}
 }
 
 void g() {
Index: test/CXX/temp/temp.spec/no-body.cpp
===
--- test/CXX/temp/temp.spec/no-body.cpp
+++ test/CXX/temp/temp.spec/no-body.cpp
@@ -43,7 +43,7 @@
 
 namespace unsupported {
 #ifndef FIXING
- template struct y; // expected-error {{elaborated type refers to a template}}
+ template struct y; // expected-error {{'y' is a template that cannot be referenced with a struct tag}}
 #endif
 }
 
Index: test/CXX/temp/temp.decls/temp.friend/p1.cpp
===
--- test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -174,7 +174,7 @@
 
   // This shouldn't crash.
   template  class D {
-friend class A; // expected-error {{elaborated type refers to a template}}
+friend class A; // expected-error {{'A' is a template that cannot be referenced with a class tag}}
   };
   template class D;
 }
Index: test/CXX/drs/dr4xx.cpp
===
--- test/CXX/drs/dr4xx.cpp
+++ test/CXX/drs/dr4xx.cpp
@@ -90,7 +90,7 @@
 struct S *p;
 {
   typedef struct S S; // expected-note {{here}}
-  struct S *p; // expected-error {{refers to a typedef}}
+  struct S *p; // expected-error {{'S' is a typedef}}
 }
   }
   struct S {};
Index: test/CXX/drs/dr2xx.cpp
===
--- test/CXX/drs/dr2xx.cpp
+++ test/CXX/drs/dr2xx.cpp
@@ -620,7 +620,7 @@
   template struct A {
 typedef typename T::type type; // ok even if this is a typedef-name, because
// it's not an elaborated-type-specifier
-typedef struct T::type foo; // expected-error {{elaborated type refers to a typedef}}
+typedef struct T::type foo; // expected-error {{'type' is a typedef that cannot be referenced with a struct tag}}
   };
   struct B { struct type {}; };
   struct C { typedef struct {} type; }; // expected-note {{here}}
@@ -1028,8 +1028,8 @@
   C::type i3;
 
   struct A a;
-  struct B b; // expected-error {{refers to a typedef}}
-  struct C c; // expected-error {{refers to a typedef}}
+  struct B b; // expected-error {{'B' is a typedef}}
+  struct C c; // expected-error {{'C' is a typedef}}
 
   B::B() {} // expected-error {{requires a type specifier}}
   B::A() {} // ok
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp