diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index acffd7b872c..8953e3b678b 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "tree-pretty-print.h" #include "selftest.h" +#include "langhooks.h" /* The pretty-printer code is primarily designed to closely follow (GNU) C and C++ grammars. That is to be contrasted with spaghetti @@ -1693,6 +1694,7 @@ c_pretty_printer::postfix_expression (tree e) break; case MEM_REF: + case TARGET_MEM_REF: expression (e); break; @@ -1859,6 +1861,62 @@ c_pretty_printer::unary_expression (tree e) } break; + case TARGET_MEM_REF: + /* TARGET_MEM_REF can't appear directly from source, but can appear + during late GIMPLE optimizations and through late diagnostic we might + need to support it. Print it as dereferencing of a pointer after + cast to the TARGET_MEM_REF type, with pointer arithmetics on some + pointer to single byte types, so + *(type *)((char *) ptr + step * index + index2) if all the operands + are present and the casts are needed. */ + pp_c_star (this); + if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (e)))) == NULL_TREE + || !integer_onep (TYPE_SIZE_UNIT + (TREE_TYPE (TREE_TYPE (TMR_BASE (e)))))) + { + if (TYPE_SIZE_UNIT (TREE_TYPE (e)) + && integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (e)))) + { + pp_c_left_paren (this); + pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e))); + } + else + { + pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e))); + pp_c_left_paren (this); + pp_c_type_cast (this, build_pointer_type (char_type_node)); + } + } + else if (!lang_hooks.types_compatible_p + (TREE_TYPE (e), TREE_TYPE (TREE_TYPE (TMR_BASE (e))))) + { + pp_c_type_cast (this, build_pointer_type (TREE_TYPE (e))); + pp_c_left_paren (this); + } + else + pp_c_left_paren (this); + pp_c_cast_expression (this, TMR_BASE (e)); + if (TMR_STEP (e) && TMR_INDEX (e)) + { + pp_plus (this); + pp_c_cast_expression (this, TMR_INDEX (e)); + pp_c_star (this); + pp_c_cast_expression (this, TMR_STEP (e)); + } + if (TMR_INDEX2 (e)) + { + pp_plus (this); + pp_c_cast_expression (this, TMR_INDEX2 (e)); + } + if (!integer_zerop (TMR_OFFSET (e))) + { + pp_plus (this); + pp_c_integer_constant (this, + fold_convert (ssizetype, TMR_OFFSET (e))); + } + pp_c_right_paren (this); + break; + case REALPART_EXPR: case IMAGPART_EXPR: pp_c_ws_string (this, code == REALPART_EXPR ? "__real__" : "__imag__"); @@ -2295,6 +2353,7 @@ c_pretty_printer::expression (tree e) case ADDR_EXPR: case INDIRECT_REF: case MEM_REF: + case TARGET_MEM_REF: case NEGATE_EXPR: case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: diff --git a/gcc/cp/error.c b/gcc/cp/error.c index ecb41e82d8c..ad22b00cb0b 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2400,6 +2400,64 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags) } break; + case TARGET_MEM_REF: + /* TARGET_MEM_REF can't appear directly from source, but can appear + during late GIMPLE optimizations and through late diagnostic we might + need to support it. Print it as dereferencing of a pointer after + cast to the TARGET_MEM_REF type, with pointer arithmetics on some + pointer to single byte types, so + *(type *)((char *) ptr + step * index + index2) if all the operands + are present and the casts are needed. */ + pp_cxx_star (pp); + pp_cxx_left_paren (pp); + if (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (TMR_BASE (t)))) == NULL_TREE + || !integer_onep (TYPE_SIZE_UNIT + (TREE_TYPE (TREE_TYPE (TMR_BASE (t)))))) + { + if (TYPE_SIZE_UNIT (TREE_TYPE (t)) + && integer_onep (TYPE_SIZE_UNIT (TREE_TYPE (t)))) + { + pp_cxx_left_paren (pp); + dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags); + } + else + { + dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags); + pp_cxx_right_paren (pp); + pp_cxx_left_paren (pp); + pp_cxx_left_paren (pp); + dump_type (pp, build_pointer_type (char_type_node), flags); + } + pp_cxx_right_paren (pp); + } + else if (!same_type_p (TREE_TYPE (t), + TREE_TYPE (TREE_TYPE (TMR_BASE (t))))) + { + dump_type (pp, build_pointer_type (TREE_TYPE (t)), flags); + pp_cxx_right_paren (pp); + pp_cxx_left_paren (pp); + } + dump_expr (pp, TMR_BASE (t), flags); + if (TMR_STEP (t) && TMR_INDEX (t)) + { + pp_cxx_ws_string (pp, "+"); + dump_expr (pp, TMR_INDEX (t), flags); + pp_cxx_ws_string (pp, "*"); + dump_expr (pp, TMR_STEP (t), flags); + } + if (TMR_INDEX2 (t)) + { + pp_cxx_ws_string (pp, "+"); + dump_expr (pp, TMR_INDEX2 (t), flags); + } + if (!integer_zerop (TMR_OFFSET (t))) + { + pp_cxx_ws_string (pp, "+"); + dump_expr (pp, fold_convert (ssizetype, TMR_OFFSET (t)), flags); + } + pp_cxx_right_paren (pp); + break; + case NEGATE_EXPR: case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: