diff options
author | Marek Polacek <polacek@redhat.com> | 2014-10-30 17:22:12 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2014-10-30 17:22:12 +0000 |
commit | 2d51fcef56807789d5a6d929174a4581bd9e2ce3 (patch) | |
tree | 2fd76e3280f97f23caaf399ce9bfb9c9683bd287 /gcc/c/c-objc-common.c | |
parent | f1308e4b82467d9293ed989ff3e5a191a76fbef4 (diff) | |
download | gcc-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.c | 57 |
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) |