/* Subroutines common to both C and C++ pretty-printers.
- Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA. */
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
#include "config.h"
#include "system.h"
case INTEGER_TYPE:
case REAL_TYPE:
if (TYPE_NAME (t))
- t = TYPE_NAME (t);
+ {
+ t = TYPE_NAME (t);
+ pp_c_type_specifier (pp, t);
+ }
else
- t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
- pp_c_type_specifier (pp, t);
+ {
+ int prec = TYPE_PRECISION (t);
+ t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
+ pp_c_type_specifier (pp, t);
+ if (TYPE_PRECISION (t) != prec)
+ {
+ pp_string (pp, ":");
+ pp_decimal_int (pp, prec);
+ }
+ }
break;
case TYPE_DECL:
\f
/* Expressions. */
-/* Print out a c-char. */
+/* Print out a c-char. This is called solely for characters which are
+ in the *target* execution character set. We ought to convert them
+ back to the *host* execution character set before printing, but we
+ have no way to do this at present. A decent compromise is to print
+ all characters as if they were in the host execution character set,
+ and not attempt to recover any named escape characters, but render
+ all unprintables as octal escapes. If the host and target character
+ sets are the same, this produces relatively readable output. If they
+ are not the same, strings may appear as gibberish, but that's okay
+ (in fact, it may well be what the reader wants, e.g. if they are looking
+ to see if conversion to the target character set happened correctly).
+
+ A special case: we need to prefix \, ", and ' with backslashes. It is
+ correct to do so for the *host*'s \, ", and ', because the rest of the
+ file appears in the host character set. */
static void
pp_c_char (c_pretty_printer *pp, int c)
{
- switch (c)
+ if (ISPRINT (c))
{
- case TARGET_NEWLINE:
- pp_string (pp, "\\n");
- break;
- case TARGET_TAB:
- pp_string (pp, "\\t");
- break;
- case TARGET_VT:
- pp_string (pp, "\\v");
- break;
- case TARGET_BS:
- pp_string (pp, "\\b");
- break;
- case TARGET_CR:
- pp_string (pp, "\\r");
- break;
- case TARGET_FF:
- pp_string (pp, "\\f");
- break;
- case TARGET_BELL:
- pp_string (pp, "\\a");
- break;
- case '\\':
- pp_string (pp, "\\\\");
- break;
- case '\'':
- pp_string (pp, "\\'");
- break;
- case '\"':
- pp_string (pp, "\\\"");
- break;
- default:
- if (ISPRINT (c))
- pp_character (pp, c);
- else
- pp_scalar (pp, "\\%03o", (unsigned) c);
- break;
+ switch (c)
+ {
+ case '\\': pp_string (pp, "\\\\"); break;
+ case '\'': pp_string (pp, "\\\'"); break;
+ case '\"': pp_string (pp, "\\\""); break;
+ default: pp_character (pp, c);
+ }
}
+ else
+ pp_scalar (pp, "\\%03o", (unsigned) c);
}
/* Print out a STRING literal. */
{
if (tree_int_cst_sgn (i) < 0)
{
- pp_c_char (pp, '-');
- i = build_int_2 (-TREE_INT_CST_LOW (i),
- ~TREE_INT_CST_HIGH (i) + !TREE_INT_CST_LOW (i));
+ pp_character (pp, '-');
+ i = build_int_cst_wide (NULL_TREE,
+ -TREE_INT_CST_LOW (i),
+ ~TREE_INT_CST_HIGH (i)
+ + !TREE_INT_CST_LOW (i));
}
sprintf (pp_buffer (pp)->digit_buffer,
HOST_WIDE_INT_PRINT_DOUBLE_HEX,
pp_c_right_paren (pp);
break;
- case STMT_EXPR:
- pp_c_left_paren (pp);
- pp_statement (pp, STMT_EXPR_STMT (e));
- pp_c_right_paren (pp);
- break;
-
default:
/* FIXME: Make sure we won't get into an infinie loop. */
pp_c_left_paren (pp);
if (TREE_CODE (e) == VECTOR_CST)
pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e));
else if (TREE_CODE (e) == CONSTRUCTOR)
- pp_c_expression_list (pp, CONSTRUCTOR_ELTS (e));
+ pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
else
break;
return;
case COMPLEX_TYPE:
if (TREE_CODE (e) == CONSTRUCTOR)
- pp_c_expression_list (pp, CONSTRUCTOR_ELTS (e));
+ pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e));
else if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
{
const bool cst = TREE_CODE (e) == COMPLEX_CST;
pp_identifier (pp, code == POSTINCREMENT_EXPR ? "++" : "--");
break;
- case ARROW_EXPR:
- pp_postfix_expression (pp, TREE_OPERAND (e, 0));
- pp_c_arrow (pp);
- break;
-
case ARRAY_REF:
pp_postfix_expression (pp, TREE_OPERAND (e, 0));
pp_c_left_bracket (pp);
}
}
+/* Print out V, which contains the elements of a constructor. */
+
+void
+pp_c_constructor_elts (c_pretty_printer *pp, VEC(constructor_elt,gc) *v)
+{
+ unsigned HOST_WIDE_INT ix;
+ tree value;
+
+ FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
+ {
+ pp_expression (pp, value);
+ if (ix != VEC_length (constructor_elt, v) - 1)
+ pp_separate_with (pp, ',');
+ }
+}
+
/* Print out an expression-list in parens, as in a function call. */
void
pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
break;
- case SIZEOF_EXPR:
- case ALIGNOF_EXPR:
- pp_c_identifier (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
- pp_c_whitespace (pp);
- if (TYPE_P (TREE_OPERAND (e, 0)))
- pp_c_type_cast (pp, TREE_OPERAND (e, 0));
- else
- pp_unary_expression (pp, TREE_OPERAND (e, 0));
- break;
-
case REALPART_EXPR:
case IMAGPART_EXPR:
pp_c_identifier (pp, code == REALPART_EXPR ? "__real__" : "__imag__");
case FIELD_DECL:
case LABEL_DECL:
case ERROR_MARK:
- case STMT_EXPR:
pp_primary_expression (pp, e);
break;
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
- case ARROW_EXPR:
case ARRAY_REF:
case CALL_EXPR:
case COMPONENT_REF:
case TRUTH_NOT_EXPR:
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
- case SIZEOF_EXPR:
- case ALIGNOF_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
pp_c_unary_expression (pp, e);
\f
/* Statements. */
-/* statement:
- labeled-statement
- compound-statement
- expression-statement
- selection-statement
- iteration-statement
- jump-statement */
-
void
pp_c_statement (c_pretty_printer *pp, tree stmt)
{
- enum tree_code code;
-
if (stmt == NULL)
return;
if (pp_needs_newline (pp))
pp_newline_and_indent (pp, 0);
- code = TREE_CODE (stmt);
- switch (code)
- {
- /* expression-statement:
- expression(opt) ; */
- case EXPR_STMT:
- pp_expression (pp, EXPR_STMT_EXPR (stmt));
- pp_c_semicolon (pp);
- pp_needs_newline (pp) = true;
- break;
-
- case SWITCH_STMT:
- pp_c_identifier (pp, "switch");
- pp_space (pp);
- pp_c_left_paren (pp);
- pp_expression (pp, SWITCH_COND (stmt));
- pp_c_right_paren (pp);
- pp_indentation (pp) += 3;
- pp_needs_newline (pp) = true;
- pp_statement (pp, SWITCH_BODY (stmt));
- pp_newline_and_indent (pp, -3);
- break;
-
- /* iteration-statement:
- while ( expression ) statement
- do statement while ( expression ) ;
- for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
- for ( declaration expression(opt) ; expression(opt) ) statement */
- case WHILE_STMT:
- pp_c_identifier (pp, "while");
- pp_space (pp);
- pp_c_left_paren (pp);
- pp_expression (pp, WHILE_COND (stmt));
- pp_c_right_paren (pp);
- pp_newline_and_indent (pp, 3);
- pp_statement (pp, WHILE_BODY (stmt));
- pp_indentation (pp) -= 3;
- pp_needs_newline (pp) = true;
- break;
-
- case DO_STMT:
- pp_c_identifier (pp, "do");
- pp_newline_and_indent (pp, 3);
- pp_statement (pp, DO_BODY (stmt));
- pp_newline_and_indent (pp, -3);
- pp_c_identifier (pp, "while");
- pp_space (pp);
- pp_c_left_paren (pp);
- pp_expression (pp, DO_COND (stmt));
- pp_c_right_paren (pp);
- pp_c_semicolon (pp);
- pp_needs_newline (pp) = true;
- break;
-
- case FOR_STMT:
- pp_c_identifier (pp, "for");
- pp_space (pp);
- pp_c_left_paren (pp);
- if (FOR_INIT_STMT (stmt))
- pp_statement (pp, FOR_INIT_STMT (stmt));
- else
- pp_c_semicolon (pp);
- pp_needs_newline (pp) = false;
- pp_c_whitespace (pp);
- if (FOR_COND (stmt))
- pp_expression (pp, FOR_COND (stmt));
- pp_c_semicolon (pp);
- pp_needs_newline (pp) = false;
- pp_c_whitespace (pp);
- if (FOR_EXPR (stmt))
- pp_expression (pp, FOR_EXPR (stmt));
- pp_c_right_paren (pp);
- pp_newline_and_indent (pp, 3);
- pp_statement (pp, FOR_BODY (stmt));
- pp_indentation (pp) -= 3;
- pp_needs_newline (pp) = true;
- break;
-
- /* jump-statement:
- goto identifier;
- continue ;
- return expression(opt) ; */
- case BREAK_STMT:
- case CONTINUE_STMT:
- pp_identifier (pp, code == BREAK_STMT ? "break" : "continue");
- pp_c_semicolon (pp);
- pp_needs_newline (pp) = true;
- break;
-
- default:
- dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
- break;
- }
+ dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
}
\f
{
const char *name;
- if (!DECL_P (t))
- abort ();
+ gcc_assert (DECL_P (t));
if (DECL_NAME (t))
name = IDENTIFIER_POINTER (DECL_NAME (t));