OSDN Git Service

2004-07-14 Andreas Tobler <a.tobler@schweiz.ch>
[pf3gnuchains/gcc-fork.git] / gcc / tree-pretty-print.c
index ce1f750..e660b44 100644 (file)
@@ -55,8 +55,6 @@ static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
    lang_hooks.decl_printable_name (TREE_OPERAND (NODE, 0), 1) : \
    lang_hooks.decl_printable_name (NODE, 1))
 
-#define MASK_POINTER(P)        ((unsigned)((unsigned long)(P) & 0xffff))
-
 static pretty_printer buffer;
 static int initialized = 0;
 static bool dumping_stmts;
@@ -170,6 +168,40 @@ dump_decl_name (pretty_printer *buffer, tree node, int flags)
     }
 }
 
+/* Dump a function declaration.  NODE is the FUNCTION_TYPE.  BUFFER, SPC and
+   FLAGS are as in dump_generic_node.  */
+
+static void
+dump_function_declaration (pretty_printer *buffer, tree node,
+                          int spc, int flags)
+{
+  bool wrote_arg = false;
+  tree arg;
+
+  pp_space (buffer);
+  pp_character (buffer, '(');
+
+  /* Print the argument types.  The last element in the list is a VOID_TYPE.
+     The following avoids printing the last element.  */
+  arg = TYPE_ARG_TYPES (node);
+  while (arg && TREE_CHAIN (arg) && arg != error_mark_node)
+    {
+      wrote_arg = true;
+      dump_generic_node (buffer, TREE_VALUE (arg), spc, flags, false);
+      arg = TREE_CHAIN (arg);
+      if (TREE_CHAIN (arg) && TREE_CODE (TREE_CHAIN (arg)) == TREE_LIST)
+       {
+         pp_character (buffer, ',');
+         pp_space (buffer);
+       }
+    }
+
+  if (!wrote_arg)
+    pp_string (buffer, "void");
+
+  pp_character (buffer, ')');
+}
+
 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
    FLAGS specifies details to show in the dump (see TDF_* in tree.h).  If
    IS_STMT is true, the object printed is considered to be a statement
@@ -181,7 +213,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 {
   tree type;
   tree op0, op1;
-  const charstr;
+  const char *str;
   bool is_expr;
 
   if (node == NULL_TREE)
@@ -199,13 +231,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       && (flags & TDF_LINENO)
       && EXPR_HAS_LOCATION (node))
     {
+      expanded_location xloc = expand_location (EXPR_LOCATION (node));
       pp_character (buffer, '[');
-      if (EXPR_FILENAME (node))
+      if (xloc.file)
        {
-         pp_string (buffer, EXPR_FILENAME (node));
+         pp_string (buffer, xloc.file);
          pp_string (buffer, " : ");
        }
-      pp_decimal_int (buffer, EXPR_LINENO (node));
+      pp_decimal_int (buffer, xloc.line);
       pp_string (buffer, "] ");
     }
 
@@ -298,6 +331,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
         {
          tree fnode = TREE_TYPE (node);
+
          dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
          pp_space (buffer);
          pp_character (buffer, '(');
@@ -308,24 +342,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
            pp_printf (buffer, "<T%x>", TYPE_UID (node));
 
          pp_character (buffer, ')');
-          pp_space (buffer);
-         pp_character (buffer, '(');
-         /* Print the argument types.  The last element in the list is a
-            VOID_TYPE.  The following avoid to print the last element.  */
-         {
-           tree tmp = TYPE_ARG_TYPES (fnode);
-           while (tmp && TREE_CHAIN (tmp) && tmp != error_mark_node)
-             {
-               dump_generic_node (buffer, TREE_VALUE (tmp), spc, flags, false);
-               tmp = TREE_CHAIN (tmp);
-               if (TREE_CHAIN (tmp) && TREE_CODE (TREE_CHAIN (tmp)) == TREE_LIST)
-                 {
-                   pp_character (buffer, ',');
-                   pp_space (buffer);
-                 }
-             }
-         }
-         pp_character (buffer, ')');
+         dump_function_declaration (buffer, fnode, spc, flags);
        }
       else
         {
@@ -361,27 +378,37 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       {
        tree tmp;
 
-       /* Print the array type.  */
-       dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+       /* Print the innermost component type.  */
+       for (tmp = TREE_TYPE (node); TREE_CODE (tmp) == ARRAY_TYPE;
+            tmp = TREE_TYPE (tmp))
+         ;
+       dump_generic_node (buffer, tmp, spc, flags, false);
 
        /* Print the dimensions.  */
-       tmp = node;
-       while (tmp && TREE_CODE (tmp) == ARRAY_TYPE)
+       for (tmp = node; TREE_CODE (tmp) == ARRAY_TYPE;
+            tmp = TREE_TYPE (tmp))
          {
+           tree domain = TYPE_DOMAIN (tmp);
+
            pp_character (buffer, '[');
-           if (TYPE_SIZE (tmp))
+           if (domain)
              {
-               tree size = TYPE_SIZE (tmp);
-               if (TREE_CODE (size) == INTEGER_CST)
-                 pp_wide_integer (buffer,
-                                 TREE_INT_CST_LOW (TYPE_SIZE (tmp)) /
-                                 TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tmp))));
-               else if (TREE_CODE (size) == MULT_EXPR)
-                 dump_generic_node (buffer, TREE_OPERAND (size, 0), spc, flags, false);
-               /* else punt.  */
+               if (TYPE_MIN_VALUE (domain)
+                   && !integer_zerop (TYPE_MIN_VALUE (domain)))
+                 {
+                   dump_generic_node (buffer, TYPE_MIN_VALUE (domain),
+                                      spc, flags, false);
+                   pp_string (buffer, " .. ");
+                 }
+
+               if (TYPE_MAX_VALUE (domain))
+                 dump_generic_node (buffer, TYPE_MAX_VALUE (domain),
+                                    spc, flags, false);
              }
