[PATCH] D25216: Improve error message when referencing a non-tag type with a tag
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
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
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
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
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
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
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
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
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