From e072b0c410818178beda7e3da622d7ff29d0c3be Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Sat, 15 Apr 2017 03:28:31 +0000 Subject: [PATCH] [libcp1] handle anon aggregates linkage-named by typedefs Arrange for the first typedef to an anonymous type in the same context to be used as the linkage name for the type. for gcc/cp/ChangeLog * decl.c (name_unnamed_type): Split out of... (grokdeclarator): ... this. * decl.h (name_unnamed_type): Declare. for libcc1/ChangeLog * libcp1plugin.cc (plugin_build_decl): Call name_unnamed_type. From-SVN: r246938 --- gcc/cp/ChangeLog | 6 ++++ gcc/cp/decl.c | 75 +++++++++++++++++++++++++----------------- gcc/cp/decl.h | 1 + libcc1/ChangeLog | 4 +++ libcc1/libcp1plugin.cc | 9 +++++ 5 files changed, 64 insertions(+), 31 deletions(-) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9997825e805..0aa6351c06b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-04-15 Alexandre Oliva + + * decl.c (name_unnamed_type): Split out of... + (grokdeclarator): ... this. + * decl.h (name_unnamed_type): Declare. + 2017-04-12 Richard Biener Bernd Edlinger diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 438a4ec1c51..8e9a466afa0 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -9852,6 +9852,49 @@ mark_inline_variable (tree decl) } } + +/* Assign a typedef-given name to a class or enumeration type declared + as anonymous at first. This was split out of grokdeclarator + because it is also used in libcc1. */ + +void +name_unnamed_type (tree type, tree decl) +{ + gcc_assert (TYPE_UNNAMED_P (type)); + + /* Replace the anonymous name with the real name everywhere. */ + for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) + { + if (anon_aggrname_p (TYPE_IDENTIFIER (t))) + /* We do not rename the debug info representing the + unnamed tagged type because the standard says in + [dcl.typedef] that the naming applies only for + linkage purposes. */ + /*debug_hooks->set_name (t, decl);*/ + TYPE_NAME (t) = decl; + } + + if (TYPE_LANG_SPECIFIC (type)) + TYPE_WAS_UNNAMED (type) = 1; + + /* If this is a typedef within a template class, the nested + type is a (non-primary) template. The name for the + template needs updating as well. */ + if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type)) + DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) + = TYPE_IDENTIFIER (type); + + /* Adjust linkage now that we aren't unnamed anymore. */ + reset_type_linkage (type); + + /* FIXME remangle member functions; member functions of a + type with external linkage have external linkage. */ + + /* Check that our job is done, and that it would fail if we + attempted to do it again. */ + gcc_assert (!TYPE_UNNAMED_P (type)); +} + /* Given declspecs and a declarator (abstract or otherwise), determine the name and type of the object declared and construct a DECL node for it. @@ -11576,37 +11619,7 @@ grokdeclarator (const cp_declarator *declarator, && declspecs->type_definition_p && attributes_naming_typedef_ok (*attrlist) && cp_type_quals (type) == TYPE_UNQUALIFIED) - { - tree t; - - /* Replace the anonymous name with the real name everywhere. */ - for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t)) - { - if (anon_aggrname_p (TYPE_IDENTIFIER (t))) - /* We do not rename the debug info representing the - unnamed tagged type because the standard says in - [dcl.typedef] that the naming applies only for - linkage purposes. */ - /*debug_hooks->set_name (t, decl);*/ - TYPE_NAME (t) = decl; - } - - if (TYPE_LANG_SPECIFIC (type)) - TYPE_WAS_UNNAMED (type) = 1; - - /* If this is a typedef within a template class, the nested - type is a (non-primary) template. The name for the - template needs updating as well. */ - if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type)) - DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) - = TYPE_IDENTIFIER (type); - - /* Adjust linkage now that we aren't unnamed anymore. */ - reset_type_linkage (type); - - /* FIXME remangle member functions; member functions of a - type with external linkage have external linkage. */ - } + name_unnamed_type (type, decl); if (signed_p || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) diff --git a/gcc/cp/decl.h b/gcc/cp/decl.h index 3e1d91f7092..d84d90c82d2 100644 --- a/gcc/cp/decl.h +++ b/gcc/cp/decl.h @@ -35,6 +35,7 @@ enum decl_context extern tree grokdeclarator (const cp_declarator *, cp_decl_specifier_seq *, enum decl_context, int, tree*); +extern void name_unnamed_type (tree, tree); /* States indicating how grokdeclarator() should handle declspecs marked with __attribute__((deprecated)). An object declared as diff --git a/libcc1/ChangeLog b/libcc1/ChangeLog index 5db05c58ba7..a6b9985e4ab 100644 --- a/libcc1/ChangeLog +++ b/libcc1/ChangeLog @@ -1,3 +1,7 @@ +2017-04-15 Alexandre Oliva + + * libcp1plugin.cc (plugin_build_decl): Call name_unnamed_type. + 2017-01-30 Alexandre Oliva Introduce C++ support. diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc index 545f28b9861..2464aa2f39d 100644 --- a/libcc1/libcp1plugin.cc +++ b/libcc1/libcp1plugin.cc @@ -1494,6 +1494,15 @@ plugin_build_decl (cc1_plugin::connection *self, set_access_flags (decl, acc_flags); + /* If this is the typedef that names an otherwise anonymous type, + propagate the typedef name to the type. In normal compilation, + this is done in grokdeclarator. */ + if (sym_kind == GCC_CP_SYMBOL_TYPEDEF + && !template_decl_p + && DECL_CONTEXT (decl) == TYPE_CONTEXT (sym_type) + && TYPE_UNNAMED_P (sym_type)) + name_unnamed_type (sym_type, decl); + if (sym_kind != GCC_CP_SYMBOL_TYPEDEF && sym_kind != GCC_CP_SYMBOL_CLASS && sym_kind != GCC_CP_SYMBOL_UNION -- 2.30.2