From e6a9521238a12d8bbee47fcf74dd8db389095bf0 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 5 May 2016 19:16:15 +0000 Subject: [PATCH] Add a FixItHint for the new diagnostic for a non-class-scope using-declaration that names a class-scope enumerator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@268664 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 4 +-- lib/Sema/SemaDeclCXX.cpp | 14 ++++++++++ .../namespace.udecl/p8-cxx0x.cpp | 27 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b0b6004ac0..c5bf16ba6d 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -393,8 +393,8 @@ def note_using_decl_constructor_ellipsis : Note< def err_using_decl_can_not_refer_to_class_member : Error< "using declaration cannot refer to class member">; def note_using_decl_class_member_workaround : Note< - "use %select{an alias declaration|a typedef declaration|a reference}0 " - "instead">; + "use %select{an alias declaration|a typedef declaration|a reference|" + "a const variable|a constexpr variable}0 instead">; def err_using_decl_can_not_refer_to_namespace : Error< "using declaration cannot refer to a namespace">; def err_using_decl_can_not_refer_to_scoped_enum : Error< diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index f478f0419b..95f10f8ccc 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -8421,6 +8421,20 @@ bool Sema::CheckUsingDeclQualifier(SourceLocation UsingLoc, Diag(UsingLoc, diag::note_using_decl_class_member_workaround) << 2 // reference declaration << FixIt; + } else if (R.getAsSingle()) { + // Don't provide a fixit outside C++11 mode; we don't want to suggest + // repeating the type of the enumeration here, and we can't do so if + // the type is anonymous. + FixItHint FixIt; + if (getLangOpts().CPlusPlus11) { + // Convert 'using X::Y;' to 'auto &Y = X::Y;'. + FixIt = FixItHint::CreateReplacement( + UsingLoc, "constexpr auto " + NameInfo.getName().getAsString() + " = "); + } + + Diag(UsingLoc, diag::note_using_decl_class_member_workaround) + << (getLangOpts().CPlusPlus11 ? 4 : 3) // const[expr] variable + << FixIt; } return true; } diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp index ebe5388d65..6c63f061ab 100644 --- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp +++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp @@ -7,14 +7,41 @@ struct X { int i; static int a; + enum E { e }; }; using X::i; // expected-error{{using declaration cannot refer to class member}} using X::s; // expected-error{{using declaration cannot refer to class member}} +using X::e; // expected-error{{using declaration cannot refer to class member}} +using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}} +#if __cplusplus < 201103L +// expected-note@-3 {{use a const variable}} +// expected-note@-3 {{use a const variable}} +// CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: +// CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: +#else +// expected-note@-8 {{use a constexpr variable}} +// expected-note@-8 {{use a constexpr variable}} +// CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = " +// CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:1-[[@LINE-10]]:6}:"constexpr auto e = " +#endif void f() { using X::i; // expected-error{{using declaration cannot refer to class member}} using X::s; // expected-error{{using declaration cannot refer to class member}} + using X::e; // expected-error{{using declaration cannot refer to class member}} + using X::E::e; // expected-error{{using declaration cannot refer to class member}} expected-warning 0-1{{C++11}} +#if __cplusplus < 201103L + // expected-note@-3 {{use a const variable}} + // expected-note@-3 {{use a const variable}} + // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: + // CXX98-NOT: fix-it:"{{.*}}":{[[@LINE-5]]: +#else + // expected-note@-8 {{use a constexpr variable}} + // expected-note@-8 {{use a constexpr variable}} + // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = " + // CXX11: fix-it:"{{.*}}":{[[@LINE-10]]:3-[[@LINE-10]]:8}:"constexpr auto e = " +#endif } template -- 2.40.0