diff options
author | Jason Merrill <jason@redhat.com> | 2020-11-10 17:17:19 -0500 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2020-11-13 13:36:29 -0500 |
commit | d50310408f54e38031f34931e591c63ff36fee09 (patch) | |
tree | 8797b7178962c36a470b2e374fd5b3c8d2fb45fe /gcc/dwarf2out.c | |
parent | e3b3b59683c1e7d31a9d313dd97394abebf644be (diff) | |
download | gcc-d50310408f54e38031f34931e591c63ff36fee09.zip gcc-d50310408f54e38031f34931e591c63ff36fee09.tar.gz gcc-d50310408f54e38031f34931e591c63ff36fee09.tar.bz2 |
c++: Implement C++20 'using enum'. [PR91367]
This feature allows the programmer to import enumerator names into the
current scope so later mentions don't need to use the fully-qualified name.
These usings are not subject to the usual restrictions on using-decls: in
particular, they can move between class and non-class scopes, and between
classes that are not related by inheritance. This last caused difficulty
for our normal approach to using-decls within a class hierarchy, as we
assume that the class where we looked up a used declaration is derived from
the class where it was first declared. So to simplify things, in that case
we make a clone of the CONST_DECL in the using class.
Thanks to Nathan for the start of this work: in particular, the
lookup_using_decl rewrite.
The changes to dwarf2out revealed an existing issue with the D front-end: we
were doing the wrong thing for importing a D CONST_DECL, because
dwarf2out_imported_module_or_decl_1 was looking through it to its type,
expecting it to be an enumerator, but in one case in thread.d, the constant
had type int. Adding the ability to import a C++ enumerator also fixed
that, but that led to a crash in force_decl_die, which didn't know what to
do with a CONST_DECL. So now it does.
Co-authored-by: Nathan Sidwell <nathan@acm.org>
gcc/cp/ChangeLog:
* cp-tree.h (USING_DECL_UNRELATED_P): New.
(CONST_DECL_USING_P): New.
* class.c (handle_using_decl): If USING_DECL_UNRELATED_P,
clone the CONST_DECL.
* name-lookup.c (supplement_binding_1): A clone hides its
using-declaration.
(lookup_using_decl): Rewrite to separate lookup and validation.
(do_class_using_decl): Adjust.
(finish_nonmember_using_decl): Adjust.
* parser.c (make_location): Add cp_token overload.
(finish_using_decl): Split out from...
(cp_parser_using_declaration): ...here. Don't look through enums.
(cp_parser_using_enum): New.
(cp_parser_block_declaration): Call it.
(cp_parser_member_declaration): Call it.
* semantics.c (finish_id_expression_1): Handle enumerator
used from class scope.
gcc/ChangeLog:
* dwarf2out.c (gen_enumeration_type_die): Call
equate_decl_number_to_die for enumerators.
(gen_member_die): Don't move enumerators to their
enclosing class.
(dwarf2out_imported_module_or_decl_1): Allow importing
individual enumerators.
(force_decl_die): Handle CONST_DECL.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/inh-ctor28.C: Adjust expected diagnostic.
* g++.dg/cpp0x/inh-ctor33.C: Likewise.
* g++.dg/cpp0x/using-enum-1.C: Add comment.
* g++.dg/cpp0x/using-enum-2.C: Allowed in C++20.
* g++.dg/cpp0x/using-enum-3.C: Likewise.
* g++.dg/cpp1z/class-deduction69.C: Adjust diagnostic.
* g++.dg/inherit/using5.C: Likewise.
* g++.dg/cpp2a/using-enum-1.C: New test.
* g++.dg/cpp2a/using-enum-2.C: New test.
* g++.dg/cpp2a/using-enum-3.C: New test.
* g++.dg/cpp2a/using-enum-4.C: New test.
* g++.dg/cpp2a/using-enum-5.C: New test.
* g++.dg/cpp2a/using-enum-6.C: New test.
* g++.dg/debug/dwarf2/using-enum.C: New test.
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r-- | gcc/dwarf2out.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 4452b9fa..0e8436e 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -22193,6 +22193,9 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link); tree value = TREE_VALUE (link); + if (DECL_P (value)) + equate_decl_number_to_die (value, enum_die); + gcc_assert (!ENUM_IS_OPAQUE (type)); add_name_attribute (enum_die, IDENTIFIER_POINTER (TREE_PURPOSE (link))); @@ -25247,6 +25250,10 @@ gen_member_die (tree type, dw_die_ref context_die) splice = false; } } + else if (child->die_tag == DW_TAG_enumerator) + /* Enumerators remain under their enumeration even if + their names are introduced in the enclosing scope. */ + splice = false; if (splice) splice_child_die (context_die, child); @@ -26158,6 +26165,13 @@ force_decl_die (tree decl) decl_die = comp_unit_die (); break; + case CONST_DECL: + /* Enumerators shouldn't need force_decl_die. */ + gcc_assert (DECL_CONTEXT (decl) == NULL_TREE + || TREE_CODE (DECL_CONTEXT (decl)) != ENUMERAL_TYPE); + gen_decl_die (decl, NULL, NULL, context_die); + break; + case TRANSLATION_UNIT_DECL: decl_die = comp_unit_die (); break; @@ -26743,7 +26757,7 @@ dwarf2out_imported_module_or_decl_1 (tree decl, else xloc = expand_location (input_location); - if (TREE_CODE (decl) == TYPE_DECL || TREE_CODE (decl) == CONST_DECL) + if (TREE_CODE (decl) == TYPE_DECL) { at_import_die = force_type_die (TREE_TYPE (decl)); /* For namespace N { typedef void T; } using N::T; base_type_die |