Patchwork [Ada] Fix small inaccuracies in debug info

login
register
mail settings
Submitter Eric Botcazou
Date Jan. 4, 2011, 9:28 a.m.
Message ID <201101041028.14014.ebotcazou@adacore.com>
Download mbox | patch
Permalink /patch/77440/
State New
Headers show

Comments

Eric Botcazou - Jan. 4, 2011, 9:28 a.m.
This fixes small inaccuracies in debug info, more precisely source line info, 
related to the cleanup code associated with VLAs.

Tested on i586-suse-linux, applied on the mainline.


2011-01-04  Olivier Hainque  <hainque@adacore.com>
            Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/trans.c (BLOCK_SOURCE_END_LOCATION): Provide default.
	(set_end_locus_from_node): New function.
	(Subprogram_Body_to_gnu): Use it to mark both the inner BIND_EXPR we
	make and the function end_locus.
	(Compilation_Unit_to_gnu): Call it instead of a straight Sloc_to_locus
	for the elaboration subprogram.
	(set_gnu_expr_location_from_node) <default case>: Use it to attempt to
	set the end_locus of the expression as well.

Patch

Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 168454)
+++ gcc-interface/trans.c	(working copy)
@@ -64,6 +64,13 @@ 
 #define TARGET_ABI_OPEN_VMS 0
 #endif
 
+/* In configurations where blocks have no end_locus attached, just
+   sink assignments into a dummy global.  */
+#ifndef BLOCK_SOURCE_END_LOCATION
+static location_t block_end_locus_sink;
+#define BLOCK_SOURCE_END_LOCATION(BLOCK) block_end_locus_sink
+#endif
+
 /* For efficient float-to-int rounding, it is necessary to know whether
    floating-point arithmetic may use wider intermediate results.  When
    FP_ARITH_MAY_WIDEN is not defined, be conservative and only assume
@@ -205,6 +212,7 @@  static tree extract_values (tree, tree);
 static tree pos_to_constructor (Node_Id, tree, Entity_Id);
 static tree maybe_implicit_deref (tree);
 static void set_expr_location_from_node (tree, Node_Id);
+static bool set_end_locus_from_node (tree, Node_Id);
 static void set_gnu_expr_location_from_node (tree, Node_Id);
 static int lvalue_required_p (Node_Id, tree, bool, bool, bool);
 static tree build_raise_check (int, tree, enum exception_info_kind);
@@ -2654,15 +2662,14 @@  Subprogram_Body_to_gnu (Node_Id gnat_nod
       gnu_result = end_stmt_group ();
     }
 
-  /* Set the end location.  */
-  Sloc_to_locus
-    ((Present (End_Label (Handled_Statement_Sequence (gnat_node)))
-      ? Sloc (End_Label (Handled_Statement_Sequence (gnat_node)))
-      : Sloc (gnat_node)),
-     &DECL_STRUCT_FUNCTION (gnu_subprog_decl)->function_end_locus);
-
   end_subprog_body (gnu_result);
 
+  /* Attempt setting the end_locus of our GCC body tree, typically a
+     BIND_EXPR or STATEMENT_LIST, then the end_locus of our GCC subprogram
+     declaration tree.  */
+  set_end_locus_from_node (gnu_result, gnat_node);
+  set_end_locus_from_node (gnu_subprog_decl, gnat_node);
+
   /* Finally annotate the parameters and disconnect the trees for parameters
      that we have turned into variables since they are now unusable.  */
   for (gnat_param = First_Formal_With_Extras (gnat_subprog_id);
@@ -3797,9 +3804,7 @@  Compilation_Unit_to_gnu (Node_Id gnat_no
   gnat_poplevel ();
   DECL_SAVED_TREE (gnu_elab_proc_decl) = end_stmt_group ();
 
-  Sloc_to_locus
-    (Sloc (gnat_unit),
-     &DECL_STRUCT_FUNCTION (gnu_elab_proc_decl)->function_end_locus);
+  set_end_locus_from_node (gnu_elab_proc_decl, gnat_unit);
 
   info->next = elab_info_list;
   info->elab_proc = gnu_elab_proc_decl;
@@ -7741,7 +7746,10 @@  set_gnu_expr_location_from_node (tree no
 
     default:
       if (!REFERENCE_CLASS_P (node) && !EXPR_HAS_LOCATION (node))
-	set_expr_location_from_node (node, gnat_node);
+	{
+	  set_expr_location_from_node (node, gnat_node);
+	  set_end_locus_from_node (node, gnat_node);
+	}
       break;
     }
 }
@@ -7806,6 +7814,61 @@  post_error_ne_num (const char *msg, Node
   Error_Msg_Uint_1 = UI_From_Int (num);
   post_error_ne (msg, node, ent);
 }
+
+/* Set the end_locus information for GNU_NODE, if any, from an explicit end
+   location associated with GNAT_NODE or GNAT_NODE itself, whichever makes
+   most sense.  Return true if a sensible assignment was performed.  */
+
+static bool
+set_end_locus_from_node (tree gnu_node, Node_Id gnat_node)
+{
+  Node_Id gnat_end_label = Empty;
+  location_t end_locus;
+
+  /* Pick the GNAT node of which we'll take the sloc to assign to the GCC node
+     end_locus when there is one.  We consider only GNAT nodes with a possible
+     End_Label attached.  If the End_Label actually was unassigned, fallback
+     on the orginal node.  We'd better assign an explicit sloc associated with
+     the outer construct in any case.  */
+
+  switch (Nkind (gnat_node))
+    {
+    case N_Package_Body:
+    case N_Subprogram_Body:
+    case N_Block_Statement:
+      gnat_end_label = End_Label (Handled_Statement_Sequence (gnat_node));
+      break;
+
+    case N_Package_Declaration:
+      gnat_end_label = End_Label (Specification (gnat_node));
+      break;
+
+    default:
+      return false;
+    }
+
+  gnat_node = Present (gnat_end_label) ? gnat_end_label : gnat_node;
+
+  /* Some expanded subprograms have neither an End_Label nor a Sloc
+     attached.  Notify that to callers.  */
+
+  if (!Sloc_to_locus (Sloc (gnat_node), &end_locus))
+    return false;
+
+  switch (TREE_CODE (gnu_node))
+    {
+    case BIND_EXPR:
+      BLOCK_SOURCE_END_LOCATION (BIND_EXPR_BLOCK (gnu_node)) = end_locus;
+      return true;
+
+    case FUNCTION_DECL:
+      DECL_STRUCT_FUNCTION (gnu_node)->function_end_locus = end_locus;
+      return true;
+
+    default:
+      return false;
+    }
+}
 
 /* Similar to post_error_ne, but T is a GCC tree representing the number to
    write.  If T represents a constant, the text inside curly brackets in