This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Ada] Preserve Taft Amendment types in debug info


Taft Amendment types are incomplete types declared in the spec and whose 
completion is in the body of the package.  As such, their full definition 
isn't visible from other compilation units.  Therefore, they need a specific 
treatment to make sure that the definition is preserved in the debug info.

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


2011-04-02  Eric Botcazou  <ebotcazou@adacore.com>

	* gcc-interface/ada-tree.h (DECL_TAFT_TYPE_P): New flag.
	* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Incomplete_Type>: Set it
	if this is a Taft amendment type and the full declaration is available.
	* gcc-interface/trans.c (process_type): Likewise.
	If there is an old type, mark the new one as used if DECL_TAFT_TYPE_P.
	(process_freeze_entity): Likewise.
	* gcc-interface/utils.c (dummy_global): New static variable.
	(gnat_write_global_declarations): If there are types declared as used
	at the global level, insert them in the global hash table.


-- 
Eric Botcazou
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 171880)
+++ gcc-interface/utils.c	(working copy)
@@ -4736,9 +4736,28 @@ smaller_form_type_p (tree type, tree ori
 
 /* Perform final processing on global variables.  */
 
+static GTY (()) tree dummy_global;
+
 void
 gnat_write_global_declarations (void)
 {
+  /* If we have declared types as used at the global level, insert them in
+     the global hash table.  We use a dummy variable for this purpose.  */
+  if (!VEC_empty (tree, types_used_by_cur_var_decl))
+    {
+      dummy_global
+	= build_decl (BUILTINS_LOCATION, VAR_DECL, NULL_TREE, void_type_node);
+      TREE_STATIC (dummy_global) = 1;
+      TREE_ASM_WRITTEN (dummy_global) = 1;
+      varpool_mark_needed_node (varpool_node (dummy_global));
+
+      while (!VEC_empty (tree, types_used_by_cur_var_decl))
+	{
+	  tree t = VEC_pop (tree, types_used_by_cur_var_decl);
+	  types_used_by_var_decl_insert (t, dummy_global);
+	}
+    }
+
   /* Proceed to optimize and emit assembly.
      FIXME: shouldn't be the front end's responsibility to call this.  */
   cgraph_finalize_compilation_unit ();
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c	(revision 171879)
+++ gcc-interface/decl.c	(working copy)
@@ -4469,6 +4469,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
 	   we can do any needed updates when we see it.  */
 	gnu_type = make_dummy_type (gnat_entity);
 	gnu_decl = TYPE_STUB_DECL (gnu_type);
+	if (Has_Completion_In_Body (gnat_entity))
+	  DECL_TAFT_TYPE_P (gnu_decl) = 1;
 	save_gnu_tree (full_view, gnu_decl, 0);
 	break;
       }
Index: gcc-interface/trans.c
===================================================================
--- gcc-interface/trans.c	(revision 171880)
+++ gcc-interface/trans.c	(working copy)
@@ -6609,11 +6609,17 @@ process_freeze_entity (Node_Id gnat_node
       && Root_Type (Class_Wide_Type (gnat_entity)) == gnat_entity)
     save_gnu_tree (Class_Wide_Type (gnat_entity), gnu_new, false);
 
-  /* If we've made any pointers to the old version of this type, we
-     have to update them.  */
+  /* If we have an old type and we've made pointers to this type, update those
+     pointers.  If this is a Taft amendment type in the main unit, we need to
+     mark the type as used since other units referencing it don't see the full
+     declaration and, therefore, cannot mark it as used themselves.  */
   if (gnu_old)
-    update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
-		       TREE_TYPE (gnu_new));
+    {
+      update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
+			 TREE_TYPE (gnu_new));
+      if (DECL_TAFT_TYPE_P (gnu_old))
+	used_types_insert (TREE_TYPE (gnu_new));
+    }
 }
 
 /* Elaborate decls in the lists GNAT_DECLS and GNAT_DECLS2, if present.
@@ -7456,7 +7462,11 @@ process_type (Entity_Id gnat_entity)
 	  save_gnu_tree (gnat_entity, gnu_decl, false);
 	  if (IN (Ekind (gnat_entity), Incomplete_Or_Private_Kind)
 	      && Present (Full_View (gnat_entity)))
-	    save_gnu_tree (Full_View (gnat_entity), gnu_decl, false);
+	    {
+	      if (Has_Completion_In_Body (gnat_entity))
+		DECL_TAFT_TYPE_P (gnu_decl) = 1;
+	      save_gnu_tree (Full_View (gnat_entity), gnu_decl, false);
+	    }
 	}
 
       return;
@@ -7478,11 +7488,17 @@ process_type (Entity_Id gnat_entity)
   gnu_new = gnat_to_gnu_entity (gnat_entity, NULL_TREE, 1);
   gcc_assert (TREE_CODE (gnu_new) == TYPE_DECL);
 
-  /* If we have an old type and we've made pointers to this type,
-     update those pointers.  */
+  /* If we have an old type and we've made pointers to this type, update those
+     pointers.  If this is a Taft amendment type in the main unit, we need to
+     mark the type as used since other units referencing it don't see the full
+     declaration and, therefore, cannot mark it as used themselves.  */
   if (gnu_old)
-    update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
-		       TREE_TYPE (gnu_new));
+    {
+      update_pointer_to (TYPE_MAIN_VARIANT (TREE_TYPE (gnu_old)),
+			 TREE_TYPE (gnu_new));
+      if (DECL_TAFT_TYPE_P (gnu_old))
+	used_types_insert (TREE_TYPE (gnu_new));
+    }
 
   /* If this is a record type corresponding to a task or protected type
      that is a completion of an incomplete type, perform a similar update
Index: gcc-interface/ada-tree.h
===================================================================
--- gcc-interface/ada-tree.h	(revision 171818)
+++ gcc-interface/ada-tree.h	(working copy)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                              C Header File                               *
  *                                                                          *
- *          Copyright (C) 1992-2010, Free Software Foundation, Inc.         *
+ *          Copyright (C) 1992-2011, Free Software Foundation, Inc.         *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
@@ -336,6 +336,10 @@ do {						   \
    pair of INDIRECT_REFs is needed to access the object.  */
 #define DECL_BY_DOUBLE_REF_P(NODE) DECL_LANG_FLAG_0 (PARM_DECL_CHECK (NODE))
 
+/* Nonzero in a TYPE_DECL if this is the declaration of a Taft amendment type
+   in the main unit, i.e. the full declaration is available.  */
+#define DECL_TAFT_TYPE_P(NODE) DECL_LANG_FLAG_0 (TYPE_DECL_CHECK (NODE))
+
 /* Nonzero in a DECL if it is always used by reference, i.e. an INDIRECT_REF
    is needed to access the object.  */
 #define DECL_BY_REF_P(NODE) DECL_LANG_FLAG_1 (NODE)

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]