aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-objc-common.c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2014-10-30 17:22:12 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2014-10-30 17:22:12 +0000
commit2d51fcef56807789d5a6d929174a4581bd9e2ce3 (patch)
tree2fd76e3280f97f23caaf399ce9bfb9c9683bd287 /gcc/c/c-objc-common.c
parentf1308e4b82467d9293ed989ff3e5a191a76fbef4 (diff)
downloadgcc-2d51fcef56807789d5a6d929174a4581bd9e2ce3.zip
gcc-2d51fcef56807789d5a6d929174a4581bd9e2ce3.tar.gz
gcc-2d51fcef56807789d5a6d929174a4581bd9e2ce3.tar.bz2
c-objc-common.c (c_tree_printer): For a typedef name, print the stripped version as well, if they're not the same.
* c-objc-common.c (c_tree_printer) <case 'T'>: For a typedef name, print the stripped version as well, if they're not the same. * gcc.dg/diag-aka-1.c: New test. * gcc.dg/pr13804-1.c: Adjust dg-error. * gcc.dg/redecl-14.c: Likewise. * gcc.dg/pr56980.c: Adjust dg-message. From-SVN: r216941
Diffstat (limited to 'gcc/c/c-objc-common.c')
-rw-r--r--gcc/c/c-objc-common.c57
1 files changed, 41 insertions, 16 deletions
diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c
index 12db548..64481a5 100644
--- a/gcc/c/c-objc-common.c
+++ b/gcc/c/c-objc-common.c
@@ -127,23 +127,48 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
break;
case 'T':
- gcc_assert (TYPE_P (t));
- name = TYPE_NAME (t);
-
- if (name && TREE_CODE (name) == TYPE_DECL)
- {
- if (DECL_NAME (name))
- pp_identifier (cpp, lang_hooks.decl_printable_name (name, 2));
- else
- cpp->type_id (t);
- return true;
- }
- else
- {
+ {
+ gcc_assert (TYPE_P (t));
+ struct obstack *ob = pp_buffer (cpp)->obstack;
+ char *p = (char *) obstack_base (ob);
+ /* Remember the end of the initial dump. */
+ int len = obstack_object_size (ob);
+
+ name = TYPE_NAME (t);
+ if (name && TREE_CODE (name) == TYPE_DECL && DECL_NAME (name))
+ pp_identifier (cpp, lang_hooks.decl_printable_name (name, 2));
+ else
cpp->type_id (t);
- return true;
- }
- break;
+
+ /* If we're printing a type that involves typedefs, also print the
+ stripped version. But sometimes the stripped version looks
+ exactly the same, so we don't want it after all. To avoid
+ printing it in that case, we play ugly obstack games. */
+ if (TYPE_CANONICAL (t) && t != TYPE_CANONICAL (t))
+ {
+ c_pretty_printer cpp2;
+ /* Print the stripped version into a temporary printer. */
+ cpp2.type_id (TYPE_CANONICAL (t));
+ struct obstack *ob2 = cpp2.buffer->obstack;
+ /* Get the stripped version from the temporary printer. */
+ const char *aka = (char *) obstack_base (ob2);
+ int aka_len = obstack_object_size (ob2);
+ int type1_len = obstack_object_size (ob) - len;
+
+ /* If they are identical, bail out. */
+ if (aka_len == type1_len && memcmp (p + len, aka, aka_len) == 0)
+ return true;
+
+ /* They're not, print the stripped version now. */
+ pp_c_whitespace (cpp);
+ pp_left_brace (cpp);
+ pp_c_ws_string (cpp, _("aka"));
+ pp_c_whitespace (cpp);
+ cpp->type_id (TYPE_CANONICAL (t));
+ pp_right_brace (cpp);
+ }
+ return true;
+ }
case 'E':
if (TREE_CODE (t) == IDENTIFIER_NODE)