aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2017-04-15 03:28:31 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2017-04-15 03:28:31 +0000
commite072b0c410818178beda7e3da622d7ff29d0c3be (patch)
tree4d33781a146f21c9564a837fd95a447a96ac847c
parent51477ac2b9eeaf48c330942e281518d8b6b5c230 (diff)
downloadgcc-e072b0c410818178beda7e3da622d7ff29d0c3be.zip
gcc-e072b0c410818178beda7e3da622d7ff29d0c3be.tar.gz
gcc-e072b0c410818178beda7e3da622d7ff29d0c3be.tar.bz2
[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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c75
-rw-r--r--gcc/cp/decl.h1
-rw-r--r--libcc1/ChangeLog4
-rw-r--r--libcc1/libcp1plugin.cc9
5 files changed, 64 insertions, 31 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9997825..0aa6351 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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>
Bernd Edlinger <bernd.edlinger@hotmail.de>
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 438a4ec..8e9a466 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 3e1d91f..d84d90c 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 5db05c5..a6b9985 100644
--- a/libcc1/ChangeLog
+++ b/libcc1/ChangeLog
@@ -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>
Introduce C++ support.
diff --git a/libcc1/libcp1plugin.cc b/libcc1/libcp1plugin.cc
index 545f28b..2464aa2 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