[Ada] Implementation of aspects within generic units

Arnaud Charlet charlet@adacore.com
Wed Aug 31 12:32:00 GMT 2011


If a declaration within a generic unit has aspects, the capture of references
within the aspect expressions has to be done in a separate step because the
aspect specificatios are not directly attached to the tree for the declaration.

The following must compile quietly:

   gcc -c -gnat12 -gnata ml.ads

with Ml_Type;
with Generic_Matrix;
package Ml is

   subtype T_Int32 is Ml_Type.T_Int32;
   subtype T_Float32 is Ml_Type.T_Float32;

   package M32 is new Generic_Matrix(G_Float => T_Float32);
   type T_Matrix32 is new M32.G_Matrix;

   subtype Range2 is T_Int32 range 0 .. 1;
   subtype Range3 is T_Int32 range 0 .. 2;
end Ml;
---
package Ml_Type is
   type T_Int32 is range (-2 ** 31) .. (2 ** 31 - 1);

   type T_Float32 is digits 6  range -3.40282E+38 .. 3.40282E+38;
end Ml_Type;
---
with Ml_Type;

generic
     type G_Float is digits <>;
package Generic_Matrix is
   type G_Matrix is array (Ml_Type.T_Int32 range <>,
                           Ml_Type.T_Int32 range <>) of G_Float;

   function "+" (Left,
                 Right : G_Matrix)
                 return G_Matrix;

   function "-" (Left,
                 Right : G_Matrix)
                 return G_Matrix
     with Pre => (Left'Length (1) = Right'Length (1) and then
     Left'Length (2) = Right'Length (2) );
end Generic_Matrix;
---
package body Generic_Matrix is
   function "+" (Left,
                 Right : G_Matrix)
                 return G_Matrix is
      Res : G_Matrix(Left'Range(1), Left'Range(2));
   begin

      if Left'Length (1) /= Right'Length (1)
        or else Left'Length (2) /= Right'Length (2)
      then
         raise Constraint_Error with
           "matrices are of different dimension in elementwise operation";
      end if;

      for I in Res'Range(1) loop
         for J in Res'Range(2) loop
            Res(I,J) := Left(I,J) + Right(I,J);
         end loop;
      end loop;

      return Res;
   end "+";

   function "-" (Left,
                 Right : G_Matrix)
                 return G_Matrix is
      Res : G_Matrix(Left'Range(1), Left'Range(2));
   begin

      for I in Res'Range(1) loop
         for J in Res'Range(2) loop
            Res(I,J) := Left(I,J) - Right(I,J);
         end loop;
      end loop;

      return Res;
   end "-";
end Generic_Matrix;

Tested on x86_64-pc-linux-gnu, committed on trunk

2011-08-31  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch12.adb (Save_References): If the node has aspects, save
	references within the corresponding expressions in a separate step,
	because the aspects are not directly in the tree for the declaration
	to which they belong.

-------------- next part --------------
Index: sem_ch12.adb
===================================================================
--- sem_ch12.adb	(revision 178372)
+++ sem_ch12.adb	(working copy)
@@ -12737,6 +12737,23 @@
                end if;
             end;
          end if;
+
+         --  If a node has aspects, references within their expressions must
+         --  be saved separately, given that they are not directly in the
+         --  tree.
+
+         if Has_Aspects (N) then
+            declare
+               Aspect : Node_Id;
+
+            begin
+               Aspect := First (Aspect_Specifications (N));
+               while Present (Aspect) loop
+                  Save_Global_References (Expression (Aspect));
+                  Next (Aspect);
+               end loop;
+            end;
+         end if;
       end Save_References;
 
    --  Start of processing for Save_Global_References


More information about the Gcc-patches mailing list