Mercurial > hg > CbC > CbC_gcc
comparison gcc/ada/sem_ch5.adb @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
4 -- -- | 4 -- -- |
5 -- S E M _ C H 5 -- | 5 -- S E M _ C H 5 -- |
6 -- -- | 6 -- -- |
7 -- B o d y -- | 7 -- B o d y -- |
8 -- -- | 8 -- -- |
9 -- Copyright (C) 1992-2017, Free Software Foundation, Inc. -- | 9 -- Copyright (C) 1992-2018, Free Software Foundation, Inc. -- |
10 -- -- | 10 -- -- |
11 -- GNAT is free software; you can redistribute it and/or modify it under -- | 11 -- GNAT is free software; you can redistribute it and/or modify it under -- |
12 -- terms of the GNU General Public License as published by the Free Soft- -- | 12 -- terms of the GNU General Public License as published by the Free Soft- -- |
13 -- ware Foundation; either version 3, or (at your option) any later ver- -- | 13 -- ware Foundation; either version 3, or (at your option) any later ver- -- |
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- | 14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- |
81 -- this count is zero, it means that control cannot fall through the IF, | 81 -- this count is zero, it means that control cannot fall through the IF, |
82 -- CASE or block statement. This is used for the generation of warning | 82 -- CASE or block statement. This is used for the generation of warning |
83 -- messages. This variable is recursively saved on entry to processing the | 83 -- messages. This variable is recursively saved on entry to processing the |
84 -- construct, and restored on exit. | 84 -- construct, and restored on exit. |
85 | 85 |
86 function Has_Sec_Stack_Call (N : Node_Id) return Boolean; | |
87 -- N is the node for an arbitrary construct. This function searches the | |
88 -- construct N to see if any expressions within it contain function | |
89 -- calls that use the secondary stack, returning True if any such call | |
90 -- is found, and False otherwise. | |
91 | |
86 procedure Preanalyze_Range (R_Copy : Node_Id); | 92 procedure Preanalyze_Range (R_Copy : Node_Id); |
87 -- Determine expected type of range or domain of iteration of Ada 2012 | 93 -- Determine expected type of range or domain of iteration of Ada 2012 |
88 -- loop by analyzing separate copy. Do the analysis and resolution of the | 94 -- loop by analyzing separate copy. Do the analysis and resolution of the |
89 -- copy of the bound(s) with expansion disabled, to prevent the generation | 95 -- copy of the bound(s) with expansion disabled, to prevent the generation |
90 -- of finalization actions. This prevents memory leaks when the bounds | 96 -- of finalization actions. This prevents memory leaks when the bounds |
104 Rhs : Node_Id := Expression (N); | 110 Rhs : Node_Id := Expression (N); |
105 | 111 |
106 procedure Diagnose_Non_Variable_Lhs (N : Node_Id); | 112 procedure Diagnose_Non_Variable_Lhs (N : Node_Id); |
107 -- N is the node for the left hand side of an assignment, and it is not | 113 -- N is the node for the left hand side of an assignment, and it is not |
108 -- a variable. This routine issues an appropriate diagnostic. | 114 -- a variable. This routine issues an appropriate diagnostic. |
115 | |
116 function Is_Protected_Part_Of_Constituent | |
117 (Nod : Node_Id) return Boolean; | |
118 -- Determine whether arbitrary node Nod denotes a Part_Of constituent of | |
119 -- a single protected type. | |
109 | 120 |
110 procedure Kill_Lhs; | 121 procedure Kill_Lhs; |
111 -- This is called to kill current value settings of a simple variable | 122 -- This is called to kill current value settings of a simple variable |
112 -- on the left hand side. We call it if we find any error in analyzing | 123 -- on the left hand side. We call it if we find any error in analyzing |
113 -- the assignment, and at the end of processing before setting any new | 124 -- the assignment, and at the end of processing before setting any new |
139 -- | 150 -- |
140 -- Similarly, for nonlimited types, aggregates and init procs generate | 151 -- Similarly, for nonlimited types, aggregates and init procs generate |
141 -- assignment statements that are really initializations. These are | 152 -- assignment statements that are really initializations. These are |
142 -- marked No_Ctrl_Actions. | 153 -- marked No_Ctrl_Actions. |
143 | 154 |
155 function Within_Function return Boolean; | |
156 -- Determine whether the current scope is a function or appears within | |
157 -- one. | |
158 | |
144 ------------------------------- | 159 ------------------------------- |
145 -- Diagnose_Non_Variable_Lhs -- | 160 -- Diagnose_Non_Variable_Lhs -- |
146 ------------------------------- | 161 ------------------------------- |
147 | 162 |
148 procedure Diagnose_Non_Variable_Lhs (N : Node_Id) is | 163 procedure Diagnose_Non_Variable_Lhs (N : Node_Id) is |
158 elsif Is_Entity_Name (N) then | 173 elsif Is_Entity_Name (N) then |
159 declare | 174 declare |
160 Ent : constant Entity_Id := Entity (N); | 175 Ent : constant Entity_Id := Entity (N); |
161 | 176 |
162 begin | 177 begin |
163 if Ekind (Ent) = E_In_Parameter then | 178 if Ekind (Ent) = E_Loop_Parameter |
179 or else Is_Loop_Parameter (Ent) | |
180 then | |
181 Error_Msg_N ("assignment to loop parameter not allowed", N); | |
182 return; | |
183 | |
184 elsif Ekind (Ent) = E_In_Parameter then | |
164 Error_Msg_N | 185 Error_Msg_N |
165 ("assignment to IN mode parameter not allowed", N); | 186 ("assignment to IN mode parameter not allowed", N); |
166 return; | 187 return; |
167 | 188 |
168 -- Renamings of protected private components are turned into | 189 -- Renamings of protected private components are turned into |
169 -- constants when compiling a protected function. In the case | 190 -- constants when compiling a protected function. In the case |
170 -- of single protected types, the private component appears | 191 -- of single protected types, the private component appears |
171 -- directly. | 192 -- directly. |
172 | 193 |
173 elsif (Is_Prival (Ent) | 194 elsif (Is_Prival (Ent) and then Within_Function) |
174 and then | |
175 (Ekind (Current_Scope) = E_Function | |
176 or else Ekind (Enclosing_Dynamic_Scope | |
177 (Current_Scope)) = E_Function)) | |
178 or else | 195 or else |
179 (Ekind (Ent) = E_Component | 196 (Ekind (Ent) = E_Component |
180 and then Is_Protected_Type (Scope (Ent))) | 197 and then Is_Protected_Type (Scope (Ent))) |
181 then | 198 then |
182 Error_Msg_N | 199 Error_Msg_N |
183 ("protected function cannot modify protected object", N); | 200 ("protected function cannot modify protected object", N); |
184 return; | 201 return; |
185 | |
186 elsif Ekind (Ent) = E_Loop_Parameter then | |
187 Error_Msg_N ("assignment to loop parameter not allowed", N); | |
188 return; | |
189 end if; | 202 end if; |
190 end; | 203 end; |
191 | 204 |
192 -- For indexed components, test prefix if it is in array. We do not | 205 -- For indexed components, test prefix if it is in array. We do not |
193 -- want to recurse for cases where the prefix is a pointer, since we | 206 -- want to recurse for cases where the prefix is a pointer, since we |
219 | 232 |
220 -- If we fall through, we have no special message to issue | 233 -- If we fall through, we have no special message to issue |
221 | 234 |
222 Error_Msg_N ("left hand side of assignment must be a variable", N); | 235 Error_Msg_N ("left hand side of assignment must be a variable", N); |
223 end Diagnose_Non_Variable_Lhs; | 236 end Diagnose_Non_Variable_Lhs; |
237 | |
238 -------------------------------------- | |
239 -- Is_Protected_Part_Of_Constituent -- | |
240 -------------------------------------- | |
241 | |
242 function Is_Protected_Part_Of_Constituent | |
243 (Nod : Node_Id) return Boolean | |
244 is | |
245 Encap_Id : Entity_Id; | |
246 Var_Id : Entity_Id; | |
247 | |
248 begin | |
249 -- Abstract states and variables may act as Part_Of constituents of | |
250 -- single protected types, however only variables can be modified by | |
251 -- an assignment. | |
252 | |
253 if Is_Entity_Name (Nod) then | |
254 Var_Id := Entity (Nod); | |
255 | |
256 if Present (Var_Id) and then Ekind (Var_Id) = E_Variable then | |
257 Encap_Id := Encapsulating_State (Var_Id); | |
258 | |
259 -- To qualify, the node must denote a reference to a variable | |
260 -- whose encapsulating state is a single protected object. | |
261 | |
262 return | |
263 Present (Encap_Id) | |
264 and then Is_Single_Protected_Object (Encap_Id); | |
265 end if; | |
266 end if; | |
267 | |
268 return False; | |
269 end Is_Protected_Part_Of_Constituent; | |
224 | 270 |
225 -------------- | 271 -------------- |
226 -- Kill_Lhs -- | 272 -- Kill_Lhs -- |
227 -------------- | 273 -------------- |
228 | 274 |
384 Rhs := Expression (N); | 430 Rhs := Expression (N); |
385 | 431 |
386 Insert_Action (N, Obj_Decl); | 432 Insert_Action (N, Obj_Decl); |
387 end Transform_BIP_Assignment; | 433 end Transform_BIP_Assignment; |
388 | 434 |
435 --------------------- | |
436 -- Within_Function -- | |
437 --------------------- | |
438 | |
439 function Within_Function return Boolean is | |
440 Scop_Id : constant Entity_Id := Current_Scope; | |
441 | |
442 begin | |
443 if Ekind (Scop_Id) = E_Function then | |
444 return True; | |
445 | |
446 elsif Ekind (Enclosing_Dynamic_Scope (Scop_Id)) = E_Function then | |
447 return True; | |
448 end if; | |
449 | |
450 return False; | |
451 end Within_Function; | |
452 | |
389 -- Local variables | 453 -- Local variables |
390 | 454 |
391 T1 : Entity_Id; | 455 T1 : Entity_Id; |
392 T2 : Entity_Id; | 456 T2 : Entity_Id; |
393 | 457 |
394 Save_Full_Analysis : Boolean; | 458 Save_Full_Analysis : Boolean := False; |
395 | 459 -- Force initialization to facilitate static analysis |
396 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; | 460 |
397 -- Save the Ghost mode to restore on exit | 461 Saved_GM : constant Ghost_Mode_Type := Ghost_Mode; |
462 Saved_IGR : constant Node_Id := Ignored_Ghost_Region; | |
463 -- Save the Ghost-related attributes to restore on exit | |
398 | 464 |
399 -- Start of processing for Analyze_Assignment | 465 -- Start of processing for Analyze_Assignment |
400 | 466 |
401 begin | 467 begin |
402 Mark_Coextensions (N, Rhs); | 468 Mark_Coextensions (N, Rhs); |
549 -- Deal with build-in-place calls for nonlimited types. We don't do this | 615 -- Deal with build-in-place calls for nonlimited types. We don't do this |
550 -- later, because resolving the rhs tranforms it incorrectly for build- | 616 -- later, because resolving the rhs tranforms it incorrectly for build- |
551 -- in-place. | 617 -- in-place. |
552 | 618 |
553 if Should_Transform_BIP_Assignment (Typ => T1) then | 619 if Should_Transform_BIP_Assignment (Typ => T1) then |
620 | |
621 -- In certain cases involving user-defined concatenation operators, | |
622 -- we need to resolve the right-hand side before transforming the | |
623 -- assignment. | |
624 | |
625 case Nkind (Unqual_Conv (Rhs)) is | |
626 when N_Function_Call => | |
627 declare | |
628 Actual : Node_Id := | |
629 First (Parameter_Associations (Unqual_Conv (Rhs))); | |
630 Actual_Exp : Node_Id; | |
631 | |
632 begin | |
633 while Present (Actual) loop | |
634 if Nkind (Actual) = N_Parameter_Association then | |
635 Actual_Exp := Explicit_Actual_Parameter (Actual); | |
636 else | |
637 Actual_Exp := Actual; | |
638 end if; | |
639 | |
640 if Nkind (Actual_Exp) = N_Op_Concat then | |
641 Resolve (Rhs, T1); | |
642 exit; | |
643 end if; | |
644 | |
645 Next (Actual); | |
646 end loop; | |
647 end; | |
648 | |
649 when N_Attribute_Reference | |
650 | N_Expanded_Name | |
651 | N_Identifier | |
652 | N_Op | |
653 => | |
654 null; | |
655 | |
656 when others => | |
657 raise Program_Error; | |
658 end case; | |
659 | |
554 Transform_BIP_Assignment (Typ => T1); | 660 Transform_BIP_Assignment (Typ => T1); |
555 end if; | 661 end if; |
556 | 662 |
557 pragma Assert (not Should_Transform_BIP_Assignment (Typ => T1)); | 663 pragma Assert (not Should_Transform_BIP_Assignment (Typ => T1)); |
558 | 664 |
668 -- in the _assign operation for an abstract type). | 774 -- in the _assign operation for an abstract type). |
669 | 775 |
670 elsif Is_Abstract_Type (T1) and then Comes_From_Source (N) then | 776 elsif Is_Abstract_Type (T1) and then Comes_From_Source (N) then |
671 Error_Msg_N | 777 Error_Msg_N |
672 ("target of assignment operation must not be abstract", Lhs); | 778 ("target of assignment operation must not be abstract", Lhs); |
779 end if; | |
780 | |
781 -- Variables which are Part_Of constituents of single protected types | |
782 -- behave in similar fashion to protected components. Such variables | |
783 -- cannot be modified by protected functions. | |
784 | |
785 if Is_Protected_Part_Of_Constituent (Lhs) and then Within_Function then | |
786 Error_Msg_N | |
787 ("protected function cannot modify protected object", Lhs); | |
673 end if; | 788 end if; |
674 | 789 |
675 -- Resolution may have updated the subtype, in case the left-hand side | 790 -- Resolution may have updated the subtype, in case the left-hand side |
676 -- is a private protected component. Use the correct subtype to avoid | 791 -- is a private protected component. Use the correct subtype to avoid |
677 -- scoping issues in the back-end. | 792 -- scoping issues in the back-end. |
945 and then (not Has_Size_Clause (T1) or else Esize (T1) > 64) | 1060 and then (not Has_Size_Clause (T1) or else Esize (T1) > 64) |
946 then | 1061 then |
947 Error_Msg_CRT ("composite assignment", N); | 1062 Error_Msg_CRT ("composite assignment", N); |
948 end if; | 1063 end if; |
949 | 1064 |
1065 -- Check elaboration warning for left side if not in elab code | |
1066 | |
1067 if Legacy_Elaboration_Checks | |
1068 and not In_Subprogram_Or_Concurrent_Unit | |
1069 then | |
1070 Check_Elab_Assign (Lhs); | |
1071 end if; | |
1072 | |
950 -- Save the scenario for later examination by the ABE Processing phase | 1073 -- Save the scenario for later examination by the ABE Processing phase |
951 | 1074 |
952 Record_Elaboration_Scenario (N); | 1075 Record_Elaboration_Scenario (N); |
953 | 1076 |
954 -- Set Referenced_As_LHS if appropriate. We only set this flag if the | 1077 -- Set Referenced_As_LHS if appropriate. We only set this flag if the |
1081 end; | 1204 end; |
1082 | 1205 |
1083 Analyze_Dimension (N); | 1206 Analyze_Dimension (N); |
1084 | 1207 |
1085 <<Leave>> | 1208 <<Leave>> |
1086 Restore_Ghost_Mode (Saved_GM); | 1209 Restore_Ghost_Region (Saved_GM, Saved_IGR); |
1087 | 1210 |
1088 -- If the right-hand side contains target names, expansion has been | 1211 -- If the right-hand side contains target names, expansion has been |
1089 -- disabled to prevent expansion that might move target names out of | 1212 -- disabled to prevent expansion that might move target names out of |
1090 -- the context of the assignment statement. Restore the expander mode | 1213 -- the context of the assignment statement. Restore the expander mode |
1091 -- now so that assignment statement can be properly expanded. | 1214 -- now so that assignment statement can be properly expanded. |
1942 ------------------------------------ | 2065 ------------------------------------ |
1943 -- Analyze_Iterator_Specification -- | 2066 -- Analyze_Iterator_Specification -- |
1944 ------------------------------------ | 2067 ------------------------------------ |
1945 | 2068 |
1946 procedure Analyze_Iterator_Specification (N : Node_Id) is | 2069 procedure Analyze_Iterator_Specification (N : Node_Id) is |
2070 Def_Id : constant Node_Id := Defining_Identifier (N); | |
2071 Iter_Name : constant Node_Id := Name (N); | |
2072 Loc : constant Source_Ptr := Sloc (N); | |
2073 Subt : constant Node_Id := Subtype_Indication (N); | |
2074 | |
2075 Bas : Entity_Id := Empty; -- initialize to prevent warning | |
2076 Typ : Entity_Id; | |
2077 | |
1947 procedure Check_Reverse_Iteration (Typ : Entity_Id); | 2078 procedure Check_Reverse_Iteration (Typ : Entity_Id); |
1948 -- For an iteration over a container, if the loop carries the Reverse | 2079 -- For an iteration over a container, if the loop carries the Reverse |
1949 -- indicator, verify that the container type has an Iterate aspect that | 2080 -- indicator, verify that the container type has an Iterate aspect that |
1950 -- implements the reversible iterator interface. | 2081 -- implements the reversible iterator interface. |
2082 | |
2083 procedure Check_Subtype_Indication (Comp_Type : Entity_Id); | |
2084 -- If a subtype indication is present, verify that it is consistent | |
2085 -- with the component type of the array or container name. | |
1951 | 2086 |
1952 function Get_Cursor_Type (Typ : Entity_Id) return Entity_Id; | 2087 function Get_Cursor_Type (Typ : Entity_Id) return Entity_Id; |
1953 -- For containers with Iterator and related aspects, the cursor is | 2088 -- For containers with Iterator and related aspects, the cursor is |
1954 -- obtained by locating an entity with the proper name in the scope | 2089 -- obtained by locating an entity with the proper name in the scope |
1955 -- of the type. | 2090 -- of the type. |
1975 ("container type does not support reverse iteration", N, Typ); | 2110 ("container type does not support reverse iteration", N, Typ); |
1976 end if; | 2111 end if; |
1977 end if; | 2112 end if; |
1978 end Check_Reverse_Iteration; | 2113 end Check_Reverse_Iteration; |
1979 | 2114 |
2115 ------------------------------- | |
2116 -- Check_Subtype_Indication -- | |
2117 ------------------------------- | |
2118 | |
2119 procedure Check_Subtype_Indication (Comp_Type : Entity_Id) is | |
2120 begin | |
2121 if Present (Subt) | |
2122 and then (not Covers (Base_Type ((Bas)), Comp_Type) | |
2123 or else not Subtypes_Statically_Match (Bas, Comp_Type)) | |
2124 then | |
2125 if Is_Array_Type (Typ) then | |
2126 Error_Msg_N | |
2127 ("subtype indication does not match component type", Subt); | |
2128 else | |
2129 Error_Msg_N | |
2130 ("subtype indication does not match element type", Subt); | |
2131 end if; | |
2132 end if; | |
2133 end Check_Subtype_Indication; | |
2134 | |
1980 --------------------- | 2135 --------------------- |
1981 -- Get_Cursor_Type -- | 2136 -- Get_Cursor_Type -- |
1982 --------------------- | 2137 --------------------- |
1983 | 2138 |
1984 function Get_Cursor_Type (Typ : Entity_Id) return Entity_Id is | 2139 function Get_Cursor_Type (Typ : Entity_Id) return Entity_Id is |
2010 Error_Msg_N ("cursor type cannot be limited", N); | 2165 Error_Msg_N ("cursor type cannot be limited", N); |
2011 end if; | 2166 end if; |
2012 | 2167 |
2013 return Etype (Ent); | 2168 return Etype (Ent); |
2014 end Get_Cursor_Type; | 2169 end Get_Cursor_Type; |
2015 | |
2016 -- Local variables | |
2017 | |
2018 Def_Id : constant Node_Id := Defining_Identifier (N); | |
2019 Iter_Name : constant Node_Id := Name (N); | |
2020 Loc : constant Source_Ptr := Sloc (N); | |
2021 Subt : constant Node_Id := Subtype_Indication (N); | |
2022 | |
2023 Bas : Entity_Id := Empty; -- initialize to prevent warning | |
2024 Typ : Entity_Id; | |
2025 | 2170 |
2026 -- Start of processing for Analyze_Iterator_Specification | 2171 -- Start of processing for Analyze_Iterator_Specification |
2027 | 2172 |
2028 begin | 2173 begin |
2029 Enter_Name (Def_Id); | 2174 Enter_Name (Def_Id); |
2056 Bas := Entity (Subt); | 2201 Bas := Entity (Subt); |
2057 end if; | 2202 end if; |
2058 | 2203 |
2059 Preanalyze_Range (Iter_Name); | 2204 Preanalyze_Range (Iter_Name); |
2060 | 2205 |
2206 -- If the domain of iteration is a function call, make sure the function | |
2207 -- itself is frozen. This is an issue if this is a local expression | |
2208 -- function. | |
2209 | |
2210 if Nkind (Iter_Name) = N_Function_Call | |
2211 and then Is_Entity_Name (Name (Iter_Name)) | |
2212 and then Full_Analysis | |
2213 and then (In_Assertion_Expr = 0 or else Assertions_Enabled) | |
2214 then | |
2215 Freeze_Before (N, Entity (Name (Iter_Name))); | |
2216 end if; | |
2217 | |
2061 -- Set the kind of the loop variable, which is not visible within the | 2218 -- Set the kind of the loop variable, which is not visible within the |
2062 -- iterator name. | 2219 -- iterator name. |
2063 | 2220 |
2064 Set_Ekind (Def_Id, E_Variable); | 2221 Set_Ekind (Def_Id, E_Variable); |
2065 | 2222 |
2137 Act_S : Node_Id; | 2294 Act_S : Node_Id; |
2138 | 2295 |
2139 begin | 2296 begin |
2140 | 2297 |
2141 -- If the domain of iteration is an array component that depends | 2298 -- If the domain of iteration is an array component that depends |
2142 -- on a discriminant, create actual subtype for it. Pre-analysis | 2299 -- on a discriminant, create actual subtype for it. preanalysis |
2143 -- does not generate the actual subtype of a selected component. | 2300 -- does not generate the actual subtype of a selected component. |
2144 | 2301 |
2145 if Nkind (Iter_Name) = N_Selected_Component | 2302 if Nkind (Iter_Name) = N_Selected_Component |
2146 and then Is_Array_Type (Etype (Iter_Name)) | 2303 and then Is_Array_Type (Etype (Iter_Name)) |
2147 then | 2304 then |
2278 Error_Msg_N | 2435 Error_Msg_N |
2279 ("iterable name cannot be a discriminant-dependent " | 2436 ("iterable name cannot be a discriminant-dependent " |
2280 & "component of a mutable object", N); | 2437 & "component of a mutable object", N); |
2281 end if; | 2438 end if; |
2282 | 2439 |
2283 if Present (Subt) | 2440 Check_Subtype_Indication (Component_Type (Typ)); |
2284 and then | |
2285 (Base_Type (Bas) /= Base_Type (Component_Type (Typ)) | |
2286 or else | |
2287 not Subtypes_Statically_Match (Bas, Component_Type (Typ))) | |
2288 then | |
2289 Error_Msg_N | |
2290 ("subtype indication does not match component type", Subt); | |
2291 end if; | |
2292 | 2441 |
2293 -- Here we have a missing Range attribute | 2442 -- Here we have a missing Range attribute |
2294 | 2443 |
2295 else | 2444 else |
2296 Error_Msg_N | 2445 Error_Msg_N |
2336 Set_Etype (Def_Id, Etype (Elt)); | 2485 Set_Etype (Def_Id, Etype (Elt)); |
2337 Check_Reverse_Iteration (Typ); | 2486 Check_Reverse_Iteration (Typ); |
2338 end if; | 2487 end if; |
2339 end; | 2488 end; |
2340 | 2489 |
2490 Check_Subtype_Indication (Etype (Def_Id)); | |
2491 | |
2341 -- For a predefined container, The type of the loop variable is | 2492 -- For a predefined container, The type of the loop variable is |
2342 -- the Iterator_Element aspect of the container type. | 2493 -- the Iterator_Element aspect of the container type. |
2343 | 2494 |
2344 else | 2495 else |
2345 declare | 2496 declare |
2361 else | 2512 else |
2362 Set_Etype (Def_Id, Entity (Element)); | 2513 Set_Etype (Def_Id, Entity (Element)); |
2363 Cursor_Type := Get_Cursor_Type (Typ); | 2514 Cursor_Type := Get_Cursor_Type (Typ); |
2364 pragma Assert (Present (Cursor_Type)); | 2515 pragma Assert (Present (Cursor_Type)); |
2365 | 2516 |
2366 -- If subtype indication was given, verify that it covers | 2517 Check_Subtype_Indication (Etype (Def_Id)); |
2367 -- the element type of the container. | |
2368 | |
2369 if Present (Subt) | |
2370 and then (not Covers (Bas, Etype (Def_Id)) | |
2371 or else not Subtypes_Statically_Match | |
2372 (Bas, Etype (Def_Id))) | |
2373 then | |
2374 Error_Msg_N | |
2375 ("subtype indication does not match element type", | |
2376 Subt); | |
2377 end if; | |
2378 | 2518 |
2379 -- If the container has a variable indexing aspect, the | 2519 -- If the container has a variable indexing aspect, the |
2380 -- element is a variable and is modifiable in the loop. | 2520 -- element is a variable and is modifiable in the loop. |
2381 | 2521 |
2382 if Has_Aspect (Typ, Aspect_Variable_Indexing) then | 2522 if Has_Aspect (Typ, Aspect_Variable_Indexing) then |
2568 -- Diagnose Attempt to iterate through non-static predicate. Note that | 2708 -- Diagnose Attempt to iterate through non-static predicate. Note that |
2569 -- a type with inherited predicates may have both static and dynamic | 2709 -- a type with inherited predicates may have both static and dynamic |
2570 -- forms. In this case it is not sufficent to check the static predicate | 2710 -- forms. In this case it is not sufficent to check the static predicate |
2571 -- function only, look for a dynamic predicate aspect as well. | 2711 -- function only, look for a dynamic predicate aspect as well. |
2572 | 2712 |
2573 function Has_Call_Using_Secondary_Stack (N : Node_Id) return Boolean; | |
2574 -- N is the node for an arbitrary construct. This function searches the | |
2575 -- construct N to see if any expressions within it contain function | |
2576 -- calls that use the secondary stack, returning True if any such call | |
2577 -- is found, and False otherwise. | |
2578 | |
2579 procedure Process_Bounds (R : Node_Id); | 2713 procedure Process_Bounds (R : Node_Id); |
2580 -- If the iteration is given by a range, create temporaries and | 2714 -- If the iteration is given by a range, create temporaries and |
2581 -- assignment statements block to capture the bounds and perform | 2715 -- assignment statements block to capture the bounds and perform |
2582 -- required finalization actions in case a bound includes a function | 2716 -- required finalization actions in case a bound includes a function |
2583 -- call that uses the temporary stack. We first pre-analyze a copy of | 2717 -- call that uses the temporary stack. We first preanalyze a copy of |
2584 -- the range in order to determine the expected type, and analyze and | 2718 -- the range in order to determine the expected type, and analyze and |
2585 -- resolve the original bounds. | 2719 -- resolve the original bounds. |
2586 | 2720 |
2587 -------------------------------------- | 2721 -------------------------------------- |
2588 -- Check_Controlled_Array_Attribute -- | 2722 -- Check_Controlled_Array_Attribute -- |
2658 then | 2792 then |
2659 Set_No_Dynamic_Predicate_On_Actual (T); | 2793 Set_No_Dynamic_Predicate_On_Actual (T); |
2660 end if; | 2794 end if; |
2661 end Check_Predicate_Use; | 2795 end Check_Predicate_Use; |
2662 | 2796 |
2663 ------------------------------------ | |
2664 -- Has_Call_Using_Secondary_Stack -- | |
2665 ------------------------------------ | |
2666 | |
2667 function Has_Call_Using_Secondary_Stack (N : Node_Id) return Boolean is | |
2668 | |
2669 function Check_Call (N : Node_Id) return Traverse_Result; | |
2670 -- Check if N is a function call which uses the secondary stack | |
2671 | |
2672 ---------------- | |
2673 -- Check_Call -- | |
2674 ---------------- | |
2675 | |
2676 function Check_Call (N : Node_Id) return Traverse_Result is | |
2677 Nam : Node_Id; | |
2678 Subp : Entity_Id; | |
2679 Return_Typ : Entity_Id; | |
2680 | |
2681 begin | |
2682 if Nkind (N) = N_Function_Call then | |
2683 Nam := Name (N); | |
2684 | |
2685 -- Call using access to subprogram with explicit dereference | |
2686 | |
2687 if Nkind (Nam) = N_Explicit_Dereference then | |
2688 Subp := Etype (Nam); | |
2689 | |
2690 -- Call using a selected component notation or Ada 2005 object | |
2691 -- operation notation | |
2692 | |
2693 elsif Nkind (Nam) = N_Selected_Component then | |
2694 Subp := Entity (Selector_Name (Nam)); | |
2695 | |
2696 -- Common case | |
2697 | |
2698 else | |
2699 Subp := Entity (Nam); | |
2700 end if; | |
2701 | |
2702 Return_Typ := Etype (Subp); | |
2703 | |
2704 if Is_Composite_Type (Return_Typ) | |
2705 and then not Is_Constrained (Return_Typ) | |
2706 then | |
2707 return Abandon; | |
2708 | |
2709 elsif Sec_Stack_Needed_For_Return (Subp) then | |
2710 return Abandon; | |
2711 end if; | |
2712 end if; | |
2713 | |
2714 -- Continue traversing the tree | |
2715 | |
2716 return OK; | |
2717 end Check_Call; | |
2718 | |
2719 function Check_Calls is new Traverse_Func (Check_Call); | |
2720 | |
2721 -- Start of processing for Has_Call_Using_Secondary_Stack | |
2722 | |
2723 begin | |
2724 return Check_Calls (N) = Abandon; | |
2725 end Has_Call_Using_Secondary_Stack; | |
2726 | |
2727 -------------------- | 2797 -------------------- |
2728 -- Process_Bounds -- | 2798 -- Process_Bounds -- |
2729 -------------------- | 2799 -------------------- |
2730 | 2800 |
2731 procedure Process_Bounds (R : Node_Id) is | 2801 procedure Process_Bounds (R : Node_Id) is |
2778 | 2848 |
2779 -- We prefer the constant declaration, since it leaves us with a | 2849 -- We prefer the constant declaration, since it leaves us with a |
2780 -- proper trace of the value, useful in optimizations that get rid | 2850 -- proper trace of the value, useful in optimizations that get rid |
2781 -- of junk range checks. | 2851 -- of junk range checks. |
2782 | 2852 |
2783 if not Has_Call_Using_Secondary_Stack (Analyzed_Bound) then | 2853 if not Has_Sec_Stack_Call (Analyzed_Bound) then |
2784 Analyze_And_Resolve (Original_Bound, Typ); | 2854 Analyze_And_Resolve (Original_Bound, Typ); |
2785 | 2855 |
2786 -- Ensure that the bound is valid. This check should not be | 2856 -- Ensure that the bound is valid. This check should not be |
2787 -- generated when the range belongs to a quantified expression | 2857 -- generated when the range belongs to a quantified expression |
2788 -- as the construct is still not expanded into its final form. | 2858 -- as the construct is still not expanded into its final form. |
3012 -- Domain of iteration is not a function call, and is side-effect | 3082 -- Domain of iteration is not a function call, and is side-effect |
3013 -- free. | 3083 -- free. |
3014 | 3084 |
3015 else | 3085 else |
3016 -- A quantified expression that appears in a pre/post condition | 3086 -- A quantified expression that appears in a pre/post condition |
3017 -- is pre-analyzed several times. If the range is given by an | 3087 -- is preanalyzed several times. If the range is given by an |
3018 -- attribute reference it is rewritten as a range, and this is | 3088 -- attribute reference it is rewritten as a range, and this is |
3019 -- done even with expansion disabled. If the type is already set | 3089 -- done even with expansion disabled. If the type is already set |
3020 -- do not reanalyze, because a range with static bounds may be | 3090 -- do not reanalyze, because a range with static bounds may be |
3021 -- typed Integer by default. | 3091 -- typed Integer by default. |
3022 | 3092 |
3288 -- Analyze_Loop_Statement -- | 3358 -- Analyze_Loop_Statement -- |
3289 ---------------------------- | 3359 ---------------------------- |
3290 | 3360 |
3291 procedure Analyze_Loop_Statement (N : Node_Id) is | 3361 procedure Analyze_Loop_Statement (N : Node_Id) is |
3292 | 3362 |
3293 function Is_Container_Iterator (Iter : Node_Id) return Boolean; | 3363 -- The following exception is raised by routine Prepare_Loop_Statement |
3294 -- Given a loop iteration scheme, determine whether it is an Ada 2012 | 3364 -- to avoid further analysis of a transformed loop. |
3295 -- container iteration. | 3365 |
3296 | 3366 Skip_Analysis : exception; |
3297 function Is_Wrapped_In_Block (N : Node_Id) return Boolean; | 3367 |
3298 -- Determine whether loop statement N has been wrapped in a block to | 3368 function Disable_Constant (N : Node_Id) return Traverse_Result; |
3299 -- capture finalization actions that may be generated for container | 3369 -- If N represents an E_Variable entity, set Is_True_Constant To False |
3300 -- iterators. Prevents infinite recursion when block is analyzed. | 3370 |
3301 -- Routine is a noop if loop is single statement within source block. | 3371 procedure Disable_Constants is new Traverse_Proc (Disable_Constant); |
3302 | 3372 -- Helper for Analyze_Loop_Statement, to unset Is_True_Constant on |
3303 --------------------------- | 3373 -- variables referenced within an OpenACC construct. |
3304 -- Is_Container_Iterator -- | 3374 |
3305 --------------------------- | 3375 procedure Prepare_Loop_Statement (Iter : Node_Id); |
3306 | 3376 -- Determine whether loop statement N with iteration scheme Iter must be |
3307 function Is_Container_Iterator (Iter : Node_Id) return Boolean is | 3377 -- transformed prior to analysis, and if so, perform it. The routine |
3378 -- raises Skip_Analysis to prevent further analysis of the transformed | |
3379 -- loop. | |
3380 | |
3381 ---------------------- | |
3382 -- Disable_Constant -- | |
3383 ---------------------- | |
3384 | |
3385 function Disable_Constant (N : Node_Id) return Traverse_Result is | |
3308 begin | 3386 begin |
3309 -- Infinite loop | 3387 if Is_Entity_Name (N) |
3310 | 3388 and then Present (Entity (N)) |
3311 if No (Iter) then | 3389 and then Ekind (Entity (N)) = E_Variable |
3390 then | |
3391 Set_Is_True_Constant (Entity (N), False); | |
3392 end if; | |
3393 | |
3394 return OK; | |
3395 end Disable_Constant; | |
3396 | |
3397 ---------------------------- | |
3398 -- Prepare_Loop_Statement -- | |
3399 ---------------------------- | |
3400 | |
3401 procedure Prepare_Loop_Statement (Iter : Node_Id) is | |
3402 function Has_Sec_Stack_Default_Iterator | |
3403 (Cont_Typ : Entity_Id) return Boolean; | |
3404 pragma Inline (Has_Sec_Stack_Default_Iterator); | |
3405 -- Determine whether container type Cont_Typ has a default iterator | |
3406 -- that requires secondary stack management. | |
3407 | |
3408 function Is_Sec_Stack_Iteration_Primitive | |
3409 (Cont_Typ : Entity_Id; | |
3410 Iter_Prim_Nam : Name_Id) return Boolean; | |
3411 pragma Inline (Is_Sec_Stack_Iteration_Primitive); | |
3412 -- Determine whether container type Cont_Typ has an iteration routine | |
3413 -- described by its name Iter_Prim_Nam that requires secondary stack | |
3414 -- management. | |
3415 | |
3416 function Is_Wrapped_In_Block (Stmt : Node_Id) return Boolean; | |
3417 pragma Inline (Is_Wrapped_In_Block); | |
3418 -- Determine whether arbitrary statement Stmt is the sole statement | |
3419 -- wrapped within some block, excluding pragmas. | |
3420 | |
3421 procedure Prepare_Iterator_Loop (Iter_Spec : Node_Id); | |
3422 pragma Inline (Prepare_Iterator_Loop); | |
3423 -- Prepare an iterator loop with iteration specification Iter_Spec | |
3424 -- for transformation if needed. | |
3425 | |
3426 procedure Prepare_Param_Spec_Loop (Param_Spec : Node_Id); | |
3427 pragma Inline (Prepare_Param_Spec_Loop); | |
3428 -- Prepare a discrete loop with parameter specification Param_Spec | |
3429 -- for transformation if needed. | |
3430 | |
3431 procedure Wrap_Loop_Statement (Manage_Sec_Stack : Boolean); | |
3432 pragma Inline (Wrap_Loop_Statement); | |
3433 pragma No_Return (Wrap_Loop_Statement); | |
3434 -- Wrap loop statement N within a block. Flag Manage_Sec_Stack must | |
3435 -- be set when the block must mark and release the secondary stack. | |
3436 | |
3437 ------------------------------------ | |
3438 -- Has_Sec_Stack_Default_Iterator -- | |
3439 ------------------------------------ | |
3440 | |
3441 function Has_Sec_Stack_Default_Iterator | |
3442 (Cont_Typ : Entity_Id) return Boolean | |
3443 is | |
3444 Def_Iter : constant Node_Id := | |
3445 Find_Value_Of_Aspect | |
3446 (Cont_Typ, Aspect_Default_Iterator); | |
3447 begin | |
3448 return | |
3449 Present (Def_Iter) | |
3450 and then Requires_Transient_Scope (Etype (Def_Iter)); | |
3451 end Has_Sec_Stack_Default_Iterator; | |
3452 | |
3453 -------------------------------------- | |
3454 -- Is_Sec_Stack_Iteration_Primitive -- | |
3455 -------------------------------------- | |
3456 | |
3457 function Is_Sec_Stack_Iteration_Primitive | |
3458 (Cont_Typ : Entity_Id; | |
3459 Iter_Prim_Nam : Name_Id) return Boolean | |
3460 is | |
3461 Iter_Prim : constant Entity_Id := | |
3462 Get_Iterable_Type_Primitive | |
3463 (Cont_Typ, Iter_Prim_Nam); | |
3464 begin | |
3465 return | |
3466 Present (Iter_Prim) | |
3467 and then Requires_Transient_Scope (Etype (Iter_Prim)); | |
3468 end Is_Sec_Stack_Iteration_Primitive; | |
3469 | |
3470 ------------------------- | |
3471 -- Is_Wrapped_In_Block -- | |
3472 ------------------------- | |
3473 | |
3474 function Is_Wrapped_In_Block (Stmt : Node_Id) return Boolean is | |
3475 Blk_HSS : Node_Id; | |
3476 Blk_Id : Entity_Id; | |
3477 Blk_Stmt : Node_Id; | |
3478 | |
3479 begin | |
3480 Blk_Id := Current_Scope; | |
3481 | |
3482 -- The current context is a block. Inspect the statements of the | |
3483 -- block to determine whether it wraps Stmt. | |
3484 | |
3485 if Ekind (Blk_Id) = E_Block | |
3486 and then Present (Block_Node (Blk_Id)) | |
3487 then | |
3488 Blk_HSS := | |
3489 Handled_Statement_Sequence (Parent (Block_Node (Blk_Id))); | |
3490 | |
3491 -- Skip leading pragmas introduced for invariant and predicate | |
3492 -- checks. | |
3493 | |
3494 Blk_Stmt := First (Statements (Blk_HSS)); | |
3495 while Present (Blk_Stmt) | |
3496 and then Nkind (Blk_Stmt) = N_Pragma | |
3497 loop | |
3498 Next (Blk_Stmt); | |
3499 end loop; | |
3500 | |
3501 return Blk_Stmt = Stmt and then No (Next (Blk_Stmt)); | |
3502 end if; | |
3503 | |
3312 return False; | 3504 return False; |
3313 | 3505 end Is_Wrapped_In_Block; |
3314 -- While loop | 3506 |
3315 | 3507 --------------------------- |
3316 elsif Present (Condition (Iter)) then | 3508 -- Prepare_Iterator_Loop -- |
3317 return False; | 3509 --------------------------- |
3318 | 3510 |
3319 -- for Def_Id in [reverse] Name loop | 3511 procedure Prepare_Iterator_Loop (Iter_Spec : Node_Id) is |
3320 -- for Def_Id [: Subtype_Indication] of [reverse] Name loop | 3512 Cont_Typ : Entity_Id; |
3321 | 3513 Nam : Node_Id; |
3322 elsif Present (Iterator_Specification (Iter)) then | 3514 Nam_Copy : Node_Id; |
3323 declare | 3515 |
3324 Nam : constant Node_Id := Name (Iterator_Specification (Iter)); | 3516 begin |
3325 Nam_Copy : Node_Id; | 3517 -- The iterator specification has syntactic errors. Transform the |
3326 | 3518 -- loop into an infinite loop in order to safely perform at least |
3327 begin | 3519 -- some minor analysis. This check must come first. |
3520 | |
3521 if Error_Posted (Iter_Spec) then | |
3522 Set_Iteration_Scheme (N, Empty); | |
3523 Analyze (N); | |
3524 | |
3525 raise Skip_Analysis; | |
3526 | |
3527 -- Nothing to do when the loop is already wrapped in a block | |
3528 | |
3529 elsif Is_Wrapped_In_Block (N) then | |
3530 null; | |
3531 | |
3532 -- Otherwise the iterator loop traverses an array or a container | |
3533 -- and appears in the form | |
3534 -- | |
3535 -- for Def_Id in [reverse] Iterator_Name loop | |
3536 -- for Def_Id [: Subtyp_Indic] of [reverse] Iterable_Name loop | |
3537 | |
3538 else | |
3539 -- Prepare a copy of the iterated name for preanalysis. The | |
3540 -- copy is semi inserted into the tree by setting its Parent | |
3541 -- pointer. | |
3542 | |
3543 Nam := Name (Iter_Spec); | |
3328 Nam_Copy := New_Copy_Tree (Nam); | 3544 Nam_Copy := New_Copy_Tree (Nam); |
3329 Set_Parent (Nam_Copy, Parent (Nam)); | 3545 Set_Parent (Nam_Copy, Parent (Nam)); |
3546 | |
3547 -- Determine what the loop is iterating on | |
3548 | |
3330 Preanalyze_Range (Nam_Copy); | 3549 Preanalyze_Range (Nam_Copy); |
3331 | 3550 Cont_Typ := Etype (Nam_Copy); |
3332 -- The only two options here are iteration over a container or | 3551 |
3333 -- an array. | 3552 -- The iterator loop is traversing an array. This case does not |
3334 | 3553 -- require any transformation. |
3335 return not Is_Array_Type (Etype (Nam_Copy)); | 3554 |
3336 end; | 3555 if Is_Array_Type (Cont_Typ) then |
3337 | 3556 null; |
3338 -- for Def_Id in [reverse] Discrete_Subtype_Definition loop | 3557 |
3339 | 3558 -- Otherwise unconditionally wrap the loop statement within |
3340 else | 3559 -- a block. The expansion of iterator loops may relocate the |
3341 declare | 3560 -- iterator outside the loop, thus "leaking" its entity into |
3342 LP : constant Node_Id := Loop_Parameter_Specification (Iter); | 3561 -- the enclosing scope. Wrapping the loop statement allows |
3343 DS : constant Node_Id := Discrete_Subtype_Definition (LP); | 3562 -- for multiple iterator loops using the same iterator name |
3344 DS_Copy : Node_Id; | 3563 -- to coexist within the same scope. |
3345 | 3564 -- |
3346 begin | 3565 -- The block must manage the secondary stack when the iterator |
3347 DS_Copy := New_Copy_Tree (DS); | 3566 -- loop is traversing a container using either |
3348 Set_Parent (DS_Copy, Parent (DS)); | 3567 -- |
3349 Preanalyze_Range (DS_Copy); | 3568 -- * A default iterator obtained on the secondary stack |
3350 | 3569 -- |
3351 -- Check for a call to Iterate () or an expression with | 3570 -- * Call to Iterate where the iterator is returned on the |
3352 -- an iterator type. | 3571 -- secondary stack. |
3353 | 3572 -- |
3354 return | 3573 -- * Combination of First, Next, and Has_Element where the |
3355 (Nkind (DS_Copy) = N_Function_Call | 3574 -- first two return a cursor on the secondary stack. |
3356 and then Needs_Finalization (Etype (DS_Copy))) | 3575 |
3357 or else Is_Iterator (Etype (DS_Copy)); | 3576 else |
3358 end; | 3577 Wrap_Loop_Statement |
3359 end if; | 3578 (Manage_Sec_Stack => |
3360 end Is_Container_Iterator; | 3579 Has_Sec_Stack_Default_Iterator (Cont_Typ) |
3361 | 3580 or else Has_Sec_Stack_Call (Nam_Copy) |
3362 ------------------------- | 3581 or else Is_Sec_Stack_Iteration_Primitive |
3363 -- Is_Wrapped_In_Block -- | 3582 (Cont_Typ, Name_First) |
3364 ------------------------- | 3583 or else Is_Sec_Stack_Iteration_Primitive |
3365 | 3584 (Cont_Typ, Name_Next)); |
3366 function Is_Wrapped_In_Block (N : Node_Id) return Boolean is | 3585 end if; |
3367 HSS : Node_Id; | 3586 end if; |
3368 Stat : Node_Id; | 3587 end Prepare_Iterator_Loop; |
3588 | |
3589 ----------------------------- | |
3590 -- Prepare_Param_Spec_Loop -- | |
3591 ----------------------------- | |
3592 | |
3593 procedure Prepare_Param_Spec_Loop (Param_Spec : Node_Id) is | |
3594 High : Node_Id; | |
3595 Low : Node_Id; | |
3596 Rng : Node_Id; | |
3597 Rng_Copy : Node_Id; | |
3598 Rng_Typ : Entity_Id; | |
3599 | |
3600 begin | |
3601 Rng := Discrete_Subtype_Definition (Param_Spec); | |
3602 | |
3603 -- Nothing to do when the loop is already wrapped in a block | |
3604 | |
3605 if Is_Wrapped_In_Block (N) then | |
3606 null; | |
3607 | |
3608 -- The parameter specification appears in the form | |
3609 -- | |
3610 -- for Def_Id in Subtype_Mark Constraint loop | |
3611 | |
3612 elsif Nkind (Rng) = N_Subtype_Indication | |
3613 and then Nkind (Range_Expression (Constraint (Rng))) = N_Range | |
3614 then | |
3615 Rng := Range_Expression (Constraint (Rng)); | |
3616 | |
3617 -- Preanalyze the bounds of the range constraint | |
3618 | |
3619 Low := New_Copy_Tree (Low_Bound (Rng)); | |
3620 High := New_Copy_Tree (High_Bound (Rng)); | |
3621 | |
3622 Preanalyze (Low); | |
3623 Preanalyze (High); | |
3624 | |
3625 -- The bounds contain at least one function call that returns | |
3626 -- on the secondary stack. Note that the loop must be wrapped | |
3627 -- only when such a call exists. | |
3628 | |
3629 if Has_Sec_Stack_Call (Low) | |
3630 or else | |
3631 Has_Sec_Stack_Call (High) | |
3632 then | |
3633 Wrap_Loop_Statement (Manage_Sec_Stack => True); | |
3634 end if; | |
3635 | |
3636 -- Otherwise the parameter specification appears in the form | |
3637 -- | |
3638 -- for Def_Id in Range loop | |
3639 | |
3640 else | |
3641 -- Prepare a copy of the discrete range for preanalysis. The | |
3642 -- copy is semi inserted into the tree by setting its Parent | |
3643 -- pointer. | |
3644 | |
3645 Rng_Copy := New_Copy_Tree (Rng); | |
3646 Set_Parent (Rng_Copy, Parent (Rng)); | |
3647 | |
3648 -- Determine what the loop is iterating on | |
3649 | |
3650 Preanalyze_Range (Rng_Copy); | |
3651 Rng_Typ := Etype (Rng_Copy); | |
3652 | |
3653 -- Wrap the loop statement within a block in order to manage | |
3654 -- the secondary stack when the discrete range is | |
3655 -- | |
3656 -- * Either a Forward_Iterator or a Reverse_Iterator | |
3657 -- | |
3658 -- * Function call whose return type requires finalization | |
3659 -- actions. | |
3660 | |
3661 -- ??? it is unclear why using Has_Sec_Stack_Call directly on | |
3662 -- the discrete range causes the freeze node of an itype to be | |
3663 -- in the wrong scope in complex assertion expressions. | |
3664 | |
3665 if Is_Iterator (Rng_Typ) | |
3666 or else (Nkind (Rng_Copy) = N_Function_Call | |
3667 and then Needs_Finalization (Rng_Typ)) | |
3668 then | |
3669 Wrap_Loop_Statement (Manage_Sec_Stack => True); | |
3670 end if; | |
3671 end if; | |
3672 end Prepare_Param_Spec_Loop; | |
3673 | |
3674 ------------------------- | |
3675 -- Wrap_Loop_Statement -- | |
3676 ------------------------- | |
3677 | |
3678 procedure Wrap_Loop_Statement (Manage_Sec_Stack : Boolean) is | |
3679 Loc : constant Source_Ptr := Sloc (N); | |
3680 | |
3681 Blk : Node_Id; | |
3682 Blk_Id : Entity_Id; | |
3683 | |
3684 begin | |
3685 Blk := | |
3686 Make_Block_Statement (Loc, | |
3687 Declarations => New_List, | |
3688 Handled_Statement_Sequence => | |
3689 Make_Handled_Sequence_Of_Statements (Loc, | |
3690 Statements => New_List (Relocate_Node (N)))); | |
3691 | |
3692 Add_Block_Identifier (Blk, Blk_Id); | |
3693 Set_Uses_Sec_Stack (Blk_Id, Manage_Sec_Stack); | |
3694 | |
3695 Rewrite (N, Blk); | |
3696 Analyze (N); | |
3697 | |
3698 raise Skip_Analysis; | |
3699 end Wrap_Loop_Statement; | |
3700 | |
3701 -- Local variables | |
3702 | |
3703 Iter_Spec : constant Node_Id := Iterator_Specification (Iter); | |
3704 Param_Spec : constant Node_Id := Loop_Parameter_Specification (Iter); | |
3705 | |
3706 -- Start of processing for Prepare_Loop_Statement | |
3369 | 3707 |
3370 begin | 3708 begin |
3371 | 3709 if Present (Iter_Spec) then |
3372 -- Check if current scope is a block that is not a transient block. | 3710 Prepare_Iterator_Loop (Iter_Spec); |
3373 | 3711 |
3374 if Ekind (Current_Scope) /= E_Block | 3712 elsif Present (Param_Spec) then |
3375 or else No (Block_Node (Current_Scope)) | 3713 Prepare_Param_Spec_Loop (Param_Spec); |
3376 then | 3714 end if; |
3377 return False; | 3715 end Prepare_Loop_Statement; |
3378 | |
3379 else | |
3380 HSS := | |
3381 Handled_Statement_Sequence (Parent (Block_Node (Current_Scope))); | |
3382 | |
3383 -- Skip leading pragmas that may be introduced for invariant and | |
3384 -- predicate checks. | |
3385 | |
3386 Stat := First (Statements (HSS)); | |
3387 while Present (Stat) and then Nkind (Stat) = N_Pragma loop | |
3388 Stat := Next (Stat); | |
3389 end loop; | |
3390 | |
3391 return Stat = N and then No (Next (Stat)); | |
3392 end if; | |
3393 end Is_Wrapped_In_Block; | |
3394 | 3716 |
3395 -- Local declarations | 3717 -- Local declarations |
3396 | 3718 |
3397 Id : constant Node_Id := Identifier (N); | 3719 Id : constant Node_Id := Identifier (N); |
3398 Iter : constant Node_Id := Iteration_Scheme (N); | 3720 Iter : constant Node_Id := Iteration_Scheme (N); |
3467 Set_Identifier (N, New_Occurrence_Of (Ent, Loc)); | 3789 Set_Identifier (N, New_Occurrence_Of (Ent, Loc)); |
3468 Set_Parent (Ent, N); | 3790 Set_Parent (Ent, N); |
3469 Set_Has_Created_Identifier (N); | 3791 Set_Has_Created_Identifier (N); |
3470 end if; | 3792 end if; |
3471 | 3793 |
3472 -- If the iterator specification has a syntactic error, transform | 3794 -- Determine whether the loop statement must be transformed prior to |
3473 -- construct into an infinite loop to prevent a crash and perform | 3795 -- analysis, and if so, perform it. This early modification is needed |
3474 -- some analysis. | 3796 -- when: |
3475 | 3797 -- |
3476 if Present (Iter) | 3798 -- * The loop has an erroneous iteration scheme. In this case the |
3477 and then Present (Iterator_Specification (Iter)) | 3799 -- loop is converted into an infinite loop in order to perform |
3478 and then Error_Posted (Iterator_Specification (Iter)) | 3800 -- minor analysis. |
3479 then | 3801 -- |
3480 Set_Iteration_Scheme (N, Empty); | 3802 -- * The loop is an Ada 2012 iterator loop. In this case the loop is |
3481 Analyze (N); | 3803 -- wrapped within a block to provide a local scope for the iterator. |
3482 return; | 3804 -- If the iterator specification requires the secondary stack in any |
3483 end if; | 3805 -- way, the block is marked in order to manage it. |
3484 | 3806 -- |
3485 -- Iteration over a container in Ada 2012 involves the creation of a | 3807 -- * The loop is using a parameter specification where the discrete |
3486 -- controlled iterator object. Wrap the loop in a block to ensure the | 3808 -- range requires the secondary stack. In this case the loop is |
3487 -- timely finalization of the iterator and release of container locks. | 3809 -- wrapped within a block in order to manage the secondary stack. |
3488 -- The same applies to the use of secondary stack when obtaining an | 3810 |
3489 -- iterator. | 3811 if Present (Iter) then |
3490 | 3812 Prepare_Loop_Statement (Iter); |
3491 if Ada_Version >= Ada_2012 | |
3492 and then Is_Container_Iterator (Iter) | |
3493 and then not Is_Wrapped_In_Block (N) | |
3494 then | |
3495 declare | |
3496 Block_Nod : Node_Id; | |
3497 Block_Id : Entity_Id; | |
3498 | |
3499 begin | |
3500 Block_Nod := | |
3501 Make_Block_Statement (Loc, | |
3502 Declarations => New_List, | |
3503 Handled_Statement_Sequence => | |
3504 Make_Handled_Sequence_Of_Statements (Loc, | |
3505 Statements => New_List (Relocate_Node (N)))); | |
3506 | |
3507 Add_Block_Identifier (Block_Nod, Block_Id); | |
3508 | |
3509 -- The expansion of iterator loops generates an iterator in order | |
3510 -- to traverse the elements of a container: | |
3511 | |
3512 -- Iter : <iterator type> := Iterate (Container)'reference; | |
3513 | |
3514 -- The iterator is controlled and returned on the secondary stack. | |
3515 -- The analysis of the call to Iterate establishes a transient | |
3516 -- scope to deal with the secondary stack management, but never | |
3517 -- really creates a physical block as this would kill the iterator | |
3518 -- too early (see Wrap_Transient_Declaration). To address this | |
3519 -- case, mark the generated block as needing secondary stack | |
3520 -- management. | |
3521 | |
3522 Set_Uses_Sec_Stack (Block_Id); | |
3523 | |
3524 Rewrite (N, Block_Nod); | |
3525 Analyze (N); | |
3526 return; | |
3527 end; | |
3528 end if; | 3813 end if; |
3529 | 3814 |
3530 -- Kill current values on entry to loop, since statements in the body of | 3815 -- Kill current values on entry to loop, since statements in the body of |
3531 -- the loop may have been executed before the loop is entered. Similarly | 3816 -- the loop may have been executed before the loop is entered. Similarly |
3532 -- we kill values after the loop, since we do not know that the body of | 3817 -- we kill values after the loop, since we do not know that the body of |
3687 -- contains no EXIT statements within the body of the loop. | 3972 -- contains no EXIT statements within the body of the loop. |
3688 | 3973 |
3689 if No (Iter) and then not Has_Exit (Ent) then | 3974 if No (Iter) and then not Has_Exit (Ent) then |
3690 Check_Unreachable_Code (Stmt); | 3975 Check_Unreachable_Code (Stmt); |
3691 end if; | 3976 end if; |
3977 | |
3978 -- Variables referenced within a loop subject to possible OpenACC | |
3979 -- offloading may be implicitly written to as part of the OpenACC | |
3980 -- transaction. Clear flags possibly conveying that they are constant, | |
3981 -- set for example when the code does not explicitly assign them. | |
3982 | |
3983 if Is_OpenAcc_Environment (Stmt) then | |
3984 Disable_Constants (Stmt); | |
3985 end if; | |
3986 | |
3987 exception | |
3988 when Skip_Analysis => | |
3989 null; | |
3692 end Analyze_Loop_Statement; | 3990 end Analyze_Loop_Statement; |
3693 | 3991 |
3694 ---------------------------- | 3992 ---------------------------- |
3695 -- Analyze_Null_Statement -- | 3993 -- Analyze_Null_Statement -- |
3696 ---------------------------- | 3994 ---------------------------- |
3953 end if; | 4251 end if; |
3954 end; | 4252 end; |
3955 end if; | 4253 end if; |
3956 end Check_Unreachable_Code; | 4254 end Check_Unreachable_Code; |
3957 | 4255 |
4256 ------------------------ | |
4257 -- Has_Sec_Stack_Call -- | |
4258 ------------------------ | |
4259 | |
4260 function Has_Sec_Stack_Call (N : Node_Id) return Boolean is | |
4261 function Check_Call (N : Node_Id) return Traverse_Result; | |
4262 -- Check if N is a function call which uses the secondary stack | |
4263 | |
4264 ---------------- | |
4265 -- Check_Call -- | |
4266 ---------------- | |
4267 | |
4268 function Check_Call (N : Node_Id) return Traverse_Result is | |
4269 Nam : Node_Id; | |
4270 Subp : Entity_Id; | |
4271 Typ : Entity_Id; | |
4272 | |
4273 begin | |
4274 if Nkind (N) = N_Function_Call then | |
4275 Nam := Name (N); | |
4276 | |
4277 -- Obtain the subprogram being invoked | |
4278 | |
4279 loop | |
4280 if Nkind (Nam) = N_Explicit_Dereference then | |
4281 Nam := Prefix (Nam); | |
4282 | |
4283 elsif Nkind (Nam) = N_Selected_Component then | |
4284 Nam := Selector_Name (Nam); | |
4285 | |
4286 else | |
4287 exit; | |
4288 end if; | |
4289 end loop; | |
4290 | |
4291 Subp := Entity (Nam); | |
4292 | |
4293 if Present (Subp) then | |
4294 Typ := Etype (Subp); | |
4295 | |
4296 if Requires_Transient_Scope (Typ) then | |
4297 return Abandon; | |
4298 | |
4299 elsif Sec_Stack_Needed_For_Return (Subp) then | |
4300 return Abandon; | |
4301 end if; | |
4302 end if; | |
4303 end if; | |
4304 | |
4305 -- Continue traversing the tree | |
4306 | |
4307 return OK; | |
4308 end Check_Call; | |
4309 | |
4310 function Check_Calls is new Traverse_Func (Check_Call); | |
4311 | |
4312 -- Start of processing for Has_Sec_Stack_Call | |
4313 | |
4314 begin | |
4315 return Check_Calls (N) = Abandon; | |
4316 end Has_Sec_Stack_Call; | |
4317 | |
3958 ---------------------- | 4318 ---------------------- |
3959 -- Preanalyze_Range -- | 4319 -- Preanalyze_Range -- |
3960 ---------------------- | 4320 ---------------------- |
3961 | 4321 |
3962 procedure Preanalyze_Range (R_Copy : Node_Id) is | 4322 procedure Preanalyze_Range (R_Copy : Node_Id) is |
3964 Typ : Entity_Id; | 4324 Typ : Entity_Id; |
3965 | 4325 |
3966 begin | 4326 begin |
3967 Full_Analysis := False; | 4327 Full_Analysis := False; |
3968 Expander_Mode_Save_And_Set (False); | 4328 Expander_Mode_Save_And_Set (False); |
4329 | |
4330 -- In addition to the above we must explicitly suppress the generation | |
4331 -- of freeze nodes that might otherwise be generated during resolution | |
4332 -- of the range (e.g. if given by an attribute that will freeze its | |
4333 -- prefix). | |
4334 | |
4335 Set_Must_Not_Freeze (R_Copy); | |
4336 | |
4337 if Nkind (R_Copy) = N_Attribute_Reference then | |
4338 Set_Must_Not_Freeze (Prefix (R_Copy)); | |
4339 end if; | |
3969 | 4340 |
3970 Analyze (R_Copy); | 4341 Analyze (R_Copy); |
3971 | 4342 |
3972 if Nkind (R_Copy) in N_Subexpr and then Is_Overloaded (R_Copy) then | 4343 if Nkind (R_Copy) in N_Subexpr and then Is_Overloaded (R_Copy) then |
3973 | 4344 |