annotate gcc/ada/exp_prag.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- E X P _ P R A G --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 1992-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
kono
parents:
diff changeset
17 -- for more details. You should have received a copy of the GNU General --
kono
parents:
diff changeset
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
kono
parents:
diff changeset
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
kono
parents:
diff changeset
20 -- --
kono
parents:
diff changeset
21 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
23 -- --
kono
parents:
diff changeset
24 ------------------------------------------------------------------------------
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 with Atree; use Atree;
kono
parents:
diff changeset
27 with Casing; use Casing;
kono
parents:
diff changeset
28 with Checks; use Checks;
kono
parents:
diff changeset
29 with Debug; use Debug;
kono
parents:
diff changeset
30 with Einfo; use Einfo;
kono
parents:
diff changeset
31 with Errout; use Errout;
kono
parents:
diff changeset
32 with Exp_Ch11; use Exp_Ch11;
kono
parents:
diff changeset
33 with Exp_Util; use Exp_Util;
kono
parents:
diff changeset
34 with Expander; use Expander;
kono
parents:
diff changeset
35 with Inline; use Inline;
kono
parents:
diff changeset
36 with Lib; use Lib;
kono
parents:
diff changeset
37 with Namet; use Namet;
kono
parents:
diff changeset
38 with Nlists; use Nlists;
kono
parents:
diff changeset
39 with Nmake; use Nmake;
kono
parents:
diff changeset
40 with Opt; use Opt;
kono
parents:
diff changeset
41 with Restrict; use Restrict;
kono
parents:
diff changeset
42 with Rident; use Rident;
kono
parents:
diff changeset
43 with Rtsfind; use Rtsfind;
kono
parents:
diff changeset
44 with Sem; use Sem;
kono
parents:
diff changeset
45 with Sem_Aux; use Sem_Aux;
kono
parents:
diff changeset
46 with Sem_Ch8; use Sem_Ch8;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
47 with Sem_Prag; use Sem_Prag;
111
kono
parents:
diff changeset
48 with Sem_Util; use Sem_Util;
kono
parents:
diff changeset
49 with Sinfo; use Sinfo;
kono
parents:
diff changeset
50 with Sinput; use Sinput;
kono
parents:
diff changeset
51 with Snames; use Snames;
kono
parents:
diff changeset
52 with Stringt; use Stringt;
kono
parents:
diff changeset
53 with Stand; use Stand;
kono
parents:
diff changeset
54 with Tbuild; use Tbuild;
kono
parents:
diff changeset
55 with Uintp; use Uintp;
kono
parents:
diff changeset
56 with Validsw; use Validsw;
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 package body Exp_Prag is
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 -----------------------
kono
parents:
diff changeset
61 -- Local Subprograms --
kono
parents:
diff changeset
62 -----------------------
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 function Arg1 (N : Node_Id) return Node_Id;
kono
parents:
diff changeset
65 function Arg2 (N : Node_Id) return Node_Id;
kono
parents:
diff changeset
66 function Arg3 (N : Node_Id) return Node_Id;
kono
parents:
diff changeset
67 -- Obtain specified pragma argument expression
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 procedure Expand_Pragma_Abort_Defer (N : Node_Id);
kono
parents:
diff changeset
70 procedure Expand_Pragma_Check (N : Node_Id);
kono
parents:
diff changeset
71 procedure Expand_Pragma_Common_Object (N : Node_Id);
kono
parents:
diff changeset
72 procedure Expand_Pragma_Import_Or_Interface (N : Node_Id);
kono
parents:
diff changeset
73 procedure Expand_Pragma_Inspection_Point (N : Node_Id);
kono
parents:
diff changeset
74 procedure Expand_Pragma_Interrupt_Priority (N : Node_Id);
kono
parents:
diff changeset
75 procedure Expand_Pragma_Loop_Variant (N : Node_Id);
kono
parents:
diff changeset
76 procedure Expand_Pragma_Psect_Object (N : Node_Id);
kono
parents:
diff changeset
77 procedure Expand_Pragma_Relative_Deadline (N : Node_Id);
kono
parents:
diff changeset
78 procedure Expand_Pragma_Suppress_Initialization (N : Node_Id);
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 procedure Undo_Initialization (Def_Id : Entity_Id; N : Node_Id);
kono
parents:
diff changeset
81 -- This procedure is used to undo initialization already done for Def_Id,
kono
parents:
diff changeset
82 -- which is always an E_Variable, in response to the occurrence of the
kono
parents:
diff changeset
83 -- pragma N, a pragma Interface, Import, or Suppress_Initialization. In all
kono
parents:
diff changeset
84 -- these cases we want no initialization to occur, but we have already done
kono
parents:
diff changeset
85 -- the initialization by the time we see the pragma, so we have to undo it.
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 ----------
kono
parents:
diff changeset
88 -- Arg1 --
kono
parents:
diff changeset
89 ----------
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 function Arg1 (N : Node_Id) return Node_Id is
kono
parents:
diff changeset
92 Arg : constant Node_Id := First (Pragma_Argument_Associations (N));
kono
parents:
diff changeset
93 begin
kono
parents:
diff changeset
94 if Present (Arg)
kono
parents:
diff changeset
95 and then Nkind (Arg) = N_Pragma_Argument_Association
kono
parents:
diff changeset
96 then
kono
parents:
diff changeset
97 return Expression (Arg);
kono
parents:
diff changeset
98 else
kono
parents:
diff changeset
99 return Arg;
kono
parents:
diff changeset
100 end if;
kono
parents:
diff changeset
101 end Arg1;
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 ----------
kono
parents:
diff changeset
104 -- Arg2 --
kono
parents:
diff changeset
105 ----------
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 function Arg2 (N : Node_Id) return Node_Id is
kono
parents:
diff changeset
108 Arg1 : constant Node_Id := First (Pragma_Argument_Associations (N));
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 begin
kono
parents:
diff changeset
111 if No (Arg1) then
kono
parents:
diff changeset
112 return Empty;
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 else
kono
parents:
diff changeset
115 declare
kono
parents:
diff changeset
116 Arg : constant Node_Id := Next (Arg1);
kono
parents:
diff changeset
117 begin
kono
parents:
diff changeset
118 if Present (Arg)
kono
parents:
diff changeset
119 and then Nkind (Arg) = N_Pragma_Argument_Association
kono
parents:
diff changeset
120 then
kono
parents:
diff changeset
121 return Expression (Arg);
kono
parents:
diff changeset
122 else
kono
parents:
diff changeset
123 return Arg;
kono
parents:
diff changeset
124 end if;
kono
parents:
diff changeset
125 end;
kono
parents:
diff changeset
126 end if;
kono
parents:
diff changeset
127 end Arg2;
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 ----------
kono
parents:
diff changeset
130 -- Arg3 --
kono
parents:
diff changeset
131 ----------
kono
parents:
diff changeset
132
kono
parents:
diff changeset
133 function Arg3 (N : Node_Id) return Node_Id is
kono
parents:
diff changeset
134 Arg1 : constant Node_Id := First (Pragma_Argument_Associations (N));
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 begin
kono
parents:
diff changeset
137 if No (Arg1) then
kono
parents:
diff changeset
138 return Empty;
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 else
kono
parents:
diff changeset
141 declare
kono
parents:
diff changeset
142 Arg : Node_Id := Next (Arg1);
kono
parents:
diff changeset
143 begin
kono
parents:
diff changeset
144 if No (Arg) then
kono
parents:
diff changeset
145 return Empty;
kono
parents:
diff changeset
146
kono
parents:
diff changeset
147 else
kono
parents:
diff changeset
148 Next (Arg);
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 if Present (Arg)
kono
parents:
diff changeset
151 and then Nkind (Arg) = N_Pragma_Argument_Association
kono
parents:
diff changeset
152 then
kono
parents:
diff changeset
153 return Expression (Arg);
kono
parents:
diff changeset
154 else
kono
parents:
diff changeset
155 return Arg;
kono
parents:
diff changeset
156 end if;
kono
parents:
diff changeset
157 end if;
kono
parents:
diff changeset
158 end;
kono
parents:
diff changeset
159 end if;
kono
parents:
diff changeset
160 end Arg3;
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 ---------------------
kono
parents:
diff changeset
163 -- Expand_N_Pragma --
kono
parents:
diff changeset
164 ---------------------
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 procedure Expand_N_Pragma (N : Node_Id) is
kono
parents:
diff changeset
167 Pname : constant Name_Id := Pragma_Name (N);
kono
parents:
diff changeset
168 Prag_Id : constant Pragma_Id := Get_Pragma_Id (Pname);
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 begin
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
171 -- Suppress the expansion of an ignored assertion pragma. Such a pragma
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
172 -- should not be transformed into a null statment because:
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
173 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
174 -- * The pragma may be part of the rep item chain of a type, in which
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
175 -- case rewriting it will destroy the chain.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
176 --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
177 -- * The analysis of the pragma may involve two parts (see routines
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
178 -- Analyze_xxx_In_Decl_Part). The second part of the analysis will
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
179 -- not happen if the pragma is rewritten.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
180
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
181 if Assertion_Expression_Pragma (Prag_Id) and then Is_Ignored (N) then
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
182 return;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
183
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
184 -- Rewrite the pragma into a null statement when it is ignored using
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
185 -- pragma Ignore_Pragma, or denotes Default_Scalar_Storage_Order and
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
186 -- compilation switch -gnatI is in effect.
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
187
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
188 elsif Should_Ignore_Pragma_Sem (N)
111
kono
parents:
diff changeset
189 or else (Prag_Id = Pragma_Default_Scalar_Storage_Order
kono
parents:
diff changeset
190 and then Ignore_Rep_Clauses)
kono
parents:
diff changeset
191 then
kono
parents:
diff changeset
192 Rewrite (N, Make_Null_Statement (Sloc (N)));
kono
parents:
diff changeset
193 return;
kono
parents:
diff changeset
194 end if;
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 case Prag_Id is
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 -- Pragmas requiring special expander action
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 when Pragma_Abort_Defer =>
kono
parents:
diff changeset
201 Expand_Pragma_Abort_Defer (N);
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 when Pragma_Check =>
kono
parents:
diff changeset
204 Expand_Pragma_Check (N);
kono
parents:
diff changeset
205
kono
parents:
diff changeset
206 when Pragma_Common_Object =>
kono
parents:
diff changeset
207 Expand_Pragma_Common_Object (N);
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 when Pragma_Import =>
kono
parents:
diff changeset
210 Expand_Pragma_Import_Or_Interface (N);
kono
parents:
diff changeset
211
kono
parents:
diff changeset
212 when Pragma_Inspection_Point =>
kono
parents:
diff changeset
213 Expand_Pragma_Inspection_Point (N);
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 when Pragma_Interface =>
kono
parents:
diff changeset
216 Expand_Pragma_Import_Or_Interface (N);
kono
parents:
diff changeset
217
kono
parents:
diff changeset
218 when Pragma_Interrupt_Priority =>
kono
parents:
diff changeset
219 Expand_Pragma_Interrupt_Priority (N);
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 when Pragma_Loop_Variant =>
kono
parents:
diff changeset
222 Expand_Pragma_Loop_Variant (N);
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 when Pragma_Psect_Object =>
kono
parents:
diff changeset
225 Expand_Pragma_Psect_Object (N);
kono
parents:
diff changeset
226
kono
parents:
diff changeset
227 when Pragma_Relative_Deadline =>
kono
parents:
diff changeset
228 Expand_Pragma_Relative_Deadline (N);
kono
parents:
diff changeset
229
kono
parents:
diff changeset
230 when Pragma_Suppress_Initialization =>
kono
parents:
diff changeset
231 Expand_Pragma_Suppress_Initialization (N);
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 -- All other pragmas need no expander action (includes
kono
parents:
diff changeset
234 -- Unknown_Pragma).
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 when others => null;
kono
parents:
diff changeset
237 end case;
kono
parents:
diff changeset
238 end Expand_N_Pragma;
kono
parents:
diff changeset
239
kono
parents:
diff changeset
240 -------------------------------
kono
parents:
diff changeset
241 -- Expand_Pragma_Abort_Defer --
kono
parents:
diff changeset
242 -------------------------------
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244 -- An Abort_Defer pragma appears as the first statement in a handled
kono
parents:
diff changeset
245 -- statement sequence (right after the begin). It defers aborts for
kono
parents:
diff changeset
246 -- the entire statement sequence, but not for any declarations or
kono
parents:
diff changeset
247 -- handlers (if any) associated with this statement sequence.
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 -- The transformation is to transform
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 -- pragma Abort_Defer;
kono
parents:
diff changeset
252 -- statements;
kono
parents:
diff changeset
253
kono
parents:
diff changeset
254 -- into
kono
parents:
diff changeset
255
kono
parents:
diff changeset
256 -- begin
kono
parents:
diff changeset
257 -- Abort_Defer.all;
kono
parents:
diff changeset
258 -- statements
kono
parents:
diff changeset
259 -- exception
kono
parents:
diff changeset
260 -- when all others =>
kono
parents:
diff changeset
261 -- Abort_Undefer.all;
kono
parents:
diff changeset
262 -- raise;
kono
parents:
diff changeset
263 -- at end
kono
parents:
diff changeset
264 -- Abort_Undefer_Direct;
kono
parents:
diff changeset
265 -- end;
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 procedure Expand_Pragma_Abort_Defer (N : Node_Id) is
kono
parents:
diff changeset
268 begin
kono
parents:
diff changeset
269 -- Abort_Defer has no useful effect if Abort's are not allowed
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 if not Abort_Allowed then
kono
parents:
diff changeset
272 return;
kono
parents:
diff changeset
273 end if;
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 -- Normal case where abort is possible
kono
parents:
diff changeset
276
kono
parents:
diff changeset
277 declare
kono
parents:
diff changeset
278 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
279 Stm : Node_Id;
kono
parents:
diff changeset
280 Stms : List_Id;
kono
parents:
diff changeset
281 HSS : Node_Id;
kono
parents:
diff changeset
282 Blk : constant Entity_Id :=
kono
parents:
diff changeset
283 New_Internal_Entity (E_Block, Current_Scope, Sloc (N), 'B');
kono
parents:
diff changeset
284 AUD : constant Entity_Id := RTE (RE_Abort_Undefer_Direct);
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 begin
kono
parents:
diff changeset
287 Stms := New_List (Build_Runtime_Call (Loc, RE_Abort_Defer));
kono
parents:
diff changeset
288 loop
kono
parents:
diff changeset
289 Stm := Remove_Next (N);
kono
parents:
diff changeset
290 exit when No (Stm);
kono
parents:
diff changeset
291 Append (Stm, Stms);
kono
parents:
diff changeset
292 end loop;
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 HSS :=
kono
parents:
diff changeset
295 Make_Handled_Sequence_Of_Statements (Loc,
kono
parents:
diff changeset
296 Statements => Stms,
kono
parents:
diff changeset
297 At_End_Proc => New_Occurrence_Of (AUD, Loc));
kono
parents:
diff changeset
298
kono
parents:
diff changeset
299 -- Present the Abort_Undefer_Direct function to the backend so that
kono
parents:
diff changeset
300 -- it can inline the call to the function.
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 Add_Inlined_Body (AUD, N);
kono
parents:
diff changeset
303
kono
parents:
diff changeset
304 Rewrite (N,
kono
parents:
diff changeset
305 Make_Block_Statement (Loc, Handled_Statement_Sequence => HSS));
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 Set_Scope (Blk, Current_Scope);
kono
parents:
diff changeset
308 Set_Etype (Blk, Standard_Void_Type);
kono
parents:
diff changeset
309 Set_Identifier (N, New_Occurrence_Of (Blk, Sloc (N)));
kono
parents:
diff changeset
310 Expand_At_End_Handler (HSS, Blk);
kono
parents:
diff changeset
311 Analyze (N);
kono
parents:
diff changeset
312 end;
kono
parents:
diff changeset
313 end Expand_Pragma_Abort_Defer;
kono
parents:
diff changeset
314
kono
parents:
diff changeset
315 --------------------------
kono
parents:
diff changeset
316 -- Expand_Pragma_Check --
kono
parents:
diff changeset
317 --------------------------
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 procedure Expand_Pragma_Check (N : Node_Id) is
kono
parents:
diff changeset
320 Cond : constant Node_Id := Arg2 (N);
kono
parents:
diff changeset
321 Nam : constant Name_Id := Chars (Arg1 (N));
kono
parents:
diff changeset
322 Msg : Node_Id;
kono
parents:
diff changeset
323
kono
parents:
diff changeset
324 Loc : constant Source_Ptr := Sloc (First_Node (Cond));
kono
parents:
diff changeset
325 -- Source location used in the case of a failed assertion: point to the
kono
parents:
diff changeset
326 -- failing condition, not Loc. Note that the source location of the
kono
parents:
diff changeset
327 -- expression is not usually the best choice here, because it points to
kono
parents:
diff changeset
328 -- the location of the topmost tree node, which may be an operator in
kono
parents:
diff changeset
329 -- the middle of the source text of the expression. For example, it gets
kono
parents:
diff changeset
330 -- located on the last AND keyword in a chain of boolean expressiond
kono
parents:
diff changeset
331 -- AND'ed together. It is best to put the message on the first character
kono
parents:
diff changeset
332 -- of the condition, which is the effect of the First_Node call here.
kono
parents:
diff changeset
333 -- This source location is used to build the default exception message,
kono
parents:
diff changeset
334 -- and also as the sloc of the call to the runtime subprogram raising
kono
parents:
diff changeset
335 -- Assert_Failure, so that coverage analysis tools can relate the
kono
parents:
diff changeset
336 -- call to the failed check.
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 procedure Replace_Discriminals_Of_Protected_Op (Expr : Node_Id);
kono
parents:
diff changeset
339 -- Discriminants of the enclosing protected object may be referenced
kono
parents:
diff changeset
340 -- in the expression of a precondition of a protected operation.
kono
parents:
diff changeset
341 -- In the body of the operation these references must be replaced by
kono
parents:
diff changeset
342 -- the discriminal created for them, which are renamings of the
kono
parents:
diff changeset
343 -- discriminants of the object that is the target of the operation.
kono
parents:
diff changeset
344 -- This replacement is done by visibility when the references appear
kono
parents:
diff changeset
345 -- in the subprogram body, but in the case of a condition which appears
kono
parents:
diff changeset
346 -- on the specification of the subprogram it has be done separately
kono
parents:
diff changeset
347 -- because the condition has been replaced by a Check pragma and
kono
parents:
diff changeset
348 -- analyzed earlier, before the creation of the discriminal renaming
kono
parents:
diff changeset
349 -- declarations that are added to the subprogram body.
kono
parents:
diff changeset
350
kono
parents:
diff changeset
351 ------------------------------------------
kono
parents:
diff changeset
352 -- Replace_Discriminals_Of_Protected_Op --
kono
parents:
diff changeset
353 ------------------------------------------
kono
parents:
diff changeset
354
kono
parents:
diff changeset
355 procedure Replace_Discriminals_Of_Protected_Op (Expr : Node_Id) is
kono
parents:
diff changeset
356 function Find_Corresponding_Discriminal
kono
parents:
diff changeset
357 (E : Entity_Id) return Entity_Id;
kono
parents:
diff changeset
358 -- Find the local entity that renames a discriminant of the enclosing
kono
parents:
diff changeset
359 -- protected type, and has a matching name.
kono
parents:
diff changeset
360
kono
parents:
diff changeset
361 function Replace_Discr_Ref (N : Node_Id) return Traverse_Result;
kono
parents:
diff changeset
362 -- Replace a reference to a discriminant of the original protected
kono
parents:
diff changeset
363 -- type by the local renaming declaration of the discriminant of
kono
parents:
diff changeset
364 -- the target object.
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 ------------------------------------
kono
parents:
diff changeset
367 -- Find_Corresponding_Discriminal --
kono
parents:
diff changeset
368 ------------------------------------
kono
parents:
diff changeset
369
kono
parents:
diff changeset
370 function Find_Corresponding_Discriminal
kono
parents:
diff changeset
371 (E : Entity_Id) return Entity_Id
kono
parents:
diff changeset
372 is
kono
parents:
diff changeset
373 R : Entity_Id;
kono
parents:
diff changeset
374
kono
parents:
diff changeset
375 begin
kono
parents:
diff changeset
376 R := First_Entity (Current_Scope);
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 while Present (R) loop
kono
parents:
diff changeset
379 if Nkind (Parent (R)) = N_Object_Renaming_Declaration
kono
parents:
diff changeset
380 and then Present (Discriminal_Link (R))
kono
parents:
diff changeset
381 and then Chars (Discriminal_Link (R)) = Chars (E)
kono
parents:
diff changeset
382 then
kono
parents:
diff changeset
383 return R;
kono
parents:
diff changeset
384 end if;
kono
parents:
diff changeset
385
kono
parents:
diff changeset
386 Next_Entity (R);
kono
parents:
diff changeset
387 end loop;
kono
parents:
diff changeset
388
kono
parents:
diff changeset
389 return Empty;
kono
parents:
diff changeset
390 end Find_Corresponding_Discriminal;
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 -----------------------
kono
parents:
diff changeset
393 -- Replace_Discr_Ref --
kono
parents:
diff changeset
394 -----------------------
kono
parents:
diff changeset
395
kono
parents:
diff changeset
396 function Replace_Discr_Ref (N : Node_Id) return Traverse_Result is
kono
parents:
diff changeset
397 R : Entity_Id;
kono
parents:
diff changeset
398
kono
parents:
diff changeset
399 begin
kono
parents:
diff changeset
400 if Is_Entity_Name (N)
kono
parents:
diff changeset
401 and then Present (Discriminal_Link (Entity (N)))
kono
parents:
diff changeset
402 then
kono
parents:
diff changeset
403 R := Find_Corresponding_Discriminal (Entity (N));
kono
parents:
diff changeset
404 Rewrite (N, New_Occurrence_Of (R, Sloc (N)));
kono
parents:
diff changeset
405 end if;
kono
parents:
diff changeset
406
kono
parents:
diff changeset
407 return OK;
kono
parents:
diff changeset
408 end Replace_Discr_Ref;
kono
parents:
diff changeset
409
kono
parents:
diff changeset
410 procedure Replace_Discriminant_References is
kono
parents:
diff changeset
411 new Traverse_Proc (Replace_Discr_Ref);
kono
parents:
diff changeset
412
kono
parents:
diff changeset
413 -- Start of processing for Replace_Discriminals_Of_Protected_Op
kono
parents:
diff changeset
414
kono
parents:
diff changeset
415 begin
kono
parents:
diff changeset
416 Replace_Discriminant_References (Expr);
kono
parents:
diff changeset
417 end Replace_Discriminals_Of_Protected_Op;
kono
parents:
diff changeset
418
kono
parents:
diff changeset
419 -- Start of processing for Expand_Pragma_Check
kono
parents:
diff changeset
420
kono
parents:
diff changeset
421 begin
kono
parents:
diff changeset
422 -- Nothing to do if pragma is ignored
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 if Is_Ignored (N) then
kono
parents:
diff changeset
425 return;
kono
parents:
diff changeset
426 end if;
kono
parents:
diff changeset
427
kono
parents:
diff changeset
428 -- Since this check is active, rewrite the pragma into a corresponding
kono
parents:
diff changeset
429 -- if statement, and then analyze the statement.
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 -- The normal case expansion transforms:
kono
parents:
diff changeset
432
kono
parents:
diff changeset
433 -- pragma Check (name, condition [,message]);
kono
parents:
diff changeset
434
kono
parents:
diff changeset
435 -- into
kono
parents:
diff changeset
436
kono
parents:
diff changeset
437 -- if not condition then
kono
parents:
diff changeset
438 -- System.Assertions.Raise_Assert_Failure (Str);
kono
parents:
diff changeset
439 -- end if;
kono
parents:
diff changeset
440
kono
parents:
diff changeset
441 -- where Str is the message if one is present, or the default of
kono
parents:
diff changeset
442 -- name failed at file:line if no message is given (the "name failed
kono
parents:
diff changeset
443 -- at" is omitted for name = Assertion, since it is redundant, given
kono
parents:
diff changeset
444 -- that the name of the exception is Assert_Failure.)
kono
parents:
diff changeset
445
kono
parents:
diff changeset
446 -- Also, instead of "XXX failed at", we generate slightly
kono
parents:
diff changeset
447 -- different messages for some of the contract assertions (see
kono
parents:
diff changeset
448 -- code below for details).
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 -- An alternative expansion is used when the No_Exception_Propagation
kono
parents:
diff changeset
451 -- restriction is active and there is a local Assert_Failure handler.
kono
parents:
diff changeset
452 -- This is not a common combination of circumstances, but it occurs in
kono
parents:
diff changeset
453 -- the context of Aunit and the zero footprint profile. In this case we
kono
parents:
diff changeset
454 -- generate:
kono
parents:
diff changeset
455
kono
parents:
diff changeset
456 -- if not condition then
kono
parents:
diff changeset
457 -- raise Assert_Failure;
kono
parents:
diff changeset
458 -- end if;
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 -- This will then be transformed into a goto, and the local handler will
kono
parents:
diff changeset
461 -- be able to handle the assert error (which would not be the case if a
kono
parents:
diff changeset
462 -- call is made to the Raise_Assert_Failure procedure).
kono
parents:
diff changeset
463
kono
parents:
diff changeset
464 -- We also generate the direct raise if the Suppress_Exception_Locations
kono
parents:
diff changeset
465 -- is active, since we don't want to generate messages in this case.
kono
parents:
diff changeset
466
kono
parents:
diff changeset
467 -- Note that the reason we do not always generate a direct raise is that
kono
parents:
diff changeset
468 -- the form in which the procedure is called allows for more efficient
kono
parents:
diff changeset
469 -- breakpointing of assertion errors.
kono
parents:
diff changeset
470
kono
parents:
diff changeset
471 -- Generate the appropriate if statement. Note that we consider this to
kono
parents:
diff changeset
472 -- be an explicit conditional in the source, not an implicit if, so we
kono
parents:
diff changeset
473 -- do not call Make_Implicit_If_Statement.
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 -- Case where we generate a direct raise
kono
parents:
diff changeset
476
kono
parents:
diff changeset
477 if ((Debug_Flag_Dot_G
kono
parents:
diff changeset
478 or else Restriction_Active (No_Exception_Propagation))
kono
parents:
diff changeset
479 and then Present (Find_Local_Handler (RTE (RE_Assert_Failure), N)))
kono
parents:
diff changeset
480 or else (Opt.Exception_Locations_Suppressed and then No (Arg3 (N)))
kono
parents:
diff changeset
481 then
kono
parents:
diff changeset
482 Rewrite (N,
kono
parents:
diff changeset
483 Make_If_Statement (Loc,
kono
parents:
diff changeset
484 Condition => Make_Op_Not (Loc, Right_Opnd => Cond),
kono
parents:
diff changeset
485 Then_Statements => New_List (
kono
parents:
diff changeset
486 Make_Raise_Statement (Loc,
kono
parents:
diff changeset
487 Name => New_Occurrence_Of (RTE (RE_Assert_Failure), Loc)))));
kono
parents:
diff changeset
488
kono
parents:
diff changeset
489 -- Case where we call the procedure
kono
parents:
diff changeset
490
kono
parents:
diff changeset
491 else
kono
parents:
diff changeset
492 -- If we have a message given, use it
kono
parents:
diff changeset
493
kono
parents:
diff changeset
494 if Present (Arg3 (N)) then
kono
parents:
diff changeset
495 Msg := Get_Pragma_Arg (Arg3 (N));
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 -- Here we have no string, so prepare one
kono
parents:
diff changeset
498
kono
parents:
diff changeset
499 else
kono
parents:
diff changeset
500 declare
kono
parents:
diff changeset
501 Loc_Str : constant String := Build_Location_String (Loc);
kono
parents:
diff changeset
502
kono
parents:
diff changeset
503 begin
kono
parents:
diff changeset
504 Name_Len := 0;
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 -- For Assert, we just use the location
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 if Nam = Name_Assert then
kono
parents:
diff changeset
509 null;
kono
parents:
diff changeset
510
kono
parents:
diff changeset
511 -- For predicate, we generate the string "predicate failed at
kono
parents:
diff changeset
512 -- yyy". We prefer all lower case for predicate.
kono
parents:
diff changeset
513
kono
parents:
diff changeset
514 elsif Nam = Name_Predicate then
kono
parents:
diff changeset
515 Add_Str_To_Name_Buffer ("predicate failed at ");
kono
parents:
diff changeset
516
kono
parents:
diff changeset
517 -- For special case of Precondition/Postcondition the string is
kono
parents:
diff changeset
518 -- "failed xx from yy" where xx is precondition/postcondition
kono
parents:
diff changeset
519 -- in all lower case. The reason for this different wording is
kono
parents:
diff changeset
520 -- that the failure is not at the point of occurrence of the
kono
parents:
diff changeset
521 -- pragma, unlike the other Check cases.
kono
parents:
diff changeset
522
kono
parents:
diff changeset
523 elsif Nam_In (Nam, Name_Precondition, Name_Postcondition) then
kono
parents:
diff changeset
524 Get_Name_String (Nam);
kono
parents:
diff changeset
525 Insert_Str_In_Name_Buffer ("failed ", 1);
kono
parents:
diff changeset
526 Add_Str_To_Name_Buffer (" from ");
kono
parents:
diff changeset
527
kono
parents:
diff changeset
528 -- For special case of Invariant, the string is "failed
kono
parents:
diff changeset
529 -- invariant from yy", to be consistent with the string that is
kono
parents:
diff changeset
530 -- generated for the aspect case (the code later on checks for
kono
parents:
diff changeset
531 -- this specific string to modify it in some cases, so this is
kono
parents:
diff changeset
532 -- functionally important).
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 elsif Nam = Name_Invariant then
kono
parents:
diff changeset
535 Add_Str_To_Name_Buffer ("failed invariant from ");
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 -- For all other checks, the string is "xxx failed at yyy"
kono
parents:
diff changeset
538 -- where xxx is the check name with appropriate casing.
kono
parents:
diff changeset
539
kono
parents:
diff changeset
540 else
kono
parents:
diff changeset
541 Get_Name_String (Nam);
kono
parents:
diff changeset
542 Set_Casing
kono
parents:
diff changeset
543 (Identifier_Casing (Source_Index (Current_Sem_Unit)));
kono
parents:
diff changeset
544 Add_Str_To_Name_Buffer (" failed at ");
kono
parents:
diff changeset
545 end if;
kono
parents:
diff changeset
546
kono
parents:
diff changeset
547 -- In all cases, add location string
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 Add_Str_To_Name_Buffer (Loc_Str);
kono
parents:
diff changeset
550
kono
parents:
diff changeset
551 -- Build the message
kono
parents:
diff changeset
552
kono
parents:
diff changeset
553 Msg := Make_String_Literal (Loc, Name_Buffer (1 .. Name_Len));
kono
parents:
diff changeset
554 end;
kono
parents:
diff changeset
555 end if;
kono
parents:
diff changeset
556
kono
parents:
diff changeset
557 -- For a precondition, replace references to discriminants of a
kono
parents:
diff changeset
558 -- protected type with the local discriminals.
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 if Is_Protected_Type (Scope (Current_Scope))
kono
parents:
diff changeset
561 and then Has_Discriminants (Scope (Current_Scope))
kono
parents:
diff changeset
562 and then From_Aspect_Specification (N)
kono
parents:
diff changeset
563 then
kono
parents:
diff changeset
564 Replace_Discriminals_Of_Protected_Op (Cond);
kono
parents:
diff changeset
565 end if;
kono
parents:
diff changeset
566
kono
parents:
diff changeset
567 -- Now rewrite as an if statement
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 Rewrite (N,
kono
parents:
diff changeset
570 Make_If_Statement (Loc,
kono
parents:
diff changeset
571 Condition => Make_Op_Not (Loc, Right_Opnd => Cond),
kono
parents:
diff changeset
572 Then_Statements => New_List (
kono
parents:
diff changeset
573 Make_Procedure_Call_Statement (Loc,
kono
parents:
diff changeset
574 Name =>
kono
parents:
diff changeset
575 New_Occurrence_Of (RTE (RE_Raise_Assert_Failure), Loc),
kono
parents:
diff changeset
576 Parameter_Associations => New_List (Relocate_Node (Msg))))));
kono
parents:
diff changeset
577 end if;
kono
parents:
diff changeset
578
kono
parents:
diff changeset
579 Analyze (N);
kono
parents:
diff changeset
580
kono
parents:
diff changeset
581 -- If new condition is always false, give a warning
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 if Warn_On_Assertion_Failure
kono
parents:
diff changeset
584 and then Nkind (N) = N_Procedure_Call_Statement
kono
parents:
diff changeset
585 and then Is_RTE (Entity (Name (N)), RE_Raise_Assert_Failure)
kono
parents:
diff changeset
586 then
kono
parents:
diff changeset
587 -- If original condition was a Standard.False, we assume that this is
kono
parents:
diff changeset
588 -- indeed intended to raise assert error and no warning is required.
kono
parents:
diff changeset
589
kono
parents:
diff changeset
590 if Is_Entity_Name (Original_Node (Cond))
kono
parents:
diff changeset
591 and then Entity (Original_Node (Cond)) = Standard_False
kono
parents:
diff changeset
592 then
kono
parents:
diff changeset
593 null;
kono
parents:
diff changeset
594
kono
parents:
diff changeset
595 elsif Nam = Name_Assert then
kono
parents:
diff changeset
596 Error_Msg_N ("?A?assertion will fail at run time", N);
kono
parents:
diff changeset
597 else
kono
parents:
diff changeset
598 Error_Msg_N ("?A?check will fail at run time", N);
kono
parents:
diff changeset
599 end if;
kono
parents:
diff changeset
600 end if;
kono
parents:
diff changeset
601 end Expand_Pragma_Check;
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 ---------------------------------
kono
parents:
diff changeset
604 -- Expand_Pragma_Common_Object --
kono
parents:
diff changeset
605 ---------------------------------
kono
parents:
diff changeset
606
kono
parents:
diff changeset
607 -- Use a machine attribute to replicate semantic effect in DEC Ada
kono
parents:
diff changeset
608
kono
parents:
diff changeset
609 -- pragma Machine_Attribute (intern_name, "common_object", extern_name);
kono
parents:
diff changeset
610
kono
parents:
diff changeset
611 -- For now we do nothing with the size attribute ???
kono
parents:
diff changeset
612
kono
parents:
diff changeset
613 -- Note: Psect_Object shares this processing
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 procedure Expand_Pragma_Common_Object (N : Node_Id) is
kono
parents:
diff changeset
616 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
617
kono
parents:
diff changeset
618 Internal : constant Node_Id := Arg1 (N);
kono
parents:
diff changeset
619 External : constant Node_Id := Arg2 (N);
kono
parents:
diff changeset
620
kono
parents:
diff changeset
621 Psect : Node_Id;
kono
parents:
diff changeset
622 -- Psect value upper cased as string literal
kono
parents:
diff changeset
623
kono
parents:
diff changeset
624 Iloc : constant Source_Ptr := Sloc (Internal);
kono
parents:
diff changeset
625 Eloc : constant Source_Ptr := Sloc (External);
kono
parents:
diff changeset
626 Ploc : Source_Ptr;
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 begin
kono
parents:
diff changeset
629 -- Acquire Psect value and fold to upper case
kono
parents:
diff changeset
630
kono
parents:
diff changeset
631 if Present (External) then
kono
parents:
diff changeset
632 if Nkind (External) = N_String_Literal then
kono
parents:
diff changeset
633 String_To_Name_Buffer (Strval (External));
kono
parents:
diff changeset
634 else
kono
parents:
diff changeset
635 Get_Name_String (Chars (External));
kono
parents:
diff changeset
636 end if;
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 Set_All_Upper_Case;
kono
parents:
diff changeset
639
kono
parents:
diff changeset
640 Psect :=
kono
parents:
diff changeset
641 Make_String_Literal (Eloc, Strval => String_From_Name_Buffer);
kono
parents:
diff changeset
642
kono
parents:
diff changeset
643 else
kono
parents:
diff changeset
644 Get_Name_String (Chars (Internal));
kono
parents:
diff changeset
645 Set_All_Upper_Case;
kono
parents:
diff changeset
646 Psect :=
kono
parents:
diff changeset
647 Make_String_Literal (Iloc, Strval => String_From_Name_Buffer);
kono
parents:
diff changeset
648 end if;
kono
parents:
diff changeset
649
kono
parents:
diff changeset
650 Ploc := Sloc (Psect);
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 -- Insert the pragma
kono
parents:
diff changeset
653
kono
parents:
diff changeset
654 Insert_After_And_Analyze (N,
kono
parents:
diff changeset
655 Make_Pragma (Loc,
kono
parents:
diff changeset
656 Chars => Name_Machine_Attribute,
kono
parents:
diff changeset
657 Pragma_Argument_Associations => New_List (
kono
parents:
diff changeset
658 Make_Pragma_Argument_Association (Iloc,
kono
parents:
diff changeset
659 Expression => New_Copy_Tree (Internal)),
kono
parents:
diff changeset
660 Make_Pragma_Argument_Association (Eloc,
kono
parents:
diff changeset
661 Expression =>
kono
parents:
diff changeset
662 Make_String_Literal (Sloc => Ploc, Strval => "common_object")),
kono
parents:
diff changeset
663 Make_Pragma_Argument_Association (Ploc,
kono
parents:
diff changeset
664 Expression => New_Copy_Tree (Psect)))));
kono
parents:
diff changeset
665 end Expand_Pragma_Common_Object;
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 ----------------------------------
kono
parents:
diff changeset
668 -- Expand_Pragma_Contract_Cases --
kono
parents:
diff changeset
669 ----------------------------------
kono
parents:
diff changeset
670
kono
parents:
diff changeset
671 -- Pragma Contract_Cases is expanded in the following manner:
kono
parents:
diff changeset
672
kono
parents:
diff changeset
673 -- subprogram S is
kono
parents:
diff changeset
674 -- Count : Natural := 0;
kono
parents:
diff changeset
675 -- Flag_1 : Boolean := False;
kono
parents:
diff changeset
676 -- . . .
kono
parents:
diff changeset
677 -- Flag_N : Boolean := False;
kono
parents:
diff changeset
678 -- Flag_N+1 : Boolean := False; -- when "others" present
kono
parents:
diff changeset
679 -- Pref_1 : ...;
kono
parents:
diff changeset
680 -- . . .
kono
parents:
diff changeset
681 -- Pref_M : ...;
kono
parents:
diff changeset
682
kono
parents:
diff changeset
683 -- <preconditions (if any)>
kono
parents:
diff changeset
684
kono
parents:
diff changeset
685 -- -- Evaluate all case guards
kono
parents:
diff changeset
686
kono
parents:
diff changeset
687 -- if Case_Guard_1 then
kono
parents:
diff changeset
688 -- Flag_1 := True;
kono
parents:
diff changeset
689 -- Count := Count + 1;
kono
parents:
diff changeset
690 -- end if;
kono
parents:
diff changeset
691 -- . . .
kono
parents:
diff changeset
692 -- if Case_Guard_N then
kono
parents:
diff changeset
693 -- Flag_N := True;
kono
parents:
diff changeset
694 -- Count := Count + 1;
kono
parents:
diff changeset
695 -- end if;
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 -- -- Emit errors depending on the number of case guards that
kono
parents:
diff changeset
698 -- -- evaluated to True.
kono
parents:
diff changeset
699
kono
parents:
diff changeset
700 -- if Count = 0 then
kono
parents:
diff changeset
701 -- raise Assertion_Error with "xxx contract cases incomplete";
kono
parents:
diff changeset
702 -- <or>
kono
parents:
diff changeset
703 -- Flag_N+1 := True; -- when "others" present
kono
parents:
diff changeset
704
kono
parents:
diff changeset
705 -- elsif Count > 1 then
kono
parents:
diff changeset
706 -- declare
kono
parents:
diff changeset
707 -- Str0 : constant String :=
kono
parents:
diff changeset
708 -- "contract cases overlap for subprogram ABC";
kono
parents:
diff changeset
709 -- Str1 : constant String :=
kono
parents:
diff changeset
710 -- (if Flag_1 then
kono
parents:
diff changeset
711 -- Str0 & "case guard at xxx evaluates to True"
kono
parents:
diff changeset
712 -- else Str0);
kono
parents:
diff changeset
713 -- StrN : constant String :=
kono
parents:
diff changeset
714 -- (if Flag_N then
kono
parents:
diff changeset
715 -- StrN-1 & "case guard at xxx evaluates to True"
kono
parents:
diff changeset
716 -- else StrN-1);
kono
parents:
diff changeset
717 -- begin
kono
parents:
diff changeset
718 -- raise Assertion_Error with StrN;
kono
parents:
diff changeset
719 -- end;
kono
parents:
diff changeset
720 -- end if;
kono
parents:
diff changeset
721
kono
parents:
diff changeset
722 -- -- Evaluate all attribute 'Old prefixes found in the selected
kono
parents:
diff changeset
723 -- -- consequence.
kono
parents:
diff changeset
724
kono
parents:
diff changeset
725 -- if Flag_1 then
kono
parents:
diff changeset
726 -- Pref_1 := <prefix of 'Old found in Consequence_1>
kono
parents:
diff changeset
727 -- . . .
kono
parents:
diff changeset
728 -- elsif Flag_N then
kono
parents:
diff changeset
729 -- Pref_M := <prefix of 'Old found in Consequence_N>
kono
parents:
diff changeset
730 -- end if;
kono
parents:
diff changeset
731
kono
parents:
diff changeset
732 -- procedure _Postconditions is
kono
parents:
diff changeset
733 -- begin
kono
parents:
diff changeset
734 -- <postconditions (if any)>
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 -- if Flag_1 and then not Consequence_1 then
kono
parents:
diff changeset
737 -- raise Assertion_Error with "failed contract case at xxx";
kono
parents:
diff changeset
738 -- end if;
kono
parents:
diff changeset
739 -- . . .
kono
parents:
diff changeset
740 -- if Flag_N[+1] and then not Consequence_N[+1] then
kono
parents:
diff changeset
741 -- raise Assertion_Error with "failed contract case at xxx";
kono
parents:
diff changeset
742 -- end if;
kono
parents:
diff changeset
743 -- end _Postconditions;
kono
parents:
diff changeset
744 -- begin
kono
parents:
diff changeset
745 -- . . .
kono
parents:
diff changeset
746 -- end S;
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 procedure Expand_Pragma_Contract_Cases
kono
parents:
diff changeset
749 (CCs : Node_Id;
kono
parents:
diff changeset
750 Subp_Id : Entity_Id;
kono
parents:
diff changeset
751 Decls : List_Id;
kono
parents:
diff changeset
752 Stmts : in out List_Id)
kono
parents:
diff changeset
753 is
kono
parents:
diff changeset
754 Loc : constant Source_Ptr := Sloc (CCs);
kono
parents:
diff changeset
755
kono
parents:
diff changeset
756 procedure Case_Guard_Error
kono
parents:
diff changeset
757 (Decls : List_Id;
kono
parents:
diff changeset
758 Flag : Entity_Id;
kono
parents:
diff changeset
759 Error_Loc : Source_Ptr;
kono
parents:
diff changeset
760 Msg : in out Entity_Id);
kono
parents:
diff changeset
761 -- Given a declarative list Decls, status flag Flag, the location of the
kono
parents:
diff changeset
762 -- error and a string Msg, construct the following check:
kono
parents:
diff changeset
763 -- Msg : constant String :=
kono
parents:
diff changeset
764 -- (if Flag then
kono
parents:
diff changeset
765 -- Msg & "case guard at Error_Loc evaluates to True"
kono
parents:
diff changeset
766 -- else Msg);
kono
parents:
diff changeset
767 -- The resulting code is added to Decls
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 procedure Consequence_Error
kono
parents:
diff changeset
770 (Checks : in out Node_Id;
kono
parents:
diff changeset
771 Flag : Entity_Id;
kono
parents:
diff changeset
772 Conseq : Node_Id);
kono
parents:
diff changeset
773 -- Given an if statement Checks, status flag Flag and a consequence
kono
parents:
diff changeset
774 -- Conseq, construct the following check:
kono
parents:
diff changeset
775 -- [els]if Flag and then not Conseq then
kono
parents:
diff changeset
776 -- raise Assertion_Error
kono
parents:
diff changeset
777 -- with "failed contract case at Sloc (Conseq)";
kono
parents:
diff changeset
778 -- [end if;]
kono
parents:
diff changeset
779 -- The resulting code is added to Checks
kono
parents:
diff changeset
780
kono
parents:
diff changeset
781 function Declaration_Of (Id : Entity_Id) return Node_Id;
kono
parents:
diff changeset
782 -- Given the entity Id of a boolean flag, generate:
kono
parents:
diff changeset
783 -- Id : Boolean := False;
kono
parents:
diff changeset
784
kono
parents:
diff changeset
785 procedure Expand_Attributes_In_Consequence
kono
parents:
diff changeset
786 (Decls : List_Id;
kono
parents:
diff changeset
787 Evals : in out Node_Id;
kono
parents:
diff changeset
788 Flag : Entity_Id;
kono
parents:
diff changeset
789 Conseq : Node_Id);
kono
parents:
diff changeset
790 -- Perform specialized expansion of all attribute 'Old references found
kono
parents:
diff changeset
791 -- in consequence Conseq such that at runtime only prefixes coming from
kono
parents:
diff changeset
792 -- the selected consequence are evaluated. Similarly expand attribute
kono
parents:
diff changeset
793 -- 'Result references by replacing them with identifier _result which
kono
parents:
diff changeset
794 -- resolves to the sole formal parameter of procedure _Postconditions.
kono
parents:
diff changeset
795 -- Any temporaries generated in the process are added to declarations
kono
parents:
diff changeset
796 -- Decls. Evals is a complex if statement tasked with the evaluation of
kono
parents:
diff changeset
797 -- all prefixes coming from a single selected consequence. Flag is the
kono
parents:
diff changeset
798 -- corresponding case guard flag. Conseq is the consequence expression.
kono
parents:
diff changeset
799
kono
parents:
diff changeset
800 function Increment (Id : Entity_Id) return Node_Id;
kono
parents:
diff changeset
801 -- Given the entity Id of a numerical variable, generate:
kono
parents:
diff changeset
802 -- Id := Id + 1;
kono
parents:
diff changeset
803
kono
parents:
diff changeset
804 function Set (Id : Entity_Id) return Node_Id;
kono
parents:
diff changeset
805 -- Given the entity Id of a boolean variable, generate:
kono
parents:
diff changeset
806 -- Id := True;
kono
parents:
diff changeset
807
kono
parents:
diff changeset
808 ----------------------
kono
parents:
diff changeset
809 -- Case_Guard_Error --
kono
parents:
diff changeset
810 ----------------------
kono
parents:
diff changeset
811
kono
parents:
diff changeset
812 procedure Case_Guard_Error
kono
parents:
diff changeset
813 (Decls : List_Id;
kono
parents:
diff changeset
814 Flag : Entity_Id;
kono
parents:
diff changeset
815 Error_Loc : Source_Ptr;
kono
parents:
diff changeset
816 Msg : in out Entity_Id)
kono
parents:
diff changeset
817 is
kono
parents:
diff changeset
818 New_Line : constant Character := Character'Val (10);
kono
parents:
diff changeset
819 New_Msg : constant Entity_Id := Make_Temporary (Loc, 'S');
kono
parents:
diff changeset
820
kono
parents:
diff changeset
821 begin
kono
parents:
diff changeset
822 Start_String;
kono
parents:
diff changeset
823 Store_String_Char (New_Line);
kono
parents:
diff changeset
824 Store_String_Chars (" case guard at ");
kono
parents:
diff changeset
825 Store_String_Chars (Build_Location_String (Error_Loc));
kono
parents:
diff changeset
826 Store_String_Chars (" evaluates to True");
kono
parents:
diff changeset
827
kono
parents:
diff changeset
828 -- Generate:
kono
parents:
diff changeset
829 -- New_Msg : constant String :=
kono
parents:
diff changeset
830 -- (if Flag then
kono
parents:
diff changeset
831 -- Msg & "case guard at Error_Loc evaluates to True"
kono
parents:
diff changeset
832 -- else Msg);
kono
parents:
diff changeset
833
kono
parents:
diff changeset
834 Append_To (Decls,
kono
parents:
diff changeset
835 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
836 Defining_Identifier => New_Msg,
kono
parents:
diff changeset
837 Constant_Present => True,
kono
parents:
diff changeset
838 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
kono
parents:
diff changeset
839 Expression =>
kono
parents:
diff changeset
840 Make_If_Expression (Loc,
kono
parents:
diff changeset
841 Expressions => New_List (
kono
parents:
diff changeset
842 New_Occurrence_Of (Flag, Loc),
kono
parents:
diff changeset
843
kono
parents:
diff changeset
844 Make_Op_Concat (Loc,
kono
parents:
diff changeset
845 Left_Opnd => New_Occurrence_Of (Msg, Loc),
kono
parents:
diff changeset
846 Right_Opnd => Make_String_Literal (Loc, End_String)),
kono
parents:
diff changeset
847
kono
parents:
diff changeset
848 New_Occurrence_Of (Msg, Loc)))));
kono
parents:
diff changeset
849
kono
parents:
diff changeset
850 Msg := New_Msg;
kono
parents:
diff changeset
851 end Case_Guard_Error;
kono
parents:
diff changeset
852
kono
parents:
diff changeset
853 -----------------------
kono
parents:
diff changeset
854 -- Consequence_Error --
kono
parents:
diff changeset
855 -----------------------
kono
parents:
diff changeset
856
kono
parents:
diff changeset
857 procedure Consequence_Error
kono
parents:
diff changeset
858 (Checks : in out Node_Id;
kono
parents:
diff changeset
859 Flag : Entity_Id;
kono
parents:
diff changeset
860 Conseq : Node_Id)
kono
parents:
diff changeset
861 is
kono
parents:
diff changeset
862 Cond : Node_Id;
kono
parents:
diff changeset
863 Error : Node_Id;
kono
parents:
diff changeset
864
kono
parents:
diff changeset
865 begin
kono
parents:
diff changeset
866 -- Generate:
kono
parents:
diff changeset
867 -- Flag and then not Conseq
kono
parents:
diff changeset
868
kono
parents:
diff changeset
869 Cond :=
kono
parents:
diff changeset
870 Make_And_Then (Loc,
kono
parents:
diff changeset
871 Left_Opnd => New_Occurrence_Of (Flag, Loc),
kono
parents:
diff changeset
872 Right_Opnd =>
kono
parents:
diff changeset
873 Make_Op_Not (Loc,
kono
parents:
diff changeset
874 Right_Opnd => Relocate_Node (Conseq)));
kono
parents:
diff changeset
875
kono
parents:
diff changeset
876 -- Generate:
kono
parents:
diff changeset
877 -- raise Assertion_Error
kono
parents:
diff changeset
878 -- with "failed contract case at Sloc (Conseq)";
kono
parents:
diff changeset
879
kono
parents:
diff changeset
880 Start_String;
kono
parents:
diff changeset
881 Store_String_Chars ("failed contract case at ");
kono
parents:
diff changeset
882 Store_String_Chars (Build_Location_String (Sloc (Conseq)));
kono
parents:
diff changeset
883
kono
parents:
diff changeset
884 Error :=
kono
parents:
diff changeset
885 Make_Procedure_Call_Statement (Loc,
kono
parents:
diff changeset
886 Name =>
kono
parents:
diff changeset
887 New_Occurrence_Of (RTE (RE_Raise_Assert_Failure), Loc),
kono
parents:
diff changeset
888 Parameter_Associations => New_List (
kono
parents:
diff changeset
889 Make_String_Literal (Loc, End_String)));
kono
parents:
diff changeset
890
kono
parents:
diff changeset
891 if No (Checks) then
kono
parents:
diff changeset
892 Checks :=
kono
parents:
diff changeset
893 Make_Implicit_If_Statement (CCs,
kono
parents:
diff changeset
894 Condition => Cond,
kono
parents:
diff changeset
895 Then_Statements => New_List (Error));
kono
parents:
diff changeset
896
kono
parents:
diff changeset
897 else
kono
parents:
diff changeset
898 if No (Elsif_Parts (Checks)) then
kono
parents:
diff changeset
899 Set_Elsif_Parts (Checks, New_List);
kono
parents:
diff changeset
900 end if;
kono
parents:
diff changeset
901
kono
parents:
diff changeset
902 Append_To (Elsif_Parts (Checks),
kono
parents:
diff changeset
903 Make_Elsif_Part (Loc,
kono
parents:
diff changeset
904 Condition => Cond,
kono
parents:
diff changeset
905 Then_Statements => New_List (Error)));
kono
parents:
diff changeset
906 end if;
kono
parents:
diff changeset
907 end Consequence_Error;
kono
parents:
diff changeset
908
kono
parents:
diff changeset
909 --------------------
kono
parents:
diff changeset
910 -- Declaration_Of --
kono
parents:
diff changeset
911 --------------------
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 function Declaration_Of (Id : Entity_Id) return Node_Id is
kono
parents:
diff changeset
914 begin
kono
parents:
diff changeset
915 return
kono
parents:
diff changeset
916 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
917 Defining_Identifier => Id,
kono
parents:
diff changeset
918 Object_Definition => New_Occurrence_Of (Standard_Boolean, Loc),
kono
parents:
diff changeset
919 Expression => New_Occurrence_Of (Standard_False, Loc));
kono
parents:
diff changeset
920 end Declaration_Of;
kono
parents:
diff changeset
921
kono
parents:
diff changeset
922 --------------------------------------
kono
parents:
diff changeset
923 -- Expand_Attributes_In_Consequence --
kono
parents:
diff changeset
924 --------------------------------------
kono
parents:
diff changeset
925
kono
parents:
diff changeset
926 procedure Expand_Attributes_In_Consequence
kono
parents:
diff changeset
927 (Decls : List_Id;
kono
parents:
diff changeset
928 Evals : in out Node_Id;
kono
parents:
diff changeset
929 Flag : Entity_Id;
kono
parents:
diff changeset
930 Conseq : Node_Id)
kono
parents:
diff changeset
931 is
kono
parents:
diff changeset
932 Eval_Stmts : List_Id := No_List;
kono
parents:
diff changeset
933 -- The evaluation sequence expressed as assignment statements of all
kono
parents:
diff changeset
934 -- prefixes of attribute 'Old found in the current consequence.
kono
parents:
diff changeset
935
kono
parents:
diff changeset
936 function Expand_Attributes (N : Node_Id) return Traverse_Result;
kono
parents:
diff changeset
937 -- Determine whether an arbitrary node denotes attribute 'Old or
kono
parents:
diff changeset
938 -- 'Result and if it does, perform all expansion-related actions.
kono
parents:
diff changeset
939
kono
parents:
diff changeset
940 -----------------------
kono
parents:
diff changeset
941 -- Expand_Attributes --
kono
parents:
diff changeset
942 -----------------------
kono
parents:
diff changeset
943
kono
parents:
diff changeset
944 function Expand_Attributes (N : Node_Id) return Traverse_Result is
kono
parents:
diff changeset
945 Decl : Node_Id;
kono
parents:
diff changeset
946 Pref : Node_Id;
kono
parents:
diff changeset
947 Temp : Entity_Id;
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 begin
kono
parents:
diff changeset
950 -- Attribute 'Old
kono
parents:
diff changeset
951
kono
parents:
diff changeset
952 if Nkind (N) = N_Attribute_Reference
kono
parents:
diff changeset
953 and then Attribute_Name (N) = Name_Old
kono
parents:
diff changeset
954 then
kono
parents:
diff changeset
955 Pref := Prefix (N);
kono
parents:
diff changeset
956 Temp := Make_Temporary (Loc, 'T', Pref);
kono
parents:
diff changeset
957 Set_Etype (Temp, Etype (Pref));
kono
parents:
diff changeset
958
kono
parents:
diff changeset
959 -- Generate a temporary to capture the value of the prefix:
kono
parents:
diff changeset
960 -- Temp : <Pref type>;
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 Decl :=
kono
parents:
diff changeset
963 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
964 Defining_Identifier => Temp,
kono
parents:
diff changeset
965 Object_Definition =>
kono
parents:
diff changeset
966 New_Occurrence_Of (Etype (Pref), Loc));
kono
parents:
diff changeset
967
kono
parents:
diff changeset
968 -- Place that temporary at the beginning of declarations, to
kono
parents:
diff changeset
969 -- prevent anomalies in the GNATprove flow-analysis pass in
kono
parents:
diff changeset
970 -- the precondition procedure that follows.
kono
parents:
diff changeset
971
kono
parents:
diff changeset
972 Prepend_To (Decls, Decl);
kono
parents:
diff changeset
973
kono
parents:
diff changeset
974 -- If the type is unconstrained, the prefix provides its
kono
parents:
diff changeset
975 -- value and constraint, so add it to declaration.
kono
parents:
diff changeset
976
kono
parents:
diff changeset
977 if not Is_Constrained (Etype (Pref))
kono
parents:
diff changeset
978 and then Is_Entity_Name (Pref)
kono
parents:
diff changeset
979 then
kono
parents:
diff changeset
980 Set_Expression (Decl, Pref);
kono
parents:
diff changeset
981 Analyze (Decl);
kono
parents:
diff changeset
982
kono
parents:
diff changeset
983 -- Otherwise add an assignment statement to temporary using
kono
parents:
diff changeset
984 -- prefix as RHS.
kono
parents:
diff changeset
985
kono
parents:
diff changeset
986 else
kono
parents:
diff changeset
987 Analyze (Decl);
kono
parents:
diff changeset
988
kono
parents:
diff changeset
989 if No (Eval_Stmts) then
kono
parents:
diff changeset
990 Eval_Stmts := New_List;
kono
parents:
diff changeset
991 end if;
kono
parents:
diff changeset
992
kono
parents:
diff changeset
993 Append_To (Eval_Stmts,
kono
parents:
diff changeset
994 Make_Assignment_Statement (Loc,
kono
parents:
diff changeset
995 Name => New_Occurrence_Of (Temp, Loc),
kono
parents:
diff changeset
996 Expression => Pref));
kono
parents:
diff changeset
997
kono
parents:
diff changeset
998 end if;
kono
parents:
diff changeset
999
kono
parents:
diff changeset
1000 -- Ensure that the prefix is valid
kono
parents:
diff changeset
1001
kono
parents:
diff changeset
1002 if Validity_Checks_On and then Validity_Check_Operands then
kono
parents:
diff changeset
1003 Ensure_Valid (Pref);
kono
parents:
diff changeset
1004 end if;
kono
parents:
diff changeset
1005
kono
parents:
diff changeset
1006 -- Replace the original attribute 'Old by a reference to the
kono
parents:
diff changeset
1007 -- generated temporary.
kono
parents:
diff changeset
1008
kono
parents:
diff changeset
1009 Rewrite (N, New_Occurrence_Of (Temp, Loc));
kono
parents:
diff changeset
1010
kono
parents:
diff changeset
1011 -- Attribute 'Result
kono
parents:
diff changeset
1012
kono
parents:
diff changeset
1013 elsif Is_Attribute_Result (N) then
kono
parents:
diff changeset
1014 Rewrite (N, Make_Identifier (Loc, Name_uResult));
kono
parents:
diff changeset
1015 end if;
kono
parents:
diff changeset
1016
kono
parents:
diff changeset
1017 return OK;
kono
parents:
diff changeset
1018 end Expand_Attributes;
kono
parents:
diff changeset
1019
kono
parents:
diff changeset
1020 procedure Expand_Attributes_In is
kono
parents:
diff changeset
1021 new Traverse_Proc (Expand_Attributes);
kono
parents:
diff changeset
1022
kono
parents:
diff changeset
1023 -- Start of processing for Expand_Attributes_In_Consequence
kono
parents:
diff changeset
1024
kono
parents:
diff changeset
1025 begin
kono
parents:
diff changeset
1026 -- Inspect the consequence and expand any attribute 'Old and 'Result
kono
parents:
diff changeset
1027 -- references found within.
kono
parents:
diff changeset
1028
kono
parents:
diff changeset
1029 Expand_Attributes_In (Conseq);
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 -- The consequence does not contain any attribute 'Old references
kono
parents:
diff changeset
1032
kono
parents:
diff changeset
1033 if No (Eval_Stmts) then
kono
parents:
diff changeset
1034 return;
kono
parents:
diff changeset
1035 end if;
kono
parents:
diff changeset
1036
kono
parents:
diff changeset
1037 -- Augment the machinery to trigger the evaluation of all prefixes
kono
parents:
diff changeset
1038 -- found in the step above. If Eval is empty, then this is the first
kono
parents:
diff changeset
1039 -- consequence to yield expansion of 'Old. Generate:
kono
parents:
diff changeset
1040
kono
parents:
diff changeset
1041 -- if Flag then
kono
parents:
diff changeset
1042 -- <evaluation statements>
kono
parents:
diff changeset
1043 -- end if;
kono
parents:
diff changeset
1044
kono
parents:
diff changeset
1045 if No (Evals) then
kono
parents:
diff changeset
1046 Evals :=
kono
parents:
diff changeset
1047 Make_Implicit_If_Statement (CCs,
kono
parents:
diff changeset
1048 Condition => New_Occurrence_Of (Flag, Loc),
kono
parents:
diff changeset
1049 Then_Statements => Eval_Stmts);
kono
parents:
diff changeset
1050
kono
parents:
diff changeset
1051 -- Otherwise generate:
kono
parents:
diff changeset
1052 -- elsif Flag then
kono
parents:
diff changeset
1053 -- <evaluation statements>
kono
parents:
diff changeset
1054 -- end if;
kono
parents:
diff changeset
1055
kono
parents:
diff changeset
1056 else
kono
parents:
diff changeset
1057 if No (Elsif_Parts (Evals)) then
kono
parents:
diff changeset
1058 Set_Elsif_Parts (Evals, New_List);
kono
parents:
diff changeset
1059 end if;
kono
parents:
diff changeset
1060
kono
parents:
diff changeset
1061 Append_To (Elsif_Parts (Evals),
kono
parents:
diff changeset
1062 Make_Elsif_Part (Loc,
kono
parents:
diff changeset
1063 Condition => New_Occurrence_Of (Flag, Loc),
kono
parents:
diff changeset
1064 Then_Statements => Eval_Stmts));
kono
parents:
diff changeset
1065 end if;
kono
parents:
diff changeset
1066 end Expand_Attributes_In_Consequence;
kono
parents:
diff changeset
1067
kono
parents:
diff changeset
1068 ---------------
kono
parents:
diff changeset
1069 -- Increment --
kono
parents:
diff changeset
1070 ---------------
kono
parents:
diff changeset
1071
kono
parents:
diff changeset
1072 function Increment (Id : Entity_Id) return Node_Id is
kono
parents:
diff changeset
1073 begin
kono
parents:
diff changeset
1074 return
kono
parents:
diff changeset
1075 Make_Assignment_Statement (Loc,
kono
parents:
diff changeset
1076 Name => New_Occurrence_Of (Id, Loc),
kono
parents:
diff changeset
1077 Expression =>
kono
parents:
diff changeset
1078 Make_Op_Add (Loc,
kono
parents:
diff changeset
1079 Left_Opnd => New_Occurrence_Of (Id, Loc),
kono
parents:
diff changeset
1080 Right_Opnd => Make_Integer_Literal (Loc, 1)));
kono
parents:
diff changeset
1081 end Increment;
kono
parents:
diff changeset
1082
kono
parents:
diff changeset
1083 ---------
kono
parents:
diff changeset
1084 -- Set --
kono
parents:
diff changeset
1085 ---------
kono
parents:
diff changeset
1086
kono
parents:
diff changeset
1087 function Set (Id : Entity_Id) return Node_Id is
kono
parents:
diff changeset
1088 begin
kono
parents:
diff changeset
1089 return
kono
parents:
diff changeset
1090 Make_Assignment_Statement (Loc,
kono
parents:
diff changeset
1091 Name => New_Occurrence_Of (Id, Loc),
kono
parents:
diff changeset
1092 Expression => New_Occurrence_Of (Standard_True, Loc));
kono
parents:
diff changeset
1093 end Set;
kono
parents:
diff changeset
1094
kono
parents:
diff changeset
1095 -- Local variables
kono
parents:
diff changeset
1096
kono
parents:
diff changeset
1097 Aggr : constant Node_Id :=
kono
parents:
diff changeset
1098 Expression (First (Pragma_Argument_Associations (CCs)));
kono
parents:
diff changeset
1099
kono
parents:
diff changeset
1100 Case_Guard : Node_Id;
kono
parents:
diff changeset
1101 CG_Checks : Node_Id;
kono
parents:
diff changeset
1102 CG_Stmts : List_Id;
kono
parents:
diff changeset
1103 Conseq : Node_Id;
kono
parents:
diff changeset
1104 Conseq_Checks : Node_Id := Empty;
kono
parents:
diff changeset
1105 Count : Entity_Id;
kono
parents:
diff changeset
1106 Count_Decl : Node_Id;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1107 Error_Decls : List_Id := No_List; -- init to avoid warning
111
kono
parents:
diff changeset
1108 Flag : Entity_Id;
kono
parents:
diff changeset
1109 Flag_Decl : Node_Id;
kono
parents:
diff changeset
1110 If_Stmt : Node_Id;
kono
parents:
diff changeset
1111 Msg_Str : Entity_Id := Empty;
kono
parents:
diff changeset
1112 Multiple_PCs : Boolean;
kono
parents:
diff changeset
1113 Old_Evals : Node_Id := Empty;
kono
parents:
diff changeset
1114 Others_Decl : Node_Id;
kono
parents:
diff changeset
1115 Others_Flag : Entity_Id := Empty;
kono
parents:
diff changeset
1116 Post_Case : Node_Id;
kono
parents:
diff changeset
1117
kono
parents:
diff changeset
1118 -- Start of processing for Expand_Pragma_Contract_Cases
kono
parents:
diff changeset
1119
kono
parents:
diff changeset
1120 begin
kono
parents:
diff changeset
1121 -- Do nothing if pragma is not enabled. If pragma is disabled, it has
kono
parents:
diff changeset
1122 -- already been rewritten as a Null statement.
kono
parents:
diff changeset
1123
kono
parents:
diff changeset
1124 if Is_Ignored (CCs) then
kono
parents:
diff changeset
1125 return;
kono
parents:
diff changeset
1126
kono
parents:
diff changeset
1127 -- Guard against malformed contract cases
kono
parents:
diff changeset
1128
kono
parents:
diff changeset
1129 elsif Nkind (Aggr) /= N_Aggregate then
kono
parents:
diff changeset
1130 return;
kono
parents:
diff changeset
1131 end if;
kono
parents:
diff changeset
1132
kono
parents:
diff changeset
1133 -- The expansion of contract cases is quite distributed as it produces
kono
parents:
diff changeset
1134 -- various statements to evaluate the case guards and consequences. To
kono
parents:
diff changeset
1135 -- preserve the original context, set the Is_Assertion_Expr flag. This
kono
parents:
diff changeset
1136 -- aids the Ghost legality checks when verifying the placement of a
kono
parents:
diff changeset
1137 -- reference to a Ghost entity.
kono
parents:
diff changeset
1138
kono
parents:
diff changeset
1139 In_Assertion_Expr := In_Assertion_Expr + 1;
kono
parents:
diff changeset
1140
kono
parents:
diff changeset
1141 Multiple_PCs := List_Length (Component_Associations (Aggr)) > 1;
kono
parents:
diff changeset
1142
kono
parents:
diff changeset
1143 -- Create the counter which tracks the number of case guards that
kono
parents:
diff changeset
1144 -- evaluate to True.
kono
parents:
diff changeset
1145
kono
parents:
diff changeset
1146 -- Count : Natural := 0;
kono
parents:
diff changeset
1147
kono
parents:
diff changeset
1148 Count := Make_Temporary (Loc, 'C');
kono
parents:
diff changeset
1149 Count_Decl :=
kono
parents:
diff changeset
1150 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
1151 Defining_Identifier => Count,
kono
parents:
diff changeset
1152 Object_Definition => New_Occurrence_Of (Standard_Natural, Loc),
kono
parents:
diff changeset
1153 Expression => Make_Integer_Literal (Loc, 0));
kono
parents:
diff changeset
1154
kono
parents:
diff changeset
1155 Prepend_To (Decls, Count_Decl);
kono
parents:
diff changeset
1156 Analyze (Count_Decl);
kono
parents:
diff changeset
1157
kono
parents:
diff changeset
1158 -- Create the base error message for multiple overlapping case guards
kono
parents:
diff changeset
1159
kono
parents:
diff changeset
1160 -- Msg_Str : constant String :=
kono
parents:
diff changeset
1161 -- "contract cases overlap for subprogram Subp_Id";
kono
parents:
diff changeset
1162
kono
parents:
diff changeset
1163 if Multiple_PCs then
kono
parents:
diff changeset
1164 Msg_Str := Make_Temporary (Loc, 'S');
kono
parents:
diff changeset
1165
kono
parents:
diff changeset
1166 Start_String;
kono
parents:
diff changeset
1167 Store_String_Chars ("contract cases overlap for subprogram ");
kono
parents:
diff changeset
1168 Store_String_Chars (Get_Name_String (Chars (Subp_Id)));
kono
parents:
diff changeset
1169
kono
parents:
diff changeset
1170 Error_Decls := New_List (
kono
parents:
diff changeset
1171 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
1172 Defining_Identifier => Msg_Str,
kono
parents:
diff changeset
1173 Constant_Present => True,
kono
parents:
diff changeset
1174 Object_Definition => New_Occurrence_Of (Standard_String, Loc),
kono
parents:
diff changeset
1175 Expression => Make_String_Literal (Loc, End_String)));
kono
parents:
diff changeset
1176 end if;
kono
parents:
diff changeset
1177
kono
parents:
diff changeset
1178 -- Process individual post cases
kono
parents:
diff changeset
1179
kono
parents:
diff changeset
1180 Post_Case := First (Component_Associations (Aggr));
kono
parents:
diff changeset
1181 while Present (Post_Case) loop
kono
parents:
diff changeset
1182 Case_Guard := First (Choices (Post_Case));
kono
parents:
diff changeset
1183 Conseq := Expression (Post_Case);
kono
parents:
diff changeset
1184
kono
parents:
diff changeset
1185 -- The "others" choice requires special processing
kono
parents:
diff changeset
1186
kono
parents:
diff changeset
1187 if Nkind (Case_Guard) = N_Others_Choice then
kono
parents:
diff changeset
1188 Others_Flag := Make_Temporary (Loc, 'F');
kono
parents:
diff changeset
1189 Others_Decl := Declaration_Of (Others_Flag);
kono
parents:
diff changeset
1190
kono
parents:
diff changeset
1191 Prepend_To (Decls, Others_Decl);
kono
parents:
diff changeset
1192 Analyze (Others_Decl);
kono
parents:
diff changeset
1193
kono
parents:
diff changeset
1194 -- Check possible overlap between a case guard and "others"
kono
parents:
diff changeset
1195
kono
parents:
diff changeset
1196 if Multiple_PCs and Exception_Extra_Info then
kono
parents:
diff changeset
1197 Case_Guard_Error
kono
parents:
diff changeset
1198 (Decls => Error_Decls,
kono
parents:
diff changeset
1199 Flag => Others_Flag,
kono
parents:
diff changeset
1200 Error_Loc => Sloc (Case_Guard),
kono
parents:
diff changeset
1201 Msg => Msg_Str);
kono
parents:
diff changeset
1202 end if;
kono
parents:
diff changeset
1203
kono
parents:
diff changeset
1204 -- Inspect the consequence and perform special expansion of any
kono
parents:
diff changeset
1205 -- attribute 'Old and 'Result references found within.
kono
parents:
diff changeset
1206
kono
parents:
diff changeset
1207 Expand_Attributes_In_Consequence
kono
parents:
diff changeset
1208 (Decls => Decls,
kono
parents:
diff changeset
1209 Evals => Old_Evals,
kono
parents:
diff changeset
1210 Flag => Others_Flag,
kono
parents:
diff changeset
1211 Conseq => Conseq);
kono
parents:
diff changeset
1212
kono
parents:
diff changeset
1213 -- Check the corresponding consequence of "others"
kono
parents:
diff changeset
1214
kono
parents:
diff changeset
1215 Consequence_Error
kono
parents:
diff changeset
1216 (Checks => Conseq_Checks,
kono
parents:
diff changeset
1217 Flag => Others_Flag,
kono
parents:
diff changeset
1218 Conseq => Conseq);
kono
parents:
diff changeset
1219
kono
parents:
diff changeset
1220 -- Regular post case
kono
parents:
diff changeset
1221
kono
parents:
diff changeset
1222 else
kono
parents:
diff changeset
1223 -- Create the flag which tracks the state of its associated case
kono
parents:
diff changeset
1224 -- guard.
kono
parents:
diff changeset
1225
kono
parents:
diff changeset
1226 Flag := Make_Temporary (Loc, 'F');
kono
parents:
diff changeset
1227 Flag_Decl := Declaration_Of (Flag);
kono
parents:
diff changeset
1228
kono
parents:
diff changeset
1229 Prepend_To (Decls, Flag_Decl);
kono
parents:
diff changeset
1230 Analyze (Flag_Decl);
kono
parents:
diff changeset
1231
kono
parents:
diff changeset
1232 -- The flag is set when the case guard is evaluated to True
kono
parents:
diff changeset
1233 -- if Case_Guard then
kono
parents:
diff changeset
1234 -- Flag := True;
kono
parents:
diff changeset
1235 -- Count := Count + 1;
kono
parents:
diff changeset
1236 -- end if;
kono
parents:
diff changeset
1237
kono
parents:
diff changeset
1238 If_Stmt :=
kono
parents:
diff changeset
1239 Make_Implicit_If_Statement (CCs,
kono
parents:
diff changeset
1240 Condition => Relocate_Node (Case_Guard),
kono
parents:
diff changeset
1241 Then_Statements => New_List (
kono
parents:
diff changeset
1242 Set (Flag),
kono
parents:
diff changeset
1243 Increment (Count)));
kono
parents:
diff changeset
1244
kono
parents:
diff changeset
1245 Append_To (Decls, If_Stmt);
kono
parents:
diff changeset
1246 Analyze (If_Stmt);
kono
parents:
diff changeset
1247
kono
parents:
diff changeset
1248 -- Check whether this case guard overlaps with another one
kono
parents:
diff changeset
1249
kono
parents:
diff changeset
1250 if Multiple_PCs and Exception_Extra_Info then
kono
parents:
diff changeset
1251 Case_Guard_Error
kono
parents:
diff changeset
1252 (Decls => Error_Decls,
kono
parents:
diff changeset
1253 Flag => Flag,
kono
parents:
diff changeset
1254 Error_Loc => Sloc (Case_Guard),
kono
parents:
diff changeset
1255 Msg => Msg_Str);
kono
parents:
diff changeset
1256 end if;
kono
parents:
diff changeset
1257
kono
parents:
diff changeset
1258 -- Inspect the consequence and perform special expansion of any
kono
parents:
diff changeset
1259 -- attribute 'Old and 'Result references found within.
kono
parents:
diff changeset
1260
kono
parents:
diff changeset
1261 Expand_Attributes_In_Consequence
kono
parents:
diff changeset
1262 (Decls => Decls,
kono
parents:
diff changeset
1263 Evals => Old_Evals,
kono
parents:
diff changeset
1264 Flag => Flag,
kono
parents:
diff changeset
1265 Conseq => Conseq);
kono
parents:
diff changeset
1266
kono
parents:
diff changeset
1267 -- The corresponding consequence of the case guard which evaluated
kono
parents:
diff changeset
1268 -- to True must hold on exit from the subprogram.
kono
parents:
diff changeset
1269
kono
parents:
diff changeset
1270 Consequence_Error
kono
parents:
diff changeset
1271 (Checks => Conseq_Checks,
kono
parents:
diff changeset
1272 Flag => Flag,
kono
parents:
diff changeset
1273 Conseq => Conseq);
kono
parents:
diff changeset
1274 end if;
kono
parents:
diff changeset
1275
kono
parents:
diff changeset
1276 Next (Post_Case);
kono
parents:
diff changeset
1277 end loop;
kono
parents:
diff changeset
1278
kono
parents:
diff changeset
1279 -- Raise Assertion_Error when none of the case guards evaluate to True.
kono
parents:
diff changeset
1280 -- The only exception is when we have "others", in which case there is
kono
parents:
diff changeset
1281 -- no error because "others" acts as a default True.
kono
parents:
diff changeset
1282
kono
parents:
diff changeset
1283 -- Generate:
kono
parents:
diff changeset
1284 -- Flag := True;
kono
parents:
diff changeset
1285
kono
parents:
diff changeset
1286 if Present (Others_Flag) then
kono
parents:
diff changeset
1287 CG_Stmts := New_List (Set (Others_Flag));
kono
parents:
diff changeset
1288
kono
parents:
diff changeset
1289 -- Generate:
kono
parents:
diff changeset
1290 -- raise Assertion_Error with "xxx contract cases incomplete";
kono
parents:
diff changeset
1291
kono
parents:
diff changeset
1292 else
kono
parents:
diff changeset
1293 Start_String;
kono
parents:
diff changeset
1294 Store_String_Chars (Build_Location_String (Loc));
kono
parents:
diff changeset
1295 Store_String_Chars (" contract cases incomplete");
kono
parents:
diff changeset
1296
kono
parents:
diff changeset
1297 CG_Stmts := New_List (
kono
parents:
diff changeset
1298 Make_Procedure_Call_Statement (Loc,
kono
parents:
diff changeset
1299 Name =>
kono
parents:
diff changeset
1300 New_Occurrence_Of (RTE (RE_Raise_Assert_Failure), Loc),
kono
parents:
diff changeset
1301 Parameter_Associations => New_List (
kono
parents:
diff changeset
1302 Make_String_Literal (Loc, End_String))));
kono
parents:
diff changeset
1303 end if;
kono
parents:
diff changeset
1304
kono
parents:
diff changeset
1305 CG_Checks :=
kono
parents:
diff changeset
1306 Make_Implicit_If_Statement (CCs,
kono
parents:
diff changeset
1307 Condition =>
kono
parents:
diff changeset
1308 Make_Op_Eq (Loc,
kono
parents:
diff changeset
1309 Left_Opnd => New_Occurrence_Of (Count, Loc),
kono
parents:
diff changeset
1310 Right_Opnd => Make_Integer_Literal (Loc, 0)),
kono
parents:
diff changeset
1311 Then_Statements => CG_Stmts);
kono
parents:
diff changeset
1312
kono
parents:
diff changeset
1313 -- Detect a possible failure due to several case guards evaluating to
kono
parents:
diff changeset
1314 -- True.
kono
parents:
diff changeset
1315
kono
parents:
diff changeset
1316 -- Generate:
kono
parents:
diff changeset
1317 -- elsif Count > 0 then
kono
parents:
diff changeset
1318 -- declare
kono
parents:
diff changeset
1319 -- <Error_Decls>
kono
parents:
diff changeset
1320 -- begin
kono
parents:
diff changeset
1321 -- raise Assertion_Error with <Msg_Str>;
kono
parents:
diff changeset
1322 -- end if;
kono
parents:
diff changeset
1323
kono
parents:
diff changeset
1324 if Multiple_PCs then
kono
parents:
diff changeset
1325 Set_Elsif_Parts (CG_Checks, New_List (
kono
parents:
diff changeset
1326 Make_Elsif_Part (Loc,
kono
parents:
diff changeset
1327 Condition =>
kono
parents:
diff changeset
1328 Make_Op_Gt (Loc,
kono
parents:
diff changeset
1329 Left_Opnd => New_Occurrence_Of (Count, Loc),
kono
parents:
diff changeset
1330 Right_Opnd => Make_Integer_Literal (Loc, 1)),
kono
parents:
diff changeset
1331
kono
parents:
diff changeset
1332 Then_Statements => New_List (
kono
parents:
diff changeset
1333 Make_Block_Statement (Loc,
kono
parents:
diff changeset
1334 Declarations => Error_Decls,
kono
parents:
diff changeset
1335 Handled_Statement_Sequence =>
kono
parents:
diff changeset
1336 Make_Handled_Sequence_Of_Statements (Loc,
kono
parents:
diff changeset
1337 Statements => New_List (
kono
parents:
diff changeset
1338 Make_Procedure_Call_Statement (Loc,
kono
parents:
diff changeset
1339 Name =>
kono
parents:
diff changeset
1340 New_Occurrence_Of
kono
parents:
diff changeset
1341 (RTE (RE_Raise_Assert_Failure), Loc),
kono
parents:
diff changeset
1342 Parameter_Associations => New_List (
kono
parents:
diff changeset
1343 New_Occurrence_Of (Msg_Str, Loc))))))))));
kono
parents:
diff changeset
1344 end if;
kono
parents:
diff changeset
1345
kono
parents:
diff changeset
1346 Append_To (Decls, CG_Checks);
kono
parents:
diff changeset
1347 Analyze (CG_Checks);
kono
parents:
diff changeset
1348
kono
parents:
diff changeset
1349 -- Once all case guards are evaluated and checked, evaluate any prefixes
kono
parents:
diff changeset
1350 -- of attribute 'Old founds in the selected consequence.
kono
parents:
diff changeset
1351
kono
parents:
diff changeset
1352 if Present (Old_Evals) then
kono
parents:
diff changeset
1353 Append_To (Decls, Old_Evals);
kono
parents:
diff changeset
1354 Analyze (Old_Evals);
kono
parents:
diff changeset
1355 end if;
kono
parents:
diff changeset
1356
kono
parents:
diff changeset
1357 -- Raise Assertion_Error when the corresponding consequence of a case
kono
parents:
diff changeset
1358 -- guard that evaluated to True fails.
kono
parents:
diff changeset
1359
kono
parents:
diff changeset
1360 if No (Stmts) then
kono
parents:
diff changeset
1361 Stmts := New_List;
kono
parents:
diff changeset
1362 end if;
kono
parents:
diff changeset
1363
kono
parents:
diff changeset
1364 Append_To (Stmts, Conseq_Checks);
kono
parents:
diff changeset
1365
kono
parents:
diff changeset
1366 In_Assertion_Expr := In_Assertion_Expr - 1;
kono
parents:
diff changeset
1367 end Expand_Pragma_Contract_Cases;
kono
parents:
diff changeset
1368
kono
parents:
diff changeset
1369 ---------------------------------------
kono
parents:
diff changeset
1370 -- Expand_Pragma_Import_Or_Interface --
kono
parents:
diff changeset
1371 ---------------------------------------
kono
parents:
diff changeset
1372
kono
parents:
diff changeset
1373 procedure Expand_Pragma_Import_Or_Interface (N : Node_Id) is
kono
parents:
diff changeset
1374 Def_Id : Entity_Id;
kono
parents:
diff changeset
1375
kono
parents:
diff changeset
1376 begin
kono
parents:
diff changeset
1377 -- In Relaxed_RM_Semantics, support old Ada 83 style:
kono
parents:
diff changeset
1378 -- pragma Import (Entity, "external name");
kono
parents:
diff changeset
1379
kono
parents:
diff changeset
1380 if Relaxed_RM_Semantics
kono
parents:
diff changeset
1381 and then List_Length (Pragma_Argument_Associations (N)) = 2
kono
parents:
diff changeset
1382 and then Pragma_Name (N) = Name_Import
kono
parents:
diff changeset
1383 and then Nkind (Arg2 (N)) = N_String_Literal
kono
parents:
diff changeset
1384 then
kono
parents:
diff changeset
1385 Def_Id := Entity (Arg1 (N));
kono
parents:
diff changeset
1386 else
kono
parents:
diff changeset
1387 Def_Id := Entity (Arg2 (N));
kono
parents:
diff changeset
1388 end if;
kono
parents:
diff changeset
1389
kono
parents:
diff changeset
1390 -- Variable case (we have to undo any initialization already done)
kono
parents:
diff changeset
1391
kono
parents:
diff changeset
1392 if Ekind (Def_Id) = E_Variable then
kono
parents:
diff changeset
1393 Undo_Initialization (Def_Id, N);
kono
parents:
diff changeset
1394
kono
parents:
diff changeset
1395 -- Case of exception with convention C++
kono
parents:
diff changeset
1396
kono
parents:
diff changeset
1397 elsif Ekind (Def_Id) = E_Exception
kono
parents:
diff changeset
1398 and then Convention (Def_Id) = Convention_CPP
kono
parents:
diff changeset
1399 then
kono
parents:
diff changeset
1400 -- Import a C++ convention
kono
parents:
diff changeset
1401
kono
parents:
diff changeset
1402 declare
kono
parents:
diff changeset
1403 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
1404 Rtti_Name : constant Node_Id := Arg3 (N);
kono
parents:
diff changeset
1405 Dum : constant Entity_Id := Make_Temporary (Loc, 'D');
kono
parents:
diff changeset
1406 Exdata : List_Id;
kono
parents:
diff changeset
1407 Lang_Char : Node_Id;
kono
parents:
diff changeset
1408 Foreign_Data : Node_Id;
kono
parents:
diff changeset
1409
kono
parents:
diff changeset
1410 begin
kono
parents:
diff changeset
1411 Exdata := Component_Associations (Expression (Parent (Def_Id)));
kono
parents:
diff changeset
1412
kono
parents:
diff changeset
1413 Lang_Char := Next (First (Exdata));
kono
parents:
diff changeset
1414
kono
parents:
diff changeset
1415 -- Change the one-character language designator to 'C'
kono
parents:
diff changeset
1416
kono
parents:
diff changeset
1417 Rewrite (Expression (Lang_Char),
kono
parents:
diff changeset
1418 Make_Character_Literal (Loc,
kono
parents:
diff changeset
1419 Chars => Name_uC,
kono
parents:
diff changeset
1420 Char_Literal_Value => UI_From_Int (Character'Pos ('C'))));
kono
parents:
diff changeset
1421 Analyze (Expression (Lang_Char));
kono
parents:
diff changeset
1422
kono
parents:
diff changeset
1423 -- Change the value of Foreign_Data
kono
parents:
diff changeset
1424
kono
parents:
diff changeset
1425 Foreign_Data := Next (Next (Next (Next (Lang_Char))));
kono
parents:
diff changeset
1426
kono
parents:
diff changeset
1427 Insert_Actions (Def_Id, New_List (
kono
parents:
diff changeset
1428 Make_Object_Declaration (Loc,
kono
parents:
diff changeset
1429 Defining_Identifier => Dum,
kono
parents:
diff changeset
1430 Object_Definition =>
kono
parents:
diff changeset
1431 New_Occurrence_Of (Standard_Character, Loc)),
kono
parents:
diff changeset
1432
kono
parents:
diff changeset
1433 Make_Pragma (Loc,
kono
parents:
diff changeset
1434 Chars => Name_Import,
kono
parents:
diff changeset
1435 Pragma_Argument_Associations => New_List (
kono
parents:
diff changeset
1436 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
1437 Expression => Make_Identifier (Loc, Name_Ada)),
kono
parents:
diff changeset
1438
kono
parents:
diff changeset
1439 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
1440 Expression => Make_Identifier (Loc, Chars (Dum))),
kono
parents:
diff changeset
1441
kono
parents:
diff changeset
1442 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
1443 Chars => Name_External_Name,
kono
parents:
diff changeset
1444 Expression => Relocate_Node (Rtti_Name))))));
kono
parents:
diff changeset
1445
kono
parents:
diff changeset
1446 Rewrite (Expression (Foreign_Data),
kono
parents:
diff changeset
1447 Unchecked_Convert_To (Standard_A_Char,
kono
parents:
diff changeset
1448 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1449 Prefix => Make_Identifier (Loc, Chars (Dum)),
kono
parents:
diff changeset
1450 Attribute_Name => Name_Address)));
kono
parents:
diff changeset
1451 Analyze (Expression (Foreign_Data));
kono
parents:
diff changeset
1452 end;
kono
parents:
diff changeset
1453
kono
parents:
diff changeset
1454 -- No special expansion required for any other case
kono
parents:
diff changeset
1455
kono
parents:
diff changeset
1456 else
kono
parents:
diff changeset
1457 null;
kono
parents:
diff changeset
1458 end if;
kono
parents:
diff changeset
1459 end Expand_Pragma_Import_Or_Interface;
kono
parents:
diff changeset
1460
kono
parents:
diff changeset
1461 -------------------------------------
kono
parents:
diff changeset
1462 -- Expand_Pragma_Initial_Condition --
kono
parents:
diff changeset
1463 -------------------------------------
kono
parents:
diff changeset
1464
kono
parents:
diff changeset
1465 procedure Expand_Pragma_Initial_Condition
kono
parents:
diff changeset
1466 (Pack_Id : Entity_Id;
kono
parents:
diff changeset
1467 N : Node_Id)
kono
parents:
diff changeset
1468 is
kono
parents:
diff changeset
1469 procedure Extract_Package_Body_Lists
kono
parents:
diff changeset
1470 (Pack_Body : Node_Id;
kono
parents:
diff changeset
1471 Body_List : out List_Id;
kono
parents:
diff changeset
1472 Call_List : out List_Id;
kono
parents:
diff changeset
1473 Spec_List : out List_Id);
kono
parents:
diff changeset
1474 -- Obtain the various declarative and statement lists of package body
kono
parents:
diff changeset
1475 -- Pack_Body needed to insert the initial condition procedure and the
kono
parents:
diff changeset
1476 -- call to it. The lists are as follows:
kono
parents:
diff changeset
1477 --
kono
parents:
diff changeset
1478 -- * Body_List - used to insert the initial condition procedure body
kono
parents:
diff changeset
1479 --
kono
parents:
diff changeset
1480 -- * Call_List - used to insert the call to the initial condition
kono
parents:
diff changeset
1481 -- procedure.
kono
parents:
diff changeset
1482 --
kono
parents:
diff changeset
1483 -- * Spec_List - used to insert the initial condition procedure spec
kono
parents:
diff changeset
1484
kono
parents:
diff changeset
1485 procedure Extract_Package_Declaration_Lists
kono
parents:
diff changeset
1486 (Pack_Decl : Node_Id;
kono
parents:
diff changeset
1487 Body_List : out List_Id;
kono
parents:
diff changeset
1488 Call_List : out List_Id;
kono
parents:
diff changeset
1489 Spec_List : out List_Id);
kono
parents:
diff changeset
1490 -- Obtain the various declarative lists of package declaration Pack_Decl
kono
parents:
diff changeset
1491 -- needed to insert the initial condition procedure and the call to it.
kono
parents:
diff changeset
1492 -- The lists are as follows:
kono
parents:
diff changeset
1493 --
kono
parents:
diff changeset
1494 -- * Body_List - used to insert the initial condition procedure body
kono
parents:
diff changeset
1495 --
kono
parents:
diff changeset
1496 -- * Call_List - used to insert the call to the initial condition
kono
parents:
diff changeset
1497 -- procedure.
kono
parents:
diff changeset
1498 --
kono
parents:
diff changeset
1499 -- * Spec_List - used to insert the initial condition procedure spec
kono
parents:
diff changeset
1500
kono
parents:
diff changeset
1501 --------------------------------
kono
parents:
diff changeset
1502 -- Extract_Package_Body_Lists --
kono
parents:
diff changeset
1503 --------------------------------
kono
parents:
diff changeset
1504
kono
parents:
diff changeset
1505 procedure Extract_Package_Body_Lists
kono
parents:
diff changeset
1506 (Pack_Body : Node_Id;
kono
parents:
diff changeset
1507 Body_List : out List_Id;
kono
parents:
diff changeset
1508 Call_List : out List_Id;
kono
parents:
diff changeset
1509 Spec_List : out List_Id)
kono
parents:
diff changeset
1510 is
kono
parents:
diff changeset
1511 Pack_Spec : constant Entity_Id := Corresponding_Spec (Pack_Body);
kono
parents:
diff changeset
1512
kono
parents:
diff changeset
1513 Dummy_1 : List_Id;
kono
parents:
diff changeset
1514 Dummy_2 : List_Id;
kono
parents:
diff changeset
1515 HSS : Node_Id;
kono
parents:
diff changeset
1516
kono
parents:
diff changeset
1517 begin
kono
parents:
diff changeset
1518 pragma Assert (Present (Pack_Spec));
kono
parents:
diff changeset
1519
kono
parents:
diff changeset
1520 -- The different parts of the invariant procedure are inserted as
kono
parents:
diff changeset
1521 -- follows:
kono
parents:
diff changeset
1522
kono
parents:
diff changeset
1523 -- package Pack is package body Pack is
kono
parents:
diff changeset
1524 -- <IC spec> <IC body>
kono
parents:
diff changeset
1525 -- private begin
kono
parents:
diff changeset
1526 -- ... <IC call>
kono
parents:
diff changeset
1527 -- end Pack; end Pack;
kono
parents:
diff changeset
1528
kono
parents:
diff changeset
1529 -- The initial condition procedure spec is inserted in the visible
kono
parents:
diff changeset
1530 -- declaration of the corresponding package spec.
kono
parents:
diff changeset
1531
kono
parents:
diff changeset
1532 Extract_Package_Declaration_Lists
kono
parents:
diff changeset
1533 (Pack_Decl => Unit_Declaration_Node (Pack_Spec),
kono
parents:
diff changeset
1534 Body_List => Dummy_1,
kono
parents:
diff changeset
1535 Call_List => Dummy_2,
kono
parents:
diff changeset
1536 Spec_List => Spec_List);
kono
parents:
diff changeset
1537
kono
parents:
diff changeset
1538 -- The initial condition procedure body is added to the declarations
kono
parents:
diff changeset
1539 -- of the package body.
kono
parents:
diff changeset
1540
kono
parents:
diff changeset
1541 Body_List := Declarations (Pack_Body);
kono
parents:
diff changeset
1542
kono
parents:
diff changeset
1543 if No (Body_List) then
kono
parents:
diff changeset
1544 Body_List := New_List;
kono
parents:
diff changeset
1545 Set_Declarations (Pack_Body, Body_List);
kono
parents:
diff changeset
1546 end if;
kono
parents:
diff changeset
1547
kono
parents:
diff changeset
1548 -- The call to the initial condition procedure is inserted in the
kono
parents:
diff changeset
1549 -- statements of the package body.
kono
parents:
diff changeset
1550
kono
parents:
diff changeset
1551 HSS := Handled_Statement_Sequence (Pack_Body);
kono
parents:
diff changeset
1552
kono
parents:
diff changeset
1553 if No (HSS) then
kono
parents:
diff changeset
1554 HSS :=
kono
parents:
diff changeset
1555 Make_Handled_Sequence_Of_Statements (Sloc (Pack_Body),
kono
parents:
diff changeset
1556 Statements => New_List);
kono
parents:
diff changeset
1557 Set_Handled_Statement_Sequence (Pack_Body, HSS);
kono
parents:
diff changeset
1558 end if;
kono
parents:
diff changeset
1559
kono
parents:
diff changeset
1560 Call_List := Statements (HSS);
kono
parents:
diff changeset
1561 end Extract_Package_Body_Lists;
kono
parents:
diff changeset
1562
kono
parents:
diff changeset
1563 ---------------------------------------
kono
parents:
diff changeset
1564 -- Extract_Package_Declaration_Lists --
kono
parents:
diff changeset
1565 ---------------------------------------
kono
parents:
diff changeset
1566
kono
parents:
diff changeset
1567 procedure Extract_Package_Declaration_Lists
kono
parents:
diff changeset
1568 (Pack_Decl : Node_Id;
kono
parents:
diff changeset
1569 Body_List : out List_Id;
kono
parents:
diff changeset
1570 Call_List : out List_Id;
kono
parents:
diff changeset
1571 Spec_List : out List_Id)
kono
parents:
diff changeset
1572 is
kono
parents:
diff changeset
1573 Pack_Spec : constant Node_Id := Specification (Pack_Decl);
kono
parents:
diff changeset
1574
kono
parents:
diff changeset
1575 begin
kono
parents:
diff changeset
1576 -- The different parts of the invariant procedure are inserted as
kono
parents:
diff changeset
1577 -- follows:
kono
parents:
diff changeset
1578
kono
parents:
diff changeset
1579 -- package Pack is
kono
parents:
diff changeset
1580 -- <IC spec>
kono
parents:
diff changeset
1581 -- <IC body>
kono
parents:
diff changeset
1582 -- private
kono
parents:
diff changeset
1583 -- <IC call>
kono
parents:
diff changeset
1584 -- end Pack;
kono
parents:
diff changeset
1585
kono
parents:
diff changeset
1586 -- The initial condition procedure spec and body are inserted in the
kono
parents:
diff changeset
1587 -- visible declarations of the package spec.
kono
parents:
diff changeset
1588
kono
parents:
diff changeset
1589 Body_List := Visible_Declarations (Pack_Spec);
kono
parents:
diff changeset
1590
kono
parents:
diff changeset
1591 if No (Body_List) then
kono
parents:
diff changeset
1592 Body_List := New_List;
kono
parents:
diff changeset
1593 Set_Visible_Declarations (Pack_Spec, Body_List);
kono
parents:
diff changeset
1594 end if;
kono
parents:
diff changeset
1595
kono
parents:
diff changeset
1596 Spec_List := Body_List;
kono
parents:
diff changeset
1597
kono
parents:
diff changeset
1598 -- The call to the initial procedure is inserted in the private
kono
parents:
diff changeset
1599 -- declarations of the package spec.
kono
parents:
diff changeset
1600
kono
parents:
diff changeset
1601 Call_List := Private_Declarations (Pack_Spec);
kono
parents:
diff changeset
1602
kono
parents:
diff changeset
1603 if No (Call_List) then
kono
parents:
diff changeset
1604 Call_List := New_List;
kono
parents:
diff changeset
1605 Set_Private_Declarations (Pack_Spec, Call_List);
kono
parents:
diff changeset
1606 end if;
kono
parents:
diff changeset
1607 end Extract_Package_Declaration_Lists;
kono
parents:
diff changeset
1608
kono
parents:
diff changeset
1609 -- Local variables
kono
parents:
diff changeset
1610
kono
parents:
diff changeset
1611 IC_Prag : constant Node_Id :=
kono
parents:
diff changeset
1612 Get_Pragma (Pack_Id, Pragma_Initial_Condition);
kono
parents:
diff changeset
1613
kono
parents:
diff changeset
1614 Body_List : List_Id;
kono
parents:
diff changeset
1615 Call : Node_Id;
kono
parents:
diff changeset
1616 Call_List : List_Id;
kono
parents:
diff changeset
1617 Call_Loc : Source_Ptr;
kono
parents:
diff changeset
1618 Expr : Node_Id;
kono
parents:
diff changeset
1619 Loc : Source_Ptr;
kono
parents:
diff changeset
1620 Proc_Body : Node_Id;
kono
parents:
diff changeset
1621 Proc_Body_Id : Entity_Id;
kono
parents:
diff changeset
1622 Proc_Decl : Node_Id;
kono
parents:
diff changeset
1623 Proc_Id : Entity_Id;
kono
parents:
diff changeset
1624 Spec_List : List_Id;
kono
parents:
diff changeset
1625
kono
parents:
diff changeset
1626 -- Start of processing for Expand_Pragma_Initial_Condition
kono
parents:
diff changeset
1627
kono
parents:
diff changeset
1628 begin
kono
parents:
diff changeset
1629 -- Nothing to do when the package is not subject to an Initial_Condition
kono
parents:
diff changeset
1630 -- pragma.
kono
parents:
diff changeset
1631
kono
parents:
diff changeset
1632 if No (IC_Prag) then
kono
parents:
diff changeset
1633 return;
kono
parents:
diff changeset
1634 end if;
kono
parents:
diff changeset
1635
kono
parents:
diff changeset
1636 Expr := Get_Pragma_Arg (First (Pragma_Argument_Associations (IC_Prag)));
kono
parents:
diff changeset
1637 Loc := Sloc (IC_Prag);
kono
parents:
diff changeset
1638
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1639 -- Nothing to do when the pragma is ignored because its semantics are
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1640 -- suppressed.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1641
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1642 if Is_Ignored (IC_Prag) then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1643 return;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1644
111
kono
parents:
diff changeset
1645 -- Nothing to do when the pragma or its argument are illegal because
kono
parents:
diff changeset
1646 -- there is no valid expression to check.
kono
parents:
diff changeset
1647
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1648 elsif Error_Posted (IC_Prag) or else Error_Posted (Expr) then
111
kono
parents:
diff changeset
1649 return;
kono
parents:
diff changeset
1650 end if;
kono
parents:
diff changeset
1651
kono
parents:
diff changeset
1652 -- Obtain the various lists of the context where the individual pieces
kono
parents:
diff changeset
1653 -- of the initial condition procedure are to be inserted.
kono
parents:
diff changeset
1654
kono
parents:
diff changeset
1655 if Nkind (N) = N_Package_Body then
kono
parents:
diff changeset
1656 Extract_Package_Body_Lists
kono
parents:
diff changeset
1657 (Pack_Body => N,
kono
parents:
diff changeset
1658 Body_List => Body_List,
kono
parents:
diff changeset
1659 Call_List => Call_List,
kono
parents:
diff changeset
1660 Spec_List => Spec_List);
kono
parents:
diff changeset
1661
kono
parents:
diff changeset
1662 elsif Nkind (N) = N_Package_Declaration then
kono
parents:
diff changeset
1663 Extract_Package_Declaration_Lists
kono
parents:
diff changeset
1664 (Pack_Decl => N,
kono
parents:
diff changeset
1665 Body_List => Body_List,
kono
parents:
diff changeset
1666 Call_List => Call_List,
kono
parents:
diff changeset
1667 Spec_List => Spec_List);
kono
parents:
diff changeset
1668
kono
parents:
diff changeset
1669 -- This routine should not be used on anything other than packages
kono
parents:
diff changeset
1670
kono
parents:
diff changeset
1671 else
kono
parents:
diff changeset
1672 pragma Assert (False);
kono
parents:
diff changeset
1673 return;
kono
parents:
diff changeset
1674 end if;
kono
parents:
diff changeset
1675
kono
parents:
diff changeset
1676 Proc_Id :=
kono
parents:
diff changeset
1677 Make_Defining_Identifier (Loc,
kono
parents:
diff changeset
1678 Chars => New_External_Name (Chars (Pack_Id), "Initial_Condition"));
kono
parents:
diff changeset
1679
kono
parents:
diff changeset
1680 Set_Ekind (Proc_Id, E_Procedure);
kono
parents:
diff changeset
1681 Set_Is_Initial_Condition_Procedure (Proc_Id);
kono
parents:
diff changeset
1682
kono
parents:
diff changeset
1683 -- Generate:
kono
parents:
diff changeset
1684 -- procedure <Pack_Id>Initial_Condition;
kono
parents:
diff changeset
1685
kono
parents:
diff changeset
1686 Proc_Decl :=
kono
parents:
diff changeset
1687 Make_Subprogram_Declaration (Loc,
kono
parents:
diff changeset
1688 Make_Procedure_Specification (Loc,
kono
parents:
diff changeset
1689 Defining_Unit_Name => Proc_Id));
kono
parents:
diff changeset
1690
kono
parents:
diff changeset
1691 Append_To (Spec_List, Proc_Decl);
kono
parents:
diff changeset
1692
kono
parents:
diff changeset
1693 -- The initial condition procedure requires debug info when initial
kono
parents:
diff changeset
1694 -- condition is subject to Source Coverage Obligations.
kono
parents:
diff changeset
1695
kono
parents:
diff changeset
1696 if Generate_SCO then
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1697 Set_Debug_Info_Needed (Proc_Id);
111
kono
parents:
diff changeset
1698 end if;
kono
parents:
diff changeset
1699
kono
parents:
diff changeset
1700 -- Generate:
kono
parents:
diff changeset
1701 -- procedure <Pack_Id>Initial_Condition is
kono
parents:
diff changeset
1702 -- begin
kono
parents:
diff changeset
1703 -- pragma Check (Initial_Condition, <Expr>);
kono
parents:
diff changeset
1704 -- end <Pack_Id>Initial_Condition;
kono
parents:
diff changeset
1705
kono
parents:
diff changeset
1706 Proc_Body :=
kono
parents:
diff changeset
1707 Make_Subprogram_Body (Loc,
kono
parents:
diff changeset
1708 Specification =>
kono
parents:
diff changeset
1709 Copy_Subprogram_Spec (Specification (Proc_Decl)),
kono
parents:
diff changeset
1710 Declarations => Empty_List,
kono
parents:
diff changeset
1711 Handled_Statement_Sequence =>
kono
parents:
diff changeset
1712 Make_Handled_Sequence_Of_Statements (Loc,
kono
parents:
diff changeset
1713 Statements => New_List (
kono
parents:
diff changeset
1714 Make_Pragma (Loc,
kono
parents:
diff changeset
1715 Chars => Name_Check,
kono
parents:
diff changeset
1716 Pragma_Argument_Associations => New_List (
kono
parents:
diff changeset
1717 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
1718 Expression =>
kono
parents:
diff changeset
1719 Make_Identifier (Loc, Name_Initial_Condition)),
kono
parents:
diff changeset
1720 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
1721 Expression => New_Copy_Tree (Expr)))))));
kono
parents:
diff changeset
1722
kono
parents:
diff changeset
1723 Append_To (Body_List, Proc_Body);
kono
parents:
diff changeset
1724
kono
parents:
diff changeset
1725 -- The initial condition procedure requires debug info when initial
kono
parents:
diff changeset
1726 -- condition is subject to Source Coverage Obligations.
kono
parents:
diff changeset
1727
kono
parents:
diff changeset
1728 Proc_Body_Id := Defining_Entity (Proc_Body);
kono
parents:
diff changeset
1729
kono
parents:
diff changeset
1730 if Generate_SCO then
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1731 Set_Debug_Info_Needed (Proc_Body_Id);
111
kono
parents:
diff changeset
1732 end if;
kono
parents:
diff changeset
1733
kono
parents:
diff changeset
1734 -- The location of the initial condition procedure call must be as close
kono
parents:
diff changeset
1735 -- as possible to the intended semantic location of the check because
kono
parents:
diff changeset
1736 -- the ABE mechanism relies heavily on accurate locations.
kono
parents:
diff changeset
1737
kono
parents:
diff changeset
1738 Call_Loc := End_Keyword_Location (N);
kono
parents:
diff changeset
1739
kono
parents:
diff changeset
1740 -- Generate:
kono
parents:
diff changeset
1741 -- <Pack_Id>Initial_Condition;
kono
parents:
diff changeset
1742
kono
parents:
diff changeset
1743 Call :=
kono
parents:
diff changeset
1744 Make_Procedure_Call_Statement (Call_Loc,
kono
parents:
diff changeset
1745 Name => New_Occurrence_Of (Proc_Id, Call_Loc));
kono
parents:
diff changeset
1746
kono
parents:
diff changeset
1747 Append_To (Call_List, Call);
kono
parents:
diff changeset
1748
kono
parents:
diff changeset
1749 Analyze (Proc_Decl);
kono
parents:
diff changeset
1750 Analyze (Proc_Body);
kono
parents:
diff changeset
1751 Analyze (Call);
kono
parents:
diff changeset
1752 end Expand_Pragma_Initial_Condition;
kono
parents:
diff changeset
1753
kono
parents:
diff changeset
1754 ------------------------------------
kono
parents:
diff changeset
1755 -- Expand_Pragma_Inspection_Point --
kono
parents:
diff changeset
1756 ------------------------------------
kono
parents:
diff changeset
1757
kono
parents:
diff changeset
1758 -- If no argument is given, then we supply a default argument list that
kono
parents:
diff changeset
1759 -- includes all objects declared at the source level in all subprograms
kono
parents:
diff changeset
1760 -- that enclose the inspection point pragma.
kono
parents:
diff changeset
1761
kono
parents:
diff changeset
1762 procedure Expand_Pragma_Inspection_Point (N : Node_Id) is
kono
parents:
diff changeset
1763 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
1764 A : List_Id;
kono
parents:
diff changeset
1765 Assoc : Node_Id;
kono
parents:
diff changeset
1766 S : Entity_Id;
kono
parents:
diff changeset
1767 E : Entity_Id;
kono
parents:
diff changeset
1768
kono
parents:
diff changeset
1769 begin
kono
parents:
diff changeset
1770 if No (Pragma_Argument_Associations (N)) then
kono
parents:
diff changeset
1771 A := New_List;
kono
parents:
diff changeset
1772 S := Current_Scope;
kono
parents:
diff changeset
1773
kono
parents:
diff changeset
1774 while S /= Standard_Standard loop
kono
parents:
diff changeset
1775 E := First_Entity (S);
kono
parents:
diff changeset
1776 while Present (E) loop
kono
parents:
diff changeset
1777 if Comes_From_Source (E)
kono
parents:
diff changeset
1778 and then Is_Object (E)
kono
parents:
diff changeset
1779 and then not Is_Entry_Formal (E)
kono
parents:
diff changeset
1780 and then Ekind (E) /= E_Component
kono
parents:
diff changeset
1781 and then Ekind (E) /= E_Discriminant
kono
parents:
diff changeset
1782 and then Ekind (E) /= E_Generic_In_Parameter
kono
parents:
diff changeset
1783 and then Ekind (E) /= E_Generic_In_Out_Parameter
kono
parents:
diff changeset
1784 then
kono
parents:
diff changeset
1785 Append_To (A,
kono
parents:
diff changeset
1786 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
1787 Expression => New_Occurrence_Of (E, Loc)));
kono
parents:
diff changeset
1788 end if;
kono
parents:
diff changeset
1789
kono
parents:
diff changeset
1790 Next_Entity (E);
kono
parents:
diff changeset
1791 end loop;
kono
parents:
diff changeset
1792
kono
parents:
diff changeset
1793 S := Scope (S);
kono
parents:
diff changeset
1794 end loop;
kono
parents:
diff changeset
1795
kono
parents:
diff changeset
1796 Set_Pragma_Argument_Associations (N, A);
kono
parents:
diff changeset
1797 end if;
kono
parents:
diff changeset
1798
kono
parents:
diff changeset
1799 -- Expand the arguments of the pragma. Expanding an entity reference
kono
parents:
diff changeset
1800 -- is a noop, except in a protected operation, where a reference may
kono
parents:
diff changeset
1801 -- have to be transformed into a reference to the corresponding prival.
kono
parents:
diff changeset
1802 -- Are there other pragmas that may require this ???
kono
parents:
diff changeset
1803
kono
parents:
diff changeset
1804 Assoc := First (Pragma_Argument_Associations (N));
kono
parents:
diff changeset
1805 while Present (Assoc) loop
kono
parents:
diff changeset
1806 Expand (Expression (Assoc));
kono
parents:
diff changeset
1807 Next (Assoc);
kono
parents:
diff changeset
1808 end loop;
kono
parents:
diff changeset
1809 end Expand_Pragma_Inspection_Point;
kono
parents:
diff changeset
1810
kono
parents:
diff changeset
1811 --------------------------------------
kono
parents:
diff changeset
1812 -- Expand_Pragma_Interrupt_Priority --
kono
parents:
diff changeset
1813 --------------------------------------
kono
parents:
diff changeset
1814
kono
parents:
diff changeset
1815 -- Supply default argument if none exists (System.Interrupt_Priority'Last)
kono
parents:
diff changeset
1816
kono
parents:
diff changeset
1817 procedure Expand_Pragma_Interrupt_Priority (N : Node_Id) is
kono
parents:
diff changeset
1818 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
1819 begin
kono
parents:
diff changeset
1820 if No (Pragma_Argument_Associations (N)) then
kono
parents:
diff changeset
1821 Set_Pragma_Argument_Associations (N, New_List (
kono
parents:
diff changeset
1822 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
1823 Expression =>
kono
parents:
diff changeset
1824 Make_Attribute_Reference (Loc,
kono
parents:
diff changeset
1825 Prefix =>
kono
parents:
diff changeset
1826 New_Occurrence_Of (RTE (RE_Interrupt_Priority), Loc),
kono
parents:
diff changeset
1827 Attribute_Name => Name_Last))));
kono
parents:
diff changeset
1828 end if;
kono
parents:
diff changeset
1829 end Expand_Pragma_Interrupt_Priority;
kono
parents:
diff changeset
1830
kono
parents:
diff changeset
1831 --------------------------------
kono
parents:
diff changeset
1832 -- Expand_Pragma_Loop_Variant --
kono
parents:
diff changeset
1833 --------------------------------
kono
parents:
diff changeset
1834
kono
parents:
diff changeset
1835 -- Pragma Loop_Variant is expanded in the following manner:
kono
parents:
diff changeset
1836
kono
parents:
diff changeset
1837 -- Original code
kono
parents:
diff changeset
1838
kono
parents:
diff changeset
1839 -- for | while ... loop
kono
parents:
diff changeset
1840 -- <preceding source statements>
kono
parents:
diff changeset
1841 -- pragma Loop_Variant
kono
parents:
diff changeset
1842 -- (Increases => Incr_Expr,
kono
parents:
diff changeset
1843 -- Decreases => Decr_Expr);
kono
parents:
diff changeset
1844 -- <succeeding source statements>
kono
parents:
diff changeset
1845 -- end loop;
kono
parents:
diff changeset
1846
kono
parents:
diff changeset
1847 -- Expanded code
kono
parents:
diff changeset
1848
kono
parents:
diff changeset
1849 -- Curr_1 : <type of Incr_Expr>;
kono
parents:
diff changeset
1850 -- Curr_2 : <type of Decr_Expr>;
kono
parents:
diff changeset
1851 -- Old_1 : <type of Incr_Expr>;
kono
parents:
diff changeset
1852 -- Old_2 : <type of Decr_Expr>;
kono
parents:
diff changeset
1853 -- Flag : Boolean := False;
kono
parents:
diff changeset
1854
kono
parents:
diff changeset
1855 -- for | while ... loop
kono
parents:
diff changeset
1856 -- <preceding source statements>
kono
parents:
diff changeset
1857
kono
parents:
diff changeset
1858 -- if Flag then
kono
parents:
diff changeset
1859 -- Old_1 := Curr_1;
kono
parents:
diff changeset
1860 -- Old_2 := Curr_2;
kono
parents:
diff changeset
1861 -- end if;
kono
parents:
diff changeset
1862
kono
parents:
diff changeset
1863 -- Curr_1 := <Incr_Expr>;
kono
parents:
diff changeset
1864 -- Curr_2 := <Decr_Expr>;
kono
parents:
diff changeset
1865
kono
parents:
diff changeset
1866 -- if Flag then
kono
parents:
diff changeset
1867 -- if Curr_1 /= Old_1 then
kono
parents:
diff changeset
1868 -- pragma Check (Loop_Variant, Curr_1 > Old_1);
kono
parents:
diff changeset
1869 -- else
kono
parents:
diff changeset
1870 -- pragma Check (Loop_Variant, Curr_2 < Old_2);
kono
parents:
diff changeset
1871 -- end if;
kono
parents:
diff changeset
1872 -- else
kono
parents:
diff changeset
1873 -- Flag := True;
kono
parents:
diff changeset
1874 -- end if;
kono
parents:
diff changeset
1875
kono
parents:
diff changeset
1876 -- <succeeding source statements>
kono
parents:
diff changeset
1877 -- end loop;
kono
parents:
diff changeset
1878
kono
parents:
diff changeset
1879 procedure Expand_Pragma_Loop_Variant (N : Node_Id) is
kono
parents:
diff changeset
1880 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
1881 Last_Var : constant Node_Id :=
kono
parents:
diff changeset
1882 Last (Pragma_Argument_Associations (N));
kono
parents:
diff changeset
1883
kono
parents:
diff changeset
1884 Curr_Assign : List_Id := No_List;
kono
parents:
diff changeset
1885 Flag_Id : Entity_Id := Empty;
kono
parents:
diff changeset
1886 If_Stmt : Node_Id := Empty;
kono
parents:
diff changeset
1887 Old_Assign : List_Id := No_List;
kono
parents:
diff changeset
1888 Loop_Scop : Entity_Id;
kono
parents:
diff changeset
1889 Loop_Stmt : Node_Id;
kono
parents:
diff changeset
1890 Variant : Node_Id;
kono
parents:
diff changeset
1891
kono
parents:
diff changeset
1892 procedure Process_Variant (Variant : Node_Id; Is_Last : Boolean);
kono
parents:
diff changeset
1893 -- Process a single increasing / decreasing termination variant. Flag
kono
parents:
diff changeset
1894 -- Is_Last should be set when processing the last variant.
kono
parents:
diff changeset
1895
kono
parents:
diff changeset
1896 ---------------------
kono
parents:
diff changeset
1897 -- Process_Variant --
kono
parents:
diff changeset
1898 ---------------------
kono
parents:
diff changeset
1899
kono
parents:
diff changeset
1900 procedure Process_Variant (Variant : Node_Id; Is_Last : Boolean) is
kono
parents:
diff changeset
1901 function Make_Op
kono
parents:
diff changeset
1902 (Loc : Source_Ptr;
kono
parents:
diff changeset
1903 Curr_Val : Node_Id;
kono
parents:
diff changeset
1904 Old_Val : Node_Id) return Node_Id;
kono
parents:
diff changeset
1905 -- Generate a comparison between Curr_Val and Old_Val depending on
kono
parents:
diff changeset
1906 -- the change mode (Increases / Decreases) of the variant.
kono
parents:
diff changeset
1907
kono
parents:
diff changeset
1908 -------------
kono
parents:
diff changeset
1909 -- Make_Op --
kono
parents:
diff changeset
1910 -------------
kono
parents:
diff changeset
1911
kono
parents:
diff changeset
1912 function Make_Op
kono
parents:
diff changeset
1913 (Loc : Source_Ptr;
kono
parents:
diff changeset
1914 Curr_Val : Node_Id;
kono
parents:
diff changeset
1915 Old_Val : Node_Id) return Node_Id
kono
parents:
diff changeset
1916 is
kono
parents:
diff changeset
1917 begin
kono
parents:
diff changeset
1918 if Chars (Variant) = Name_Increases then
kono
parents:
diff changeset
1919 return Make_Op_Gt (Loc, Curr_Val, Old_Val);
kono
parents:
diff changeset
1920 else pragma Assert (Chars (Variant) = Name_Decreases);
kono
parents:
diff changeset
1921 return Make_Op_Lt (Loc, Curr_Val, Old_Val);
kono
parents:
diff changeset
1922 end if;
kono
parents:
diff changeset
1923 end Make_Op;
kono
parents:
diff changeset
1924
kono
parents:
diff changeset
1925 -- Local variables
kono
parents:
diff changeset
1926
kono
parents:
diff changeset
1927 Expr : constant Node_Id := Expression (Variant);
kono
parents:
diff changeset
1928 Expr_Typ : constant Entity_Id := Etype (Expr);
kono
parents:
diff changeset
1929 Loc : constant Source_Ptr := Sloc (Expr);
kono
parents:
diff changeset
1930 Loop_Loc : constant Source_Ptr := Sloc (Loop_Stmt);
kono
parents:
diff changeset
1931 Curr_Id : Entity_Id;
kono
parents:
diff changeset
1932 Old_Id : Entity_Id;
kono
parents:
diff changeset
1933 Prag : Node_Id;
kono
parents:
diff changeset
1934
kono
parents:
diff changeset
1935 -- Start of processing for Process_Variant
kono
parents:
diff changeset
1936
kono
parents:
diff changeset
1937 begin
kono
parents:
diff changeset
1938 -- All temporaries generated in this routine must be inserted before
kono
parents:
diff changeset
1939 -- the related loop statement. Ensure that the proper scope is on the
kono
parents:
diff changeset
1940 -- stack when analyzing the temporaries. Note that we also use the
kono
parents:
diff changeset
1941 -- Sloc of the related loop.
kono
parents:
diff changeset
1942
kono
parents:
diff changeset
1943 Push_Scope (Scope (Loop_Scop));
kono
parents:
diff changeset
1944
kono
parents:
diff changeset
1945 -- Step 1: Create the declaration of the flag which controls the
kono
parents:
diff changeset
1946 -- behavior of the assertion on the first iteration of the loop.
kono
parents:
diff changeset
1947
kono
parents:
diff changeset
1948 if No (Flag_Id) then
kono
parents:
diff changeset
1949
kono
parents:
diff changeset
1950 -- Generate:
kono
parents:
diff changeset
1951 -- Flag : Boolean := False;
kono
parents:
diff changeset
1952
kono
parents:
diff changeset
1953 Flag_Id := Make_Temporary (Loop_Loc, 'F');
kono
parents:
diff changeset
1954
kono
parents:
diff changeset
1955 Insert_Action (Loop_Stmt,
kono
parents:
diff changeset
1956 Make_Object_Declaration (Loop_Loc,
kono
parents:
diff changeset
1957 Defining_Identifier => Flag_Id,
kono
parents:
diff changeset
1958 Object_Definition =>
kono
parents:
diff changeset
1959 New_Occurrence_Of (Standard_Boolean, Loop_Loc),
kono
parents:
diff changeset
1960 Expression =>
kono
parents:
diff changeset
1961 New_Occurrence_Of (Standard_False, Loop_Loc)));
kono
parents:
diff changeset
1962
kono
parents:
diff changeset
1963 -- Prevent an unwanted optimization where the Current_Value of
kono
parents:
diff changeset
1964 -- the flag eliminates the if statement which stores the variant
kono
parents:
diff changeset
1965 -- values coming from the previous iteration.
kono
parents:
diff changeset
1966
kono
parents:
diff changeset
1967 -- Flag : Boolean := False;
kono
parents:
diff changeset
1968 -- loop
kono
parents:
diff changeset
1969 -- if Flag then -- condition rewritten to False
kono
parents:
diff changeset
1970 -- Old_N := Curr_N; -- and if statement eliminated
kono
parents:
diff changeset
1971 -- end if;
kono
parents:
diff changeset
1972 -- . . .
kono
parents:
diff changeset
1973 -- Flag := True;
kono
parents:
diff changeset
1974 -- end loop;
kono
parents:
diff changeset
1975
kono
parents:
diff changeset
1976 Set_Current_Value (Flag_Id, Empty);
kono
parents:
diff changeset
1977 end if;
kono
parents:
diff changeset
1978
kono
parents:
diff changeset
1979 -- Step 2: Create the temporaries which store the old and current
kono
parents:
diff changeset
1980 -- values of the associated expression.
kono
parents:
diff changeset
1981
kono
parents:
diff changeset
1982 -- Generate:
kono
parents:
diff changeset
1983 -- Curr : <type of Expr>;
kono
parents:
diff changeset
1984
kono
parents:
diff changeset
1985 Curr_Id := Make_Temporary (Loc, 'C');
kono
parents:
diff changeset
1986
kono
parents:
diff changeset
1987 Insert_Action (Loop_Stmt,
kono
parents:
diff changeset
1988 Make_Object_Declaration (Loop_Loc,
kono
parents:
diff changeset
1989 Defining_Identifier => Curr_Id,
kono
parents:
diff changeset
1990 Object_Definition => New_Occurrence_Of (Expr_Typ, Loop_Loc)));
kono
parents:
diff changeset
1991
kono
parents:
diff changeset
1992 -- Generate:
kono
parents:
diff changeset
1993 -- Old : <type of Expr>;
kono
parents:
diff changeset
1994
kono
parents:
diff changeset
1995 Old_Id := Make_Temporary (Loc, 'P');
kono
parents:
diff changeset
1996
kono
parents:
diff changeset
1997 Insert_Action (Loop_Stmt,
kono
parents:
diff changeset
1998 Make_Object_Declaration (Loop_Loc,
kono
parents:
diff changeset
1999 Defining_Identifier => Old_Id,
kono
parents:
diff changeset
2000 Object_Definition => New_Occurrence_Of (Expr_Typ, Loop_Loc)));
kono
parents:
diff changeset
2001
kono
parents:
diff changeset
2002 -- Restore original scope after all temporaries have been analyzed
kono
parents:
diff changeset
2003
kono
parents:
diff changeset
2004 Pop_Scope;
kono
parents:
diff changeset
2005
kono
parents:
diff changeset
2006 -- Step 3: Store value of the expression from the previous iteration
kono
parents:
diff changeset
2007
kono
parents:
diff changeset
2008 if No (Old_Assign) then
kono
parents:
diff changeset
2009 Old_Assign := New_List;
kono
parents:
diff changeset
2010 end if;
kono
parents:
diff changeset
2011
kono
parents:
diff changeset
2012 -- Generate:
kono
parents:
diff changeset
2013 -- Old := Curr;
kono
parents:
diff changeset
2014
kono
parents:
diff changeset
2015 Append_To (Old_Assign,
kono
parents:
diff changeset
2016 Make_Assignment_Statement (Loc,
kono
parents:
diff changeset
2017 Name => New_Occurrence_Of (Old_Id, Loc),
kono
parents:
diff changeset
2018 Expression => New_Occurrence_Of (Curr_Id, Loc)));
kono
parents:
diff changeset
2019
kono
parents:
diff changeset
2020 -- Step 4: Store the current value of the expression
kono
parents:
diff changeset
2021
kono
parents:
diff changeset
2022 if No (Curr_Assign) then
kono
parents:
diff changeset
2023 Curr_Assign := New_List;
kono
parents:
diff changeset
2024 end if;
kono
parents:
diff changeset
2025
kono
parents:
diff changeset
2026 -- Generate:
kono
parents:
diff changeset
2027 -- Curr := <Expr>;
kono
parents:
diff changeset
2028
kono
parents:
diff changeset
2029 Append_To (Curr_Assign,
kono
parents:
diff changeset
2030 Make_Assignment_Statement (Loc,
kono
parents:
diff changeset
2031 Name => New_Occurrence_Of (Curr_Id, Loc),
kono
parents:
diff changeset
2032 Expression => Relocate_Node (Expr)));
kono
parents:
diff changeset
2033
kono
parents:
diff changeset
2034 -- Step 5: Create corresponding assertion to verify change of value
kono
parents:
diff changeset
2035
kono
parents:
diff changeset
2036 -- Generate:
kono
parents:
diff changeset
2037 -- pragma Check (Loop_Variant, Curr <|> Old);
kono
parents:
diff changeset
2038
kono
parents:
diff changeset
2039 Prag :=
kono
parents:
diff changeset
2040 Make_Pragma (Loc,
kono
parents:
diff changeset
2041 Chars => Name_Check,
kono
parents:
diff changeset
2042 Pragma_Argument_Associations => New_List (
kono
parents:
diff changeset
2043 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
2044 Expression => Make_Identifier (Loc, Name_Loop_Variant)),
kono
parents:
diff changeset
2045 Make_Pragma_Argument_Association (Loc,
kono
parents:
diff changeset
2046 Expression =>
kono
parents:
diff changeset
2047 Make_Op (Loc,
kono
parents:
diff changeset
2048 Curr_Val => New_Occurrence_Of (Curr_Id, Loc),
kono
parents:
diff changeset
2049 Old_Val => New_Occurrence_Of (Old_Id, Loc)))));
kono
parents:
diff changeset
2050
kono
parents:
diff changeset
2051 -- Generate:
kono
parents:
diff changeset
2052 -- if Curr /= Old then
kono
parents:
diff changeset
2053 -- <Prag>;
kono
parents:
diff changeset
2054
kono
parents:
diff changeset
2055 if No (If_Stmt) then
kono
parents:
diff changeset
2056
kono
parents:
diff changeset
2057 -- When there is just one termination variant, do not compare the
kono
parents:
diff changeset
2058 -- old and current value for equality, just check the pragma.
kono
parents:
diff changeset
2059
kono
parents:
diff changeset
2060 if Is_Last then
kono
parents:
diff changeset
2061 If_Stmt := Prag;
kono
parents:
diff changeset
2062 else
kono
parents:
diff changeset
2063 If_Stmt :=
kono
parents:
diff changeset
2064 Make_If_Statement (Loc,
kono
parents:
diff changeset
2065 Condition =>
kono
parents:
diff changeset
2066 Make_Op_Ne (Loc,
kono
parents:
diff changeset
2067 Left_Opnd => New_Occurrence_Of (Curr_Id, Loc),
kono
parents:
diff changeset
2068 Right_Opnd => New_Occurrence_Of (Old_Id, Loc)),
kono
parents:
diff changeset
2069 Then_Statements => New_List (Prag));
kono
parents:
diff changeset
2070 end if;
kono
parents:
diff changeset
2071
kono
parents:
diff changeset
2072 -- Generate:
kono
parents:
diff changeset
2073 -- else
kono
parents:
diff changeset
2074 -- <Prag>;
kono
parents:
diff changeset
2075 -- end if;
kono
parents:
diff changeset
2076
kono
parents:
diff changeset
2077 elsif Is_Last then
kono
parents:
diff changeset
2078 Set_Else_Statements (If_Stmt, New_List (Prag));
kono
parents:
diff changeset
2079
kono
parents:
diff changeset
2080 -- Generate:
kono
parents:
diff changeset
2081 -- elsif Curr /= Old then
kono
parents:
diff changeset
2082 -- <Prag>;
kono
parents:
diff changeset
2083
kono
parents:
diff changeset
2084 else
kono
parents:
diff changeset
2085 if Elsif_Parts (If_Stmt) = No_List then
kono
parents:
diff changeset
2086 Set_Elsif_Parts (If_Stmt, New_List);
kono
parents:
diff changeset
2087 end if;
kono
parents:
diff changeset
2088
kono
parents:
diff changeset
2089 Append_To (Elsif_Parts (If_Stmt),
kono
parents:
diff changeset
2090 Make_Elsif_Part (Loc,
kono
parents:
diff changeset
2091 Condition =>
kono
parents:
diff changeset
2092 Make_Op_Ne (Loc,
kono
parents:
diff changeset
2093 Left_Opnd => New_Occurrence_Of (Curr_Id, Loc),
kono
parents:
diff changeset
2094 Right_Opnd => New_Occurrence_Of (Old_Id, Loc)),
kono
parents:
diff changeset
2095 Then_Statements => New_List (Prag)));
kono
parents:
diff changeset
2096 end if;
kono
parents:
diff changeset
2097 end Process_Variant;
kono
parents:
diff changeset
2098
kono
parents:
diff changeset
2099 -- Start of processing for Expand_Pragma_Loop_Variant
kono
parents:
diff changeset
2100
kono
parents:
diff changeset
2101 begin
kono
parents:
diff changeset
2102 -- If pragma is not enabled, rewrite as Null statement. If pragma is
kono
parents:
diff changeset
2103 -- disabled, it has already been rewritten as a Null statement.
kono
parents:
diff changeset
2104
kono
parents:
diff changeset
2105 if Is_Ignored (N) then
kono
parents:
diff changeset
2106 Rewrite (N, Make_Null_Statement (Loc));
kono
parents:
diff changeset
2107 Analyze (N);
kono
parents:
diff changeset
2108 return;
kono
parents:
diff changeset
2109 end if;
kono
parents:
diff changeset
2110
kono
parents:
diff changeset
2111 -- The expansion of Loop_Variant is quite distributed as it produces
kono
parents:
diff changeset
2112 -- various statements to capture and compare the arguments. To preserve
kono
parents:
diff changeset
2113 -- the original context, set the Is_Assertion_Expr flag. This aids the
kono
parents:
diff changeset
2114 -- Ghost legality checks when verifying the placement of a reference to
kono
parents:
diff changeset
2115 -- a Ghost entity.
kono
parents:
diff changeset
2116
kono
parents:
diff changeset
2117 In_Assertion_Expr := In_Assertion_Expr + 1;
kono
parents:
diff changeset
2118
kono
parents:
diff changeset
2119 -- Locate the enclosing loop for which this assertion applies. In the
kono
parents:
diff changeset
2120 -- case of Ada 2012 array iteration, we might be dealing with nested
kono
parents:
diff changeset
2121 -- loops. Only the outermost loop has an identifier.
kono
parents:
diff changeset
2122
kono
parents:
diff changeset
2123 Loop_Stmt := N;
kono
parents:
diff changeset
2124 while Present (Loop_Stmt) loop
kono
parents:
diff changeset
2125 if Nkind (Loop_Stmt) = N_Loop_Statement
kono
parents:
diff changeset
2126 and then Present (Identifier (Loop_Stmt))
kono
parents:
diff changeset
2127 then
kono
parents:
diff changeset
2128 exit;
kono
parents:
diff changeset
2129 end if;
kono
parents:
diff changeset
2130
kono
parents:
diff changeset
2131 Loop_Stmt := Parent (Loop_Stmt);
kono
parents:
diff changeset
2132 end loop;
kono
parents:
diff changeset
2133
kono
parents:
diff changeset
2134 Loop_Scop := Entity (Identifier (Loop_Stmt));
kono
parents:
diff changeset
2135
kono
parents:
diff changeset
2136 -- Create the circuitry which verifies individual variants
kono
parents:
diff changeset
2137
kono
parents:
diff changeset
2138 Variant := First (Pragma_Argument_Associations (N));
kono
parents:
diff changeset
2139 while Present (Variant) loop
kono
parents:
diff changeset
2140 Process_Variant (Variant, Is_Last => Variant = Last_Var);
kono
parents:
diff changeset
2141 Next (Variant);
kono
parents:
diff changeset
2142 end loop;
kono
parents:
diff changeset
2143
kono
parents:
diff changeset
2144 -- Construct the segment which stores the old values of all expressions.
kono
parents:
diff changeset
2145 -- Generate:
kono
parents:
diff changeset
2146 -- if Flag then
kono
parents:
diff changeset
2147 -- <Old_Assign>
kono
parents:
diff changeset
2148 -- end if;
kono
parents:
diff changeset
2149
kono
parents:
diff changeset
2150 Insert_Action (N,
kono
parents:
diff changeset
2151 Make_If_Statement (Loc,
kono
parents:
diff changeset
2152 Condition => New_Occurrence_Of (Flag_Id, Loc),
kono
parents:
diff changeset
2153 Then_Statements => Old_Assign));
kono
parents:
diff changeset
2154
kono
parents:
diff changeset
2155 -- Update the values of all expressions
kono
parents:
diff changeset
2156
kono
parents:
diff changeset
2157 Insert_Actions (N, Curr_Assign);
kono
parents:
diff changeset
2158
kono
parents:
diff changeset
2159 -- Add the assertion circuitry to test all changes in expressions.
kono
parents:
diff changeset
2160 -- Generate:
kono
parents:
diff changeset
2161 -- if Flag then
kono
parents:
diff changeset
2162 -- <If_Stmt>
kono
parents:
diff changeset
2163 -- else
kono
parents:
diff changeset
2164 -- Flag := True;
kono
parents:
diff changeset
2165 -- end if;
kono
parents:
diff changeset
2166
kono
parents:
diff changeset
2167 Insert_Action (N,
kono
parents:
diff changeset
2168 Make_If_Statement (Loc,
kono
parents:
diff changeset
2169 Condition => New_Occurrence_Of (Flag_Id, Loc),
kono
parents:
diff changeset
2170 Then_Statements => New_List (If_Stmt),
kono
parents:
diff changeset
2171 Else_Statements => New_List (
kono
parents:
diff changeset
2172 Make_Assignment_Statement (Loc,
kono
parents:
diff changeset
2173 Name => New_Occurrence_Of (Flag_Id, Loc),
kono
parents:
diff changeset
2174 Expression => New_Occurrence_Of (Standard_True, Loc)))));
kono
parents:
diff changeset
2175
kono
parents:
diff changeset
2176 -- Note: the pragma has been completely transformed into a sequence of
kono
parents:
diff changeset
2177 -- corresponding declarations and statements. We leave it in the tree
kono
parents:
diff changeset
2178 -- for documentation purposes. It will be ignored by the backend.
kono
parents:
diff changeset
2179
kono
parents:
diff changeset
2180 In_Assertion_Expr := In_Assertion_Expr - 1;
kono
parents:
diff changeset
2181 end Expand_Pragma_Loop_Variant;
kono
parents:
diff changeset
2182
kono
parents:
diff changeset
2183 --------------------------------
kono
parents:
diff changeset
2184 -- Expand_Pragma_Psect_Object --
kono
parents:
diff changeset
2185 --------------------------------
kono
parents:
diff changeset
2186
kono
parents:
diff changeset
2187 -- Convert to Common_Object, and expand the resulting pragma
kono
parents:
diff changeset
2188
kono
parents:
diff changeset
2189 procedure Expand_Pragma_Psect_Object (N : Node_Id)
kono
parents:
diff changeset
2190 renames Expand_Pragma_Common_Object;
kono
parents:
diff changeset
2191
kono
parents:
diff changeset
2192 -------------------------------------
kono
parents:
diff changeset
2193 -- Expand_Pragma_Relative_Deadline --
kono
parents:
diff changeset
2194 -------------------------------------
kono
parents:
diff changeset
2195
kono
parents:
diff changeset
2196 procedure Expand_Pragma_Relative_Deadline (N : Node_Id) is
kono
parents:
diff changeset
2197 P : constant Node_Id := Parent (N);
kono
parents:
diff changeset
2198 Loc : constant Source_Ptr := Sloc (N);
kono
parents:
diff changeset
2199
kono
parents:
diff changeset
2200 begin
kono
parents:
diff changeset
2201 -- Expand the pragma only in the case of the main subprogram. For tasks
kono
parents:
diff changeset
2202 -- the expansion is done in exp_ch9. Generate a call to Set_Deadline
kono
parents:
diff changeset
2203 -- at Clock plus the relative deadline specified in the pragma. Time
kono
parents:
diff changeset
2204 -- values are translated into Duration to allow for non-private
kono
parents:
diff changeset
2205 -- addition operation.
kono
parents:
diff changeset
2206
kono
parents:
diff changeset
2207 if Nkind (P) = N_Subprogram_Body then
kono
parents:
diff changeset
2208 Rewrite
kono
parents:
diff changeset
2209 (N,
kono
parents:
diff changeset
2210 Make_Procedure_Call_Statement (Loc,
kono
parents:
diff changeset
2211 Name => New_Occurrence_Of (RTE (RE_Set_Deadline), Loc),
kono
parents:
diff changeset
2212 Parameter_Associations => New_List (
kono
parents:
diff changeset
2213 Unchecked_Convert_To (RTE (RO_RT_Time),
kono
parents:
diff changeset
2214 Make_Op_Add (Loc,
kono
parents:
diff changeset
2215 Left_Opnd =>
kono
parents:
diff changeset
2216 Make_Function_Call (Loc,
kono
parents:
diff changeset
2217 New_Occurrence_Of (RTE (RO_RT_To_Duration), Loc),
kono
parents:
diff changeset
2218 New_List
kono
parents:
diff changeset
2219 (Make_Function_Call
kono
parents:
diff changeset
2220 (Loc, New_Occurrence_Of (RTE (RE_Clock), Loc)))),
kono
parents:
diff changeset
2221 Right_Opnd =>
kono
parents:
diff changeset
2222 Unchecked_Convert_To (Standard_Duration, Arg1 (N)))))));
kono
parents:
diff changeset
2223
kono
parents:
diff changeset
2224 Analyze (N);
kono
parents:
diff changeset
2225 end if;
kono
parents:
diff changeset
2226 end Expand_Pragma_Relative_Deadline;
kono
parents:
diff changeset
2227
kono
parents:
diff changeset
2228 -------------------------------------------
kono
parents:
diff changeset
2229 -- Expand_Pragma_Suppress_Initialization --
kono
parents:
diff changeset
2230 -------------------------------------------
kono
parents:
diff changeset
2231
kono
parents:
diff changeset
2232 procedure Expand_Pragma_Suppress_Initialization (N : Node_Id) is
kono
parents:
diff changeset
2233 Def_Id : constant Entity_Id := Entity (Arg1 (N));
kono
parents:
diff changeset
2234
kono
parents:
diff changeset
2235 begin
kono
parents:
diff changeset
2236 -- Variable case (we have to undo any initialization already done)
kono
parents:
diff changeset
2237
kono
parents:
diff changeset
2238 if Ekind (Def_Id) = E_Variable then
kono
parents:
diff changeset
2239 Undo_Initialization (Def_Id, N);
kono
parents:
diff changeset
2240 end if;
kono
parents:
diff changeset
2241 end Expand_Pragma_Suppress_Initialization;
kono
parents:
diff changeset
2242
kono
parents:
diff changeset
2243 -------------------------
kono
parents:
diff changeset
2244 -- Undo_Initialization --
kono
parents:
diff changeset
2245 -------------------------
kono
parents:
diff changeset
2246
kono
parents:
diff changeset
2247 procedure Undo_Initialization (Def_Id : Entity_Id; N : Node_Id) is
kono
parents:
diff changeset
2248 Init_Call : Node_Id;
kono
parents:
diff changeset
2249
kono
parents:
diff changeset
2250 begin
kono
parents:
diff changeset
2251 -- When applied to a variable, the default initialization must not be
kono
parents:
diff changeset
2252 -- done. As it is already done when the pragma is found, we just get rid
kono
parents:
diff changeset
2253 -- of the call the initialization procedure which followed the object
kono
parents:
diff changeset
2254 -- declaration. The call is inserted after the declaration, but validity
kono
parents:
diff changeset
2255 -- checks may also have been inserted and thus the initialization call
kono
parents:
diff changeset
2256 -- does not necessarily appear immediately after the object declaration.
kono
parents:
diff changeset
2257
kono
parents:
diff changeset
2258 -- We can't use the freezing mechanism for this purpose, since we have
kono
parents:
diff changeset
2259 -- to elaborate the initialization expression when it is first seen (so
kono
parents:
diff changeset
2260 -- this elaboration cannot be deferred to the freeze point).
kono
parents:
diff changeset
2261
kono
parents:
diff changeset
2262 -- Find and remove generated initialization call for object, if any
kono
parents:
diff changeset
2263
kono
parents:
diff changeset
2264 Init_Call := Remove_Init_Call (Def_Id, Rep_Clause => N);
kono
parents:
diff changeset
2265
kono
parents:
diff changeset
2266 -- Any default initialization expression should be removed (e.g.
kono
parents:
diff changeset
2267 -- null defaults for access objects, zero initialization of packed
kono
parents:
diff changeset
2268 -- bit arrays). Imported objects aren't allowed to have explicit
kono
parents:
diff changeset
2269 -- initialization, so the expression must have been generated by
kono
parents:
diff changeset
2270 -- the compiler.
kono
parents:
diff changeset
2271
kono
parents:
diff changeset
2272 if No (Init_Call) and then Present (Expression (Parent (Def_Id))) then
kono
parents:
diff changeset
2273 Set_Expression (Parent (Def_Id), Empty);
kono
parents:
diff changeset
2274 end if;
kono
parents:
diff changeset
2275
kono
parents:
diff changeset
2276 -- The object may not have any initialization, but in the presence of
kono
parents:
diff changeset
2277 -- Initialize_Scalars code is inserted after then declaration, which
kono
parents:
diff changeset
2278 -- must now be removed as well. The code carries the same source
kono
parents:
diff changeset
2279 -- location as the declaration itself.
kono
parents:
diff changeset
2280
kono
parents:
diff changeset
2281 if Initialize_Scalars and then Is_Array_Type (Etype (Def_Id)) then
kono
parents:
diff changeset
2282 declare
kono
parents:
diff changeset
2283 Init : Node_Id;
kono
parents:
diff changeset
2284 Nxt : Node_Id;
kono
parents:
diff changeset
2285 begin
kono
parents:
diff changeset
2286 Init := Next (Parent (Def_Id));
kono
parents:
diff changeset
2287 while not Comes_From_Source (Init)
kono
parents:
diff changeset
2288 and then Sloc (Init) = Sloc (Def_Id)
kono
parents:
diff changeset
2289 loop
kono
parents:
diff changeset
2290 Nxt := Next (Init);
kono
parents:
diff changeset
2291 Remove (Init);
kono
parents:
diff changeset
2292 Init := Nxt;
kono
parents:
diff changeset
2293 end loop;
kono
parents:
diff changeset
2294 end;
kono
parents:
diff changeset
2295 end if;
kono
parents:
diff changeset
2296 end Undo_Initialization;
kono
parents:
diff changeset
2297
kono
parents:
diff changeset
2298 end Exp_Prag;