+           else
+             pp_string (buffer, "<unknown>");
+
            pp_character (buffer, ']');
-           tmp = TREE_TYPE (tmp);
          }
        break;
       }
@@ -392,6 +419,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 
     case RECORD_TYPE:
     case UNION_TYPE:
+    case QUAL_UNION_TYPE:
       /* Print the name of the structure.  */
       if (TREE_CODE (node) == RECORD_TYPE)
        pp_string (buffer, "struct ");
@@ -404,11 +432,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
        print_struct_decl (buffer, node, spc, flags);
       break;
 
-    case QUAL_UNION_TYPE:
-      NIY;
-      break;
-
-
     case LANG_TYPE:
       NIY;
       break;
@@ -544,30 +567,30 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       break;
 
     case TYPE_DECL:
-      if (strcmp (DECL_SOURCE_FILE (node), "<built-in>") == 0)
+      if (DECL_IS_BUILTIN (node))
        {
          /* Don't print the declaration of built-in types.  */
          break;
        }
       if (DECL_NAME (node))
-       {
-         dump_decl_name (buffer, node, flags);
-       }
+       dump_decl_name (buffer, node, flags);
       else
        {
-         if (TYPE_METHODS (TREE_TYPE (node)))
+         if ((TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
+              || TREE_CODE (TREE_TYPE (node)) == UNION_TYPE)
+             && TYPE_METHODS (TREE_TYPE (node)))
            {
              /* The type is a c++ class: all structures have at least
-                4 methods. */
+                4 methods.  */
              pp_string (buffer, "class ");
              dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
            }
          else
            {
-             pp_string (buffer, "struct ");
+             pp_string (buffer,
+                        (TREE_CODE (TREE_TYPE (node)) == UNION_TYPE
+                         ? "union" : "struct "));
              dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
-             pp_character (buffer, ';');
-             pp_newline (buffer);
            }
        }
       break;
@@ -598,6 +621,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
        pp_character (buffer, ')');
       pp_string (buffer, str);
       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+
+      op0 = component_ref_field_offset (node);
+      if (op0 && TREE_CODE (op0) != INTEGER_CST)
+       {
+         pp_string (buffer, "{off: ");
+         dump_generic_node (buffer, op0, spc, flags, false);
+         pp_character (buffer, '}');
+       }
       break;
 
     case BIT_FIELD_REF:
@@ -610,11 +641,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_string (buffer, ">");
       break;
 
-    case BUFFER_REF:
-      NIY;
-      break;
-
     case ARRAY_REF:
+    case ARRAY_RANGE_REF:
       op0 = TREE_OPERAND (node, 0);
       if (op_prio (op0) < op_prio (node))
        pp_character (buffer, '(');
@@ -623,11 +651,23 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
        pp_character (buffer, ')');
       pp_character (buffer, '[');
       dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
+      if (TREE_CODE (node) == ARRAY_RANGE_REF)
+       pp_string (buffer, " ...");
       pp_character (buffer, ']');
-      break;
 
