[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Tue, 2 Aug 2011 13:00:21 +0000 (15:00 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Tue, 2 Aug 2011 13:00:21 +0000 (15:00 +0200)
2011-08-02  Geert Bosch  <bosch@adacore.com>

* gcc-interface/gigi.h, gcc-interface/misc.c (enumerate_modes): New
function.
* gcc-interface/Make-lang.in: Update dependencies.

2011-08-02  Olivier Hainque  <hainque@adacore.com>

* gcc-interface/trans.c (Subprogram_Body_to_gnu): Set the function
end_locus.

From-SVN: r177141

gcc/ada/ChangeLog
gcc/ada/gcc-interface/Make-lang.in
gcc/ada/gcc-interface/gigi.h
gcc/ada/gcc-interface/misc.c
gcc/ada/gcc-interface/trans.c

index 0d78dae154e7cc7e040fc39495a39de763326b57..d249de0df52c14695074a6b7884b210089815c51 100644 (file)
@@ -1,3 +1,14 @@
+2011-08-02  Geert Bosch  <bosch@adacore.com>
+
+       * gcc-interface/gigi.h, gcc-interface/misc.c (enumerate_modes): New
+       function.
+       * gcc-interface/Make-lang.in: Update dependencies.
+
+2011-08-02  Olivier Hainque  <hainque@adacore.com>
+
+       * gcc-interface/trans.c (Subprogram_Body_to_gnu): Set the function
+       end_locus.
+
 2011-08-02  Javier Miranda  <miranda@adacore.com>
 
        * sem_ch3.adb (Check_Anonymous_Access_Components): Create extra formals
index 96cf1c628ad661985234c7263d6f93d25af74cc6..c745c404f83ba0fce05619f56084860a43085a3e 100644 (file)
@@ -333,6 +333,7 @@ GNAT_ADA_OBJS =     \
  ada/urealp.o  \
  ada/usage.o   \
  ada/validsw.o \
+ ada/warnsw.o   \
  ada/widechar.o
 
 # Object files for gnat executables
@@ -1530,14 +1531,14 @@ ada/csets.o : ada/ada.ads ada/a-unccon.ads ada/a-uncdea.ads ada/csets.ads \
 
 ada/cstand.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
    ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
-   ada/atree.adb ada/casing.ads ada/checks.ads ada/csets.ads \
-   ada/cstand.ads ada/cstand.adb ada/debug.ads ada/einfo.ads ada/einfo.adb \
-   ada/elists.ads ada/err_vars.ads ada/errout.ads ada/errout.adb \
-   ada/erroutc.ads ada/erroutc.adb ada/exp_ch11.ads ada/exp_disp.ads \
-   ada/exp_tss.ads ada/exp_util.ads ada/fname.ads ada/freeze.ads \
-   ada/get_targ.ads ada/gnat.ads ada/g-htable.ads ada/gnatvsn.ads \
-   ada/hostparm.ads ada/interfac.ads ada/layout.ads ada/lib.ads \
-   ada/lib-xref.ads ada/namet.ads ada/namet.adb ada/nlists.ads \
+   ada/atree.adb ada/back_end.ads ada/casing.ads ada/checks.ads \
+   ada/csets.ads ada/cstand.ads ada/cstand.adb ada/debug.ads ada/einfo.ads \
+   ada/einfo.adb ada/elists.ads ada/err_vars.ads ada/errout.ads \
+   ada/errout.adb ada/erroutc.ads ada/erroutc.adb ada/exp_ch11.ads \
+   ada/exp_disp.ads ada/exp_tss.ads ada/exp_util.ads ada/fname.ads \
+   ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
+   ada/gnatvsn.ads ada/hostparm.ads ada/interfac.ads ada/layout.ads \
+   ada/lib.ads ada/lib-xref.ads ada/namet.ads ada/namet.adb ada/nlists.ads \
    ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
    ada/restrict.ads ada/rident.ads ada/rtsfind.ads ada/scans.ads \
    ada/scn.ads ada/scng.ads ada/scng.adb ada/sem.ads ada/sem_attr.ads \
index e8a725979e806089566b661f3af2c64389ad063d..13c9f5418f8a05f458f6079bf5da0601460b6228 100644 (file)
@@ -929,6 +929,11 @@ extern bool default_pass_by_ref (tree gnu_type);
    if it should be passed by reference.  */
 extern bool must_pass_by_ref (tree gnu_type);
 
+/* This function is called by the front-end to enumerate all the supported
+   modes for the machine, as well as some predefined C types.  */
+extern void enumerate_modes (void (*f) (const char *, int, int, int, int, int,
+                                        int));
+
 /* Return the size of the FP mode with precision PREC.  */
 extern int fp_prec_to_size (int prec);
 
index 62e7ac7769bcb528e298d1bdf95d54821de405fc..a03bb0fbf35d691ce3a648ad6cd3dfe5b2fc7cec 100644 (file)
@@ -39,6 +39,7 @@
 #include "opts.h"
 #include "options.h"
 #include "plugin.h"
+#include "real.h"
 #include "function.h"  /* For pass_by_reference.  */
 
 #include "ada.h"
@@ -636,6 +637,124 @@ must_pass_by_ref (tree gnu_type)
              && TREE_CODE (TYPE_SIZE (gnu_type)) != INTEGER_CST));
 }
 
