X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-pretty-print.c;h=516022340ca978669dbe544045b7b2982721a308;hb=89370a1eb374e74c85ca1a61447b853ee4f0c938;hp=7d0a157acf180a9660fa60f14c3a5a5ef4bcc6bd;hpb=40e55fbbd58fe04a45af0335bc0b945cec36c9c9;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-pretty-print.c b/gcc/c-pretty-print.c index 7d0a157acf1..516022340ca 100644 --- a/gcc/c-pretty-print.c +++ b/gcc/c-pretty-print.c @@ -1,5 +1,5 @@ /* Subroutines common to both C and C++ pretty-printers. - Copyright (C) 2002, 2003 Free Software Foundation, Inc. + Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis This file is part of GCC. @@ -16,8 +16,8 @@ for more details. 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" @@ -26,6 +26,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "real.h" #include "c-pretty-print.h" #include "c-tree.h" +#include "tree-iterator.h" +#include "diagnostic.h" /* The pretty-printer code is primarily designed to closely follow (GNU) C and C++ grammars. That is to be contrasted with spaghetti @@ -41,24 +43,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA pp_c_whitespace (PP); \ } while (0) -#define pp_c_left_bracket(PP) \ - do { \ - pp_left_bracket (PP); \ - pp_base (PP)->padding = pp_none; \ - } while (0) - -#define pp_c_right_bracket(PP) \ - do { \ - pp_right_bracket (PP); \ - pp_base (PP)->padding = pp_none; \ - } while (0) - -#define pp_c_star(PP) \ - do { \ - pp_star (PP); \ - pp_base (PP)->padding = pp_none; \ - } while (0) - /* literal */ static void pp_c_char (c_pretty_printer *, int); @@ -119,6 +103,20 @@ pp_c_right_brace (c_pretty_printer *pp) } void +pp_c_left_bracket (c_pretty_printer *pp) +{ + pp_left_bracket (pp); + pp_base (pp)->padding = pp_none; +} + +void +pp_c_right_bracket (c_pretty_printer *pp) +{ + pp_right_bracket (pp); + pp_base (pp)->padding = pp_none; +} + +void pp_c_dot (c_pretty_printer *pp) { pp_dot (pp); @@ -133,6 +131,13 @@ pp_c_ampersand (c_pretty_printer *pp) } void +pp_c_star (c_pretty_printer *pp) +{ + pp_star (pp); + pp_base (pp)->padding = pp_none; +} + +void pp_c_arrow (c_pretty_printer *pp) { pp_arrow (pp); @@ -140,24 +145,43 @@ pp_c_arrow (c_pretty_printer *pp) } void -pp_c_semicolon(c_pretty_printer *pp) +pp_c_semicolon (c_pretty_printer *pp) { pp_semicolon (pp); pp_base (pp)->padding = pp_none; } +void +pp_c_complement (c_pretty_printer *pp) +{ + pp_complement (pp); + pp_base (pp)->padding = pp_none; +} + +void +pp_c_exclamation (c_pretty_printer *pp) +{ + pp_exclamation (pp); + pp_base (pp)->padding = pp_none; +} + +/* Print out the external representation of CV-QUALIFIER. */ + static void pp_c_cv_qualifier (c_pretty_printer *pp, const char *cv) { const char *p = pp_last_position_in_text (pp); - if (p != NULL && *p == '*') + /* The C programming language does not have references, but it is much + simpler to handle those here rather than going through the same + logic in the C++ pretty-printer. */ + if (p != NULL && (*p == '*' || *p == '&')) pp_c_whitespace (pp); pp_c_identifier (pp, cv); } /* Pretty-print T using the type-cast notation '( type-name )'. */ -static inline void +static void pp_c_type_cast (c_pretty_printer *pp, tree t) { pp_c_left_paren (pp); @@ -165,6 +189,9 @@ pp_c_type_cast (c_pretty_printer *pp, tree t) pp_c_right_paren (pp); } +/* We're about to pretty-print a pointer type as indicated by T. + Output a whitespace, if needed, preparing for subsequent output. */ + void pp_c_space_for_pointer_operator (c_pretty_printer *pp, tree t) { @@ -198,7 +225,7 @@ void pp_c_type_qualifier_list (c_pretty_printer *pp, tree t) { int qualifiers; - + if (!TYPE_P (t)) t = TREE_TYPE (t); @@ -234,6 +261,13 @@ pp_c_pointer (c_pretty_printer *pp, tree t) pp_c_type_qualifier_list (pp, t); break; + /* ??? This node is now in GENERIC and so shouldn't be here. But + we'll fix that later. */ + case DECL_EXPR: + pp_declaration (pp, DECL_EXPR_DECL (t)); + pp_needs_newline (pp) = true; + break; + default: pp_unsupported_tree (pp, t); } @@ -272,7 +306,7 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t) break; case IDENTIFIER_NODE: - pp_c_tree_identifier (pp, t); + pp_c_tree_decl_identifier (pp, t); break; case VOID_TYPE: @@ -281,10 +315,42 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t) 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), TREE_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)); + if (TYPE_NAME (t)) + { + pp_c_type_specifier (pp, t); + if (TYPE_PRECISION (t) != prec) + { + pp_string (pp, ":"); + pp_decimal_int (pp, prec); + } + } + else + { + switch (code) + { + case INTEGER_TYPE: + pp_string (pp, (TYPE_UNSIGNED (t) + ? ""); + } + } break; case TYPE_DECL: @@ -350,6 +416,8 @@ pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t) pp_c_whitespace (pp); pp_c_left_paren (pp); } + else if (!c_dialect_cxx ()) + pp_c_whitespace (pp); pp_ptr_operator (pp, t); } break; @@ -417,7 +485,7 @@ pp_c_parameter_type_list (c_pretty_printer *pp, tree t) pointer pointer(opt) direct-abstract-declarator */ -static inline void +static void pp_c_abstract_declarator (c_pretty_printer *pp, tree t) { if (TREE_CODE (t) == POINTER_TYPE) @@ -445,7 +513,7 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t) case POINTER_TYPE: pp_abstract_declarator (pp, t); break; - + case FUNCTION_TYPE: pp_c_parameter_type_list (pp, t); pp_direct_abstract_declarator (pp, TREE_TYPE (t)); @@ -453,7 +521,7 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t) case ARRAY_TYPE: pp_c_left_bracket (pp); - if (TYPE_DOMAIN (t)) + if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t))) pp_expression (pp, TYPE_MAX_VALUE (TYPE_DOMAIN (t))); pp_c_right_bracket (pp); pp_direct_abstract_declarator (pp, TREE_TYPE (t)); @@ -471,7 +539,7 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t) case COMPLEX_TYPE: case TYPE_DECL: break; - + default: pp_unsupported_tree (pp, t); break; @@ -540,7 +608,7 @@ pp_c_declaration_specifiers (c_pretty_printer *pp, tree t) direct-declarator [ static type-qualifier-list(opt) assignment-expression(opt)] direct-declarator [ type-qualifier-list static assignment-expression ] direct-declarator [ type-qualifier-list * ] - direct-declaratpr ( parameter-type-list ) + direct-declarator ( parameter-type-list ) direct-declarator ( identifier-list(opt) ) */ void @@ -553,11 +621,10 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t) case TYPE_DECL: case FIELD_DECL: case LABEL_DECL: - if (DECL_NAME (t)) - { - pp_c_space_for_pointer_operator (pp, TREE_TYPE (t)); - pp_c_tree_identifier (pp, DECL_NAME (t)); - } + pp_c_space_for_pointer_operator (pp, TREE_TYPE (t)); + pp_c_tree_decl_identifier (pp, t); + break; + case ARRAY_TYPE: case POINTER_TYPE: pp_abstract_declarator (pp, TREE_TYPE (t)); @@ -570,7 +637,7 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t) case FUNCTION_DECL: pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t))); - pp_c_tree_identifier (pp, DECL_NAME (t)); + pp_c_tree_decl_identifier (pp, t); if (pp_c_base (pp)->flags & pp_c_flag_abstract) pp_abstract_declarator (pp, TREE_TYPE (t)); else @@ -619,7 +686,7 @@ pp_c_declarator (c_pretty_printer *pp, tree t) pp_direct_declarator (pp, t); break; - + default: pp_unsupported_tree (pp, t); break; @@ -677,50 +744,37 @@ pp_c_function_definition (c_pretty_printer *pp, tree t) /* 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. */ @@ -737,6 +791,8 @@ pp_c_string_literal (c_pretty_printer *pp, tree s) pp_doublequote (pp); } +/* Pretty-print an INTEGER literal. */ + static void pp_c_integer_constant (c_pretty_printer *pp, tree i) { @@ -748,16 +804,18 @@ pp_c_integer_constant (c_pretty_printer *pp, tree i) { 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, TREE_INT_CST_HIGH (i), TREE_INT_CST_LOW (i)); pp_string (pp, pp_buffer (pp)->digit_buffer); } - if (TREE_UNSIGNED (type)) + if (TYPE_UNSIGNED (type)) pp_character (pp, 'u'); if (type == long_integer_type_node || type == long_unsigned_type_node) pp_character (pp, 'l'); @@ -768,15 +826,15 @@ pp_c_integer_constant (c_pretty_printer *pp, tree i) /* Print out a CHARACTER literal. */ -static inline void +static void pp_c_character_constant (c_pretty_printer *pp, tree c) { tree type = TREE_TYPE (c); if (type == wchar_type_node) - pp_character (pp, 'L'); + pp_character (pp, 'L'); pp_quote (pp); - if (host_integerp (c, TREE_UNSIGNED (type))) - pp_c_char (pp, tree_low_cst (c, TREE_UNSIGNED (type))); + if (host_integerp (c, TYPE_UNSIGNED (type))) + pp_c_char (pp, tree_low_cst (c, TYPE_UNSIGNED (type))); else pp_scalar (pp, "\\x%x", (unsigned) TREE_INT_CST_LOW (c)); pp_quote (pp); @@ -843,7 +901,7 @@ pp_c_enumeration_constant (c_pretty_printer *pp, tree e) /* Print out a REAL value as a decimal-floating-constant. */ -static inline void +static void pp_c_floating_constant (c_pretty_printer *pp, tree r) { real_to_decimal (pp_buffer (pp)->digit_buffer, &TREE_REAL_CST (r), @@ -853,15 +911,21 @@ pp_c_floating_constant (c_pretty_printer *pp, tree r) pp_character (pp, 'f'); else if (TREE_TYPE (r) == long_double_type_node) pp_character (pp, 'l'); + else if (TREE_TYPE (r) == dfloat128_type_node) + pp_string (pp, "dl"); + else if (TREE_TYPE (r) == dfloat64_type_node) + pp_string (pp, "dd"); + else if (TREE_TYPE (r) == dfloat32_type_node) + pp_string (pp, "df"); } /* Pretty-print a compound literal expression. GNU extensions include - vector constants. */ + vector constants. */ static void pp_c_compound_literal (c_pretty_printer *pp, tree e) { - tree type = TREE_TYPE (e); + tree type = TREE_TYPE (e); pp_c_type_cast (pp, type); switch (TREE_CODE (type)) @@ -902,8 +966,8 @@ pp_c_constant (c_pretty_printer *pp, tree e) pp_c_character_constant (pp, e); else if (TREE_CODE (type) == ENUMERAL_TYPE && pp_c_enumeration_constant (pp, e)) - ; - else + ; + else pp_c_integer_constant (pp, e); } break; @@ -922,11 +986,13 @@ pp_c_constant (c_pretty_printer *pp, tree e) } } +/* Pretty-print an IDENTIFIER_NODE, preceded by whitespace is necessary. */ + void pp_c_identifier (c_pretty_printer *pp, const char *id) { - pp_c_maybe_whitespace (pp); - pp_identifier (pp, id); + pp_c_maybe_whitespace (pp); + pp_identifier (pp, id); pp_base (pp)->padding = pp_before; } @@ -948,8 +1014,9 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e) case CONST_DECL: case FUNCTION_DECL: case LABEL_DECL: - e = DECL_NAME (e); - /* Fall through. */ + pp_c_tree_decl_identifier (pp, e); + break; + case IDENTIFIER_NODE: pp_c_tree_identifier (pp, e); break; @@ -968,9 +1035,19 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e) pp_c_constant (pp, e); break; - case STMT_EXPR: + case TARGET_EXPR: + pp_c_identifier (pp, "__builtin_memcpy"); pp_c_left_paren (pp); - pp_statement (pp, STMT_EXPR_STMT (e)); + pp_ampersand (pp); + pp_primary_expression (pp, TREE_OPERAND (e, 0)); + pp_separate_with (pp, ','); + pp_ampersand (pp); + pp_initializer (pp, TREE_OPERAND (e, 1)); + if (TREE_OPERAND (e, 2)) + { + pp_separate_with (pp, ','); + pp_c_expression (pp, TREE_OPERAND (e, 2)); + } pp_c_right_paren (pp); break; @@ -993,13 +1070,7 @@ static void pp_c_initializer (c_pretty_printer *pp, tree e) { if (TREE_CODE (e) == CONSTRUCTOR) - { - enum tree_code code = TREE_CODE (TREE_TYPE (e)); - if (code == RECORD_TYPE || code == UNION_TYPE || code == ARRAY_TYPE) - pp_c_brace_enclosed_initializer_list (pp, e); - else - pp_unsupported_tree (pp, TREE_OPERAND (e, 1)); - } + pp_c_brace_enclosed_initializer_list (pp, e); else pp_expression (pp, e); } @@ -1012,7 +1083,9 @@ void pp_c_init_declarator (c_pretty_printer *pp, tree t) { pp_declarator (pp, t); - if (DECL_INITIAL (t)) + /* We don't want to output function definitions here. There are handled + elsewhere (and the syntactic form is bogus anyway). */ + if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t)) { tree init = DECL_INITIAL (t); /* This C++ bit is handled here because it is easier to do so. @@ -1085,28 +1158,39 @@ pp_c_initializer_list (c_pretty_printer *pp, tree e) pp_separate_with (pp, ','); } } - break; + return; case VECTOR_TYPE: - pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e)); - break; + if (TREE_CODE (e) == VECTOR_CST) + pp_c_expression_list (pp, TREE_VECTOR_CST_ELTS (e)); + else if (TREE_CODE (e) == CONSTRUCTOR) + pp_c_constructor_elts (pp, CONSTRUCTOR_ELTS (e)); + else + break; + return; case COMPLEX_TYPE: - { - const bool cst = TREE_CODE (e) == COMPLEX_CST; - pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0)); - pp_separate_with (pp, ','); - pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1)); - } - break; + if (TREE_CODE (e) == CONSTRUCTOR) + 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_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0)); + pp_separate_with (pp, ','); + pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1)); + } + else + break; + return; default: - pp_unsupported_tree (pp, type); break; } + + pp_unsupported_tree (pp, type); } -/* Pretty-print a brace-enclosed initializer-list. */ +/* Pretty-print a brace-enclosed initializer-list. */ static void pp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l) @@ -1135,7 +1219,9 @@ pp_c_id_expression (c_pretty_printer *pp, tree t) case FUNCTION_DECL: case FIELD_DECL: case LABEL_DECL: - t = DECL_NAME (t); + pp_c_tree_decl_identifier (pp, t); + break; + case IDENTIFIER_NODE: pp_c_tree_identifier (pp, t); break; @@ -1169,11 +1255,6 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e) 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); @@ -1186,6 +1267,62 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e) pp_c_call_argument_list (pp, TREE_OPERAND (e, 1)); break; + case UNORDERED_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "isunordered" + : "__builtin_isunordered"); + goto two_args_fun; + + case ORDERED_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!isunordered" + : "!__builtin_isunordered"); + goto two_args_fun; + + case UNLT_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!isgreaterequal" + : "!__builtin_isgreaterequal"); + goto two_args_fun; + + case UNLE_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!isgreater" + : "!__builtin_isgreater"); + goto two_args_fun; + + case UNGT_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!islessequal" + : "!__builtin_islessequal"); + goto two_args_fun; + + case UNGE_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!isless" + : "!__builtin_isless"); + goto two_args_fun; + + case UNEQ_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "!islessgreater" + : "!__builtin_islessgreater"); + goto two_args_fun; + + case LTGT_EXPR: + pp_c_identifier (pp, flag_isoc99 + ? "islessgreater" + : "__builtin_islessgreater"); + goto two_args_fun; + + two_args_fun: + pp_c_left_paren (pp); + pp_expression (pp, TREE_OPERAND (e, 0)); + pp_separate_with (pp, ','); + pp_expression (pp, TREE_OPERAND (e, 1)); + pp_c_right_paren (pp); + break; + case ABS_EXPR: pp_c_identifier (pp, "__builtin_abs"); pp_c_left_paren (pp); @@ -1246,7 +1383,7 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e) } } -/* Print out an expression-list; E is expected to be a TREE_LIST */ +/* Print out an expression-list; E is expected to be a TREE_LIST. */ void pp_c_expression_list (c_pretty_printer *pp, tree e) @@ -1259,7 +1396,23 @@ pp_c_expression_list (c_pretty_printer *pp, tree e) } } -/* Print out an expression-list in parens, as in a function call. */ +/* 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_call_argument_list (c_pretty_printer *pp, tree t) @@ -1280,7 +1433,7 @@ pp_c_call_argument_list (c_pretty_printer *pp, tree t) unary-operator: one of * & + - ! ~ - + GNU extensions. unary-expression: __alignof__ unary-expression @@ -1320,16 +1473,6 @@ pp_c_unary_expression (c_pretty_printer *pp, tree e) 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__"); @@ -1355,6 +1498,7 @@ pp_c_cast_expression (c_pretty_printer *pp, tree e) case FLOAT_EXPR: case FIX_TRUNC_EXPR: case CONVERT_EXPR: + case NOP_EXPR: pp_c_type_cast (pp, TREE_TYPE (e)); pp_c_cast_expression (pp, TREE_OPERAND (e, 0)); break; @@ -1402,7 +1546,7 @@ pp_c_multiplicative_expression (c_pretty_printer *pp, tree e) additive-expression + multiplicative-expression additive-expression - multiplicative-expression */ -static inline void +static void pp_c_additive_expression (c_pretty_printer *pp, tree e) { enum tree_code code = TREE_CODE (e); @@ -1417,7 +1561,7 @@ pp_c_additive_expression (c_pretty_printer *pp, tree e) else pp_minus (pp); pp_c_whitespace (pp); - pp_multiplicative_expression (pp, TREE_OPERAND (e, 1)); + pp_multiplicative_expression (pp, TREE_OPERAND (e, 1)); break; default: @@ -1431,7 +1575,7 @@ pp_c_additive_expression (c_pretty_printer *pp, tree e) shift-expression << additive-expression shift-expression >> additive-expression */ -static inline void +static void pp_c_shift_expression (c_pretty_printer *pp, tree e) { enum tree_code code = TREE_CODE (e); @@ -1493,7 +1637,7 @@ pp_c_relational_expression (c_pretty_printer *pp, tree e) equality-expression == relational-expression equality-equality != relational-expression */ -static inline void +static void pp_c_equality_expression (c_pretty_printer *pp, tree e) { enum tree_code code = TREE_CODE (e); @@ -1518,7 +1662,7 @@ pp_c_equality_expression (c_pretty_printer *pp, tree e) equality-expression AND-expression & equality-equality */ -static inline void +static void pp_c_and_expression (c_pretty_printer *pp, tree e) { if (TREE_CODE (e) == BIT_AND_EXPR) @@ -1537,7 +1681,7 @@ pp_c_and_expression (c_pretty_printer *pp, tree e) AND-expression exclusive-OR-expression ^ AND-expression */ -static inline void +static void pp_c_exclusive_or_expression (c_pretty_printer *pp, tree e) { if (TREE_CODE (e) == BIT_XOR_EXPR) @@ -1556,7 +1700,7 @@ pp_c_exclusive_or_expression (c_pretty_printer *pp, tree e) exclusive-OR-expression inclusive-OR-expression | exclusive-OR-expression */ -static inline void +static void pp_c_inclusive_or_expression (c_pretty_printer *pp, tree e) { if (TREE_CODE (e) == BIT_IOR_EXPR) @@ -1575,7 +1719,7 @@ pp_c_inclusive_or_expression (c_pretty_printer *pp, tree e) inclusive-OR-expression logical-AND-expression && inclusive-OR-expression */ -static inline void +static void pp_c_logical_and_expression (c_pretty_printer *pp, tree e) { if (TREE_CODE (e) == TRUTH_ANDIF_EXPR) @@ -1635,7 +1779,7 @@ pp_c_conditional_expression (c_pretty_printer *pp, tree e) /* assignment-expression: conditional-expression - unary-expression assignment-operator assignment-expression + unary-expression assignment-operator assignment-expression assignment-expression: one of = *= /= %= += -= >>= <<= &= ^= |= */ @@ -1691,19 +1835,25 @@ pp_c_expression (c_pretty_printer *pp, tree e) 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 COMPLEX_CST: case COMPLEX_EXPR: case VECTOR_CST: + case ORDERED_EXPR: + case UNORDERED_EXPR: + case LTGT_EXPR: + case UNEQ_EXPR: + case UNLE_EXPR: + case UNLT_EXPR: + case UNGE_EXPR: + case UNGT_EXPR: case ABS_EXPR: case CONSTRUCTOR: case COMPOUND_LITERAL_EXPR: @@ -1719,8 +1869,6 @@ pp_c_expression (c_pretty_printer *pp, tree e) 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); @@ -1729,6 +1877,7 @@ pp_c_expression (c_pretty_printer *pp, tree e) case FLOAT_EXPR: case FIX_TRUNC_EXPR: case CONVERT_EXPR: + case NOP_EXPR: pp_c_cast_expression (pp, e); break; @@ -1774,7 +1923,7 @@ pp_c_expression (c_pretty_printer *pp, tree e) case NE_EXPR: pp_c_equality_expression (pp, e); break; - + case COND_EXPR: pp_conditional_expression (pp, e); break; @@ -1797,17 +1946,15 @@ pp_c_expression (c_pretty_printer *pp, tree e) pp_c_right_paren (pp); break; - case NOP_EXPR: case NON_LVALUE_EXPR: case SAVE_EXPR: - case UNSAVE_EXPR: pp_expression (pp, TREE_OPERAND (e, 0)); break; case TARGET_EXPR: pp_postfix_expression (pp, TREE_OPERAND (e, 1)); break; - + default: pp_unsupported_tree (pp, e); break; @@ -1818,308 +1965,16 @@ pp_c_expression (c_pretty_printer *pp, tree e) /* 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; - - code = TREE_CODE (stmt); - switch (code) - { - /* labeled-statement: - identifier : statement - case constant-expression : statement - default : statement */ - case LABEL_STMT: - case CASE_LABEL: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, -3); - else - pp_indentation (pp) -= 3; - if (code == LABEL_STMT) - pp_tree_identifier (pp, DECL_NAME (LABEL_STMT_LABEL (stmt))); - else if (code == CASE_LABEL) - { - if (CASE_LOW (stmt) == NULL_TREE) - pp_identifier (pp, "default"); - else - { - pp_c_identifier (pp, "case"); - pp_c_whitespace (pp); - pp_conditional_expression (pp, CASE_LOW (stmt)); - if (CASE_HIGH (stmt)) - { - pp_identifier (pp, "..."); - pp_conditional_expression (pp, CASE_HIGH (stmt)); - } - } - } - pp_colon (pp); - pp_indentation (pp) += 3; - pp_needs_newline (pp) = true; - break; - - /* compound-statement: - { block-item-list(opt) } - - block-item-list: - block-item - block-item-list block-item - - block-item: - declaration - statement */ - case COMPOUND_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_left_brace (pp); - pp_newline_and_indent (pp, 3); - for (stmt = COMPOUND_BODY (stmt); stmt; stmt = TREE_CHAIN (stmt)) - pp_statement (pp, stmt); - pp_newline_and_indent (pp, -3); - pp_c_right_brace (pp); - pp_needs_newline (pp) = true; - break; - - /* expression-statement: - expression(opt) ; */ - case EXPR_STMT: - case CLEANUP_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - { - tree e = code == EXPR_STMT - ? EXPR_STMT_EXPR (stmt) - : CLEANUP_EXPR (stmt); - if (e) - pp_expression (pp, e); - } - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - break; - - /* selection-statement: - if ( expression ) statement - if ( expression ) statement else statement - switch ( expression ) statement */ - case IF_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_identifier (pp, "if"); - pp_c_whitespace (pp); - pp_c_left_paren (pp); - pp_expression (pp, IF_COND (stmt)); - pp_c_right_paren (pp); - pp_newline_and_indent (pp, 3); - pp_statement (pp, THEN_CLAUSE (stmt)); - pp_newline_and_indent (pp, -3); - if (ELSE_CLAUSE (stmt)) - { - tree else_clause = ELSE_CLAUSE (stmt); - pp_c_identifier (pp, "else"); - if (TREE_CODE (else_clause) == IF_STMT) - pp_c_whitespace (pp); - else - pp_newline_and_indent (pp, 3); - pp_statement (pp, else_clause); - if (TREE_CODE (else_clause) != IF_STMT) - pp_newline_and_indent (pp, -3); - } - break; - - case SWITCH_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - 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: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - 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: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - 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: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - 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: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_identifier (pp, code == BREAK_STMT ? "break" : "continue"); - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - break; - - case RETURN_STMT: - case GOTO_STMT: - { - tree e = code == RETURN_STMT - ? RETURN_STMT_EXPR (stmt) - : GOTO_DESTINATION (stmt); - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_c_identifier (pp, code == RETURN_STMT ? "return" : "goto"); - pp_c_whitespace (pp); - if (e) - { - if (TREE_CODE (e) == INIT_EXPR - && TREE_CODE (TREE_OPERAND (e, 0)) == RESULT_DECL) - e = TREE_OPERAND (e, 1); - pp_expression (pp, e); - } - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - } - break; - - case SCOPE_STMT: - if (!SCOPE_NULLIFIED_P (stmt) && SCOPE_NO_CLEANUPS_P (stmt)) - { - int i = 0; - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - if (SCOPE_BEGIN_P (stmt)) - { - pp_left_brace (pp); - i = 3; - } - else if (SCOPE_END_P (stmt)) - { - pp_right_brace (pp); - i = -3; - } - pp_indentation (pp) += i; - pp_needs_newline (pp) = true; - } - break; - - case DECL_STMT: - if (pp_needs_newline (pp)) - pp_newline_and_indent (pp, 0); - pp_declaration (pp, DECL_STMT_DECL (stmt)); - pp_needs_newline (pp) = true; - break; - - case ASM_STMT: - { - bool has_volatile_p = ASM_VOLATILE_P (stmt); - bool is_extended = has_volatile_p || ASM_INPUTS (stmt) - || ASM_OUTPUTS (stmt) || ASM_CLOBBERS (stmt); - pp_c_identifier (pp, is_extended ? "__asm__" : "asm"); - if (has_volatile_p) - pp_c_identifier (pp, "__volatile__"); - pp_space (pp); - pp_c_left_paren (pp); - pp_c_string_literal (pp, ASM_STRING (stmt)); - if (is_extended) - { - pp_space (pp); - pp_separate_with (pp, ':'); - if (ASM_OUTPUTS (stmt)) - pp_expression (pp, ASM_OUTPUTS (stmt)); - pp_space (pp); - pp_separate_with (pp, ':'); - if (ASM_INPUTS (stmt)) - pp_expression (pp, ASM_INPUTS (stmt)); - pp_space (pp); - pp_separate_with (pp, ':'); - if (ASM_CLOBBERS (stmt)) - pp_expression (pp, ASM_CLOBBERS (stmt)); - } - pp_c_right_paren (pp); - pp_newline (pp); - } - break; - case FILE_STMT: - pp_c_identifier (pp, "__FILE__"); - pp_space (pp); - pp_equal (pp); - pp_c_whitespace (pp); - pp_c_identifier (pp, FILE_STMT_FILENAME (stmt)); - pp_c_semicolon (pp); - pp_needs_newline (pp) = true; - break; + if (pp_needs_newline (pp)) + pp_newline_and_indent (pp, 0); - default: - pp_unsupported_tree (pp, stmt); - } + dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true); } @@ -2146,6 +2001,7 @@ pp_c_pretty_printer_init (c_pretty_printer *pp) pp->statement = pp_c_statement; + pp->constant = pp_c_constant; pp->id_expression = pp_c_id_expression; pp->primary_expression = pp_c_primary_expression; pp->postfix_expression = pp_c_postfix_expression; @@ -2156,3 +2012,59 @@ pp_c_pretty_printer_init (c_pretty_printer *pp) pp->assignment_expression = pp_c_assignment_expression; pp->expression = pp_c_expression; } + + +/* Print the tree T in full, on file FILE. */ + +void +print_c_tree (FILE *file, tree t) +{ + static c_pretty_printer pp_rec; + static bool initialized = 0; + c_pretty_printer *pp = &pp_rec; + + if (!initialized) + { + initialized = 1; + pp_construct (pp_base (pp), NULL, 0); + pp_c_pretty_printer_init (pp); + pp_needs_newline (pp) = true; + } + pp_base (pp)->buffer->stream = file; + + pp_statement (pp, t); + + pp_newline (pp); + pp_flush (pp); +} + +/* Print the tree T in full, on stderr. */ + +void +debug_c_tree (tree t) +{ + print_c_tree (stderr, t); + fputc ('\n', stderr); +} + +/* Output the DECL_NAME of T. If T has no DECL_NAME, output a string made + up of T's memory address. */ + +void +pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t) +{ + const char *name; + + gcc_assert (DECL_P (t)); + + if (DECL_NAME (t)) + name = IDENTIFIER_POINTER (DECL_NAME (t)); + else + { + static char xname[8]; + sprintf (xname, "", ((unsigned)((unsigned long)(t) & 0xffff))); + name = xname; + } + + pp_c_identifier (pp, name); +}