[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
This commit is contained in:
parent
51477ac2b9
commit
e072b0c410
|
@ -1,3 +1,9 @@
|
||||||
|
2017-04-15 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
|
* decl.c (name_unnamed_type): Split out of...
|
||||||
|
(grokdeclarator): ... this.
|
||||||
|
* decl.h (name_unnamed_type): Declare.
|
||||||
|
|
||||||
2017-04-12 Richard Biener <rguenther@suse.de>
|
2017-04-12 Richard Biener <rguenther@suse.de>
|
||||||
Bernd Edlinger <bernd.edlinger@hotmail.de>
|
Bernd Edlinger <bernd.edlinger@hotmail.de>
|
||||||
|
|
||||||
|
|
|
@ -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
|
/* Given declspecs and a declarator (abstract or otherwise), determine
|
||||||
the name and type of the object declared and construct a DECL node
|
the name and type of the object declared and construct a DECL node
|
||||||
for it.
|
for it.
|
||||||
|
@ -11576,37 +11619,7 @@ grokdeclarator (const cp_declarator *declarator,
|
||||||
&& declspecs->type_definition_p
|
&& declspecs->type_definition_p
|
||||||
&& attributes_naming_typedef_ok (*attrlist)
|
&& attributes_naming_typedef_ok (*attrlist)
|
||||||
&& cp_type_quals (type) == TYPE_UNQUALIFIED)
|
&& cp_type_quals (type) == TYPE_UNQUALIFIED)
|
||||||
{
|
name_unnamed_type (type, decl);
|
||||||
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. */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (signed_p
|
if (signed_p
|
||||||
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
|
|| (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
|
||||||
|
|
|
@ -35,6 +35,7 @@ enum decl_context
|
||||||
extern tree grokdeclarator (const cp_declarator *,
|
extern tree grokdeclarator (const cp_declarator *,
|
||||||
cp_decl_specifier_seq *,
|
cp_decl_specifier_seq *,
|
||||||
enum decl_context, int, tree*);
|
enum decl_context, int, tree*);
|
||||||
|
extern void name_unnamed_type (tree, tree);
|
||||||
|
|
||||||
/* States indicating how grokdeclarator() should handle declspecs marked
|
/* States indicating how grokdeclarator() should handle declspecs marked
|
||||||
with __attribute__((deprecated)). An object declared as
|
with __attribute__((deprecated)). An object declared as
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2017-04-15 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
|
* libcp1plugin.cc (plugin_build_decl): Call name_unnamed_type.
|
||||||
|
|
||||||
2017-01-30 Alexandre Oliva <aoliva@redhat.com>
|
2017-01-30 Alexandre Oliva <aoliva@redhat.com>
|
||||||
|
|
||||||
Introduce C++ support.
|
Introduce C++ support.
|
||||||
|
|
|
@ -1494,6 +1494,15 @@ plugin_build_decl (cc1_plugin::connection *self,
|
||||||
|
|
||||||
set_access_flags (decl, acc_flags);
|
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
|
if (sym_kind != GCC_CP_SYMBOL_TYPEDEF
|
||||||
&& sym_kind != GCC_CP_SYMBOL_CLASS
|
&& sym_kind != GCC_CP_SYMBOL_CLASS
|
||||||
&& sym_kind != GCC_CP_SYMBOL_UNION
|
&& sym_kind != GCC_CP_SYMBOL_UNION
|
||||||
|
|
Loading…
Reference in New Issue