+/* This function is called by the front-end to enumerate all the supported
+   modes for the machine, as well as some predefined C types.  F is a function
+   which is called back with the parameters as listed below, first a string,
+   then six ints.  The name is any arbitrary null-terminated string and has
+   no particular significance, except for the case of predefined C types, where
+   it should be the name of the C type.  For integer types, only signed types
+   should be listed, unsigned versions are assumed.  The order of types should
+   be in order of preference, with the smallest/cheapest types first.
+
+   In particular, C predefined types should be listed before other types,
+   binary floating point types before decimal ones, and narrower/cheaper
+   type versions before more expensive ones.  In type selection the first
+   matching variant will be used.
+
+   NAME                pointer to first char of type name
+   DIGS                number of decimal digits for floating-point modes, else 0
+   COMPLEX_P   nonzero is this represents a complex mode
+   COUNT       count of number of items, nonzero for vector mode
+   FLOAT_REP   Float_Rep_Kind for FP, otherwise undefined
+   SIZE                number of bits used to store data
+   ALIGN       number of bits to which mode is aligned.  */
+
+void
+enumerate_modes (void (*f) (const char *, int, int, int, int, int, int))
+{
+  const tree c_types[]
+    = { float_type_node, double_type_node, long_double_type_node };
+  const char *const c_names[]
+    = { "float", "double", "long double" };
+  int iloop;
+
+  for (iloop = 0; iloop < NUM_MACHINE_MODES; iloop++)
+    {
+      enum machine_mode i = (enum machine_mode) iloop;
+      enum machine_mode inner_mode = i;
+      bool float_p = false;
+      bool complex_p = false;
+      bool vector_p = false;
+      bool skip_p = false;
+      int digs = 0;
+      unsigned int nameloop;
+      Float_Rep_Kind float_rep = IEEE_Binary; /* Until proven otherwise */
+
+      switch (GET_MODE_CLASS (i))
+       {
+       case MODE_INT:
+         break;
+       case MODE_FLOAT:
+         float_p = true;
+         break;
+       case MODE_COMPLEX_INT:
+         complex_p = true;
+         inner_mode = GET_MODE_INNER (i);
+         break;
+       case MODE_COMPLEX_FLOAT:
+         float_p = true;
+         complex_p = true;
+         inner_mode = GET_MODE_INNER (i);
+         break;
+       case MODE_VECTOR_INT:
+         vector_p = true;
+         inner_mode = GET_MODE_INNER (i);
+         break;
+       case MODE_VECTOR_FLOAT:
+         float_p = true;
+         vector_p = true;
+         inner_mode = GET_MODE_INNER (i);
+         break;
+       default:
+         skip_p = true;
+       }
+
+      if (float_p)
+       {
+         const struct real_format *fmt = REAL_MODE_FORMAT (inner_mode);
+
+         if (fmt->b == 2)
+           digs = (fmt->p - 1) * 1233 / 4096; /* scale by log (2) */
+
+         else if (fmt->b == 10)
+           digs = fmt->p;
+
+         else
+           gcc_unreachable();
+
+         if (fmt == &vax_f_format
+             || fmt == &vax_d_format
+             || fmt == &vax_g_format)
+           float_rep = VAX_Native;
+       }
+
+      /* First register any C types for this mode that the front end
+        may need to know about, unless the mode should be skipped.  */
+
+      if (!skip_p)
+       for (nameloop = 0; nameloop < ARRAY_SIZE (c_types); nameloop++)
+         {
+           tree typ = c_types[nameloop];
+           const char *nam = c_names[nameloop];
+
+           if (TYPE_MODE (typ) == i)
+             {
+               f (nam, digs, complex_p,
+                  vector_p ? GET_MODE_NUNITS (i) : 0, float_rep,
+                  TYPE_PRECISION (typ), TYPE_ALIGN (typ));
+               skip_p = true;
+             }
+         }
+
+      /* If no predefined C types were found, register the mode itself.  */
+
+      if (!skip_p)
+       f (GET_MODE_NAME (i), digs, complex_p,
+          vector_p ? GET_MODE_NUNITS (i) : 0, float_rep,
+          GET_MODE_PRECISION (i), GET_MODE_ALIGNMENT (i));
+    }
+}
+
 /* Return the size of the FP mode with precision PREC.  */
 
 int
index b0b83b3383baf9ad29909b658f6ff2bffa3bebe0..f9acdcdfeef66aaf78edbe0c4072ad8bd5f99e66 100644 (file)
@@ -2762,6 +2762,12 @@ Subprogram_Body_to_gnu (Node_Id gnat_node)
 
   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);