[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