On Thu, 12 Jan 2017, Jakub Jelinek wrote: > On Thu, Jan 12, 2017 at 01:35:32PM +0100, Richard Biener wrote: > > It also lacks expressiveness when comparing > > > > short s; > > s_1 = (short) 1; > > s_2 = short (1); > > > > IMHO having a _Literal somewhere makes it more obvious what is meant > > (I'm still going to dump 1u or 1l instead of _Literal (unsigned) 1 > > of course as that's even more easy to recognize). > > So, with the _Literal (type) constant syntax, what are we going to emit > and parse for __int128 constants? > _Literal (__int128) (0x123456ULL << 64 || 0x123456ULL), something else?
Yes, unless we teach libcpp about larger than 64bit literals. The following patch implements _Literal (but not proper dumping of > 64bit literals for __int128 nor parsing the above). I think that's a good start which also covers pointer types nicely. For integers we might at some point want to adopt sN and uN suffixes which appearantly MSVC supports to handle native 128bit literals. For struct X { int a : 2; }; void __GIMPLE () foo (struct X * p) { p->a = _Literal (int : 2) 1; return; } and thus 2 bit literals c_parser_type_name needs to be extended or for _Literal we can handle : 2 on our own. But for loads from p->a into a temporary we need to handle that in declarations as well. struct X { int a : 2; }; int __GIMPLE () foo (struct X * p) { int : 2 a; // int a : 2; a = p->a; return a; } Richard. 2017-01-12 Richard Biener <rguent...@suse.de> c/ * gimple-parser.c (c_parser_gimple_postfix_expression): Parse _Literal ( type-name ) number. * tree-pretty-print.c (dump_generic_node): Dump INTEGER_CSTs as _Literal ( type ) number in case usual suffixes do not preserve all information. * gcc.dg/gimplefe-22.c: New testcase. Index: gcc/c/gimple-parser.c =================================================================== --- gcc/c/gimple-parser.c (revision 244350) +++ gcc/c/gimple-parser.c (working copy) @@ -799,6 +799,32 @@ c_parser_gimple_postfix_expression (c_pa type, ptr.value, alias_off); break; } + else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0) + { + /* _Literal '(' type-name ')' number */ + c_parser_consume_token (parser); + tree type = NULL_TREE; + if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + { + struct c_type_name *type_name = c_parser_type_name (parser); + tree tem; + if (type_name) + type = groktypename (type_name, &tem, NULL); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + } + tree val = c_parser_gimple_postfix_expression (parser).value; + if (! type + || ! val + || val == error_mark_node + || TREE_CODE (val) != INTEGER_CST) + { + c_parser_error (parser, "invalid _Literal"); + return expr; + } + expr.value = fold_convert (type, val); + return expr; + } /* SSA name. */ unsigned version, ver_offset; if (! lookup_name (id) Index: gcc/tree-pretty-print.c =================================================================== --- gcc/tree-pretty-print.c (revision 244350) +++ gcc/tree-pretty-print.c (working copy) @@ -1664,6 +1664,16 @@ dump_generic_node (pretty_printer *pp, t break; case INTEGER_CST: + if (flags & TDF_GIMPLE + && (POINTER_TYPE_P (TREE_TYPE (node)) + || (TYPE_PRECISION (TREE_TYPE (node)) + < TYPE_PRECISION (integer_type_node)) + || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1)) + { + pp_string (pp, "_Literal ("); + dump_generic_node (pp, TREE_TYPE (node), spc, flags, false); + pp_string (pp, ") "); + } if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE && ! (flags & TDF_GIMPLE)) { @@ -1693,11 +1703,7 @@ dump_generic_node (pretty_printer *pp, t else if (tree_fits_shwi_p (node)) pp_wide_integer (pp, tree_to_shwi (node)); else if (tree_fits_uhwi_p (node)) - { - pp_unsigned_wide_integer (pp, tree_to_uhwi (node)); - if (flags & TDF_GIMPLE) - pp_character (pp, 'U'); - } + pp_unsigned_wide_integer (pp, tree_to_uhwi (node)); else { wide_int val = node; @@ -1710,6 +1716,24 @@ dump_generic_node (pretty_printer *pp, t print_hex (val, pp_buffer (pp)->digit_buffer); pp_string (pp, pp_buffer (pp)->digit_buffer); } + if ((flags & TDF_GIMPLE) + && (POINTER_TYPE_P (TREE_TYPE (node)) + || (TYPE_PRECISION (TREE_TYPE (node)) + < TYPE_PRECISION (integer_type_node)) + || exact_log2 (TYPE_PRECISION (TREE_TYPE (node))) == -1)) + { + if (TYPE_UNSIGNED (TREE_TYPE (node))) + pp_character (pp, 'u'); + if (TYPE_PRECISION (TREE_TYPE (node)) + == TYPE_PRECISION (unsigned_type_node)) + ; + else if (TYPE_PRECISION (TREE_TYPE (node)) + == TYPE_PRECISION (long_unsigned_type_node)) + pp_character (pp, 'l'); + else if (TYPE_PRECISION (TREE_TYPE (node)) + == TYPE_PRECISION (long_long_unsigned_type_node)) + pp_string (pp, "ll"); + } if (TREE_OVERFLOW (node)) pp_string (pp, "(OVF)"); break; Index: gcc/testsuite/gcc.dg/gimplefe-22.c =================================================================== --- gcc/testsuite/gcc.dg/gimplefe-22.c (nonexistent) +++ gcc/testsuite/gcc.dg/gimplefe-22.c (working copy) @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +void __GIMPLE () +foo (short * p) +{ + *p = _Literal (short int) 1; + return; +}