/* Pretty formatting of GENERIC trees in C syntax. Copyright (C) 2001-2020 Free Software Foundation, Inc. Adapted from c-pretty-print.c by Diego Novillo This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include "coretypes.h" #include "backend.h" #include "rtl.h" #include "tree.h" #include "predict.h" #include "cgraph.h" #include "tree-pretty-print.h" #include "stor-layout.h" #include "langhooks.h" #include "tree-iterator.h" #include "dumpfile.h" #include "internal-fn.h" #include "gomp-constants.h" #include "gimple.h" #include "fold-const.h" /* Disable warnings about quoting issues in the pp_xxx calls below that (intentionally) don't follow GCC diagnostic conventions. */ #if __GNUC__ >= 10 # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wformat-diag" #endif /* Local functions, macros and variables. */ static const char *op_symbol (const_tree); static void newline_and_indent (pretty_printer *, int); static void maybe_init_pretty_print (FILE *); static void print_struct_decl (pretty_printer *, const_tree, int, dump_flags_t); static void do_niy (pretty_printer *, const_tree, dump_flags_t); #define INDENT(SPACE) do { \ int i; for (i = 0; i>>"); } /* Debugging function to print out a generic expression. */ DEBUG_FUNCTION void debug_generic_expr (tree t) { print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS); fprintf (stderr, "\n"); } /* Debugging function to print out a generic statement. */ DEBUG_FUNCTION void debug_generic_stmt (tree t) { print_generic_stmt (stderr, t, TDF_VOPS|TDF_MEMSYMS); fprintf (stderr, "\n"); } /* Debugging function to print out a chain of trees . */ DEBUG_FUNCTION void debug_tree_chain (tree t) { hash_set seen; while (t) { print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID); fprintf (stderr, " "); t = TREE_CHAIN (t); if (seen.add (t)) { fprintf (stderr, "... [cycled back to "); print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID); fprintf (stderr, "]"); break; } } fprintf (stderr, "\n"); } /* Prints declaration DECL to the FILE with details specified by FLAGS. */ void print_generic_decl (FILE *file, tree decl, dump_flags_t flags) { maybe_init_pretty_print (file); print_declaration (tree_pp, decl, 2, flags); pp_write_text_to_stream (tree_pp); } /* Print tree T, and its successors, on file FILE. FLAGS specifies details to show in the dump. See TDF_* in dumpfile.h. */ void print_generic_stmt (FILE *file, tree t, dump_flags_t flags) { maybe_init_pretty_print (file); dump_generic_node (tree_pp, t, 0, flags, true); pp_newline_and_flush (tree_pp); } /* Print tree T, and its successors, on file FILE. FLAGS specifies details to show in the dump. See TDF_* in dumpfile.h. The output is indented by INDENT spaces. */ void print_generic_stmt_indented (FILE *file, tree t, dump_flags_t flags, int indent) { int i; maybe_init_pretty_print (file); for (i = 0; i < indent; i++) pp_space (tree_pp); dump_generic_node (tree_pp, t, indent, flags, true); pp_newline_and_flush (tree_pp); } /* Print a single expression T on file FILE. FLAGS specifies details to show in the dump. See TDF_* in dumpfile.h. */ void print_generic_expr (FILE *file, tree t, dump_flags_t flags) { maybe_init_pretty_print (file); dump_generic_node (tree_pp, t, 0, flags, false); pp_flush (tree_pp); } /* Print a single expression T to string, and return it. */ char * print_generic_expr_to_str (tree t) { pretty_printer pp; dump_generic_node (&pp, t, 0, TDF_VOPS|TDF_MEMSYMS, false); return xstrdup (pp_formatted_text (&pp)); } /* Dump NAME, an IDENTIFIER_POINTER, sanitized so that D sequences in it are replaced with Dxxxx, as long as they are at the start or preceded by $ and at the end or followed by $. See make_fancy_name in tree-sra.c. */ static void dump_fancy_name (pretty_printer *pp, tree name) { int cnt = 0; int length = IDENTIFIER_LENGTH (name); const char *n = IDENTIFIER_POINTER (name); do { n = strchr (n, 'D'); if (n == NULL) break; if (ISDIGIT (n[1]) && (n == IDENTIFIER_POINTER (name) || n[-1] == '$')) { int l = 2; while (ISDIGIT (n[l])) l++; if (n[l] == '\0' || n[l] == '$') { cnt++; length += 5 - l; } n += l; } else n++; } while (1); if (cnt == 0) { pp_tree_identifier (pp, name); return; } char *str = XNEWVEC (char, length + 1); char *p = str; const char *q; q = n = IDENTIFIER_POINTER (name); do { q = strchr (q, 'D'); if (q == NULL) break; if (ISDIGIT (q[1]) && (q == IDENTIFIER_POINTER (name) || q[-1] == '$')) { int l = 2; while (ISDIGIT (q[l])) l++; if (q[l] == '\0' || q[l] == '$') { memcpy (p, n, q - n); memcpy (p + (q - n), "Dxxxx", 5); p += (q - n) + 5; n = q + l; } q += l; } else q++; } while (1); memcpy (p, n, IDENTIFIER_LENGTH (name) - (n - IDENTIFIER_POINTER (name))); str[length] = '\0'; if (pp_translate_identifiers (pp)) { const char *text = identifier_to_locale (str); pp_append_text (pp, text, text + strlen (text)); } else pp_append_text (pp, str, str + length); XDELETEVEC (str); } /* Dump the name of a _DECL node and its DECL_UID if TDF_UID is set in FLAGS. */ static void dump_decl_name (pretty_printer *pp, tree node, dump_flags_t flags) { tree name = DECL_NAME (node); if (name) { if ((flags & TDF_ASMNAME) && HAS_DECL_ASSEMBLER_NAME_P (node) && DECL_ASSEMBLER_NAME_SET_P (node)) pp_tree_identifier (pp, DECL_ASSEMBLER_NAME_RAW (node)); /* For -fcompare-debug don't dump DECL_NAMELESS names at all, -g might have created more fancy names and their indexes could get out of sync. Usually those should be DECL_IGNORED_P too, SRA can create even non-DECL_IGNORED_P DECL_NAMELESS fancy names, let's hope those never get out of sync after doing the dump_fancy_name sanitization. */ else if ((flags & TDF_COMPARE_DEBUG) && DECL_NAMELESS (node) && DECL_IGNORED_P (node)) name = NULL_TREE; /* For DECL_NAMELESS names look for embedded uids in the names and sanitize them for TDF_NOUID. */ else if ((flags & TDF_NOUID) && DECL_NAMELESS (node)) dump_fancy_name (pp, name); else pp_tree_identifier (pp, name); } char uid_sep = (flags & TDF_GIMPLE) ? '_' : '.'; if ((flags & TDF_UID) || name == NULL_TREE) { if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1) pp_printf (pp, "L%c%d", uid_sep, (int) LABEL_DECL_UID (node)); else if (TREE_CODE (node) == DEBUG_EXPR_DECL) { if (flags & TDF_NOUID) pp_string (pp, "D#xxxx"); else pp_printf (pp, "D#%i", DEBUG_TEMP_UID (node)); } else { char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D'; if (flags & TDF_NOUID) pp_printf (pp, "%c.xxxx", c); else pp_printf (pp, "%c%c%u", c, uid_sep, DECL_UID (node)); } } if ((flags & TDF_ALIAS) && DECL_PT_UID (node) != DECL_UID (node)) { if (flags & TDF_NOUID) pp_printf (pp, "ptD.xxxx"); else pp_printf (pp, "ptD.%u", DECL_PT_UID (node)); } } /* Like the above, but used for pretty printing function calls. */ static void dump_function_name (pretty_printer *pp, tree node, dump_flags_t flags) { if (CONVERT_EXPR_P (node)) node = TREE_OPERAND (node, 0); if (DECL_NAME (node) && (flags & TDF_ASMNAME) == 0) pp_string (pp, lang_hooks.decl_printable_name (node, 1)); else dump_decl_name (pp, node, flags); } /* Dump a function declaration. NODE is the FUNCTION_TYPE. PP, SPC and FLAGS are as in dump_generic_node. */ static void dump_function_declaration (pretty_printer *pp, tree node, int spc, dump_flags_t flags) { bool wrote_arg = false; tree arg; pp_space (pp); pp_left_paren (pp); /* Print the argument types. */ arg = TYPE_ARG_TYPES (node); while (arg && arg != void_list_node && arg != error_mark_node) { if (wrote_arg) { pp_comma (pp); pp_space (pp); } wrote_arg = true; dump_generic_node (pp, TREE_VALUE (arg), spc, flags, false); arg = TREE_CHAIN (arg); } /* Drop the trailing void_type_node if we had any previous argument. */ if (arg == void_list_node && !wrote_arg) pp_string (pp, "void"); /* Properly dump vararg function types. */ else if (!arg && wrote_arg) pp_string (pp, ", ..."); /* Avoid printing any arg for unprototyped functions. */ pp_right_paren (pp); } /* Dump the domain associated with an array. */ static void dump_array_domain (pretty_printer *pp, tree domain, int spc, dump_flags_t flags) { pp_left_bracket (pp); if (domain) { tree min = TYPE_MIN_VALUE (domain); tree max = TYPE_MAX_VALUE (domain); if (min && max && integer_zerop (min) && tree_fits_shwi_p (max)) pp_wide_integer (pp, tree_to_shwi (max) + 1); else { if (min) dump_generic_node (pp, min, spc, flags, false); pp_colon (pp); if (max) dump_generic_node (pp, max, spc, flags, false); } } else pp_string (pp, ""); pp_right_bracket (pp); } /* Dump OpenMP iterators ITER. */ static void dump_omp_iterators (pretty_printer *pp, tree iter, int spc, dump_flags_t flags) { pp_string (pp, "iterator("); for (tree it = iter; it; it = TREE_CHAIN (it)) { if (it != iter) pp_string (pp, ", "); dump_generic_node (pp, TREE_TYPE (TREE_VEC_ELT (it, 0)), spc, flags, false); pp_space (pp); dump_generic_node (pp, TREE_VEC_ELT (it, 0), spc, flags, false); pp_equal (pp); dump_generic_node (pp, TREE_VEC_ELT (it, 1), spc, flags, false); pp_colon (pp); dump_generic_node (pp, TREE_VEC_ELT (it, 2), spc, flags, false); pp_colon (pp); dump_generic_node (pp, TREE_VEC_ELT (it, 3), spc, flags, false); } pp_right_paren (pp); } /* Dump OpenMP clause CLAUSE. PP, CLAUSE, SPC and FLAGS are as in dump_generic_node. */ static void dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) { const char *name; const char *modifier = NULL; switch (OMP_CLAUSE_CODE (clause)) { case OMP_CLAUSE_PRIVATE: name = "private"; goto print_remap; case OMP_CLAUSE_SHARED: name = "shared"; goto print_remap; case OMP_CLAUSE_FIRSTPRIVATE: name = "firstprivate"; goto print_remap; case OMP_CLAUSE_LASTPRIVATE: name = "lastprivate"; if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (clause)) modifier = "conditional:"; goto print_remap; case OMP_CLAUSE_COPYIN: name = "copyin"; goto print_remap; case OMP_CLAUSE_COPYPRIVATE: name = "copyprivate"; goto print_remap; case OMP_CLAUSE_UNIFORM: name = "uniform"; goto print_remap; case OMP_CLAUSE_USE_DEVICE_PTR: name = "use_device_ptr"; if (OMP_CLAUSE_USE_DEVICE_PTR_IF_PRESENT (clause)) modifier = "if_present:"; goto print_remap; case OMP_CLAUSE_USE_DEVICE_ADDR: name = "use_device_addr"; goto print_remap; case OMP_CLAUSE_IS_DEVICE_PTR: name = "is_device_ptr"; goto print_remap; case OMP_CLAUSE_INCLUSIVE: name = "inclusive"; goto print_remap; case OMP_CLAUSE_EXCLUSIVE: name = "exclusive"; goto print_remap; case OMP_CLAUSE__LOOPTEMP_: name = "_looptemp_"; goto print_remap; case OMP_CLAUSE__REDUCTEMP_: name = "_reductemp_"; goto print_remap; case OMP_CLAUSE__CONDTEMP_: name = "_condtemp_"; goto print_remap; case OMP_CLAUSE__SCANTEMP_: name = "_scantemp_"; goto print_remap; case OMP_CLAUSE_TO_DECLARE: name = "to"; goto print_remap; case OMP_CLAUSE_LINK: name = "link"; goto print_remap; case OMP_CLAUSE_NONTEMPORAL: name = "nontemporal"; goto print_remap; print_remap: pp_string (pp, name); pp_left_paren (pp); if (modifier) pp_string (pp, modifier); dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_TASK_REDUCTION: case OMP_CLAUSE_IN_REDUCTION: pp_string (pp, OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_IN_REDUCTION ? "in_" : "task_"); /* FALLTHRU */ case OMP_CLAUSE_REDUCTION: pp_string (pp, "reduction("); if (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_REDUCTION) { if (OMP_CLAUSE_REDUCTION_TASK (clause)) pp_string (pp, "task,"); else if (OMP_CLAUSE_REDUCTION_INSCAN (clause)) pp_string (pp, "inscan,"); } if (OMP_CLAUSE_REDUCTION_CODE (clause) != ERROR_MARK) { pp_string (pp, op_symbol_code (OMP_CLAUSE_REDUCTION_CODE (clause))); pp_colon (pp); } dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_IF: pp_string (pp, "if("); switch (OMP_CLAUSE_IF_MODIFIER (clause)) { case ERROR_MARK: break; case VOID_CST: pp_string (pp, "cancel:"); break; case OMP_PARALLEL: pp_string (pp, "parallel:"); break; case OMP_SIMD: pp_string (pp, "simd:"); break; case OMP_TASK: pp_string (pp, "task:"); break; case OMP_TASKLOOP: pp_string (pp, "taskloop:"); break; case OMP_TARGET_DATA: pp_string (pp, "target data:"); break; case OMP_TARGET: pp_string (pp, "target:"); break; case OMP_TARGET_UPDATE: pp_string (pp, "target update:"); break; case OMP_TARGET_ENTER_DATA: pp_string (pp, "target enter data:"); break; case OMP_TARGET_EXIT_DATA: pp_string (pp, "target exit data:"); break; default: gcc_unreachable (); } dump_generic_node (pp, OMP_CLAUSE_IF_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_NUM_THREADS: pp_string (pp, "num_threads("); dump_generic_node (pp, OMP_CLAUSE_NUM_THREADS_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_NOWAIT: pp_string (pp, "nowait"); break; case OMP_CLAUSE_ORDERED: pp_string (pp, "ordered"); if (OMP_CLAUSE_ORDERED_EXPR (clause)) { pp_left_paren (pp); dump_generic_node (pp, OMP_CLAUSE_ORDERED_EXPR (clause), spc, flags, false); pp_right_paren (pp); } break; case OMP_CLAUSE_DEFAULT: pp_string (pp, "default("); switch (OMP_CLAUSE_DEFAULT_KIND (clause)) { case OMP_CLAUSE_DEFAULT_UNSPECIFIED: break; case OMP_CLAUSE_DEFAULT_SHARED: pp_string (pp, "shared"); break; case OMP_CLAUSE_DEFAULT_NONE: pp_string (pp, "none"); break; case OMP_CLAUSE_DEFAULT_PRIVATE: pp_string (pp, "private"); break; case OMP_CLAUSE_DEFAULT_FIRSTPRIVATE: pp_string (pp, "firstprivate"); break; case OMP_CLAUSE_DEFAULT_PRESENT: pp_string (pp, "present"); break; default: gcc_unreachable (); } pp_right_paren (pp); break; case OMP_CLAUSE_SCHEDULE: pp_string (pp, "schedule("); if (OMP_CLAUSE_SCHEDULE_KIND (clause) & (OMP_CLAUSE_SCHEDULE_MONOTONIC | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) { if (OMP_CLAUSE_SCHEDULE_KIND (clause) & OMP_CLAUSE_SCHEDULE_MONOTONIC) pp_string (pp, "monotonic"); else pp_string (pp, "nonmonotonic"); if (OMP_CLAUSE_SCHEDULE_SIMD (clause)) pp_comma (pp); else pp_colon (pp); } if (OMP_CLAUSE_SCHEDULE_SIMD (clause)) pp_string (pp, "simd:"); switch (OMP_CLAUSE_SCHEDULE_KIND (clause) & OMP_CLAUSE_SCHEDULE_MASK) { case OMP_CLAUSE_SCHEDULE_STATIC: pp_string (pp, "static"); break; case OMP_CLAUSE_SCHEDULE_DYNAMIC: pp_string (pp, "dynamic"); break; case OMP_CLAUSE_SCHEDULE_GUIDED: pp_string (pp, "guided"); break; case OMP_CLAUSE_SCHEDULE_RUNTIME: pp_string (pp, "runtime"); break; case OMP_CLAUSE_SCHEDULE_AUTO: pp_string (pp, "auto"); break; default: gcc_unreachable (); } if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause)) { pp_comma (pp); dump_generic_node (pp, OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause), spc, flags, false); } pp_right_paren (pp); break; case OMP_CLAUSE_UNTIED: pp_string (pp, "untied"); break; case OMP_CLAUSE_COLLAPSE: pp_string (pp, "collapse("); dump_generic_node (pp, OMP_CLAUSE_COLLAPSE_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_FINAL: pp_string (pp, "final("); dump_generic_node (pp, OMP_CLAUSE_FINAL_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_MERGEABLE: pp_string (pp, "mergeable"); break; case OMP_CLAUSE_LINEAR: pp_string (pp, "linear("); switch (OMP_CLAUSE_LINEAR_KIND (clause)) { case OMP_CLAUSE_LINEAR_DEFAULT: break; case OMP_CLAUSE_LINEAR_REF: pp_string (pp, "ref("); break; case OMP_CLAUSE_LINEAR_VAL: pp_string (pp, "val("); break; case OMP_CLAUSE_LINEAR_UVAL: pp_string (pp, "uval("); break; default: gcc_unreachable (); } dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); if (OMP_CLAUSE_LINEAR_KIND (clause) != OMP_CLAUSE_LINEAR_DEFAULT) pp_right_paren (pp); pp_colon (pp); dump_generic_node (pp, OMP_CLAUSE_LINEAR_STEP (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_ALIGNED: pp_string (pp, "aligned("); dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause)) { pp_colon (pp); dump_generic_node (pp, OMP_CLAUSE_ALIGNED_ALIGNMENT (clause), spc, flags, false); } pp_right_paren (pp); break; case OMP_CLAUSE_ALLOCATE: pp_string (pp, "allocate("); if (OMP_CLAUSE_ALLOCATE_ALLOCATOR (clause)) { dump_generic_node (pp, OMP_CLAUSE_ALLOCATE_ALLOCATOR (clause), spc, flags, false); pp_colon (pp); } dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_DEPEND: pp_string (pp, "depend("); switch (OMP_CLAUSE_DEPEND_KIND (clause)) { case OMP_CLAUSE_DEPEND_DEPOBJ: name = "depobj"; break; case OMP_CLAUSE_DEPEND_IN: name = "in"; break; case OMP_CLAUSE_DEPEND_OUT: name = "out"; break; case OMP_CLAUSE_DEPEND_INOUT: name = "inout"; break; case OMP_CLAUSE_DEPEND_MUTEXINOUTSET: name = "mutexinoutset"; break; case OMP_CLAUSE_DEPEND_SOURCE: pp_string (pp, "source)"); return; case OMP_CLAUSE_DEPEND_LAST: name = "__internal__"; break; case OMP_CLAUSE_DEPEND_SINK: pp_string (pp, "sink:"); for (tree t = OMP_CLAUSE_DECL (clause); t; t = TREE_CHAIN (t)) if (TREE_CODE (t) == TREE_LIST) { dump_generic_node (pp, TREE_VALUE (t), spc, flags, false); if (TREE_PURPOSE (t) != integer_zero_node) { if (OMP_CLAUSE_DEPEND_SINK_NEGATIVE (t)) pp_minus (pp); else pp_plus (pp); dump_generic_node (pp, TREE_PURPOSE (t), spc, flags, false); } if (TREE_CHAIN (t)) pp_comma (pp); } else gcc_unreachable (); pp_right_paren (pp); return; default: gcc_unreachable (); } { tree t = OMP_CLAUSE_DECL (clause); if (TREE_CODE (t) == TREE_LIST && TREE_PURPOSE (t) && TREE_CODE (TREE_PURPOSE (t)) == TREE_VEC) { dump_omp_iterators (pp, TREE_PURPOSE (t), spc, flags); pp_colon (pp); t = TREE_VALUE (t); } pp_string (pp, name); pp_colon (pp); dump_generic_node (pp, t, spc, flags, false); pp_right_paren (pp); } break; case OMP_CLAUSE_MAP: pp_string (pp, "map("); switch (OMP_CLAUSE_MAP_KIND (clause)) { case GOMP_MAP_ALLOC: case GOMP_MAP_POINTER: pp_string (pp, "alloc"); break; case GOMP_MAP_IF_PRESENT: pp_string (pp, "no_alloc"); break; case GOMP_MAP_TO: case GOMP_MAP_TO_PSET: pp_string (pp, "to"); break; case GOMP_MAP_FROM: pp_string (pp, "from"); break; case GOMP_MAP_TOFROM: pp_string (pp, "tofrom"); break; case GOMP_MAP_FORCE_ALLOC: pp_string (pp, "force_alloc"); break; case GOMP_MAP_FORCE_TO: pp_string (pp, "force_to"); break; case GOMP_MAP_FORCE_FROM: pp_string (pp, "force_from"); break; case GOMP_MAP_FORCE_TOFROM: pp_string (pp, "force_tofrom"); break; case GOMP_MAP_FORCE_PRESENT: pp_string (pp, "force_present"); break; case GOMP_MAP_DELETE: pp_string (pp, "delete"); break; case GOMP_MAP_FORCE_DEVICEPTR: pp_string (pp, "force_deviceptr"); break; case GOMP_MAP_ALWAYS_TO: pp_string (pp, "always,to"); break; case GOMP_MAP_ALWAYS_FROM: pp_string (pp, "always,from"); break; case GOMP_MAP_ALWAYS_TOFROM: pp_string (pp, "always,tofrom"); break; case GOMP_MAP_RELEASE: pp_string (pp, "release"); break; case GOMP_MAP_FIRSTPRIVATE_POINTER: pp_string (pp, "firstprivate"); break; case GOMP_MAP_FIRSTPRIVATE_REFERENCE: pp_string (pp, "firstprivate ref"); break; case GOMP_MAP_STRUCT: pp_string (pp, "struct"); break; case GOMP_MAP_ALWAYS_POINTER: pp_string (pp, "always_pointer"); break; case GOMP_MAP_DEVICE_RESIDENT: pp_string (pp, "device_resident"); break; case GOMP_MAP_LINK: pp_string (pp, "link"); break; case GOMP_MAP_ATTACH: pp_string (pp, "attach"); break; case GOMP_MAP_DETACH: pp_string (pp, "detach"); break; case GOMP_MAP_FORCE_DETACH: pp_string (pp, "force_detach"); break; case GOMP_MAP_ATTACH_DETACH: pp_string (pp, "attach_detach"); break; default: gcc_unreachable (); } pp_colon (pp); dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); print_clause_size: if (OMP_CLAUSE_SIZE (clause)) { switch (OMP_CLAUSE_CODE (clause) == OMP_CLAUSE_MAP ? OMP_CLAUSE_MAP_KIND (clause) : GOMP_MAP_TO) { case GOMP_MAP_POINTER: case GOMP_MAP_FIRSTPRIVATE_POINTER: case GOMP_MAP_FIRSTPRIVATE_REFERENCE: case GOMP_MAP_ALWAYS_POINTER: pp_string (pp, " [pointer assign, bias: "); break; case GOMP_MAP_TO_PSET: pp_string (pp, " [pointer set, len: "); break; case GOMP_MAP_ATTACH: case GOMP_MAP_DETACH: case GOMP_MAP_FORCE_DETACH: case GOMP_MAP_ATTACH_DETACH: pp_string (pp, " [bias: "); break; default: pp_string (pp, " [len: "); break; } dump_generic_node (pp, OMP_CLAUSE_SIZE (clause), spc, flags, false); pp_right_bracket (pp); } pp_right_paren (pp); break; case OMP_CLAUSE_FROM: pp_string (pp, "from("); dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); goto print_clause_size; case OMP_CLAUSE_TO: pp_string (pp, "to("); dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); goto print_clause_size; case OMP_CLAUSE__CACHE_: pp_string (pp, "("); dump_generic_node (pp, OMP_CLAUSE_DECL (clause), spc, flags, false); goto print_clause_size; case OMP_CLAUSE_NUM_TEAMS: pp_string (pp, "num_teams("); dump_generic_node (pp, OMP_CLAUSE_NUM_TEAMS_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_THREAD_LIMIT: pp_string (pp, "thread_limit("); dump_generic_node (pp, OMP_CLAUSE_THREAD_LIMIT_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_DEVICE: pp_string (pp, "device("); dump_generic_node (pp, OMP_CLAUSE_DEVICE_ID (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_DIST_SCHEDULE: pp_string (pp, "dist_schedule(static"); if (OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause)) { pp_comma (pp); dump_generic_node (pp, OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (clause), spc, flags, false); } pp_right_paren (pp); break; case OMP_CLAUSE_PROC_BIND: pp_string (pp, "proc_bind("); switch (OMP_CLAUSE_PROC_BIND_KIND (clause)) { case OMP_CLAUSE_PROC_BIND_MASTER: pp_string (pp, "master"); break; case OMP_CLAUSE_PROC_BIND_CLOSE: pp_string (pp, "close"); break; case OMP_CLAUSE_PROC_BIND_SPREAD: pp_string (pp, "spread"); break; default: gcc_unreachable (); } pp_right_paren (pp); break; case OMP_CLAUSE_DEVICE_TYPE: pp_string (pp, "device_type("); switch (OMP_CLAUSE_DEVICE_TYPE_KIND (clause)) { case OMP_CLAUSE_DEVICE_TYPE_HOST: pp_string (pp, "host"); break; case OMP_CLAUSE_DEVICE_TYPE_NOHOST: pp_string (pp, "nohost"); break; case OMP_CLAUSE_DEVICE_TYPE_ANY: pp_string (pp, "any"); break; default: gcc_unreachable (); } pp_right_paren (pp); break; case OMP_CLAUSE_SAFELEN: pp_string (pp, "safelen("); dump_generic_node (pp, OMP_CLAUSE_SAFELEN_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_SIMDLEN: pp_string (pp, "simdlen("); dump_generic_node (pp, OMP_CLAUSE_SIMDLEN_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_PRIORITY: pp_string (pp, "priority("); dump_generic_node (pp, OMP_CLAUSE_PRIORITY_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_GRAINSIZE: pp_string (pp, "grainsize("); dump_generic_node (pp, OMP_CLAUSE_GRAINSIZE_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_NUM_TASKS: pp_string (pp, "num_tasks("); dump_generic_node (pp, OMP_CLAUSE_NUM_TASKS_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_HINT: pp_string (pp, "hint("); dump_generic_node (pp, OMP_CLAUSE_HINT_EXPR (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_DEFAULTMAP: pp_string (pp, "defaultmap("); switch (OMP_CLAUSE_DEFAULTMAP_BEHAVIOR (clause)) { case OMP_CLAUSE_DEFAULTMAP_ALLOC: pp_string (pp, "alloc"); break; case OMP_CLAUSE_DEFAULTMAP_TO: pp_string (pp, "to"); break; case OMP_CLAUSE_DEFAULTMAP_FROM: pp_string (pp, "from"); break; case OMP_CLAUSE_DEFAULTMAP_TOFROM: pp_string (pp, "tofrom"); break; case OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE: pp_string (pp, "firstprivate"); break; case OMP_CLAUSE_DEFAULTMAP_NONE: pp_string (pp, "none"); break; case OMP_CLAUSE_DEFAULTMAP_DEFAULT: pp_string (pp, "default"); break; default: gcc_unreachable (); } switch (OMP_CLAUSE_DEFAULTMAP_CATEGORY (clause)) { case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED: break; case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR: pp_string (pp, ":scalar"); break; case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE: pp_string (pp, ":aggregate"); break; case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALLOCATABLE: pp_string (pp, ":allocatable"); break; case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER: pp_string (pp, ":pointer"); break; default: gcc_unreachable (); } pp_right_paren (pp); break; case OMP_CLAUSE_ORDER: pp_string (pp, "order(concurrent)"); break; case OMP_CLAUSE_BIND: pp_string (pp, "bind("); switch (OMP_CLAUSE_BIND_KIND (clause)) { case OMP_CLAUSE_BIND_TEAMS: pp_string (pp, "teams"); break; case OMP_CLAUSE_BIND_PARALLEL: pp_string (pp, "parallel"); break; case OMP_CLAUSE_BIND_THREAD: pp_string (pp, "thread"); break; default: gcc_unreachable (); } pp_right_paren (pp); break; case OMP_CLAUSE__SIMDUID_: pp_string (pp, "_simduid_("); dump_generic_node (pp, OMP_CLAUSE__SIMDUID__DECL (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE__SIMT_: pp_string (pp, "_simt_"); break; case OMP_CLAUSE_GANG: pp_string (pp, "gang"); if (OMP_CLAUSE_GANG_EXPR (clause) != NULL_TREE) { pp_string (pp, "(num: "); dump_generic_node (pp, OMP_CLAUSE_GANG_EXPR (clause), spc, flags, false); } if (OMP_CLAUSE_GANG_STATIC_EXPR (clause) != NULL_TREE) { if (OMP_CLAUSE_GANG_EXPR (clause) == NULL_TREE) pp_left_paren (pp); else pp_space (pp); pp_string (pp, "static:"); if (OMP_CLAUSE_GANG_STATIC_EXPR (clause) == integer_minus_one_node) pp_character (pp, '*'); else dump_generic_node (pp, OMP_CLAUSE_GANG_STATIC_EXPR (clause), spc, flags, false); } if (OMP_CLAUSE_GANG_EXPR (clause) != NULL_TREE || OMP_CLAUSE_GANG_STATIC_EXPR (clause) != NULL_TREE) pp_right_paren (pp); break; case OMP_CLAUSE_ASYNC: pp_string (pp, "async"); if (OMP_CLAUSE_ASYNC_EXPR (clause)) { pp_character(pp, '('); dump_generic_node (pp, OMP_CLAUSE_ASYNC_EXPR (clause), spc, flags, false); pp_character(pp, ')'); } break; case OMP_CLAUSE_AUTO: case OMP_CLAUSE_SEQ: pp_string (pp, omp_clause_code_name[OMP_CLAUSE_CODE (clause)]); break; case OMP_CLAUSE_WAIT: pp_string (pp, "wait("); dump_generic_node (pp, OMP_CLAUSE_WAIT_EXPR (clause), spc, flags, false); pp_character(pp, ')'); break; case OMP_CLAUSE_WORKER: pp_string (pp, "worker"); if (OMP_CLAUSE_WORKER_EXPR (clause) != NULL_TREE) { pp_left_paren (pp); dump_generic_node (pp, OMP_CLAUSE_WORKER_EXPR (clause), spc, flags, false); pp_right_paren (pp); } break; case OMP_CLAUSE_VECTOR: pp_string (pp, "vector"); if (OMP_CLAUSE_VECTOR_EXPR (clause) != NULL_TREE) { pp_left_paren (pp); dump_generic_node (pp, OMP_CLAUSE_VECTOR_EXPR (clause), spc, flags, false); pp_right_paren (pp); } break; case OMP_CLAUSE_NUM_GANGS: pp_string (pp, "num_gangs("); dump_generic_node (pp, OMP_CLAUSE_NUM_GANGS_EXPR (clause), spc, flags, false); pp_character (pp, ')'); break; case OMP_CLAUSE_NUM_WORKERS: pp_string (pp, "num_workers("); dump_generic_node (pp, OMP_CLAUSE_NUM_WORKERS_EXPR (clause), spc, flags, false); pp_character (pp, ')'); break; case OMP_CLAUSE_VECTOR_LENGTH: pp_string (pp, "vector_length("); dump_generic_node (pp, OMP_CLAUSE_VECTOR_LENGTH_EXPR (clause), spc, flags, false); pp_character (pp, ')'); break; case OMP_CLAUSE_INBRANCH: pp_string (pp, "inbranch"); break; case OMP_CLAUSE_NOTINBRANCH: pp_string (pp, "notinbranch"); break; case OMP_CLAUSE_FOR: pp_string (pp, "for"); break; case OMP_CLAUSE_PARALLEL: pp_string (pp, "parallel"); break; case OMP_CLAUSE_SECTIONS: pp_string (pp, "sections"); break; case OMP_CLAUSE_TASKGROUP: pp_string (pp, "taskgroup"); break; case OMP_CLAUSE_NOGROUP: pp_string (pp, "nogroup"); break; case OMP_CLAUSE_THREADS: pp_string (pp, "threads"); break; case OMP_CLAUSE_SIMD: pp_string (pp, "simd"); break; case OMP_CLAUSE_INDEPENDENT: pp_string (pp, "independent"); break; case OMP_CLAUSE_TILE: pp_string (pp, "tile("); dump_generic_node (pp, OMP_CLAUSE_TILE_LIST (clause), spc, flags, false); pp_right_paren (pp); break; case OMP_CLAUSE_IF_PRESENT: pp_string (pp, "if_present"); break; case OMP_CLAUSE_FINALIZE: pp_string (pp, "finalize"); break; default: gcc_unreachable (); } } /* Dump the list of OpenMP clauses. PP, SPC and FLAGS are as in dump_generic_node. */ void dump_omp_clauses (pretty_printer *pp, tree clause, int spc, dump_flags_t flags) { if (clause == NULL) return; pp_space (pp); while (1) { dump_omp_clause (pp, clause, spc, flags); clause = OMP_CLAUSE_CHAIN (clause); if (clause == NULL) return; pp_space (pp); } } /* Dump location LOC to PP. */ void dump_location (pretty_printer *pp, location_t loc) { expanded_location xloc = expand_location (loc); pp_left_bracket (pp); if (xloc.file) { pp_string (pp, xloc.file); pp_string (pp, ":"); } pp_decimal_int (pp, xloc.line); pp_colon (pp); pp_decimal_int (pp, xloc.column); pp_string (pp, "] "); } /* Dump lexical block BLOCK. PP, SPC and FLAGS are as in dump_generic_node. */ static void dump_block_node (pretty_printer *pp, tree block, int spc, dump_flags_t flags) { tree t; pp_printf (pp, "BLOCK #%d ", BLOCK_NUMBER (block)); if (flags & TDF_ADDRESS) pp_printf (pp, "[%p] ", (void *) block); if (TREE_ASM_WRITTEN (block)) pp_string (pp, "[written] "); if (flags & TDF_SLIM) return; if (BLOCK_SOURCE_LOCATION (block)) dump_location (pp, BLOCK_SOURCE_LOCATION (block)); newline_and_indent (pp, spc + 2); if (BLOCK_SUPERCONTEXT (block)) { pp_string (pp, "SUPERCONTEXT: "); dump_generic_node (pp, BLOCK_SUPERCONTEXT (block), 0, flags | TDF_SLIM, false); newline_and_indent (pp, spc + 2); } if (BLOCK_SUBBLOCKS (block)) { pp_string (pp, "SUBBLOCKS: "); for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t)) { dump_generic_node (pp, t, 0, flags | TDF_SLIM, false); pp_space (pp); } newline_and_indent (pp, spc + 2); } if (BLOCK_CHAIN (block)) { pp_string (pp, "SIBLINGS: "); for (t = BLOCK_CHAIN (block); t; t = BLOCK_CHAIN (t)) { dump_generic_node (pp, t, 0, flags | TDF_SLIM, false); pp_space (pp); } newline_and_indent (pp, spc + 2); } if (BLOCK_VARS (block)) { pp_string (pp, "VARS: "); for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t)) { dump_generic_node (pp, t, 0, flags, false); pp_space (pp); } newline_and_indent (pp, spc + 2); } if (vec_safe_length (BLOCK_NONLOCALIZED_VARS (block)) > 0) { unsigned i; vec *nlv = BLOCK_NONLOCALIZED_VARS (block); pp_string (pp, "NONLOCALIZED_VARS: "); FOR_EACH_VEC_ELT (*nlv, i, t) { dump_generic_node (pp, t, 0, flags, false); pp_space (pp); } newline_and_indent (pp, spc + 2); } if (BLOCK_ABSTRACT_ORIGIN (block)) { pp_string (pp, "ABSTRACT_ORIGIN: "); dump_generic_node (pp, BLOCK_ABSTRACT_ORIGIN (block), 0, flags | TDF_SLIM, false); newline_and_indent (pp, spc + 2); } if (BLOCK_FRAGMENT_ORIGIN (block)) { pp_string (pp, "FRAGMENT_ORIGIN: "); dump_generic_node (pp, BLOCK_FRAGMENT_ORIGIN (block), 0, flags | TDF_SLIM, false); newline_and_indent (pp, spc + 2); } if (BLOCK_FRAGMENT_CHAIN (block)) { pp_string (pp, "FRAGMENT_CHAIN: "); for (t = BLOCK_FRAGMENT_CHAIN (block); t; t = BLOCK_FRAGMENT_CHAIN (t)) { dump_generic_node (pp, t, 0, flags | TDF_SLIM, false); pp_space (pp); } newline_and_indent (pp, spc + 2); } } /* Dump #pragma omp atomic memory order clause. */ void dump_omp_atomic_memory_order (pretty_printer *pp, enum omp_memory_order mo) { switch (mo) { case OMP_MEMORY_ORDER_RELAXED: pp_string (pp, " relaxed"); break; case OMP_MEMORY_ORDER_SEQ_CST: pp_string (pp, " seq_cst"); break; case OMP_MEMORY_ORDER_ACQ_REL: pp_string (pp, " acq_rel"); break; case OMP_MEMORY_ORDER_ACQUIRE: pp_string (pp, " acquire"); break; case OMP_MEMORY_ORDER_RELEASE: pp_string (pp, " release"); break; case OMP_MEMORY_ORDER_UNSPECIFIED: break; default: gcc_unreachable (); } } /* Helper to dump a MEM_REF node. */ static void dump_mem_ref (pretty_printer *pp, tree node, int spc, dump_flags_t flags) { if (TREE_CODE (node) == MEM_REF && (flags & TDF_GIMPLE)) { pp_string (pp, "__MEM <"); dump_generic_node (pp, TREE_TYPE (node), spc, flags | TDF_SLIM, false); if (TYPE_ALIGN (TREE_TYPE (node)) != TYPE_ALIGN (TYPE_MAIN_VARIANT (TREE_TYPE (node)))) { pp_string (pp, ", "); pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (node))); } pp_greater (pp); pp_string (pp, " ("); if (TREE_TYPE (TREE_OPERAND (node, 0)) != TREE_TYPE (TREE_OPERAND (node, 1))) { pp_left_paren (pp); dump_generic_node (pp, TREE_TYPE (TREE_OPERAND (node, 1)), spc, flags | TDF_SLIM, false); pp_right_paren (pp); } dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags | TDF_SLIM, false); if (! integer_zerop (TREE_OPERAND (node, 1))) { pp_string (pp, " + "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags | TDF_SLIM, false); } pp_right_paren (pp); } else if (TREE_CODE (node) == MEM_REF && integer_zerop (TREE_OPERAND (node, 1)) /* Dump the types of INTEGER_CSTs explicitly, for we can't infer them and MEM_ATTR caching will share MEM_REFs with differently-typed op0s. */ && TREE_CODE (TREE_OPERAND (node, 0)) != INTEGER_CST /* Released SSA_NAMES have no TREE_TYPE. */ && TREE_TYPE (TREE_OPERAND (node, 0)) != NULL_TREE /* Same pointer types, but ignoring POINTER_TYPE vs. REFERENCE_TYPE. */ && (TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 0))) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1)))) && (TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 0))) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (node, 1)))) && (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 0))) == TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (node, 1)))) /* Same value types ignoring qualifiers. */ && (TYPE_MAIN_VARIANT (TREE_TYPE (node)) == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (node, 1))))) && (!(flags & TDF_ALIAS) || MR_DEPENDENCE_CLIQUE (node) == 0)) { if (TREE_CODE (TREE_OPERAND (node, 0)) != ADDR_EXPR) { /* Enclose pointers to arrays in parentheses. */ tree op0 = TREE_OPERAND (node, 0); tree op0type = TREE_TYPE (op0); if (POINTER_TYPE_P (op0type) && TREE_CODE (TREE_TYPE (op0type)) == ARRAY_TYPE) pp_left_paren (pp); pp_star (pp); dump_generic_node (pp, op0, spc, flags, false); if (POINTER_TYPE_P (op0type) && TREE_CODE (TREE_TYPE (op0type)) == ARRAY_TYPE) pp_right_paren (pp); } else dump_generic_node (pp, TREE_OPERAND (TREE_OPERAND (node, 0), 0), spc, flags, false); } else { pp_string (pp, "MEM"); tree nodetype = TREE_TYPE (node); tree op0 = TREE_OPERAND (node, 0); tree op1 = TREE_OPERAND (node, 1); tree op1type = TYPE_MAIN_VARIANT (TREE_TYPE (op1)); tree op0size = TYPE_SIZE (nodetype); tree op1size = TYPE_SIZE (TREE_TYPE (op1type)); if (!op0size || !op1size || !operand_equal_p (op0size, op1size, 0)) { pp_string (pp, " <"); /* If the size of the type of the operand is not the same as the size of the MEM_REF expression include the type of the latter similar to the TDF_GIMPLE output to make it clear how many bytes of memory are being accessed. */ dump_generic_node (pp, nodetype, spc, flags | TDF_SLIM, false); pp_string (pp, "> "); } pp_string (pp, "[("); dump_generic_node (pp, op1type, spc, flags | TDF_SLIM, false); pp_right_paren (pp); dump_generic_node (pp, op0, spc, flags, false); if (!integer_zerop (op1)) { pp_string (pp, " + "); dump_generic_node (pp, op1, spc, flags, false); } if (TREE_CODE (node) == TARGET_MEM_REF) { tree tmp = TMR_INDEX2 (node); if (tmp) { pp_string (pp, " + "); dump_generic_node (pp, tmp, spc, flags, false); } tmp = TMR_INDEX (node); if (tmp) { pp_string (pp, " + "); dump_generic_node (pp, tmp, spc, flags, false); tmp = TMR_STEP (node); pp_string (pp, " * "); if (tmp) dump_generic_node (pp, tmp, spc, flags, false); else pp_string (pp, "1"); } } if ((flags & TDF_ALIAS) && MR_DEPENDENCE_CLIQUE (node) != 0) { pp_string (pp, " clique "); pp_unsigned_wide_integer (pp, MR_DEPENDENCE_CLIQUE (node)); pp_string (pp, " base "); pp_unsigned_wide_integer (pp, MR_DEPENDENCE_BASE (node)); } pp_right_bracket (pp); } } /* Helper function for dump_generic_node. Dump INIT or COND expression for OpenMP loop non-rectangular iterators. */ void dump_omp_loop_non_rect_expr (pretty_printer *pp, tree node, int spc, dump_flags_t flags) { gcc_assert (TREE_CODE (node) == TREE_VEC); dump_generic_node (pp, TREE_VEC_ELT (node, 0), spc, flags, false); pp_string (pp, " * "); if (op_prio (TREE_VEC_ELT (node, 1)) <= op_code_prio (MULT_EXPR)) { pp_left_paren (pp); dump_generic_node (pp, TREE_VEC_ELT (node, 1), spc, flags, false); pp_right_paren (pp); } else dump_generic_node (pp, TREE_VEC_ELT (node, 1), spc, flags, false); pp_string (pp, " + "); if (op_prio (TREE_VEC_ELT (node, 1)) <= op_code_prio (PLUS_EXPR)) { pp_left_paren (pp); dump_generic_node (pp, TREE_VEC_ELT (node, 2), spc, flags, false); pp_right_paren (pp); } else dump_generic_node (pp, TREE_VEC_ELT (node, 2), spc, flags, false); } /* Dump the node NODE on the pretty_printer PP, SPC spaces of indent. FLAGS specifies details to show in the dump (see TDF_* in dumpfile.h). If IS_STMT is true, the object printed is considered to be a statement and it is terminated by ';' if appropriate. */ int dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags, bool is_stmt) { tree type; tree op0, op1; const char *str; bool is_expr; enum tree_code code; if (node == NULL_TREE) return spc; is_expr = EXPR_P (node); if (is_stmt && (flags & TDF_STMTADDR)) pp_printf (pp, "<&%p> ", (void *)node); if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node)) dump_location (pp, EXPR_LOCATION (node)); code = TREE_CODE (node); switch (code) { case ERROR_MARK: pp_string (pp, "<<< error >>>"); break; case IDENTIFIER_NODE: pp_tree_identifier (pp, node); break; case TREE_LIST: while (node && node != error_mark_node) { if (TREE_PURPOSE (node)) { dump_generic_node (pp, TREE_PURPOSE (node), spc, flags, false); pp_space (pp); } dump_generic_node (pp, TREE_VALUE (node), spc, flags, false); node = TREE_CHAIN (node); if (node && TREE_CODE (node) == TREE_LIST) { pp_comma (pp); pp_space (pp); } } break; case TREE_BINFO: dump_generic_node (pp, BINFO_TYPE (node), spc, flags, false); break; case TREE_VEC: { size_t i; if (TREE_VEC_LENGTH (node) > 0) { size_t len = TREE_VEC_LENGTH (node); for (i = 0; i < len - 1; i++) { dump_generic_node (pp, TREE_VEC_ELT (node, i), spc, flags, false); pp_comma (pp); pp_space (pp); } dump_generic_node (pp, TREE_VEC_ELT (node, len - 1), spc, flags, false); } } break; case VOID_TYPE: case INTEGER_TYPE: case REAL_TYPE: case FIXED_POINT_TYPE: case COMPLEX_TYPE: case VECTOR_TYPE: case ENUMERAL_TYPE: case BOOLEAN_TYPE: case OPAQUE_TYPE: { unsigned int quals = TYPE_QUALS (node); enum tree_code_class tclass; if (quals & TYPE_QUAL_ATOMIC) pp_string (pp, "atomic "); if (quals & TYPE_QUAL_CONST) pp_string (pp, "const "); if (quals & TYPE_QUAL_VOLATILE) pp_string (pp, "volatile "); if (quals & TYPE_QUAL_RESTRICT) pp_string (pp, "restrict "); if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node))) { pp_string (pp, " "); } tclass = TREE_CODE_CLASS (TREE_CODE (node)); if (tclass == tcc_declaration) { if (DECL_NAME (node)) dump_decl_name (pp, node, flags); else pp_string (pp, ""); } else if (tclass == tcc_type) { if (TYPE_NAME (node)) { if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE) pp_tree_identifier (pp, TYPE_NAME (node)); else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL && DECL_NAME (TYPE_NAME (node))) dump_decl_name (pp, TYPE_NAME (node), flags); else pp_string (pp, ""); } else if (TREE_CODE (node) == VECTOR_TYPE) { pp_string (pp, "vector"); pp_left_paren (pp); pp_wide_integer (pp, TYPE_VECTOR_SUBPARTS (node)); pp_string (pp, ") "); dump_generic_node (pp, TREE_TYPE (node), spc, flags, false); } else if (TREE_CODE (node) == INTEGER_TYPE) { if (TYPE_PRECISION (node) == CHAR_TYPE_SIZE) pp_string (pp, (TYPE_UNSIGNED (node) ? "unsigned char" : "signed char")); else if (TYPE_PRECISION (node) == SHORT_TYPE_SIZE) pp_string (pp, (TYPE_UNSIGNED (node) ? "unsigned short" : "signed short")); else if (TYPE_PRECISION (node) == INT_TYPE_SIZE) pp_string (pp, (TYPE_UNSIGNED (node) ? "unsigned int" : "signed int")); else if (TYPE_PRECISION (node) == LONG_TYPE_SIZE) pp_string (pp, (TYPE_UNSIGNED (node) ? "unsigned long" : "signed long")); else if (TYPE_PRECISION (node) == LONG_LONG_TYPE_SIZE) pp_string (pp, (TYPE_UNSIGNED (node) ? "unsigned long long" : "signed long long")); else if (TYPE_PRECISION (node) >= CHAR_TYPE_SIZE && pow2p_hwi (TYPE_PRECISION (node))) { pp_string (pp, (TYPE_UNSIGNED (node) ? "uint" : "int")); pp_decimal_int (pp, TYPE_PRECISION (node)); pp_string (pp, "_t"); } else { pp_string (pp, (TYPE_UNSIGNED (node) ? ""); } break; } case POINTER_TYPE: case REFERENCE_TYPE: str = (TREE_CODE (node) == POINTER_TYPE ? "*" : "&"); if (TREE_TYPE (node) == NULL) { pp_string (pp, str); pp_string (pp, ""); } else if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE) { tree fnode = TREE_TYPE (node); dump_generic_node (pp, TREE_TYPE (fnode), spc, flags, false); pp_space (pp); pp_left_paren (pp); pp_string (pp, str); if (TYPE_IDENTIFIER (node)) dump_generic_node (pp, TYPE_NAME (node), spc, flags, false); else if (flags & TDF_NOUID) pp_printf (pp, ""); else pp_printf (pp, "", TYPE_UID (node)); pp_right_paren (pp); dump_function_declaration (pp, fnode, spc, flags); } else { unsigned int quals = TYPE_QUALS (node); dump_generic_node (pp, TREE_TYPE (node), spc, flags, false); pp_space (pp); pp_string (pp, str); if (quals & TYPE_QUAL_CONST) pp_string (pp, " const"); if (quals & TYPE_QUAL_VOLATILE) pp_string (pp, " volatile"); if (quals & TYPE_QUAL_RESTRICT) pp_string (pp, " restrict"); if (!ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (node))) { pp_string (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; case POLY_INT_CST: pp_string (pp, "POLY_INT_CST ["); dump_generic_node (pp, POLY_INT_CST_COEFF (node, 0), spc, flags, false); for (unsigned int i = 1; i < NUM_POLY_INT_COEFFS; ++i) { pp_string (pp, ", "); dump_generic_node (pp, POLY_INT_CST_COEFF (node, i), spc, flags, false); } pp_string (pp, "]"); break; case REAL_CST: /* Code copied from print_node. */ { REAL_VALUE_TYPE d; if (TREE_OVERFLOW (node)) pp_string (pp, " overflow"); d = TREE_REAL_CST (node); if (REAL_VALUE_ISINF (d)) pp_string (pp, REAL_VALUE_NEGATIVE (d) ? " -Inf" : " Inf"); else if (REAL_VALUE_ISNAN (d)) pp_string (pp, " Nan"); else { char string[100]; real_to_decimal (string, &d, sizeof (string), 0, 1); pp_string (pp, string); } break; } case FIXED_CST: { char string[100]; fixed_to_decimal (string, TREE_FIXED_CST_PTR (node), sizeof (string)); pp_string (pp, string); break; } case COMPLEX_CST: pp_string (pp, "__complex__ ("); dump_generic_node (pp, TREE_REALPART (node), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_IMAGPART (node), spc, flags, false); pp_right_paren (pp); break; case STRING_CST: { pp_string (pp, "\""); if (unsigned nbytes = TREE_STRING_LENGTH (node)) pretty_print_string (pp, TREE_STRING_POINTER (node), nbytes); pp_string (pp, "\""); break; } case VECTOR_CST: { unsigned i; if (flags & TDF_GIMPLE) { pp_string (pp, "_Literal ("); dump_generic_node (pp, TREE_TYPE (node), spc, flags, false); pp_string (pp, ") "); } pp_string (pp, "{ "); unsigned HOST_WIDE_INT nunits; if (!VECTOR_CST_NELTS (node).is_constant (&nunits)) nunits = vector_cst_encoded_nelts (node); for (i = 0; i < nunits; ++i) { if (i != 0) pp_string (pp, ", "); dump_generic_node (pp, VECTOR_CST_ELT (node, i), spc, flags, false); } if (!VECTOR_CST_NELTS (node).is_constant ()) pp_string (pp, ", ..."); pp_string (pp, " }"); } break; case FUNCTION_TYPE: case METHOD_TYPE: dump_generic_node (pp, TREE_TYPE (node), spc, flags, false); pp_space (pp); if (TREE_CODE (node) == METHOD_TYPE) { if (TYPE_METHOD_BASETYPE (node)) dump_generic_node (pp, TYPE_NAME (TYPE_METHOD_BASETYPE (node)), spc, flags, false); else pp_string (pp, ""); pp_colon_colon (pp); } if (TYPE_IDENTIFIER (node)) dump_generic_node (pp, TYPE_NAME (node), spc, flags, false); else if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node))) dump_decl_name (pp, TYPE_NAME (node), flags); else if (flags & TDF_NOUID) pp_printf (pp, ""); else pp_printf (pp, "", TYPE_UID (node)); dump_function_declaration (pp, node, spc, flags); break; case FUNCTION_DECL: case CONST_DECL: dump_decl_name (pp, node, flags); break; case LABEL_DECL: if (DECL_NAME (node)) dump_decl_name (pp, node, flags); else if (LABEL_DECL_UID (node) != -1) { if (flags & TDF_GIMPLE) pp_printf (pp, "L%d", (int) LABEL_DECL_UID (node)); else pp_printf (pp, "", (int) LABEL_DECL_UID (node)); } else { if (flags & TDF_NOUID) pp_string (pp, ""); else { if (flags & TDF_GIMPLE) pp_printf (pp, "", DECL_UID (node)); else pp_printf (pp, "", DECL_UID (node)); } } break; case TYPE_DECL: if (DECL_IS_UNDECLARED_BUILTIN (node)) { /* Don't print the declaration of built-in types. */ break; } if (DECL_NAME (node)) dump_decl_name (pp, node, flags); else if (TYPE_NAME (TREE_TYPE (node)) != node) { pp_string (pp, (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE ? "union" : "struct ")); dump_generic_node (pp, TREE_TYPE (node), spc, flags, false); } else pp_string (pp, ""); break; case VAR_DECL: case PARM_DECL: case FIELD_DECL: case DEBUG_EXPR_DECL: case NAMESPACE_DECL: case NAMELIST_DECL: dump_decl_name (pp, node, flags); break; case RESULT_DECL: pp_string (pp, ""); break; case COMPONENT_REF: op0 = TREE_OPERAND (node, 0); str = "."; if (op0 && (TREE_CODE (op0) == INDIRECT_REF || (TREE_CODE (op0) == MEM_REF && TREE_CODE (TREE_OPERAND (op0, 0)) != ADDR_EXPR && integer_zerop (TREE_OPERAND (op0, 1)) /* Dump the types of INTEGER_CSTs explicitly, for we can't infer them and MEM_ATTR caching will share MEM_REFs with differently-typed op0s. */ && TREE_CODE (TREE_OPERAND (op0, 0)) != INTEGER_CST /* Released SSA_NAMES have no TREE_TYPE. */ && TREE_TYPE (TREE_OPERAND (op0, 0)) != NULL_TREE /* Same pointer types, but ignoring POINTER_TYPE vs. REFERENCE_TYPE. */ && (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 0))) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 1)))) && (TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 0))) == TYPE_MODE (TREE_TYPE (TREE_OPERAND (op0, 1)))) && (TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (op0, 0))) == TYPE_REF_CAN_ALIAS_ALL (TREE_TYPE (TREE_OPERAND (op0, 1)))) /* Same value types ignoring qualifiers. */ && (TYPE_MAIN_VARIANT (TREE_TYPE (op0)) == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 1))))) && MR_DEPENDENCE_CLIQUE (op0) == 0))) { op0 = TREE_OPERAND (op0, 0); str = "->"; } if (op_prio (op0) < op_prio (node)) pp_left_paren (pp); dump_generic_node (pp, op0, spc, flags, false); if (op_prio (op0) < op_prio (node)) pp_right_paren (pp); pp_string (pp, str); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); op0 = component_ref_field_offset (node); if (op0 && TREE_CODE (op0) != INTEGER_CST) { pp_string (pp, "{off: "); dump_generic_node (pp, op0, spc, flags, false); pp_right_brace (pp); } break; case BIT_FIELD_REF: if (flags & TDF_GIMPLE) { pp_string (pp, "__BIT_FIELD_REF <"); dump_generic_node (pp, TREE_TYPE (node), spc, flags | TDF_SLIM, false); if (TYPE_ALIGN (TREE_TYPE (node)) != TYPE_ALIGN (TYPE_MAIN_VARIANT (TREE_TYPE (node)))) { pp_string (pp, ", "); pp_decimal_int (pp, TYPE_ALIGN (TREE_TYPE (node))); } pp_greater (pp); pp_string (pp, " ("); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags | TDF_SLIM, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags | TDF_SLIM, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags | TDF_SLIM, false); pp_right_paren (pp); } else { pp_string (pp, "BIT_FIELD_REF <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); pp_greater (pp); } break; case BIT_INSERT_EXPR: pp_string (pp, "BIT_INSERT_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); pp_string (pp, " ("); if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 1)))) pp_decimal_int (pp, TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (node, 1)))); else dump_generic_node (pp, TYPE_SIZE (TREE_TYPE (TREE_OPERAND (node, 1))), spc, flags, false); pp_string (pp, " bits)>"); break; case ARRAY_REF: case ARRAY_RANGE_REF: op0 = TREE_OPERAND (node, 0); if (op_prio (op0) < op_prio (node)) pp_left_paren (pp); dump_generic_node (pp, op0, spc, flags, false); if (op_prio (op0) < op_prio (node)) pp_right_paren (pp); pp_left_bracket (pp); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); if (TREE_CODE (node) == ARRAY_RANGE_REF) pp_string (pp, " ..."); pp_right_bracket (pp); op0 = array_ref_low_bound (node); op1 = array_ref_element_size (node); if (!integer_zerop (op0) || TREE_OPERAND (node, 2) || TREE_OPERAND (node, 3)) { pp_string (pp, "{lb: "); dump_generic_node (pp, op0, spc, flags, false); pp_string (pp, " sz: "); dump_generic_node (pp, op1, spc, flags, false); pp_right_brace (pp); } break; case CONSTRUCTOR: { unsigned HOST_WIDE_INT ix; tree field, val; bool is_struct_init = false; bool is_array_init = false; widest_int curidx; if (flags & TDF_GIMPLE) { pp_string (pp, "_Literal ("); dump_generic_node (pp, TREE_TYPE (node), spc, flags, false); pp_string (pp, ") "); } pp_left_brace (pp); if (TREE_CLOBBER_P (node)) pp_string (pp, "CLOBBER"); else if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE) is_struct_init = true; else if (TREE_CODE (TREE_TYPE (node)) == ARRAY_TYPE && TYPE_DOMAIN (TREE_TYPE (node)) && TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node))) && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node)))) == INTEGER_CST) { tree minv = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (node))); is_array_init = true; curidx = wi::to_widest (minv); } FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (node), ix, field, val) { if (field) { if (is_struct_init) { pp_dot (pp); dump_generic_node (pp, field, spc, flags, false); pp_equal (pp); } else if (is_array_init && (TREE_CODE (field) != INTEGER_CST || curidx != wi::to_widest (field))) { pp_left_bracket (pp); if (TREE_CODE (field) == RANGE_EXPR) { dump_generic_node (pp, TREE_OPERAND (field, 0), spc, flags, false); pp_string (pp, " ... "); dump_generic_node (pp, TREE_OPERAND (field, 1), spc, flags, false); if (TREE_CODE (TREE_OPERAND (field, 1)) == INTEGER_CST) curidx = wi::to_widest (TREE_OPERAND (field, 1)); } else dump_generic_node (pp, field, spc, flags, false); if (TREE_CODE (field) == INTEGER_CST) curidx = wi::to_widest (field); pp_string (pp, "]="); } } if (is_array_init) curidx += 1; if (val && TREE_CODE (val) == ADDR_EXPR) if (TREE_CODE (TREE_OPERAND (val, 0)) == FUNCTION_DECL) val = TREE_OPERAND (val, 0); if (val && TREE_CODE (val) == FUNCTION_DECL) dump_decl_name (pp, val, flags); else dump_generic_node (pp, val, spc, flags, false); if (ix != CONSTRUCTOR_NELTS (node) - 1) { pp_comma (pp); pp_space (pp); } } pp_right_brace (pp); } break; case COMPOUND_EXPR: { tree *tp; if (flags & TDF_SLIM) { pp_string (pp, ""); break; } dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, !(flags & TDF_SLIM)); if (flags & TDF_SLIM) newline_and_indent (pp, spc); else { pp_comma (pp); pp_space (pp); } for (tp = &TREE_OPERAND (node, 1); TREE_CODE (*tp) == COMPOUND_EXPR; tp = &TREE_OPERAND (*tp, 1)) { dump_generic_node (pp, TREE_OPERAND (*tp, 0), spc, flags, !(flags & TDF_SLIM)); if (flags & TDF_SLIM) newline_and_indent (pp, spc); else { pp_comma (pp); pp_space (pp); } } dump_generic_node (pp, *tp, spc, flags, !(flags & TDF_SLIM)); } break; case STATEMENT_LIST: { tree_stmt_iterator si; bool first = true; if (flags & TDF_SLIM) { pp_string (pp, ""); break; } for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si)) { if (!first) newline_and_indent (pp, spc); else first = false; dump_generic_node (pp, tsi_stmt (si), spc, flags, true); } } break; case MODIFY_EXPR: case INIT_EXPR: dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_space (pp); pp_equal (pp); pp_space (pp); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); break; case TARGET_EXPR: pp_string (pp, "TARGET_EXPR <"); dump_generic_node (pp, TARGET_EXPR_SLOT (node), spc, flags, false); pp_comma (pp); pp_space (pp); dump_generic_node (pp, TARGET_EXPR_INITIAL (node), spc, flags, false); pp_greater (pp); break; case DECL_EXPR: print_declaration (pp, DECL_EXPR_DECL (node), spc, flags); is_stmt = false; break; case COND_EXPR: if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node) { pp_string (pp, "if ("); dump_generic_node (pp, COND_EXPR_COND (node), spc, flags, false); pp_right_paren (pp); /* The lowered cond_exprs should always be printed in full. */ if (COND_EXPR_THEN (node) && (IS_EMPTY_STMT (COND_EXPR_THEN (node)) || TREE_CODE (COND_EXPR_THEN (node)) == GOTO_EXPR) && COND_EXPR_ELSE (node) && (IS_EMPTY_STMT (COND_EXPR_ELSE (node)) || TREE_CODE (COND_EXPR_ELSE (node)) == GOTO_EXPR)) { pp_space (pp); dump_generic_node (pp, COND_EXPR_THEN (node), 0, flags, true); if (!IS_EMPTY_STMT (COND_EXPR_ELSE (node))) { pp_string (pp, " else "); dump_generic_node (pp, COND_EXPR_ELSE (node), 0, flags, true); } } else if (!(flags & TDF_SLIM)) { /* Output COND_EXPR_THEN. */ if (COND_EXPR_THEN (node)) { newline_and_indent (pp, spc+2); pp_left_brace (pp); newline_and_indent (pp, spc+4); dump_generic_node (pp, COND_EXPR_THEN (node), spc+4, flags, true); newline_and_indent (pp, spc+2); pp_right_brace (pp); } /* Output COND_EXPR_ELSE. */ if (COND_EXPR_ELSE (node) && !IS_EMPTY_STMT (COND_EXPR_ELSE (node))) { newline_and_indent (pp, spc); pp_string (pp, "else"); newline_and_indent (pp, spc+2); pp_left_brace (pp); newline_and_indent (pp, spc+4); dump_generic_node (pp, COND_EXPR_ELSE (node), spc+4, flags, true); newline_and_indent (pp, spc+2); pp_right_brace (pp); } } is_expr = false; } else { dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_space (pp); pp_question (pp); pp_space (pp); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_space (pp); pp_colon (pp); pp_space (pp); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); } break; case BIND_EXPR: pp_left_brace (pp); if (!(flags & TDF_SLIM)) { if (BIND_EXPR_VARS (node)) { pp_newline (pp); for (op0 = BIND_EXPR_VARS (node); op0; op0 = DECL_CHAIN (op0)) { print_declaration (pp, op0, spc+2, flags); pp_newline (pp); } } newline_and_indent (pp, spc+2); dump_generic_node (pp, BIND_EXPR_BODY (node), spc+2, flags, true); newline_and_indent (pp, spc); pp_right_brace (pp); } is_expr = false; break; case CALL_EXPR: if (CALL_EXPR_FN (node) != NULL_TREE) print_call_name (pp, CALL_EXPR_FN (node), flags); else { pp_dot (pp); pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node))); } /* Print parameters. */ pp_space (pp); pp_left_paren (pp); { tree arg; call_expr_arg_iterator iter; FOR_EACH_CALL_EXPR_ARG (arg, iter, node) { dump_generic_node (pp, arg, spc, flags, false); if (more_call_expr_args_p (&iter)) { pp_comma (pp); pp_space (pp); } } } if (CALL_EXPR_VA_ARG_PACK (node)) { if (call_expr_nargs (node) > 0) { pp_comma (pp); pp_space (pp); } pp_string (pp, "__builtin_va_arg_pack ()"); } pp_right_paren (pp); op1 = CALL_EXPR_STATIC_CHAIN (node); if (op1) { pp_string (pp, " [static-chain: "); dump_generic_node (pp, op1, spc, flags, false); pp_right_bracket (pp); } if (CALL_EXPR_RETURN_SLOT_OPT (node)) pp_string (pp, " [return slot optimization]"); if (CALL_EXPR_TAILCALL (node)) pp_string (pp, " [tail call]"); break; case WITH_CLEANUP_EXPR: NIY; break; case CLEANUP_POINT_EXPR: pp_string (pp, "<>"); break; case PLACEHOLDER_EXPR: pp_string (pp, "("); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_right_paren (pp); break; case PAREN_EXPR: pp_string (pp, "(("); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, "))"); break; case NON_LVALUE_EXPR: pp_string (pp, "NON_LVALUE_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_greater (pp); break; case SAVE_EXPR: pp_string (pp, "SAVE_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_greater (pp); break; case COMPLEX_EXPR: pp_string (pp, "COMPLEX_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_greater (pp); break; case CONJ_EXPR: pp_string (pp, "CONJ_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_greater (pp); break; case REALPART_EXPR: if (flags & TDF_GIMPLE) { pp_string (pp, "__real "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); } else { pp_string (pp, "REALPART_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_greater (pp); } break; case IMAGPART_EXPR: if (flags & TDF_GIMPLE) { pp_string (pp, "__imag "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); } else { pp_string (pp, "IMAGPART_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_greater (pp); } break; case VA_ARG_EXPR: pp_string (pp, "VA_ARG_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_greater (pp); break; case TRY_FINALLY_EXPR: case TRY_CATCH_EXPR: pp_string (pp, "try"); newline_and_indent (pp, spc+2); pp_left_brace (pp); newline_and_indent (pp, spc+4); dump_generic_node (pp, TREE_OPERAND (node, 0), spc+4, flags, true); newline_and_indent (pp, spc+2); pp_right_brace (pp); newline_and_indent (pp, spc); if (TREE_CODE (node) == TRY_CATCH_EXPR) { node = TREE_OPERAND (node, 1); pp_string (pp, "catch"); } else { gcc_assert (TREE_CODE (node) == TRY_FINALLY_EXPR); node = TREE_OPERAND (node, 1); pp_string (pp, "finally"); if (TREE_CODE (node) == EH_ELSE_EXPR) { newline_and_indent (pp, spc+2); pp_left_brace (pp); newline_and_indent (pp, spc+4); dump_generic_node (pp, TREE_OPERAND (node, 0), spc+4, flags, true); newline_and_indent (pp, spc+2); pp_right_brace (pp); newline_and_indent (pp, spc); node = TREE_OPERAND (node, 1); pp_string (pp, "else"); } } newline_and_indent (pp, spc+2); pp_left_brace (pp); newline_and_indent (pp, spc+4); dump_generic_node (pp, node, spc+4, flags, true); newline_and_indent (pp, spc+2); pp_right_brace (pp); is_expr = false; break; case CATCH_EXPR: pp_string (pp, "catch ("); dump_generic_node (pp, CATCH_TYPES (node), spc+2, flags, false); pp_right_paren (pp); newline_and_indent (pp, spc+2); pp_left_brace (pp); newline_and_indent (pp, spc+4); dump_generic_node (pp, CATCH_BODY (node), spc+4, flags, true); newline_and_indent (pp, spc+2); pp_right_brace (pp); is_expr = false; break; case EH_FILTER_EXPR: pp_string (pp, "<<>>"); newline_and_indent (pp, spc+2); pp_left_brace (pp); newline_and_indent (pp, spc+4); dump_generic_node (pp, EH_FILTER_FAILURE (node), spc+4, flags, true); newline_and_indent (pp, spc+2); pp_right_brace (pp); is_expr = false; break; case LABEL_EXPR: op0 = TREE_OPERAND (node, 0); /* If this is for break or continue, don't bother printing it. */ if (DECL_NAME (op0)) { const char *name = IDENTIFIER_POINTER (DECL_NAME (op0)); if (strcmp (name, "break") == 0 || strcmp (name, "continue") == 0) break; } dump_generic_node (pp, op0, spc, flags, false); pp_colon (pp); if (DECL_NONLOCAL (op0)) pp_string (pp, " [non-local]"); break; case LOOP_EXPR: pp_string (pp, "while (1)"); if (!(flags & TDF_SLIM)) { newline_and_indent (pp, spc+2); pp_left_brace (pp); newline_and_indent (pp, spc+4); dump_generic_node (pp, LOOP_EXPR_BODY (node), spc+4, flags, true); newline_and_indent (pp, spc+2); pp_right_brace (pp); } is_expr = false; break; case PREDICT_EXPR: pp_string (pp, "// predicted "); if (PREDICT_EXPR_OUTCOME (node)) pp_string (pp, "likely by "); else pp_string (pp, "unlikely by "); pp_string (pp, predictor_name (PREDICT_EXPR_PREDICTOR (node))); pp_string (pp, " predictor."); break; case ANNOTATE_EXPR: pp_string (pp, "ANNOTATE_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); switch ((enum annot_expr_kind) TREE_INT_CST_LOW (TREE_OPERAND (node, 1))) { case annot_expr_ivdep_kind: pp_string (pp, ", ivdep"); break; case annot_expr_unroll_kind: pp_printf (pp, ", unroll %d", (int) TREE_INT_CST_LOW (TREE_OPERAND (node, 2))); break; case annot_expr_no_vector_kind: pp_string (pp, ", no-vector"); break; case annot_expr_vector_kind: pp_string (pp, ", vector"); break; case annot_expr_parallel_kind: pp_string (pp, ", parallel"); break; default: gcc_unreachable (); } pp_greater (pp); break; case RETURN_EXPR: pp_string (pp, "return"); op0 = TREE_OPERAND (node, 0); if (op0) { pp_space (pp); if (TREE_CODE (op0) == MODIFY_EXPR) dump_generic_node (pp, TREE_OPERAND (op0, 1), spc, flags, false); else dump_generic_node (pp, op0, spc, flags, false); } break; case EXIT_EXPR: pp_string (pp, "if ("); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ") break"); break; case SWITCH_EXPR: pp_string (pp, "switch ("); dump_generic_node (pp, SWITCH_COND (node), spc, flags, false); pp_right_paren (pp); if (!(flags & TDF_SLIM)) { newline_and_indent (pp, spc+2); pp_left_brace (pp); if (SWITCH_BODY (node)) { newline_and_indent (pp, spc+4); dump_generic_node (pp, SWITCH_BODY (node), spc+4, flags, true); } newline_and_indent (pp, spc+2); pp_right_brace (pp); } is_expr = false; break; case GOTO_EXPR: op0 = GOTO_DESTINATION (node); if (TREE_CODE (op0) != SSA_NAME && DECL_P (op0) && DECL_NAME (op0)) { const char *name = IDENTIFIER_POINTER (DECL_NAME (op0)); if (strcmp (name, "break") == 0 || strcmp (name, "continue") == 0) { pp_string (pp, name); break; } } pp_string (pp, "goto "); dump_generic_node (pp, op0, spc, flags, false); break; case ASM_EXPR: pp_string (pp, "__asm__"); if (ASM_VOLATILE_P (node)) pp_string (pp, " __volatile__"); pp_left_paren (pp); dump_generic_node (pp, ASM_STRING (node), spc, flags, false); pp_colon (pp); dump_generic_node (pp, ASM_OUTPUTS (node), spc, flags, false); pp_colon (pp); dump_generic_node (pp, ASM_INPUTS (node), spc, flags, false); if (ASM_CLOBBERS (node)) { pp_colon (pp); dump_generic_node (pp, ASM_CLOBBERS (node), spc, flags, false); } pp_right_paren (pp); break; case CASE_LABEL_EXPR: if (CASE_LOW (node) && CASE_HIGH (node)) { pp_string (pp, "case "); dump_generic_node (pp, CASE_LOW (node), spc, flags, false); pp_string (pp, " ... "); dump_generic_node (pp, CASE_HIGH (node), spc, flags, false); } else if (CASE_LOW (node)) { pp_string (pp, "case "); dump_generic_node (pp, CASE_LOW (node), spc, flags, false); } else pp_string (pp, "default"); pp_colon (pp); break; case OBJ_TYPE_REF: pp_string (pp, "OBJ_TYPE_REF("); dump_generic_node (pp, OBJ_TYPE_REF_EXPR (node), spc, flags, false); pp_semicolon (pp); /* We omit the class type for -fcompare-debug because we may drop TYPE_BINFO early depending on debug info, and then virtual_method_call_p would return false, whereas when TYPE_BINFO is preserved it may still return true and then we'd print the class type. Compare tree and rtl dumps for libstdc++-prettyprinters/shared_ptr.cc with and without -g, for example, at occurrences of OBJ_TYPE_REF. */ if (!(flags & (TDF_SLIM | TDF_COMPARE_DEBUG)) && virtual_method_call_p (node, true)) { pp_string (pp, "("); dump_generic_node (pp, obj_type_ref_class (node, true), spc, flags, false); pp_string (pp, ")"); } dump_generic_node (pp, OBJ_TYPE_REF_OBJECT (node), spc, flags, false); pp_arrow (pp); dump_generic_node (pp, OBJ_TYPE_REF_TOKEN (node), spc, flags, false); pp_right_paren (pp); break; case SSA_NAME: if (SSA_NAME_IDENTIFIER (node)) { if ((flags & TDF_NOUID) && SSA_NAME_VAR (node) && DECL_NAMELESS (SSA_NAME_VAR (node))) dump_fancy_name (pp, SSA_NAME_IDENTIFIER (node)); else if (! (flags & TDF_GIMPLE) || SSA_NAME_VAR (node)) dump_generic_node (pp, SSA_NAME_IDENTIFIER (node), spc, flags, false); } pp_underscore (pp); pp_decimal_int (pp, SSA_NAME_VERSION (node)); if (SSA_NAME_IS_DEFAULT_DEF (node)) pp_string (pp, "(D)"); if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node)) pp_string (pp, "(ab)"); break; case WITH_SIZE_EXPR: pp_string (pp, "WITH_SIZE_EXPR <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_greater (pp); break; case ASSERT_EXPR: pp_string (pp, "ASSERT_EXPR <"); dump_generic_node (pp, ASSERT_EXPR_VAR (node), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, ASSERT_EXPR_COND (node), spc, flags, false); pp_greater (pp); break; case SCEV_KNOWN: pp_string (pp, "scev_known"); break; case SCEV_NOT_KNOWN: pp_string (pp, "scev_not_known"); break; case POLYNOMIAL_CHREC: pp_left_brace (pp); dump_generic_node (pp, CHREC_LEFT (node), spc, flags, false); pp_string (pp, ", +, "); dump_generic_node (pp, CHREC_RIGHT (node), spc, flags, false); pp_printf (pp, "}_%u", CHREC_VARIABLE (node)); is_stmt = false; break; case REALIGN_LOAD_EXPR: pp_string (pp, "REALIGN_LOAD <"); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); pp_greater (pp); break; case VEC_COND_EXPR: pp_string (pp, " VEC_COND_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " , "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, " , "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); pp_string (pp, " > "); break; case VEC_PERM_EXPR: pp_string (pp, " VEC_PERM_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " , "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, " , "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); pp_string (pp, " > "); break; case DOT_PROD_EXPR: pp_string (pp, " DOT_PROD_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); pp_string (pp, " > "); break; case WIDEN_MULT_PLUS_EXPR: pp_string (pp, " WIDEN_MULT_PLUS_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); pp_string (pp, " > "); break; case WIDEN_MULT_MINUS_EXPR: pp_string (pp, " WIDEN_MULT_MINUS_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false); pp_string (pp, " > "); break; case OACC_PARALLEL: pp_string (pp, "#pragma acc parallel"); goto dump_omp_clauses_body; case OACC_KERNELS: pp_string (pp, "#pragma acc kernels"); goto dump_omp_clauses_body; case OACC_SERIAL: pp_string (pp, "#pragma acc serial"); goto dump_omp_clauses_body; case OACC_DATA: pp_string (pp, "#pragma acc data"); dump_omp_clauses (pp, OACC_DATA_CLAUSES (node), spc, flags); goto dump_omp_body; case OACC_HOST_DATA: pp_string (pp, "#pragma acc host_data"); dump_omp_clauses (pp, OACC_HOST_DATA_CLAUSES (node), spc, flags); goto dump_omp_body; case OACC_DECLARE: pp_string (pp, "#pragma acc declare"); dump_omp_clauses (pp, OACC_DECLARE_CLAUSES (node), spc, flags); break; case OACC_UPDATE: pp_string (pp, "#pragma acc update"); dump_omp_clauses (pp, OACC_UPDATE_CLAUSES (node), spc, flags); break; case OACC_ENTER_DATA: pp_string (pp, "#pragma acc enter data"); dump_omp_clauses (pp, OACC_ENTER_DATA_CLAUSES (node), spc, flags); break; case OACC_EXIT_DATA: pp_string (pp, "#pragma acc exit data"); dump_omp_clauses (pp, OACC_EXIT_DATA_CLAUSES (node), spc, flags); break; case OACC_CACHE: pp_string (pp, "#pragma acc cache"); dump_omp_clauses (pp, OACC_CACHE_CLAUSES (node), spc, flags); break; case OMP_PARALLEL: pp_string (pp, "#pragma omp parallel"); dump_omp_clauses (pp, OMP_PARALLEL_CLAUSES (node), spc, flags); goto dump_omp_body; dump_omp_clauses_body: dump_omp_clauses (pp, OMP_CLAUSES (node), spc, flags); goto dump_omp_body; dump_omp_body: if (!(flags & TDF_SLIM) && OMP_BODY (node)) { newline_and_indent (pp, spc + 2); pp_left_brace (pp); newline_and_indent (pp, spc + 4); dump_generic_node (pp, OMP_BODY (node), spc + 4, flags, false); newline_and_indent (pp, spc + 2); pp_right_brace (pp); } is_expr = false; break; case OMP_TASK: pp_string (pp, OMP_TASK_BODY (node) ? "#pragma omp task" : "#pragma omp taskwait"); dump_omp_clauses (pp, OMP_TASK_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_FOR: pp_string (pp, "#pragma omp for"); goto dump_omp_loop; case OMP_SIMD: pp_string (pp, "#pragma omp simd"); goto dump_omp_loop; case OMP_DISTRIBUTE: pp_string (pp, "#pragma omp distribute"); goto dump_omp_loop; case OMP_TASKLOOP: pp_string (pp, "#pragma omp taskloop"); goto dump_omp_loop; case OMP_LOOP: pp_string (pp, "#pragma omp loop"); goto dump_omp_loop; case OACC_LOOP: pp_string (pp, "#pragma acc loop"); goto dump_omp_loop; case OMP_TEAMS: pp_string (pp, "#pragma omp teams"); dump_omp_clauses (pp, OMP_TEAMS_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_TARGET_DATA: pp_string (pp, "#pragma omp target data"); dump_omp_clauses (pp, OMP_TARGET_DATA_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_TARGET_ENTER_DATA: pp_string (pp, "#pragma omp target enter data"); dump_omp_clauses (pp, OMP_TARGET_ENTER_DATA_CLAUSES (node), spc, flags); is_expr = false; break; case OMP_TARGET_EXIT_DATA: pp_string (pp, "#pragma omp target exit data"); dump_omp_clauses (pp, OMP_TARGET_EXIT_DATA_CLAUSES (node), spc, flags); is_expr = false; break; case OMP_TARGET: pp_string (pp, "#pragma omp target"); dump_omp_clauses (pp, OMP_TARGET_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_TARGET_UPDATE: pp_string (pp, "#pragma omp target update"); dump_omp_clauses (pp, OMP_TARGET_UPDATE_CLAUSES (node), spc, flags); is_expr = false; break; dump_omp_loop: dump_omp_clauses (pp, OMP_FOR_CLAUSES (node), spc, flags); if (!(flags & TDF_SLIM)) { int i; if (OMP_FOR_PRE_BODY (node)) { newline_and_indent (pp, spc + 2); pp_left_brace (pp); spc += 4; newline_and_indent (pp, spc); dump_generic_node (pp, OMP_FOR_PRE_BODY (node), spc, flags, false); } if (OMP_FOR_INIT (node)) { spc -= 2; for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (node)); i++) { spc += 2; newline_and_indent (pp, spc); pp_string (pp, "for ("); tree init = TREE_VEC_ELT (OMP_FOR_INIT (node), i); if (TREE_CODE (init) != MODIFY_EXPR || TREE_CODE (TREE_OPERAND (init, 1)) != TREE_VEC) dump_generic_node (pp, init, spc, flags, false); else { dump_generic_node (pp, TREE_OPERAND (init, 0), spc, flags, false); pp_string (pp, " = "); dump_omp_loop_non_rect_expr (pp, TREE_OPERAND (init, 1), spc, flags); } pp_string (pp, "; "); tree cond = TREE_VEC_ELT (OMP_FOR_COND (node), i); if (!COMPARISON_CLASS_P (cond) || TREE_CODE (TREE_OPERAND (cond, 1)) != TREE_VEC) dump_generic_node (pp, cond, spc, flags, false); else { dump_generic_node (pp, TREE_OPERAND (cond, 0), spc, flags, false); const char *op = op_symbol (cond); pp_space (pp); pp_string (pp, op); pp_space (pp); dump_omp_loop_non_rect_expr (pp, TREE_OPERAND (cond, 1), spc, flags); } pp_string (pp, "; "); dump_generic_node (pp, TREE_VEC_ELT (OMP_FOR_INCR (node), i), spc, flags, false); pp_right_paren (pp); } } if (OMP_FOR_BODY (node)) { newline_and_indent (pp, spc + 2); pp_left_brace (pp); newline_and_indent (pp, spc + 4); dump_generic_node (pp, OMP_FOR_BODY (node), spc + 4, flags, false); newline_and_indent (pp, spc + 2); pp_right_brace (pp); } if (OMP_FOR_INIT (node)) spc -= 2 * TREE_VEC_LENGTH (OMP_FOR_INIT (node)) - 2; if (OMP_FOR_PRE_BODY (node)) { spc -= 4; newline_and_indent (pp, spc + 2); pp_right_brace (pp); } } is_expr = false; break; case OMP_SECTIONS: pp_string (pp, "#pragma omp sections"); dump_omp_clauses (pp, OMP_SECTIONS_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_SECTION: pp_string (pp, "#pragma omp section"); goto dump_omp_body; case OMP_SCAN: if (OMP_SCAN_CLAUSES (node)) { pp_string (pp, "#pragma omp scan"); dump_omp_clauses (pp, OMP_SCAN_CLAUSES (node), spc, flags); } goto dump_omp_body; case OMP_MASTER: pp_string (pp, "#pragma omp master"); goto dump_omp_body; case OMP_TASKGROUP: pp_string (pp, "#pragma omp taskgroup"); dump_omp_clauses (pp, OMP_TASKGROUP_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_ORDERED: pp_string (pp, "#pragma omp ordered"); dump_omp_clauses (pp, OMP_ORDERED_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_CRITICAL: pp_string (pp, "#pragma omp critical"); if (OMP_CRITICAL_NAME (node)) { pp_space (pp); pp_left_paren (pp); dump_generic_node (pp, OMP_CRITICAL_NAME (node), spc, flags, false); pp_right_paren (pp); } dump_omp_clauses (pp, OMP_CRITICAL_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_ATOMIC: pp_string (pp, "#pragma omp atomic"); dump_omp_atomic_memory_order (pp, OMP_ATOMIC_MEMORY_ORDER (node)); newline_and_indent (pp, spc + 2); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_space (pp); pp_equal (pp); pp_space (pp); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); break; case OMP_ATOMIC_READ: pp_string (pp, "#pragma omp atomic read"); dump_omp_atomic_memory_order (pp, OMP_ATOMIC_MEMORY_ORDER (node)); newline_and_indent (pp, spc + 2); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_space (pp); break; case OMP_ATOMIC_CAPTURE_OLD: case OMP_ATOMIC_CAPTURE_NEW: pp_string (pp, "#pragma omp atomic capture"); dump_omp_atomic_memory_order (pp, OMP_ATOMIC_MEMORY_ORDER (node)); newline_and_indent (pp, spc + 2); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_space (pp); pp_equal (pp); pp_space (pp); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); break; case OMP_SINGLE: pp_string (pp, "#pragma omp single"); dump_omp_clauses (pp, OMP_SINGLE_CLAUSES (node), spc, flags); goto dump_omp_body; case OMP_CLAUSE: dump_omp_clause (pp, node, spc, flags); is_expr = false; break; case TRANSACTION_EXPR: if (TRANSACTION_EXPR_OUTER (node)) pp_string (pp, "__transaction_atomic [[outer]]"); else if (TRANSACTION_EXPR_RELAXED (node)) pp_string (pp, "__transaction_relaxed"); else pp_string (pp, "__transaction_atomic"); if (!(flags & TDF_SLIM) && TRANSACTION_EXPR_BODY (node)) { newline_and_indent (pp, spc); pp_left_brace (pp); newline_and_indent (pp, spc + 2); dump_generic_node (pp, TRANSACTION_EXPR_BODY (node), spc + 2, flags, false); newline_and_indent (pp, spc); pp_right_brace (pp); } is_expr = false; break; case VEC_SERIES_EXPR: case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: case VEC_WIDEN_PLUS_HI_EXPR: case VEC_WIDEN_PLUS_LO_EXPR: case VEC_WIDEN_MINUS_HI_EXPR: case VEC_WIDEN_MINUS_LO_EXPR: case VEC_WIDEN_MULT_EVEN_EXPR: case VEC_WIDEN_MULT_ODD_EXPR: case VEC_WIDEN_LSHIFT_HI_EXPR: case VEC_WIDEN_LSHIFT_LO_EXPR: pp_space (pp); for (str = get_tree_code_name (code); *str; str++) pp_character (pp, TOUPPER (*str)); pp_string (pp, " < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, " > "); break; case VEC_DUPLICATE_EXPR: pp_space (pp); for (str = get_tree_code_name (code); *str; str++) pp_character (pp, TOUPPER (*str)); pp_string (pp, " < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " > "); break; case VEC_UNPACK_HI_EXPR: pp_string (pp, " VEC_UNPACK_HI_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " > "); break; case VEC_UNPACK_LO_EXPR: pp_string (pp, " VEC_UNPACK_LO_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " > "); break; case VEC_UNPACK_FLOAT_HI_EXPR: pp_string (pp, " VEC_UNPACK_FLOAT_HI_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " > "); break; case VEC_UNPACK_FLOAT_LO_EXPR: pp_string (pp, " VEC_UNPACK_FLOAT_LO_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " > "); break; case VEC_UNPACK_FIX_TRUNC_HI_EXPR: pp_string (pp, " VEC_UNPACK_FIX_TRUNC_HI_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " > "); break; case VEC_UNPACK_FIX_TRUNC_LO_EXPR: pp_string (pp, " VEC_UNPACK_FIX_TRUNC_LO_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, " > "); break; case VEC_PACK_TRUNC_EXPR: pp_string (pp, " VEC_PACK_TRUNC_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, " > "); break; case VEC_PACK_SAT_EXPR: pp_string (pp, " VEC_PACK_SAT_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, " > "); break; case VEC_PACK_FIX_TRUNC_EXPR: pp_string (pp, " VEC_PACK_FIX_TRUNC_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, " > "); break; case VEC_PACK_FLOAT_EXPR: pp_string (pp, " VEC_PACK_FLOAT_EXPR < "); dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false); pp_string (pp, ", "); dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false); pp_string (pp, " > "); break; case BLOCK: dump_block_node (pp, node, spc, flags); break; case DEBUG_BEGIN_STMT: pp_string (pp, "# DEBUG BEGIN STMT"); break; default: NIY; } if (is_stmt && is_expr) pp_semicolon (pp); return spc; } /* Print the declaration of a variable. */ void print_declaration (pretty_printer *pp, tree t, int spc, dump_flags_t flags) { INDENT (spc); if (TREE_CODE(t) == NAMELIST_DECL) { pp_string(pp, "namelist "); dump_decl_name (pp, t, flags); pp_semicolon (pp); return; } if (TREE_CODE (t) == TYPE_DECL) pp_string (pp, "typedef "); if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_DECL_WRTL) && DECL_REGISTER (t)) pp_string (pp, "register "); if (TREE_PUBLIC (t) && DECL_EXTERNAL (t)) pp_string (pp, "extern "); else if (TREE_STATIC (t)) pp_string (pp, "static "); /* Print the type and name. */ if (TREE_TYPE (t) && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) { tree tmp; /* Print array's type. */ tmp = TREE_TYPE (t); while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE) tmp = TREE_TYPE (tmp); dump_generic_node (pp, TREE_TYPE (tmp), spc, flags, false); /* Print variable's name. */ pp_space (pp); dump_generic_node (pp, t, spc, flags, false); /* Print the dimensions. */ tmp = TREE_TYPE (t); while (TREE_CODE (tmp) == ARRAY_TYPE) { dump_array_domain (pp, TYPE_DOMAIN (tmp), spc, flags); tmp = TREE_TYPE (tmp); } } else if (TREE_CODE (t) == FUNCTION_DECL) { dump_generic_node (pp, TREE_TYPE (TREE_TYPE (t)), spc, flags, false); pp_space (pp); dump_decl_name (pp, t, flags); dump_function_declaration (pp, TREE_TYPE (t), spc, flags); } else { /* Print type declaration. */ dump_generic_node (pp, TREE_TYPE (t), spc, flags, false); /* Print variable's name. */ pp_space (pp); dump_generic_node (pp, t, spc, flags, false); } if (VAR_P (t) && DECL_HARD_REGISTER (t)) { pp_string (pp, " __asm__ "); pp_left_paren (pp); dump_generic_node (pp, DECL_ASSEMBLER_NAME (t), spc, flags, false); pp_right_paren (pp); } /* The initial value of a function serves to determine whether the function is declared or defined. So the following does not apply to function nodes. */ if (TREE_CODE (t) != FUNCTION_DECL) { /* Print the initial value. */ if (DECL_INITIAL (t)) { pp_space (pp); pp_equal (pp); pp_space (pp); if (!(flags & TDF_SLIM)) dump_generic_node (pp, DECL_INITIAL (t), spc, flags, false); else pp_string (pp, "<<< omitted >>>"); } } if (VAR_P (t) && DECL_HAS_VALUE_EXPR_P (t)) { pp_string (pp, " [value-expr: "); dump_generic_node (pp, DECL_VALUE_EXPR (t), spc, flags, false); pp_right_bracket (pp); } pp_semicolon (pp); } /* Prints a structure: name, fields, and methods. FIXME: Still incomplete. */ static void print_struct_decl (pretty_printer *pp, const_tree node, int spc, dump_flags_t flags) { /* Print the name of the structure. */ if (TYPE_NAME (node)) { INDENT (spc); if (TREE_CODE (node) == RECORD_TYPE) pp_string (pp, "struct "); else if ((TREE_CODE (node) == UNION_TYPE || TREE_CODE (node) == QUAL_UNION_TYPE)) pp_string (pp, "union "); dump_generic_node (pp, TYPE_NAME (node), spc, TDF_NONE, false); } /* Print the contents of the structure. */ pp_newline (pp); INDENT (spc); pp_left_brace (pp); pp_newline (pp); /* Print the fields of the structure. */ { tree tmp; tmp = TYPE_FIELDS (node); while (tmp) { /* Avoid to print recursively the structure. */ /* FIXME : Not implemented correctly..., what about the case when we have a cycle in the contain graph? ... Maybe this could be solved by looking at the scope in which the structure was declared. */ if (TREE_TYPE (tmp) != node && (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE || TREE_TYPE (TREE_TYPE (tmp)) != node)) { print_declaration (pp, tmp, spc+2, flags); pp_newline (pp); } tmp = DECL_CHAIN (tmp); } } INDENT (spc); pp_right_brace (pp); } /* Return the priority of the operator CODE. From lowest to highest precedence with either left-to-right (L-R) or right-to-left (R-L) associativity]: 1 [L-R] , 2 [R-L] = += -= *= /= %= &= ^= |= <<= >>= 3 [R-L] ?: 4 [L-R] || 5 [L-R] && 6 [L-R] | 7 [L-R] ^ 8 [L-R] & 9 [L-R] == != 10 [L-R] < <= > >= 11 [L-R] << >> 12 [L-R] + - 13 [L-R] * / % 14 [R-L] ! ~ ++ -- + - * & (type) sizeof 15 [L-R] fn() [] -> . unary +, - and * have higher precedence than the corresponding binary operators. */ int op_code_prio (enum tree_code code) { switch (code) { case TREE_LIST: case COMPOUND_EXPR: case BIND_EXPR: return 1; case MODIFY_EXPR: case INIT_EXPR: return 2; case COND_EXPR: return 3; case TRUTH_OR_EXPR: case TRUTH_ORIF_EXPR: return 4; case TRUTH_AND_EXPR: case TRUTH_ANDIF_EXPR: return 5; case BIT_IOR_EXPR: return 6; case BIT_XOR_EXPR: case TRUTH_XOR_EXPR: return 7; case BIT_AND_EXPR: return 8; case EQ_EXPR: case NE_EXPR: return 9; case UNLT_EXPR: case UNLE_EXPR: case UNGT_EXPR: case UNGE_EXPR: case UNEQ_EXPR: case LTGT_EXPR: case ORDERED_EXPR: case UNORDERED_EXPR: case LT_EXPR: case LE_EXPR: case GT_EXPR: case GE_EXPR: return 10; case LSHIFT_EXPR: case RSHIFT_EXPR: case LROTATE_EXPR: case RROTATE_EXPR: case VEC_WIDEN_LSHIFT_HI_EXPR: case VEC_WIDEN_LSHIFT_LO_EXPR: case WIDEN_LSHIFT_EXPR: return 11; case WIDEN_SUM_EXPR: case PLUS_EXPR: case POINTER_PLUS_EXPR: case POINTER_DIFF_EXPR: case MINUS_EXPR: return 12; case VEC_WIDEN_MULT_HI_EXPR: case VEC_WIDEN_MULT_LO_EXPR: case WIDEN_MULT_EXPR: case DOT_PROD_EXPR: case WIDEN_MULT_PLUS_EXPR: case WIDEN_MULT_MINUS_EXPR: case MULT_EXPR: case MULT_HIGHPART_EXPR: case TRUNC_DIV_EXPR: case CEIL_DIV_EXPR: case FLOOR_DIV_EXPR: case ROUND_DIV_EXPR: case RDIV_EXPR: case EXACT_DIV_EXPR: case TRUNC_MOD_EXPR: case CEIL_MOD_EXPR: case FLOOR_MOD_EXPR: case ROUND_MOD_EXPR: return 13; case TRUTH_NOT_EXPR: case BIT_NOT_EXPR: case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: case PREINCREMENT_EXPR: case PREDECREMENT_EXPR: case NEGATE_EXPR: case INDIRECT_REF: case ADDR_EXPR: case FLOAT_EXPR: CASE_CONVERT: case FIX_TRUNC_EXPR: case TARGET_EXPR: return 14; case CALL_EXPR: case ARRAY_REF: case ARRAY_RANGE_REF: case COMPONENT_REF: return 15; /* Special expressions. */ case MIN_EXPR: case MAX_EXPR: case ABS_EXPR: case REALPART_EXPR: case IMAGPART_EXPR: case VEC_UNPACK_HI_EXPR: case VEC_UNPACK_LO_EXPR: case VEC_UNPACK_FLOAT_HI_EXPR: case VEC_UNPACK_FLOAT_LO_EXPR: case VEC_UNPACK_FIX_TRUNC_HI_EXPR: case VEC_UNPACK_FIX_TRUNC_LO_EXPR: case VEC_PACK_TRUNC_EXPR: case VEC_PACK_SAT_EXPR: return 16; default: /* Return an arbitrarily high precedence to avoid surrounding single VAR_DECLs in ()s. */ return 9999; } } /* Return the priority of the operator OP. */ int op_prio (const_tree op) { enum tree_code code; if (op == NULL) return 9999; code = TREE_CODE (op); if (code == SAVE_EXPR || code == NON_LVALUE_EXPR) return op_prio (TREE_OPERAND (op, 0)); return op_code_prio (code); } /* Return the symbol associated with operator CODE. */ const char * op_symbol_code (enum tree_code code) { switch (code) { case MODIFY_EXPR: return "="; case TRUTH_OR_EXPR: case TRUTH_ORIF_EXPR: return "||"; case TRUTH_AND_EXPR: case TRUTH_ANDIF_EXPR: return "&&"; case BIT_IOR_EXPR: return "|"; case TRUTH_XOR_EXPR: case BIT_XOR_EXPR: return "^"; case ADDR_EXPR: case BIT_AND_EXPR: return "&"; case ORDERED_EXPR: return "ord"; case UNORDERED_EXPR: return "unord"; case EQ_EXPR: return "=="; case UNEQ_EXPR: return "u=="; case NE_EXPR: return "!="; case LT_EXPR: return "<"; case UNLT_EXPR: return "u<"; case LE_EXPR: return "<="; case UNLE_EXPR: return "u<="; case GT_EXPR: return ">"; case UNGT_EXPR: return "u>"; case GE_EXPR: return ">="; case UNGE_EXPR: return "u>="; case LTGT_EXPR: return "<>"; case LSHIFT_EXPR: return "<<"; case RSHIFT_EXPR: return ">>"; case LROTATE_EXPR: return "r<<"; case RROTATE_EXPR: return "r>>"; case WIDEN_LSHIFT_EXPR: return "w<<"; case WIDEN_PLUS_EXPR: return "w+"; case WIDEN_MINUS_EXPR: return "w-"; case POINTER_PLUS_EXPR: return "+"; case PLUS_EXPR: return "+"; case WIDEN_SUM_EXPR: return "w+"; case WIDEN_MULT_EXPR: return "w*"; case MULT_HIGHPART_EXPR: return "h*"; case NEGATE_EXPR: case MINUS_EXPR: case POINTER_DIFF_EXPR: return "-"; case BIT_NOT_EXPR: return "~"; case TRUTH_NOT_EXPR: return "!"; case MULT_EXPR: case INDIRECT_REF: return "*"; case TRUNC_DIV_EXPR: case RDIV_EXPR: return "/"; case CEIL_DIV_EXPR: return "/[cl]"; case FLOOR_DIV_EXPR: return "/[fl]"; case ROUND_DIV_EXPR: return "/[rd]"; case EXACT_DIV_EXPR: return "/[ex]"; case TRUNC_MOD_EXPR: return "%"; case CEIL_MOD_EXPR: return "%[cl]"; case FLOOR_MOD_EXPR: return "%[fl]"; case ROUND_MOD_EXPR: return "%[rd]"; case PREDECREMENT_EXPR: return " --"; case PREINCREMENT_EXPR: return " ++"; case POSTDECREMENT_EXPR: return "-- "; case POSTINCREMENT_EXPR: return "++ "; case MAX_EXPR: return "max"; case MIN_EXPR: return "min"; default: return "<<< ??? >>>"; } } /* Return the symbol associated with operator OP. */ static const char * op_symbol (const_tree op) { return op_symbol_code (TREE_CODE (op)); } /* Prints the name of a call. NODE is the CALL_EXPR_FN of a CALL_EXPR or the gimple_call_fn of a GIMPLE_CALL. */ void print_call_name (pretty_printer *pp, tree node, dump_flags_t flags) { tree op0 = node; if (TREE_CODE (op0) == NON_LVALUE_EXPR) op0 = TREE_OPERAND (op0, 0); again: switch (TREE_CODE (op0)) { case VAR_DECL: case PARM_DECL: case FUNCTION_DECL: dump_function_name (pp, op0, flags); break; case ADDR_EXPR: case INDIRECT_REF: CASE_CONVERT: op0 = TREE_OPERAND (op0, 0); goto again; case COND_EXPR: pp_left_paren (pp); dump_generic_node (pp, TREE_OPERAND (op0, 0), 0, flags, false); pp_string (pp, ") ? "); dump_generic_node (pp, TREE_OPERAND (op0, 1), 0, flags, false); pp_string (pp, " : "); dump_generic_node (pp, TREE_OPERAND (op0, 2), 0, flags, false); break; case ARRAY_REF: if (TREE_CODE (TREE_OPERAND (op0, 0)) == VAR_DECL) dump_function_name (pp, TREE_OPERAND (op0, 0), flags); else dump_generic_node (pp, op0, 0, flags, false); break; case MEM_REF: if (integer_zerop (TREE_OPERAND (op0, 1))) { op0 = TREE_OPERAND (op0, 0); goto again; } /* Fallthru. */ case COMPONENT_REF: case SSA_NAME: case OBJ_TYPE_REF: dump_generic_node (pp, op0, 0, flags, false); break; default: NIY; } } /* Print the first N characters in the array STR, replacing non-printable characters (including embedded nuls) with unambiguous escape sequences. */ void pretty_print_string (pretty_printer *pp, const char *str, size_t n) { if (str == NULL) return; for ( ; n; --n, ++str) { switch (str[0]) { case '\b': pp_string (pp, "\\b"); break; case '\f': pp_string (pp, "\\f"); break; case '\n': pp_string (pp, "\\n"); break; case '\r': pp_string (pp, "\\r"); break; case '\t': pp_string (pp, "\\t"); break; case '\v': pp_string (pp, "\\v"); break; case '\\': pp_string (pp, "\\\\"); break; case '\"': pp_string (pp, "\\\""); break; case '\'': pp_string (pp, "\\'"); break; default: if (str[0] || n > 1) { if (!ISPRINT (str[0])) { char buf[5]; sprintf (buf, "\\x%02x", (unsigned char)str[0]); pp_string (pp, buf); } else pp_character (pp, str[0]); break; } } } } static void maybe_init_pretty_print (FILE *file) { if (!tree_pp) { tree_pp = new pretty_printer (); pp_needs_newline (tree_pp) = true; pp_translate_identifiers (tree_pp) = false; } tree_pp->buffer->stream = file; } static void newline_and_indent (pretty_printer *pp, int spc) { pp_newline (pp); INDENT (spc); } /* Handle the %K format for TEXT. Separate from default_tree_printer so it can also be used in front ends. The location LOC and BLOCK are expected to be extracted by the caller from the %K argument arg via EXPR_LOCATION(arg) and TREE_BLOCK(arg). */ void percent_K_format (text_info *text, location_t loc, tree block) { text->set_location (0, loc, SHOW_RANGE_WITH_CARET); gcc_assert (pp_ti_abstract_origin (text) != NULL); *pp_ti_abstract_origin (text) = NULL; while (block && TREE_CODE (block) == BLOCK && BLOCK_ABSTRACT_ORIGIN (block)) { tree ao = BLOCK_ABSTRACT_ORIGIN (block); if (TREE_CODE (ao) == FUNCTION_DECL) { *pp_ti_abstract_origin (text) = block; break; } block = BLOCK_SUPERCONTEXT (block); } } /* Print the identifier ID to PRETTY-PRINTER. */ void pp_tree_identifier (pretty_printer *pp, tree id) { if (pp_translate_identifiers (pp)) { const char *text = identifier_to_locale (IDENTIFIER_POINTER (id)); pp_append_text (pp, text, text + strlen (text)); } else pp_append_text (pp, IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id) + IDENTIFIER_LENGTH (id)); } /* A helper function that is used to dump function information before the function dump. */ void dump_function_header (FILE *dump_file, tree fdecl, dump_flags_t flags) { const char *dname, *aname; struct cgraph_node *node = cgraph_node::get (fdecl); struct function *fun = DECL_STRUCT_FUNCTION (fdecl); dname = lang_hooks.decl_printable_name (fdecl, 1); if (DECL_ASSEMBLER_NAME_SET_P (fdecl)) aname = (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fdecl))); else aname = ""; fprintf (dump_file, "\n;; Function %s (%s, funcdef_no=%d", dname, aname, fun->funcdef_no); if (!(flags & TDF_NOUID)) fprintf (dump_file, ", decl_uid=%d", DECL_UID (fdecl)); if (node) { fprintf (dump_file, ", cgraph_uid=%d", node->get_uid ()); fprintf (dump_file, ", symbol_order=%d)%s\n\n", node->order, node->frequency == NODE_FREQUENCY_HOT ? " (hot)" : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED ? " (unlikely executed)" : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE ? " (executed once)" : ""); } else fprintf (dump_file, ")\n\n"); } /* Dump double_int D to pretty_printer PP. UNS is true if D is unsigned and false otherwise. */ void pp_double_int (pretty_printer *pp, double_int d, bool uns) { if (d.fits_shwi ()) pp_wide_integer (pp, d.low); else if (d.fits_uhwi ()) pp_unsigned_wide_integer (pp, d.low); else { unsigned HOST_WIDE_INT low = d.low; HOST_WIDE_INT high = d.high; if (!uns && d.is_negative ()) { pp_minus (pp); high = ~high + !low; low = -low; } /* Would "%x%0*x" or "%x%*0x" get zero-padding on all systems? */ sprintf (pp_buffer (pp)->digit_buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX, (unsigned HOST_WIDE_INT) high, low); pp_string (pp, pp_buffer (pp)->digit_buffer); } } #if __GNUC__ >= 10 # pragma GCC diagnostic pop #endif