Mercurial > hg > CbC > CbC_gcc
comparison gcc/c-family/c-pretty-print.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | d34655255c78 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Subroutines common to both C and C++ pretty-printers. | 1 /* Subroutines common to both C and C++ pretty-printers. |
2 Copyright (C) 2002-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2002-2018 Free Software Foundation, Inc. |
3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> | 3 Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
26 #include "stor-layout.h" | 26 #include "stor-layout.h" |
27 #include "stringpool.h" | 27 #include "stringpool.h" |
28 #include "attribs.h" | 28 #include "attribs.h" |
29 #include "intl.h" | 29 #include "intl.h" |
30 #include "tree-pretty-print.h" | 30 #include "tree-pretty-print.h" |
31 #include "selftest.h" | |
31 | 32 |
32 /* The pretty-printer code is primarily designed to closely follow | 33 /* The pretty-printer code is primarily designed to closely follow |
33 (GNU) C and C++ grammars. That is to be contrasted with spaghetti | 34 (GNU) C and C++ grammars. That is to be contrasted with spaghetti |
34 codes we used to have in the past. Following a structured | 35 codes we used to have in the past. Following a structured |
35 approach (preferably the official grammars) is believed to make it | 36 approach (preferably the official grammars) is believed to make it |
189 ? "restrict" : "__restrict__")); | 190 ? "restrict" : "__restrict__")); |
190 } | 191 } |
191 | 192 |
192 /* Pretty-print T using the type-cast notation '( type-name )'. */ | 193 /* Pretty-print T using the type-cast notation '( type-name )'. */ |
193 | 194 |
194 static void | 195 void |
195 pp_c_type_cast (c_pretty_printer *pp, tree t) | 196 pp_c_type_cast (c_pretty_printer *pp, tree t) |
196 { | 197 { |
197 pp_c_left_paren (pp); | 198 pp_c_left_paren (pp); |
198 pp->type_id (t); | 199 pp->type_id (t); |
199 pp_c_right_paren (pp); | 200 pp_c_right_paren (pp); |
905 pp_string (pp, "0"); | 906 pp_string (pp, "0"); |
906 } | 907 } |
907 | 908 |
908 /* Pretty-print an INTEGER literal. */ | 909 /* Pretty-print an INTEGER literal. */ |
909 | 910 |
910 static void | 911 void |
911 pp_c_integer_constant (c_pretty_printer *pp, tree i) | 912 pp_c_integer_constant (c_pretty_printer *pp, tree i) |
912 { | 913 { |
913 if (tree_fits_shwi_p (i)) | 914 if (tree_fits_shwi_p (i)) |
914 pp_wide_integer (pp, tree_to_shwi (i)); | 915 pp_wide_integer (pp, tree_to_shwi (i)); |
915 else if (tree_fits_uhwi_p (i)) | 916 else if (tree_fits_uhwi_p (i)) |
965 pp_c_integer_constant (pp, b); | 966 pp_c_integer_constant (pp, b); |
966 else | 967 else |
967 pp_unsupported_tree (pp, b); | 968 pp_unsupported_tree (pp, b); |
968 } | 969 } |
969 | 970 |
970 /* Attempt to print out an ENUMERATOR. Return true on success. Else return | 971 /* Given a value e of ENUMERAL_TYPE: |
971 false; that means the value was obtained by a cast, in which case | 972 Print out the first ENUMERATOR id with value e, if one is found, |
972 print out the type-id part of the cast-expression -- the casted value | 973 else print out the value as a C-style cast (type-id)value. */ |
973 is then printed by pp_c_integer_literal. */ | 974 |
974 | 975 static void |
975 static bool | |
976 pp_c_enumeration_constant (c_pretty_printer *pp, tree e) | 976 pp_c_enumeration_constant (c_pretty_printer *pp, tree e) |
977 { | 977 { |
978 bool value_is_named = true; | |
979 tree type = TREE_TYPE (e); | 978 tree type = TREE_TYPE (e); |
980 tree value; | 979 tree value; |
981 | 980 |
982 /* Find the name of this constant. */ | 981 /* Find the name of this constant. */ |
983 for (value = TYPE_VALUES (type); | 982 for (value = TYPE_VALUES (type); |
984 value != NULL_TREE && !tree_int_cst_equal (TREE_VALUE (value), e); | 983 value != NULL_TREE |
984 && !tree_int_cst_equal (DECL_INITIAL (TREE_VALUE (value)), e); | |
985 value = TREE_CHAIN (value)) | 985 value = TREE_CHAIN (value)) |
986 ; | 986 ; |
987 | 987 |
988 if (value != NULL_TREE) | 988 if (value != NULL_TREE) |
989 pp->id_expression (TREE_PURPOSE (value)); | 989 pp->id_expression (TREE_PURPOSE (value)); |
990 else | 990 else |
991 { | 991 { |
992 /* Value must have been cast. */ | 992 /* Value must have been cast. */ |
993 pp_c_type_cast (pp, type); | 993 pp_c_type_cast (pp, type); |
994 value_is_named = false; | 994 pp_c_integer_constant (pp, e); |
995 } | 995 } |
996 | |
997 return value_is_named; | |
998 } | 996 } |
999 | 997 |
1000 /* Print out a REAL value as a decimal-floating-constant. */ | 998 /* Print out a REAL value as a decimal-floating-constant. */ |
1001 | 999 |
1002 static void | 1000 static void |
1137 tree type = TREE_TYPE (e); | 1135 tree type = TREE_TYPE (e); |
1138 if (type == boolean_type_node) | 1136 if (type == boolean_type_node) |
1139 pp_c_bool_constant (this, e); | 1137 pp_c_bool_constant (this, e); |
1140 else if (type == char_type_node) | 1138 else if (type == char_type_node) |
1141 pp_c_character_constant (this, e); | 1139 pp_c_character_constant (this, e); |
1142 else if (TREE_CODE (type) == ENUMERAL_TYPE | 1140 else if (TREE_CODE (type) == ENUMERAL_TYPE) |
1143 && pp_c_enumeration_constant (this, e)) | 1141 pp_c_enumeration_constant (this, e); |
1144 ; | |
1145 else | 1142 else |
1146 pp_c_integer_constant (this, e); | 1143 pp_c_integer_constant (this, e); |
1147 } | 1144 } |
1148 break; | 1145 break; |
1149 | 1146 |
1377 return; | 1374 return; |
1378 | 1375 |
1379 case VECTOR_TYPE: | 1376 case VECTOR_TYPE: |
1380 if (TREE_CODE (e) == VECTOR_CST) | 1377 if (TREE_CODE (e) == VECTOR_CST) |
1381 { | 1378 { |
1382 unsigned i; | 1379 /* We don't create variable-length VECTOR_CSTs. */ |
1383 for (i = 0; i < VECTOR_CST_NELTS (e); ++i) | 1380 unsigned int nunits = VECTOR_CST_NELTS (e).to_constant (); |
1381 for (unsigned int i = 0; i < nunits; ++i) | |
1384 { | 1382 { |
1385 if (i > 0) | 1383 if (i > 0) |
1386 pp_separate_with (pp, ','); | 1384 pp_separate_with (pp, ','); |
1387 pp->expression (VECTOR_CST_ELT (e, i)); | 1385 pp->expression (VECTOR_CST_ELT (e, i)); |
1388 } | 1386 } |
1480 pp_c_left_bracket (this); | 1478 pp_c_left_bracket (this); |
1481 expression (TREE_OPERAND (e, 1)); | 1479 expression (TREE_OPERAND (e, 1)); |
1482 pp_c_right_bracket (this); | 1480 pp_c_right_bracket (this); |
1483 break; | 1481 break; |
1484 | 1482 |
1485 case ARRAY_NOTATION_REF: | |
1486 postfix_expression (ARRAY_NOTATION_ARRAY (e)); | |
1487 pp_c_left_bracket (this); | |
1488 expression (ARRAY_NOTATION_START (e)); | |
1489 pp_colon (this); | |
1490 expression (ARRAY_NOTATION_LENGTH (e)); | |
1491 pp_colon (this); | |
1492 expression (ARRAY_NOTATION_STRIDE (e)); | |
1493 pp_c_right_bracket (this); | |
1494 break; | |
1495 | |
1496 case CALL_EXPR: | 1483 case CALL_EXPR: |
1497 { | 1484 { |
1498 call_expr_arg_iterator iter; | 1485 call_expr_arg_iterator iter; |
1499 tree arg; | 1486 tree arg; |
1500 postfix_expression (CALL_EXPR_FN (e)); | 1487 postfix_expression (CALL_EXPR_FN (e)); |
1817 { | 1804 { |
1818 case FLOAT_EXPR: | 1805 case FLOAT_EXPR: |
1819 case FIX_TRUNC_EXPR: | 1806 case FIX_TRUNC_EXPR: |
1820 CASE_CONVERT: | 1807 CASE_CONVERT: |
1821 case VIEW_CONVERT_EXPR: | 1808 case VIEW_CONVERT_EXPR: |
1822 pp_c_type_cast (pp, TREE_TYPE (e)); | 1809 if (!location_wrapper_p (e)) |
1810 pp_c_type_cast (pp, TREE_TYPE (e)); | |
1823 pp_c_cast_expression (pp, TREE_OPERAND (e, 0)); | 1811 pp_c_cast_expression (pp, TREE_OPERAND (e, 0)); |
1824 break; | 1812 break; |
1825 | 1813 |
1826 default: | 1814 default: |
1827 pp->unary_expression (e); | 1815 pp->unary_expression (e); |
1847 case RDIV_EXPR: | 1835 case RDIV_EXPR: |
1848 multiplicative_expression (TREE_OPERAND (e, 0)); | 1836 multiplicative_expression (TREE_OPERAND (e, 0)); |
1849 pp_c_whitespace (this); | 1837 pp_c_whitespace (this); |
1850 if (code == MULT_EXPR) | 1838 if (code == MULT_EXPR) |
1851 pp_c_star (this); | 1839 pp_c_star (this); |
1852 else if (code == TRUNC_DIV_EXPR) | 1840 else if (code != TRUNC_MOD_EXPR) |
1853 pp_slash (this); | 1841 pp_slash (this); |
1854 else | 1842 else |
1855 pp_modulo (this); | 1843 pp_modulo (this); |
1856 pp_c_whitespace (this); | 1844 pp_c_whitespace (this); |
1857 pp_c_cast_expression (this, TREE_OPERAND (e, 1)); | 1845 pp_c_cast_expression (this, TREE_OPERAND (e, 1)); |
1874 enum tree_code code = TREE_CODE (e); | 1862 enum tree_code code = TREE_CODE (e); |
1875 switch (code) | 1863 switch (code) |
1876 { | 1864 { |
1877 case POINTER_PLUS_EXPR: | 1865 case POINTER_PLUS_EXPR: |
1878 case PLUS_EXPR: | 1866 case PLUS_EXPR: |
1867 case POINTER_DIFF_EXPR: | |
1879 case MINUS_EXPR: | 1868 case MINUS_EXPR: |
1880 pp_c_additive_expression (pp, TREE_OPERAND (e, 0)); | 1869 pp_c_additive_expression (pp, TREE_OPERAND (e, 0)); |
1881 pp_c_whitespace (pp); | 1870 pp_c_whitespace (pp); |
1882 if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR) | 1871 if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR) |
1883 pp_plus (pp); | 1872 pp_plus (pp); |
2189 break; | 2178 break; |
2190 | 2179 |
2191 case POSTINCREMENT_EXPR: | 2180 case POSTINCREMENT_EXPR: |
2192 case POSTDECREMENT_EXPR: | 2181 case POSTDECREMENT_EXPR: |
2193 case ARRAY_REF: | 2182 case ARRAY_REF: |
2194 case ARRAY_NOTATION_REF: | |
2195 case CALL_EXPR: | 2183 case CALL_EXPR: |
2196 case COMPONENT_REF: | 2184 case COMPONENT_REF: |
2197 case BIT_FIELD_REF: | 2185 case BIT_FIELD_REF: |
2198 case COMPLEX_CST: | 2186 case COMPLEX_CST: |
2199 case COMPLEX_EXPR: | 2187 case COMPLEX_EXPR: |
2290 conditional_expression (e); | 2278 conditional_expression (e); |
2291 break; | 2279 break; |
2292 | 2280 |
2293 case POINTER_PLUS_EXPR: | 2281 case POINTER_PLUS_EXPR: |
2294 case PLUS_EXPR: | 2282 case PLUS_EXPR: |
2283 case POINTER_DIFF_EXPR: | |
2295 case MINUS_EXPR: | 2284 case MINUS_EXPR: |
2296 pp_c_additive_expression (this, e); | 2285 pp_c_additive_expression (this, e); |
2297 break; | 2286 break; |
2298 | 2287 |
2299 case MODIFY_EXPR: | 2288 case MODIFY_EXPR: |
2346 return; | 2335 return; |
2347 | 2336 |
2348 if (pp_needs_newline (this)) | 2337 if (pp_needs_newline (this)) |
2349 pp_newline_and_indent (this, 0); | 2338 pp_newline_and_indent (this, 0); |
2350 | 2339 |
2351 dump_generic_node (this, stmt, pp_indentation (this), 0, true); | 2340 dump_generic_node (this, stmt, pp_indentation (this), TDF_NONE, true); |
2352 } | 2341 } |
2353 | 2342 |
2354 | 2343 |
2355 /* Initialize the PRETTY-PRINTER for handling C codes. */ | 2344 /* Initialize the PRETTY-PRINTER for handling C codes. */ |
2356 | 2345 |
2407 name = xname; | 2396 name = xname; |
2408 } | 2397 } |
2409 | 2398 |
2410 pp_c_identifier (pp, name); | 2399 pp_c_identifier (pp, name); |
2411 } | 2400 } |
2401 | |
2402 #if CHECKING_P | |
2403 | |
2404 namespace selftest { | |
2405 | |
2406 /* Selftests for pretty-printing trees. */ | |
2407 | |
2408 /* Verify that EXPR printed by c_pretty_printer is EXPECTED, using | |
2409 LOC as the effective location for any failures. */ | |
2410 | |
2411 static void | |
2412 assert_c_pretty_printer_output (const location &loc, const char *expected, | |
2413 tree expr) | |
2414 { | |
2415 c_pretty_printer pp; | |
2416 pp.expression (expr); | |
2417 ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp)); | |
2418 } | |
2419 | |
2420 /* Helper function for calling assert_c_pretty_printer_output. | |
2421 This is to avoid having to write SELFTEST_LOCATION. */ | |
2422 | |
2423 #define ASSERT_C_PRETTY_PRINTER_OUTPUT(EXPECTED, EXPR) \ | |
2424 SELFTEST_BEGIN_STMT \ | |
2425 assert_c_pretty_printer_output ((SELFTEST_LOCATION), \ | |
2426 (EXPECTED), \ | |
2427 (EXPR)); \ | |
2428 SELFTEST_END_STMT | |
2429 | |
2430 /* Verify that location wrappers don't show up in pretty-printed output. */ | |
2431 | |
2432 static void | |
2433 test_location_wrappers () | |
2434 { | |
2435 /* VAR_DECL. */ | |
2436 tree id = get_identifier ("foo"); | |
2437 tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id, | |
2438 integer_type_node); | |
2439 tree wrapped_decl = maybe_wrap_with_location (decl, BUILTINS_LOCATION); | |
2440 ASSERT_NE (wrapped_decl, decl); | |
2441 ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", decl); | |
2442 ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", wrapped_decl); | |
2443 | |
2444 /* INTEGER_CST. */ | |
2445 tree int_cst = build_int_cst (integer_type_node, 42); | |
2446 tree wrapped_cst = maybe_wrap_with_location (int_cst, BUILTINS_LOCATION); | |
2447 ASSERT_NE (wrapped_cst, int_cst); | |
2448 ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", int_cst); | |
2449 ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", wrapped_cst); | |
2450 } | |
2451 | |
2452 /* Run all of the selftests within this file. */ | |
2453 | |
2454 void | |
2455 c_pretty_print_c_tests () | |
2456 { | |
2457 test_location_wrappers (); | |
2458 } | |
2459 | |
2460 } // namespace selftest | |
2461 | |
2462 #endif /* CHECKING_P */ |