1
1
with Nlists ; use Nlists;
2
2
with Uintp ; use Uintp;
3
-
3
+ with Namet ; use Namet;
4
4
with Tree_Walk ; use Tree_Walk;
5
5
with Follow ; use Follow;
6
6
with Range_Check ; use Range_Check;
@@ -791,19 +791,34 @@ package body Arrays is
791
791
792
792
function Do_Array_Length (N : Node_Id) return Irep
793
793
is
794
- Array_Struct : constant Irep := Do_Expression (Prefix (N));
794
+ -- It seems as though an N_Explicit_Drereference is placed in the tree
795
+ -- even when the prefix of the Length attribute is an implicit
796
+ -- dereference.
797
+ -- Hence, implicit dereferences do not have to be seperately handled,
798
+ -- they are handled as explicit dereferences.
799
+ Array_Struct : constant Irep := Do_Expression (Prefix (N));
795
800
begin
796
801
return Build_Array_Size (Array_Struct);
797
802
end Do_Array_Length ;
798
803
799
804
function Do_Array_First (N : Node_Id) return Irep
800
805
is
806
+ -- It seems as though an N_Explicit_Drereference is placed in the tree
807
+ -- even when the prefix of the Length attribute is an implicit
808
+ -- dereference.
809
+ -- Hence, implicit dereferences do not have to be seperately handled,
810
+ -- they are handled as explicit dereferences.
801
811
begin
802
812
return Get_First_Index (Do_Expression (Prefix (N)));
803
813
end Do_Array_First ;
804
814
805
815
function Do_Array_Last (N : Node_Id) return Irep
806
816
is
817
+ -- It seems as though an N_Explicit_Drereference is placed in the tree
818
+ -- even when the prefix of the Length attribute is an implicit
819
+ -- dereference.
820
+ -- Hence, implicit dereferences do not have to be seperately handled,
821
+ -- they are handled as explicit dereferences.
807
822
begin
808
823
return Get_Last_Index (Do_Expression (Prefix (N)));
809
824
end Do_Array_Last ;
@@ -857,8 +872,28 @@ package body Arrays is
857
872
-- }
858
873
-- --------------------------------------------------------------------------
859
874
function Do_Slice (N : Node_Id) return Irep is
875
+ -- The prefix to the slice may be an access to an array object
876
+ -- which must be implicitly dereferenced.
877
+ The_Prefix : constant Node_Id := Prefix (N);
878
+ Prefix_Etype : constant Node_Id := Etype (The_Prefix);
879
+ Is_Implicit_Deref : constant Boolean := Is_Access_Type (Prefix_Etype);
880
+ Prefix_Irep : constant Irep := Do_Expression (The_Prefix);
881
+ Result_Type : constant Irep :=
882
+ (if Is_Implicit_Deref then
883
+ Do_Type_Reference (Designated_Type (Prefix_Etype))
884
+ else
885
+ Do_Type_Reference (Prefix_Etype));
886
+ Base_Irep : constant Irep :=
887
+ (if Is_Implicit_Deref then
888
+ Make_Dereference_Expr
889
+ (I_Type => Result_Type,
890
+ Object => Prefix_Irep,
891
+ Source_Location => Get_Source_Location (N))
892
+ else
893
+ Prefix_Irep);
894
+
895
+ -- Where required the prefix has been implicitly dereferenced.
860
896
Source_Loc : constant Irep := Get_Source_Location (N);
861
- Result_Type : constant Irep := Do_Type_Reference (Etype (N));
862
897
Slice_Params : constant Irep := Make_Parameter_List;
863
898
Slice_Args : constant Irep := Make_Argument_List;
864
899
Function_Name : constant String := " slice_expr" ;
@@ -937,7 +972,7 @@ package body Arrays is
937
972
Func_Params => Slice_Params,
938
973
FBody => Build_Slice_Func_Body,
939
974
A_Symbol_Table => Global_Symbol_Table);
940
- Slice_Id : constant Irep := Do_Expression (Prefix (N)) ;
975
+ Slice_Id : constant Irep := Base_Irep ;
941
976
begin
942
977
Append_Argument (Slice_Args,
943
978
Slice_Id);
@@ -954,39 +989,74 @@ package body Arrays is
954
989
955
990
-- TODO: multi-dimensional arrays.
956
991
function Do_Indexed_Component (N : Node_Id) return Irep is
957
- Base_Irep : constant Irep := Do_Expression (Prefix (N));
958
- Idx_Irep : constant Irep :=
959
- Typecast_If_Necessary (Do_Expression (First (Expressions (N))),
960
- CProver_Size_T, Global_Symbol_Table);
961
-
962
- Source_Loc : constant Irep := Get_Source_Location (Base_Irep);
963
- First_Irep : constant Irep := Get_First_Index (Base_Irep);
964
- Last_Irep : constant Irep := Get_Last_Index (Base_Irep);
965
- Checked_Index : constant Irep :=
966
- Make_Index_Assert_Expr (N => N,
967
- Index => Idx_Irep,
968
- First_Index => First_Irep,
969
- Last_Index => Last_Irep);
970
- Zero_Based_Index : constant Irep :=
971
- Make_Op_Sub (Rhs => First_Irep,
972
- Lhs => Checked_Index,
973
- Source_Location => Source_Loc,
974
- Overflow_Check => False,
975
- I_Type => Get_Type (Idx_Irep),
976
- Range_Check => False);
977
-
978
- Data_Irep : constant Irep :=
979
- Get_Data_Member (Base_Irep, Global_Symbol_Table);
980
- Data_Type : constant Irep := Get_Type (Data_Irep);
981
- Indexed_Data : constant Irep :=
982
- Offset_Array_Data (Base => Base_Irep,
983
- Offset => Zero_Based_Index);
984
- Element_Type : constant Irep := Get_Subtype (Data_Type);
992
+ -- The prefix to an indexed component may be an access to an
993
+ -- array object which must be implicitly dereferenced.
994
+ The_Prefix : constant Node_Id := Prefix (N);
995
+ Prefix_Etype : constant Node_Id := Etype (The_Prefix);
996
+ Is_Implicit_Deref : constant Boolean := Is_Access_Type (Prefix_Etype);
985
997
begin
986
- return
987
- Make_Dereference_Expr (Object => Indexed_Data,
988
- Source_Location => Source_Loc,
989
- I_Type => Element_Type);
998
+ if (if Nkind (Prefix_Etype) = N_Defining_Identifier then
999
+ Get_Name_String (Chars (Etype (Etype (Prefix (N)))))
1000
+ elsif Is_Implicit_Deref then
1001
+ Get_Name_String (Chars (Designated_Type (Prefix_Etype)))
1002
+ else
1003
+ " " )
1004
+ = " string"
1005
+ then
1006
+ return Report_Unhandled_Node_Irep (N, " Do_Expression" ,
1007
+ " Index of string unsupported" );
1008
+ end if ;
1009
+
1010
+ -- Where required the prefix has been implicitly dereferenced.
1011
+ declare
1012
+ Prefix_Irep : constant Irep := Do_Expression (The_Prefix);
1013
+ Resolved_Type : constant Irep :=
1014
+ (if Is_Implicit_Deref then
1015
+ Do_Type_Reference (Designated_Type (Prefix_Etype))
1016
+ else
1017
+ Do_Type_Reference (Prefix_Etype));
1018
+ Base_Irep : constant Irep :=
1019
+ (if Is_Implicit_Deref then
1020
+ Make_Dereference_Expr
1021
+ (I_Type => Resolved_Type,
1022
+ Object => Prefix_Irep,
1023
+ Source_Location => Get_Source_Location (N))
1024
+ else
1025
+ Prefix_Irep);
1026
+
1027
+ Idx_Irep : constant Irep :=
1028
+ Typecast_If_Necessary (Do_Expression (First (Expressions (N))),
1029
+ CProver_Size_T, Global_Symbol_Table);
1030
+
1031
+ Source_Loc : constant Irep := Get_Source_Location (Base_Irep);
1032
+ First_Irep : constant Irep := Get_First_Index (Base_Irep);
1033
+ Last_Irep : constant Irep := Get_Last_Index (Base_Irep);
1034
+ Checked_Index : constant Irep :=
1035
+ Make_Index_Assert_Expr (N => N,
1036
+ Index => Idx_Irep,
1037
+ First_Index => First_Irep,
1038
+ Last_Index => Last_Irep);
1039
+ Zero_Based_Index : constant Irep :=
1040
+ Make_Op_Sub (Rhs => First_Irep,
1041
+ Lhs => Checked_Index,
1042
+ Source_Location => Source_Loc,
1043
+ Overflow_Check => False,
1044
+ I_Type => Get_Type (Idx_Irep),
1045
+ Range_Check => False);
1046
+
1047
+ Data_Irep : constant Irep :=
1048
+ Get_Data_Member (Base_Irep, Global_Symbol_Table);
1049
+ Data_Type : constant Irep := Get_Type (Data_Irep);
1050
+ Indexed_Data : constant Irep :=
1051
+ Offset_Array_Data (Base => Base_Irep,
1052
+ Offset => Zero_Based_Index);
1053
+ Element_Type : constant Irep := Get_Subtype (Data_Type);
1054
+ begin
1055
+ return
1056
+ Make_Dereference_Expr (Object => Indexed_Data,
1057
+ Source_Location => Source_Loc,
1058
+ I_Type => Element_Type);
1059
+ end ;
990
1060
end Do_Indexed_Component ;
991
1061
992
1062
function Get_First_Index_Component (Array_Struct : Irep)
0 commit comments