-    case ARRAY_RANGE_REF:
-      NIY;
+      op0 = array_ref_low_bound (node);
+      op1 = array_ref_element_size (node);
+
+      if (!integer_zerop (op0)
+         || (TYPE_SIZE_UNIT (TREE_TYPE (node))
+             && !operand_equal_p (op1, TYPE_SIZE_UNIT (TREE_TYPE (node)), 0)))
+       {
+         pp_string (buffer, "{lb: ");
+         dump_generic_node (buffer, op0, spc, flags, false);
+         pp_string (buffer, " sz: ");
+         dump_generic_node (buffer, op1, spc, flags, false);
+         pp_character (buffer, '}');
+       }
       break;
 
     case CONSTRUCTOR:
@@ -741,14 +781,21 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       break;
 
     case TARGET_EXPR:
-      dump_generic_node (buffer, TYPE_NAME (TREE_TYPE (node)), spc, flags, false);
-      pp_character (buffer, '(');
+      pp_string (buffer, "TARGET_EXPR <");
+      dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
+      pp_character (buffer, ',');
+      pp_space (buffer);
       dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
-      pp_character (buffer, ')');
+      pp_character (buffer, '>');
+      break;
+
+    case DECL_EXPR:
+      print_declaration (buffer, DECL_EXPR_DECL (node), spc, flags);
+      is_stmt = false;
       break;
 
     case COND_EXPR:
