Taft amendment types are incomplete types declared in a package spec whose 
completion is declared in the body.  This means that other units don't have 
access to their full view at all and treat them as incomplete types.  This is 
problematic when debugging information is requested because their compilation 
might be finalized in the wrong context, i.e. from within a subprogram.

Fixed thusly, tested on i586-suse-linux, applied on the mainline.


2011-06-06  Eric Botcazou  <ebotca...@adacore.com>

        * gcc-interface/utils.c: Include diagnostic.h.
        (gnat_write_global_declarations): Output debug information for all
        global type declarations before finalizing the compilation unit.
        * gcc-interface/Make-lang.in (ada/utils.o): Add dependency.


2011-06-06  Eric Botcazou  <ebotca...@adacore.com>

        * gnat.dg/test_tamdt.adb: Rename to...
        * gnat.dg/taft_type1.adb: ...this.
        * gnat.dg/tamdt.ad[sb]: Rename to...
        * gnat.dg/taft_type1_pkg1.ad[sb]: ...this.
        * gnat.dg/tamdt_aux.ads: Rename to...
        * gnat.dg/taft_type1_pkg2.ads: ...this.
        * gnat.dg/taft_type2.ad[sb]: New test.
        * gnat.dg/taft_type2_pkg.ads: New helper.
        * gnat.dg/taft_type3.adb: New test.
        * gnat.dg/taft_type3_pkg.ads: New helper.


-- 
Eric Botcazou
-- { dg-do compile }
-- { dg-options "-g" }

with Taft_Type2_Pkg; use Taft_Type2_Pkg;

package body Taft_Type2 is

   procedure Proc is
      A : T;

      function F return T is
         My_T : T;
      begin
         My_T := Open;
         return My_T;
      end;

   begin
      A := F;
   end;

end Taft_Type2;
package Taft_Type2 is

   procedure Proc;

end Taft_Type2;
package Taft_Type2_Pkg  is

   type T is private;

   function Open return T;

private

   type Buffer_T;
   type T is access Buffer_T;

end Taft_Type2_Pkg;
-- { dg-do compile }
-- { dg-options "-g" }

with Taft_Type3_Pkg; use Taft_Type3_Pkg;

procedure Taft_Type3 is

  subtype S is String (1..32);

  Empty : constant S := (others => ' ');

  procedure Proc (Data : in out T) is begin null; end;

  task type Task_T is
    entry Send (Data : in out T);
  end;

  task body Task_T is
    type List_T is array (1 .. 4) of S;
    L : List_T := (others => Empty);
  begin
    accept Send (Data : in out T) do
      Proc (Data);
    end;
  end;

begin
  null;
end;
package Taft_Type3_Pkg is

  type T is private;

private

  type Buffer_T;
  type T is access Buffer_T;

end Taft_Type3_Pkg;
Index: gcc-interface/utils.c
===================================================================
--- gcc-interface/utils.c	(revision 174631)
+++ gcc-interface/utils.c	(working copy)
@@ -38,6 +38,7 @@
 #include "target.h"
 #include "langhooks.h"
 #include "cgraph.h"
+#include "diagnostic.h"
 #include "tree-dump.h"
 #include "tree-inline.h"
 #include "tree-iterator.h"
@@ -4756,6 +4757,9 @@ static GTY (()) tree dummy_global;
 void
 gnat_write_global_declarations (void)
 {
+  unsigned int i;
+  tree iter;
+
   /* 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))
@@ -4773,13 +4777,28 @@ gnat_write_global_declarations (void)
 	}
     }
 
+  /* Output debug information for all global type declarations first.  This
+     ensures that global types whose compilation hasn't been finalized yet,
+     for example pointers to Taft amendment types, have their compilation
+     finalized in the right context.  */
+  FOR_EACH_VEC_ELT (tree, global_decls, i, iter)
+    if (TREE_CODE (iter) == TYPE_DECL)
+      debug_hooks->global_decl (iter);
+
   /* Proceed to optimize and emit assembly.
      FIXME: shouldn't be the front end's responsibility to call this.  */
   cgraph_finalize_compilation_unit ();
 
-  /* Emit debug info for all global declarations.  */
-  emit_debug_global_declarations (VEC_address (tree, global_decls),
-				  VEC_length (tree, global_decls));
+  /* After cgraph has had a chance to emit everything that's going to
+     be emitted, output debug information for the rest of globals.  */
+  if (!seen_error ())
+    {
+      timevar_push (TV_SYMOUT);
+      FOR_EACH_VEC_ELT (tree, global_decls, i, iter)
+	if (TREE_CODE (iter) != TYPE_DECL)
+	  debug_hooks->global_decl (iter);
+      timevar_pop (TV_SYMOUT);
+    }
 }
 
 /* ************************************************************************
Index: gcc-interface/Make-lang.in
===================================================================
--- gcc-interface/Make-lang.in	(revision 174631)
+++ gcc-interface/Make-lang.in	(working copy)
@@ -1237,7 +1237,7 @@ ada/trans.o : ada/gcc-interface/trans.c
 
 ada/utils.o : ada/gcc-interface/utils.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    $(TM_H) $(TREE_H) $(FLAGS_H) toplev.h $(RTL_H) output.h debug.h convert.h \
-   $(TARGET_H) function.h langhooks.h $(CGRAPH_H) \
+   $(TARGET_H) function.h langhooks.h $(CGRAPH_H) $(DIAGNOSTIC_H) \
    $(TREE_DUMP_H) $(TREE_INLINE_H) tree-iterator.h \
    ada/gcc-interface/ada.h ada/types.h ada/atree.h ada/elists.h ada/namet.h \
    ada/nlists.h ada/stringt.h ada/uintp.h ada/fe.h ada/sinfo.h ada/einfo.h \

Reply via email to