-      if (TREE_TYPE (node) == void_type_node)
+      if (TREE_TYPE (node) == NULL || TREE_TYPE (node) == void_type_node)
        {
          pp_string (buffer, "if (");
          dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
@@ -865,7 +912,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       break;
 
     case PLACEHOLDER_EXPR:
-      NIY;
+      pp_string (buffer, "<PLACEHOLDER_EXPR ");
+      dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
+      pp_character (buffer, '>');
       break;
 
       /* Binary arithmetic and logic expressions.  */
@@ -946,7 +995,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
     case BIT_NOT_EXPR:
     case TRUTH_NOT_EXPR:
     case ADDR_EXPR:
-    case REFERENCE_EXPR:
     case PREDECREMENT_EXPR:
     case PREINCREMENT_EXPR:
     case INDIRECT_REF:
@@ -1002,18 +1050,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_character (buffer, '>');
       break;
 
-    case IN_EXPR:
-      NIY;
-      break;
-
-    case SET_LE_EXPR:
-      NIY;
-      break;
-
-    case CARD_EXPR:
-      NIY;
-      break;
-
     case RANGE_EXPR:
       NIY;
       break;
@@ -1066,10 +1102,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_character (buffer, '>');
       break;
 
-    case RTL_EXPR:
-      NIY;
-      break;
-
     case ENTRY_VALUE_EXPR:
       NIY;
       break;
@@ -1153,10 +1185,6 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       is_expr = false;
       break;
 
-    case GOTO_SUBROUTINE_EXPR:
-      NIY;
-      break;
-
     case LABEL_EXPR:
       op0 = TREE_OPERAND (node, 0);
       /* If this is for break or continue, don't bother printing it.  */
@@ -1348,96 +1376,17 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_character (buffer, ':');
       break;
 
-    case VTABLE_REF:
-      pp_string (buffer, "VTABLE_REF <(");
-      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
-      pp_string (buffer, "),");
-      dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
-      pp_character (buffer, ',');
-      dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
+    case OBJ_TYPE_REF:
+      pp_string (buffer, "OBJ_TYPE_REF(");
+      dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
+      pp_character (buffer, ';');
+      dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
+      pp_character (buffer, '-');
       pp_character (buffer, '>');
+      dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
+      pp_character (buffer, ')');
       break;
 
-    case EPHI_NODE:
-      {
-       int i;
-
-       pp_string (buffer, " EPHI (");
-       dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
-       pp_string (buffer, ") ");
-       pp_character (buffer, '[');
-       pp_string (buffer, " class:");
-       pp_decimal_int (buffer, EREF_CLASS (node));
-       if (EPHI_DOWNSAFE (node))
-         pp_string (buffer, " downsafe");
-       if (EPHI_CANT_BE_AVAIL (node))
-         pp_string (buffer, " cant_be_avail");
-       if (EPHI_STOPS (node))
-         pp_string (buffer, " stops");
-       pp_string (buffer, " bb:");
-       pp_decimal_int (buffer, bb_for_stmt (node)->index);
-       pp_character (buffer, ']');
-       if (! (flags & TDF_SLIM))
-         {
-           pp_string (buffer, " <");
-           for (i = 0; i < EPHI_NUM_ARGS (node); i++)
-             {     
-               if (EPHI_ARG_DEF (node, i))
-                 {
-                   newline_and_indent (buffer, spc + 2);
-                   pp_string (buffer, " edge ");
-                   pp_decimal_int (buffer, EPHI_ARG_EDGE (node, i)->src->index);
-                   pp_string (buffer, "->");
-                   pp_decimal_int (buffer, EPHI_ARG_EDGE (node, i)->dest->index);
-                   pp_string (buffer, " [ ");
-                   if (EPHI_ARG_HAS_REAL_USE (node, i))
-                     pp_string (buffer, " real use");
-                   if (EPHI_ARG_INJURED (node, i))
-                     pp_string (buffer, " injured");
-                   if (EPHI_ARG_STOPS (node, i))
-                     pp_string (buffer, " stops");
-                   pp_string (buffer, " ] ");
-                   pp_string (buffer, " defined by:");
-                   dump_generic_node (buffer, EPHI_ARG_DEF (node, i),
-                                      spc + 4, flags | TDF_SLIM, false);
-                 }
-             }
-         }
-       pp_string (buffer, " >");
-      }
-      break;
-    case EEXIT_NODE:
-    case EKILL_NODE:
-      if (TREE_CODE (node) == EEXIT_NODE)
-       pp_string (buffer, "EEXIT (");
-      else if (TREE_CODE (node) == EKILL_NODE)
-       pp_string (buffer, "EKILL (");
-      dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
-      pp_string (buffer, ") ");
-      pp_character (buffer, '[');
-      pp_string (buffer, "class:");
-      pp_decimal_int (buffer, EREF_CLASS (node));
-      pp_string (buffer, " bb:");
-      pp_decimal_int (buffer, bb_for_stmt (node)->index);
-      pp_character (buffer, ']');
-      break;
-    case EUSE_NODE:
-      pp_string (buffer, " EUSE (");
-      dump_generic_node (buffer, EREF_NAME (node), spc, flags, false);
-
-      pp_string (buffer, ") ");
-      pp_character (buffer, '[');
-      pp_string (buffer, "class:");
-      pp_decimal_int (buffer, EREF_CLASS (node));
-      pp_string (buffer, " phiop:");
-      pp_decimal_int (buffer, EUSE_PHIOP (node));
-      pp_string (buffer, " bb:");
-      pp_decimal_int (buffer, bb_for_stmt (node)->index);
-      if (EUSE_LVAL (node))
-       pp_string (buffer, " left-occurrence");
-      pp_string (buffer, " ]");
-       
-      break;
     case PHI_NODE:
       {
        int i;
@@ -1463,6 +1412,10 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_decimal_int (buffer, SSA_NAME_VERSION (node));
       break;
 
+    case VALUE_HANDLE:
+      pp_printf (buffer, "VH.%d", VALUE_HANDLE_ID (node));
+      break;
+
     default:
       NIY;
     }
@@ -1479,12 +1432,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
 static void
 print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
 {
-  /* Don't print type declarations.  */
-  if (TREE_CODE (t) == TYPE_DECL)
-    return;
-
   INDENT (spc);
 
+  if (TREE_CODE (t) == TYPE_DECL)
+    pp_string (buffer, "typedef ");
+
   if (DECL_REGISTER (t))
     pp_string (buffer, "register ");
 
@@ -1527,6 +1479,13 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
          tmp = TREE_TYPE (tmp);
        }
     }
+  else if (TREE_CODE (t) == FUNCTION_DECL)
+    {
+      dump_generic_node (buffer, TREE_TYPE (TREE_TYPE (t)), spc, flags, false);
+      pp_space (buffer);
+      dump_decl_name (buffer, t, flags);
+      dump_function_declaration (buffer, TREE_TYPE (t), spc, flags);
+    }
   else
     {
       /* Print type declaration.  */
@@ -1568,10 +1527,10 @@ print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
       INDENT (spc);
       if (TREE_CODE (node) == RECORD_TYPE)
        pp_string (buffer, "struct ");
-      else if (TREE_CODE (node) == UNION_TYPE)
+      else if ((TREE_CODE (node) == UNION_TYPE
+               || TREE_CODE (node) == QUAL_UNION_TYPE))
        pp_string (buffer, "union ");
-      else
-       NIY;
+
       dump_generic_node (buffer, TYPE_NAME (node), spc, 0, false);
     }
 
@@ -1593,16 +1552,12 @@ print_struct_decl (pretty_printer *buffer, tree node, int spc, int flags)
           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))
+           || (TREE_CODE (TREE_TYPE (tmp)) == POINTER_TYPE
+               && TREE_TYPE (TREE_TYPE (tmp)) != node))
          {
            print_declaration (buffer, tmp, spc+2, flags);
            pp_newline (buffer);
          }
-       else
-         {
-
-         }
        tmp = TREE_CHAIN (tmp);
       }
   }
@@ -1734,6 +1689,7 @@ op_prio (tree op)
 
     case CALL_EXPR:
     case ARRAY_REF:
+    case ARRAY_RANGE_REF:
     case COMPONENT_REF:
       return 15;
 
@@ -1874,9 +1830,6 @@ op_symbol (tree op)
     case POSTINCREMENT_EXPR:
       return "++ ";
 
-    case REFERENCE_EXPR:
-      return "";
-
     default:
       return "<<< ??? >>>";
     }
@@ -1940,6 +1893,7 @@ print_call_name (pretty_printer *buffer, tree node)
       break;
 
     case SSA_NAME:
+    case OBJ_TYPE_REF:
       dump_generic_node (buffer, op0, 0, 0, false);
       break;
 
@@ -2061,15 +2015,27 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
 {
   size_t i;
   stmt_ann_t ann = stmt_ann (stmt);
-  vdef_optype vdefs = VDEF_OPS (ann);
+  v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
+  v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann);
   vuse_optype vuses = VUSE_OPS (ann);
 
-  for (i = 0; i < NUM_VDEFS (vdefs); i++)
+  for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
     {
       pp_string (buffer, "#   ");
-      dump_generic_node (buffer, VDEF_RESULT (vdefs, i), spc + 2, flags, false);
-      pp_string (buffer, " = VDEF <");
-      dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, false);
+      dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i), 
+                         spc + 2, flags, false);
+      pp_string (buffer, " = V_MAY_DEF <");
+      dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i), 
+                         spc + 2, flags, false);
+      pp_string (buffer, ">;");
+      newline_and_indent (buffer, spc);
+    }
+
+  for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
+    {
+      tree v_must_def = V_MUST_DEF_OP (v_must_defs, i);
+      pp_string (buffer, "#   V_MUST_DEF <");
+      dump_generic_node (buffer, v_must_def, spc + 2, flags, false);
       pp_string (buffer, ">;");
       newline_and_indent (buffer, spc);
     }
@@ -2189,7 +2155,7 @@ dump_phi_nodes (pretty_printer *buffer, basic_block bb, int indent, int flags)
   if (!phi)
     return;
 
-  for (; phi; phi = TREE_CHAIN (phi))
+  for (; phi; phi = PHI_CHAIN (phi))
     {
       if (is_gimple_reg (PHI_RESULT (phi)) || (flags & TDF_VOPS))
         {
@@ -2227,7 +2193,8 @@ pp_cfg_jump (pretty_printer *buffer, basic_block bb)
    by INDENT spaces, with details given by FLAGS.  */
 
 static void
-dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent)
+dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
+                    int flags)
 {
   edge e;
 
@@ -2239,6 +2206,31 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent)
   if (e && e->dest != bb->next_bb)
     {
       INDENT (indent);
+
+      if ((flags & TDF_LINENO)
+#ifdef USE_MAPPED_LOCATION
+         && e->goto_locus != UNKNOWN_LOCATION
+#else
+         && e->goto_locus
+#endif
+         )
+       {
+         expanded_location goto_xloc;
+#ifdef USE_MAPPED_LOCATION
+         goto_xloc = expand_location (e->goto_locus);
+#else
+         goto_xloc = *e->goto_locus;
+#endif
+         pp_character (buffer, '[');
+         if (goto_xloc.file)
+           {
+             pp_string (buffer, goto_xloc.file);
+             pp_string (buffer, " : ");
+           }
+         pp_decimal_int (buffer, goto_xloc.line);
+         pp_string (buffer, "] ");
+       }
+
       pp_cfg_jump (buffer, e->dest);
       pp_newline (buffer);
     }
@@ -2276,7 +2268,7 @@ dump_generic_bb_buff (pretty_printer *buffer, basic_block bb,
       pp_newline (buffer);
     }
 
-  dump_implicit_edges (buffer, bb, indent);
+  dump_implicit_edges (buffer, bb, indent, flags);
 
   if (flags & TDF_BLOCKS)
     dump_bb_end (buffer, bb, indent, flags);