Mercurial > hg > CbC > CbC_gcc
comparison gcc/ada/exp_attr.adb @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
4 -- -- | 4 -- -- |
5 -- E X P _ A T T R -- | 5 -- E X P _ A T T R -- |
6 -- -- | 6 -- -- |
7 -- B o d y -- | 7 -- B o d y -- |
8 -- -- | 8 -- -- |
9 -- Copyright (C) 1992-2017, Free Software Foundation, Inc. -- | 9 -- Copyright (C) 1992-2018, Free Software Foundation, Inc. -- |
10 -- -- | 10 -- -- |
11 -- GNAT is free software; you can redistribute it and/or modify it under -- | 11 -- GNAT is free software; you can redistribute it and/or modify it under -- |
12 -- terms of the GNU General Public License as published by the Free Soft- -- | 12 -- terms of the GNU General Public License as published by the Free Soft- -- |
13 -- ware Foundation; either version 3, or (at your option) any later ver- -- | 13 -- ware Foundation; either version 3, or (at your option) any later ver- -- |
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- | 14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- |
73 ----------------------- | 73 ----------------------- |
74 -- Local Subprograms -- | 74 -- Local Subprograms -- |
75 ----------------------- | 75 ----------------------- |
76 | 76 |
77 function Build_Array_VS_Func | 77 function Build_Array_VS_Func |
78 (A_Type : Entity_Id; | 78 (Attr : Node_Id; |
79 Nod : Node_Id) return Entity_Id; | 79 Formal_Typ : Entity_Id; |
80 -- Build function to test Valid_Scalars for array type A_Type. Nod is the | 80 Array_Typ : Entity_Id; |
81 -- Valid_Scalars attribute node, used to insert the function body, and the | 81 Comp_Typ : Entity_Id) return Entity_Id; |
82 -- value returned is the entity of the constructed function body. We do not | 82 -- Validate the components of an array type by means of a function. Return |
83 -- bother to generate a separate spec for this subprogram. | 83 -- the entity of the validation function. The parameters are as follows: |
84 -- | |
85 -- * Attr - the 'Valid_Scalars attribute for which the function is | |
86 -- generated. | |
87 -- | |
88 -- * Formal_Typ - the type of the generated function's only formal | |
89 -- parameter. | |
90 -- | |
91 -- * Array_Typ - the array type whose components are to be validated | |
92 -- | |
93 -- * Comp_Typ - the component type of the array | |
84 | 94 |
85 function Build_Disp_Get_Task_Id_Call (Actual : Node_Id) return Node_Id; | 95 function Build_Disp_Get_Task_Id_Call (Actual : Node_Id) return Node_Id; |
86 -- Build a call to Disp_Get_Task_Id, passing Actual as actual parameter | 96 -- Build a call to Disp_Get_Task_Id, passing Actual as actual parameter |
87 | 97 |
88 function Build_Record_VS_Func | 98 function Build_Record_VS_Func |
89 (R_Type : Entity_Id; | 99 (Attr : Node_Id; |
90 Nod : Node_Id) return Entity_Id; | 100 Formal_Typ : Entity_Id; |
91 -- Build function to test Valid_Scalars for record type A_Type. Nod is the | 101 Rec_Typ : Entity_Id) return Entity_Id; |
92 -- Valid_Scalars attribute node, used to insert the function body, and the | 102 -- Validate the components, discriminants, and variants of a record type by |
93 -- value returned is the entity of the constructed function body. We do not | 103 -- means of a function. Return the entity of the validation function. The |
94 -- bother to generate a separate spec for this subprogram. | 104 -- parameters are as follows: |
105 -- | |
106 -- * Attr - the 'Valid_Scalars attribute for which the function is | |
107 -- generated. | |
108 -- | |
109 -- * Formal_Typ - the type of the generated function's only formal | |
110 -- parameter. | |
111 -- | |
112 -- * Rec_Typ - the record type whose internals are to be validated | |
95 | 113 |
96 procedure Compile_Stream_Body_In_Scope | 114 procedure Compile_Stream_Body_In_Scope |
97 (N : Node_Id; | 115 (N : Node_Id; |
98 Decl : Node_Id; | 116 Decl : Node_Id; |
99 Arr : Entity_Id; | 117 Arr : Entity_Id; |
217 ------------------------- | 235 ------------------------- |
218 -- Build_Array_VS_Func -- | 236 -- Build_Array_VS_Func -- |
219 ------------------------- | 237 ------------------------- |
220 | 238 |
221 function Build_Array_VS_Func | 239 function Build_Array_VS_Func |
222 (A_Type : Entity_Id; | 240 (Attr : Node_Id; |
223 Nod : Node_Id) return Entity_Id | 241 Formal_Typ : Entity_Id; |
242 Array_Typ : Entity_Id; | |
243 Comp_Typ : Entity_Id) return Entity_Id | |
224 is | 244 is |
225 Loc : constant Source_Ptr := Sloc (Nod); | 245 Loc : constant Source_Ptr := Sloc (Attr); |
226 Func_Id : constant Entity_Id := Make_Temporary (Loc, 'V'); | 246 |
227 Comp_Type : constant Entity_Id := Component_Type (A_Type); | 247 function Validate_Component |
228 Body_Stmts : List_Id; | 248 (Obj_Id : Entity_Id; |
229 Index_List : List_Id; | 249 Indexes : List_Id) return Node_Id; |
230 Formals : List_Id; | 250 -- Process a single component denoted by indexes Indexes. Obj_Id denotes |
231 | 251 -- the entity of the validation parameter. Return the check associated |
232 function Test_Component return List_Id; | 252 -- with the component. |
233 -- Create one statement to test validity of one component designated by | 253 |
234 -- a full set of indexes. Returns statement list containing test. | 254 function Validate_Dimension |
235 | 255 (Obj_Id : Entity_Id; |
236 function Test_One_Dimension (N : Int) return List_Id; | 256 Dim : Int; |
237 -- Create loop to test one dimension of the array. The single statement | 257 Indexes : List_Id) return Node_Id; |
238 -- in the loop body tests the inner dimensions if any, or else the | 258 -- Process dimension Dim of the array type. Obj_Id denotes the entity |
239 -- single component. Note that this procedure is called recursively, | 259 -- of the validation parameter. Indexes is a list where each dimension |
240 -- with N being the dimension to be initialized. A call with N greater | 260 -- deposits its loop variable, which will later identify a component. |
241 -- than the number of dimensions simply generates the component test, | 261 -- Return the loop associated with the current dimension. |
242 -- terminating the recursion. Returns statement list containing tests. | 262 |
243 | 263 ------------------------ |
244 -------------------- | 264 -- Validate_Component -- |
245 -- Test_Component -- | 265 ------------------------ |
246 -------------------- | 266 |
247 | 267 function Validate_Component |
248 function Test_Component return List_Id is | 268 (Obj_Id : Entity_Id; |
249 Comp : Node_Id; | 269 Indexes : List_Id) return Node_Id |
250 Anam : Name_Id; | 270 is |
271 Attr_Nam : Name_Id; | |
251 | 272 |
252 begin | 273 begin |
253 Comp := | 274 if Is_Scalar_Type (Comp_Typ) then |
254 Make_Indexed_Component (Loc, | 275 Attr_Nam := Name_Valid; |
255 Prefix => Make_Identifier (Loc, Name_uA), | |
256 Expressions => Index_List); | |
257 | |
258 if Is_Scalar_Type (Comp_Type) then | |
259 Anam := Name_Valid; | |
260 else | 276 else |
261 Anam := Name_Valid_Scalars; | 277 Attr_Nam := Name_Valid_Scalars; |
262 end if; | 278 end if; |
263 | 279 |
264 return New_List ( | 280 -- Generate: |
281 -- if not Array_Typ (Obj_Id) (Indexes)'Valid[_Scalars] then | |
282 -- return False; | |
283 -- end if; | |
284 | |
285 return | |
265 Make_If_Statement (Loc, | 286 Make_If_Statement (Loc, |
266 Condition => | 287 Condition => |
267 Make_Op_Not (Loc, | 288 Make_Op_Not (Loc, |
268 Right_Opnd => | 289 Right_Opnd => |
269 Make_Attribute_Reference (Loc, | 290 Make_Attribute_Reference (Loc, |
270 Attribute_Name => Anam, | 291 Prefix => |
271 Prefix => Comp)), | 292 Make_Indexed_Component (Loc, |
293 Prefix => | |
294 Unchecked_Convert_To (Array_Typ, | |
295 New_Occurrence_Of (Obj_Id, Loc)), | |
296 Expressions => Indexes), | |
297 Attribute_Name => Attr_Nam)), | |
298 | |
272 Then_Statements => New_List ( | 299 Then_Statements => New_List ( |
273 Make_Simple_Return_Statement (Loc, | 300 Make_Simple_Return_Statement (Loc, |
274 Expression => New_Occurrence_Of (Standard_False, Loc))))); | 301 Expression => New_Occurrence_Of (Standard_False, Loc)))); |
275 end Test_Component; | 302 end Validate_Component; |
276 | 303 |
277 ------------------------ | 304 ------------------------ |
278 -- Test_One_Dimension -- | 305 -- Validate_Dimension -- |
279 ------------------------ | 306 ------------------------ |
280 | 307 |
281 function Test_One_Dimension (N : Int) return List_Id is | 308 function Validate_Dimension |
309 (Obj_Id : Entity_Id; | |
310 Dim : Int; | |
311 Indexes : List_Id) return Node_Id | |
312 is | |
282 Index : Entity_Id; | 313 Index : Entity_Id; |
283 | 314 |
284 begin | 315 begin |
285 -- If all dimensions dealt with, we simply test the component | 316 -- Validate the component once all dimensions have produced their |
286 | 317 -- individual loops. |
287 if N > Number_Dimensions (A_Type) then | 318 |
288 return Test_Component; | 319 if Dim > Number_Dimensions (Array_Typ) then |
289 | 320 return Validate_Component (Obj_Id, Indexes); |
290 -- Here we generate the required loop | 321 |
322 -- Process the current dimension | |
291 | 323 |
292 else | 324 else |
293 Index := | 325 Index := |
294 Make_Defining_Identifier (Loc, New_External_Name ('J', N)); | 326 Make_Defining_Identifier (Loc, New_External_Name ('J', Dim)); |
295 | 327 |
296 Append (New_Occurrence_Of (Index, Loc), Index_List); | 328 Append_To (Indexes, New_Occurrence_Of (Index, Loc)); |
297 | 329 |
298 return New_List ( | 330 -- Generate: |
299 Make_Implicit_Loop_Statement (Nod, | 331 -- for J1 in Array_Typ (Obj_Id)'Range (1) loop |
300 Identifier => Empty, | 332 -- for JN in Array_Typ (Obj_Id)'Range (N) loop |
333 -- if not Array_Typ (Obj_Id) (Indexes)'Valid[_Scalars] | |
334 -- then | |
335 -- return False; | |
336 -- end if; | |
337 -- end loop; | |
338 -- end loop; | |
339 | |
340 return | |
341 Make_Implicit_Loop_Statement (Attr, | |
342 Identifier => Empty, | |
301 Iteration_Scheme => | 343 Iteration_Scheme => |
302 Make_Iteration_Scheme (Loc, | 344 Make_Iteration_Scheme (Loc, |
303 Loop_Parameter_Specification => | 345 Loop_Parameter_Specification => |
304 Make_Loop_Parameter_Specification (Loc, | 346 Make_Loop_Parameter_Specification (Loc, |
305 Defining_Identifier => Index, | 347 Defining_Identifier => Index, |
306 Discrete_Subtype_Definition => | 348 Discrete_Subtype_Definition => |
307 Make_Attribute_Reference (Loc, | 349 Make_Attribute_Reference (Loc, |
308 Prefix => Make_Identifier (Loc, Name_uA), | 350 Prefix => |
351 Unchecked_Convert_To (Array_Typ, | |
352 New_Occurrence_Of (Obj_Id, Loc)), | |
309 Attribute_Name => Name_Range, | 353 Attribute_Name => Name_Range, |
310 Expressions => New_List ( | 354 Expressions => New_List ( |
311 Make_Integer_Literal (Loc, N))))), | 355 Make_Integer_Literal (Loc, Dim))))), |
312 Statements => Test_One_Dimension (N + 1)), | 356 Statements => New_List ( |
313 Make_Simple_Return_Statement (Loc, | 357 Validate_Dimension (Obj_Id, Dim + 1, Indexes))); |
314 Expression => New_Occurrence_Of (Standard_True, Loc))); | 358 end if; |
315 end if; | 359 end Validate_Dimension; |
316 end Test_One_Dimension; | 360 |
361 -- Local variables | |
362 | |
363 Func_Id : constant Entity_Id := Make_Temporary (Loc, 'V'); | |
364 Indexes : constant List_Id := New_List; | |
365 Obj_Id : constant Entity_Id := Make_Temporary (Loc, 'A'); | |
366 Stmts : List_Id; | |
317 | 367 |
318 -- Start of processing for Build_Array_VS_Func | 368 -- Start of processing for Build_Array_VS_Func |
319 | 369 |
320 begin | 370 begin |
321 Index_List := New_List; | 371 Stmts := New_List (Validate_Dimension (Obj_Id, 1, Indexes)); |
322 Body_Stmts := Test_One_Dimension (1); | 372 |
323 | 373 -- Generate: |
324 -- Parameter is always (A : A_Typ) | 374 -- return True; |
325 | 375 |
326 Formals := New_List ( | 376 Append_To (Stmts, |
327 Make_Parameter_Specification (Loc, | 377 Make_Simple_Return_Statement (Loc, |
328 Defining_Identifier => Make_Defining_Identifier (Loc, Name_uA), | 378 Expression => New_Occurrence_Of (Standard_True, Loc))); |
329 In_Present => True, | 379 |
330 Out_Present => False, | 380 -- Generate: |
331 Parameter_Type => New_Occurrence_Of (A_Type, Loc))); | 381 -- function Func_Id (Obj_Id : Formal_Typ) return Boolean is |
332 | 382 -- begin |
333 -- Build body | 383 -- Stmts |
384 -- end Func_Id; | |
334 | 385 |
335 Set_Ekind (Func_Id, E_Function); | 386 Set_Ekind (Func_Id, E_Function); |
336 Set_Is_Internal (Func_Id); | 387 Set_Is_Internal (Func_Id); |
337 | 388 Set_Is_Pure (Func_Id); |
338 Insert_Action (Nod, | 389 |
390 if not Debug_Generated_Code then | |
391 Set_Debug_Info_Off (Func_Id); | |
392 end if; | |
393 | |
394 Insert_Action (Attr, | |
339 Make_Subprogram_Body (Loc, | 395 Make_Subprogram_Body (Loc, |
340 Specification => | 396 Specification => |
341 Make_Function_Specification (Loc, | 397 Make_Function_Specification (Loc, |
342 Defining_Unit_Name => Func_Id, | 398 Defining_Unit_Name => Func_Id, |
343 Parameter_Specifications => Formals, | 399 Parameter_Specifications => New_List ( |
344 Result_Definition => | 400 Make_Parameter_Specification (Loc, |
345 New_Occurrence_Of (Standard_Boolean, Loc)), | 401 Defining_Identifier => Obj_Id, |
402 In_Present => True, | |
403 Out_Present => False, | |
404 Parameter_Type => New_Occurrence_Of (Formal_Typ, Loc))), | |
405 Result_Definition => | |
406 New_Occurrence_Of (Standard_Boolean, Loc)), | |
346 Declarations => New_List, | 407 Declarations => New_List, |
347 Handled_Statement_Sequence => | 408 Handled_Statement_Sequence => |
348 Make_Handled_Sequence_Of_Statements (Loc, | 409 Make_Handled_Sequence_Of_Statements (Loc, |
349 Statements => Body_Stmts))); | 410 Statements => Stmts))); |
350 | 411 |
351 if not Debug_Generated_Code then | |
352 Set_Debug_Info_Off (Func_Id); | |
353 end if; | |
354 | |
355 Set_Is_Pure (Func_Id); | |
356 return Func_Id; | 412 return Func_Id; |
357 end Build_Array_VS_Func; | 413 end Build_Array_VS_Func; |
358 | 414 |
359 --------------------------------- | 415 --------------------------------- |
360 -- Build_Disp_Get_Task_Id_Call -- | 416 -- Build_Disp_Get_Task_Id_Call -- |
377 | 433 |
378 -------------------------- | 434 -------------------------- |
379 -- Build_Record_VS_Func -- | 435 -- Build_Record_VS_Func -- |
380 -------------------------- | 436 -------------------------- |
381 | 437 |
382 -- Generates: | |
383 | |
384 -- function _Valid_Scalars (X : T) return Boolean is | |
385 -- begin | |
386 -- -- Check discriminants | |
387 | |
388 -- if not X.D1'Valid_Scalars or else | |
389 -- not X.D2'Valid_Scalars or else | |
390 -- ... | |
391 -- then | |
392 -- return False; | |
393 -- end if; | |
394 | |
395 -- -- Check components | |
396 | |
397 -- if not X.C1'Valid_Scalars or else | |
398 -- not X.C2'Valid_Scalars or else | |
399 -- ... | |
400 -- then | |
401 -- return False; | |
402 -- end if; | |
403 | |
404 -- -- Check variant part | |
405 | |
406 -- case X.D1 is | |
407 -- when V1 => | |
408 -- if not X.C2'Valid_Scalars or else | |
409 -- not X.C3'Valid_Scalars or else | |
410 -- ... | |
411 -- then | |
412 -- return False; | |
413 -- end if; | |
414 -- ... | |
415 -- when Vn => | |
416 -- if not X.Cn'Valid_Scalars or else | |
417 -- ... | |
418 -- then | |
419 -- return False; | |
420 -- end if; | |
421 -- end case; | |
422 | |
423 -- return True; | |
424 -- end _Valid_Scalars; | |
425 | |
426 -- If the record type is an unchecked union, we can only check components | |
427 -- in the invariant part, given that there are no discriminant values to | |
428 -- select a variant. | |
429 | |
430 function Build_Record_VS_Func | 438 function Build_Record_VS_Func |
431 (R_Type : Entity_Id; | 439 (Attr : Node_Id; |
432 Nod : Node_Id) return Entity_Id | 440 Formal_Typ : Entity_Id; |
441 Rec_Typ : Entity_Id) return Entity_Id | |
433 is | 442 is |
434 Loc : constant Source_Ptr := Sloc (R_Type); | 443 -- NOTE: The logic of Build_Record_VS_Func is intentionally passive. |
435 Func_Id : constant Entity_Id := Make_Temporary (Loc, 'V'); | 444 -- It generates code only when there are components, discriminants, |
436 X : constant Entity_Id := Make_Defining_Identifier (Loc, Name_X); | 445 -- or variant parts to validate. |
437 | 446 |
438 function Make_VS_Case | 447 -- NOTE: The routines within Build_Record_VS_Func are intentionally |
439 (E : Entity_Id; | 448 -- unnested to avoid deep indentation of code. |
440 CL : Node_Id; | 449 |
441 Discrs : Elist_Id := New_Elmt_List) return List_Id; | 450 Loc : constant Source_Ptr := Sloc (Attr); |
442 -- Building block for variant valid scalars. Given a Component_List node | 451 |
443 -- CL, it generates an 'if' followed by a 'case' statement that compares | 452 procedure Validate_Component_List |
444 -- all components of local temporaries named X and Y (that are declared | 453 (Obj_Id : Entity_Id; |
445 -- as formals at some upper level). E provides the Sloc to be used for | 454 Comp_List : Node_Id; |
446 -- the generated code. | 455 Stmts : in out List_Id); |
447 | 456 -- Process all components and variant parts of component list Comp_List. |
448 function Make_VS_If | 457 -- Obj_Id denotes the entity of the validation parameter. All new code |
449 (E : Entity_Id; | 458 -- is added to list Stmts. |
450 L : List_Id) return Node_Id; | 459 |
451 -- Building block for variant validate scalars. Given the list, L, of | 460 procedure Validate_Field |
452 -- components (or discriminants) L, it generates a return statement that | 461 (Obj_Id : Entity_Id; |
453 -- compares all components of local temporaries named X and Y (that are | 462 Field : Node_Id; |
454 -- declared as formals at some upper level). E provides the Sloc to be | 463 Cond : in out Node_Id); |
455 -- used for the generated code. | 464 -- Process component declaration or discriminant specification Field. |
456 | 465 -- Obj_Id denotes the entity of the validation parameter. Cond denotes |
457 ------------------ | 466 -- an "or else" conditional expression which contains the new code (if |
458 -- Make_VS_Case -- | 467 -- any). |
459 ------------------ | 468 |
460 | 469 procedure Validate_Fields |
461 -- <Make_VS_If on shared components> | 470 (Obj_Id : Entity_Id; |
462 | 471 Fields : List_Id; |
463 -- case X.D1 is | 472 Stmts : in out List_Id); |
464 -- when V1 => <Make_VS_Case> on subcomponents | 473 -- Process component declarations or discriminant specifications in list |
465 -- ... | 474 -- Fields. Obj_Id denotes the entity of the validation parameter. All |
466 -- when Vn => <Make_VS_Case> on subcomponents | 475 -- new code is added to list Stmts. |
467 -- end case; | 476 |
468 | 477 procedure Validate_Variant |
469 function Make_VS_Case | 478 (Obj_Id : Entity_Id; |
470 (E : Entity_Id; | 479 Var : Node_Id; |
471 CL : Node_Id; | 480 Alts : in out List_Id); |
472 Discrs : Elist_Id := New_Elmt_List) return List_Id | 481 -- Process variant Var. Obj_Id denotes the entity of the validation |
482 -- parameter. Alts denotes a list of case statement alternatives which | |
483 -- contains the new code (if any). | |
484 | |
485 procedure Validate_Variant_Part | |
486 (Obj_Id : Entity_Id; | |
487 Var_Part : Node_Id; | |
488 Stmts : in out List_Id); | |
489 -- Process variant part Var_Part. Obj_Id denotes the entity of the | |
490 -- validation parameter. All new code is added to list Stmts. | |
491 | |
492 ----------------------------- | |
493 -- Validate_Component_List -- | |
494 ----------------------------- | |
495 | |
496 procedure Validate_Component_List | |
497 (Obj_Id : Entity_Id; | |
498 Comp_List : Node_Id; | |
499 Stmts : in out List_Id) | |
473 is | 500 is |
474 Loc : constant Source_Ptr := Sloc (E); | 501 Var_Part : constant Node_Id := Variant_Part (Comp_List); |
475 Result : constant List_Id := New_List; | |
476 Variant : Node_Id; | |
477 Alt_List : List_Id; | |
478 | 502 |
479 begin | 503 begin |
480 Append_To (Result, Make_VS_If (E, Component_Items (CL))); | 504 -- Validate all components |
481 | 505 |
482 if No (Variant_Part (CL)) | 506 Validate_Fields |
483 or else Is_Unchecked_Union (R_Type) | 507 (Obj_Id => Obj_Id, |
508 Fields => Component_Items (Comp_List), | |
509 Stmts => Stmts); | |
510 | |
511 -- Validate the variant part | |
512 | |
513 if Present (Var_Part) then | |
514 Validate_Variant_Part | |
515 (Obj_Id => Obj_Id, | |
516 Var_Part => Var_Part, | |
517 Stmts => Stmts); | |
518 end if; | |
519 end Validate_Component_List; | |
520 | |
521 -------------------- | |
522 -- Validate_Field -- | |
523 -------------------- | |
524 | |
525 procedure Validate_Field | |
526 (Obj_Id : Entity_Id; | |
527 Field : Node_Id; | |
528 Cond : in out Node_Id) | |
529 is | |
530 Field_Id : constant Entity_Id := Defining_Entity (Field); | |
531 Field_Nam : constant Name_Id := Chars (Field_Id); | |
532 Field_Typ : constant Entity_Id := Validated_View (Etype (Field_Id)); | |
533 Attr_Nam : Name_Id; | |
534 | |
535 begin | |
536 -- Do not process internally-generated fields. Note that checking for | |
537 -- Comes_From_Source is not correct because this will eliminate the | |
538 -- components within the corresponding record of a protected type. | |
539 | |
540 if Nam_In (Field_Nam, Name_uObject, | |
541 Name_uParent, | |
542 Name_uTag) | |
484 then | 543 then |
485 return Result; | 544 null; |
486 end if; | 545 |
487 | 546 -- Do not process fields without any scalar components |
488 Variant := First_Non_Pragma (Variants (Variant_Part (CL))); | 547 |
489 | 548 elsif not Scalar_Part_Present (Field_Typ) then |
490 if No (Variant) then | 549 null; |
491 return Result; | 550 |
492 end if; | 551 -- Otherwise the field needs to be validated. Use Make_Identifier |
493 | 552 -- rather than New_Occurrence_Of to identify the field because the |
494 Alt_List := New_List; | 553 -- wrong entity may be picked up when private types are involved. |
495 while Present (Variant) loop | 554 |
496 Append_To (Alt_List, | 555 -- Generate: |
497 Make_Case_Statement_Alternative (Loc, | 556 -- [or else] not Rec_Typ (Obj_Id).Item_Nam'Valid[_Scalars] |
498 Discrete_Choices => New_Copy_List (Discrete_Choices (Variant)), | 557 |
499 Statements => | 558 else |
500 Make_VS_Case (E, Component_List (Variant), Discrs))); | 559 if Is_Scalar_Type (Field_Typ) then |
501 Next_Non_Pragma (Variant); | 560 Attr_Nam := Name_Valid; |
561 else | |
562 Attr_Nam := Name_Valid_Scalars; | |
563 end if; | |
564 | |
565 Evolve_Or_Else (Cond, | |
566 Make_Op_Not (Loc, | |
567 Right_Opnd => | |
568 Make_Attribute_Reference (Loc, | |
569 Prefix => | |
570 Make_Selected_Component (Loc, | |
571 Prefix => | |
572 Unchecked_Convert_To (Rec_Typ, | |
573 New_Occurrence_Of (Obj_Id, Loc)), | |
574 Selector_Name => Make_Identifier (Loc, Field_Nam)), | |
575 Attribute_Name => Attr_Nam))); | |
576 end if; | |
577 end Validate_Field; | |
578 | |
579 --------------------- | |
580 -- Validate_Fields -- | |
581 --------------------- | |
582 | |
583 procedure Validate_Fields | |
584 (Obj_Id : Entity_Id; | |
585 Fields : List_Id; | |
586 Stmts : in out List_Id) | |
587 is | |
588 Cond : Node_Id; | |
589 Field : Node_Id; | |
590 | |
591 begin | |
592 -- Assume that none of the fields are eligible for verification | |
593 | |
594 Cond := Empty; | |
595 | |
596 -- Validate all fields | |
597 | |
598 Field := First_Non_Pragma (Fields); | |
599 while Present (Field) loop | |
600 Validate_Field | |
601 (Obj_Id => Obj_Id, | |
602 Field => Field, | |
603 Cond => Cond); | |
604 | |
605 Next_Non_Pragma (Field); | |
502 end loop; | 606 end loop; |
503 | 607 |
504 Append_To (Result, | 608 -- Generate: |
609 -- if not Rec_Typ (Obj_Id).Item_Nam_1'Valid[_Scalars] | |
610 -- or else not Rec_Typ (Obj_Id).Item_Nam_N'Valid[_Scalars] | |
611 -- then | |
612 -- return False; | |
613 -- end if; | |
614 | |
615 if Present (Cond) then | |
616 Append_New_To (Stmts, | |
617 Make_Implicit_If_Statement (Attr, | |
618 Condition => Cond, | |
619 Then_Statements => New_List ( | |
620 Make_Simple_Return_Statement (Loc, | |
621 Expression => New_Occurrence_Of (Standard_False, Loc))))); | |
622 end if; | |
623 end Validate_Fields; | |
624 | |
625 ---------------------- | |
626 -- Validate_Variant -- | |
627 ---------------------- | |
628 | |
629 procedure Validate_Variant | |
630 (Obj_Id : Entity_Id; | |
631 Var : Node_Id; | |
632 Alts : in out List_Id) | |
633 is | |
634 Stmts : List_Id; | |
635 | |
636 begin | |
637 -- Assume that none of the components and variants are eligible for | |
638 -- verification. | |
639 | |
640 Stmts := No_List; | |
641 | |
642 -- Validate componants | |
643 | |
644 Validate_Component_List | |
645 (Obj_Id => Obj_Id, | |
646 Comp_List => Component_List (Var), | |
647 Stmts => Stmts); | |
648 | |
649 -- Generate a null statement in case none of the components were | |
650 -- verified because this will otherwise eliminate an alternative | |
651 -- from the variant case statement and render the generated code | |
652 -- illegal. | |
653 | |
654 if No (Stmts) then | |
655 Append_New_To (Stmts, Make_Null_Statement (Loc)); | |
656 end if; | |
657 | |
658 -- Generate: | |
659 -- when Discrete_Choices => | |
660 -- Stmts | |
661 | |
662 Append_New_To (Alts, | |
663 Make_Case_Statement_Alternative (Loc, | |
664 Discrete_Choices => | |
665 New_Copy_List_Tree (Discrete_Choices (Var)), | |
666 Statements => Stmts)); | |
667 end Validate_Variant; | |
668 | |
669 --------------------------- | |
670 -- Validate_Variant_Part -- | |
671 --------------------------- | |
672 | |
673 procedure Validate_Variant_Part | |
674 (Obj_Id : Entity_Id; | |
675 Var_Part : Node_Id; | |
676 Stmts : in out List_Id) | |
677 is | |
678 Vars : constant List_Id := Variants (Var_Part); | |
679 Alts : List_Id; | |
680 Var : Node_Id; | |
681 | |
682 begin | |
683 -- Assume that none of the variants are eligible for verification | |
684 | |
685 Alts := No_List; | |
686 | |
687 -- Validate variants | |
688 | |
689 Var := First_Non_Pragma (Vars); | |
690 while Present (Var) loop | |
691 Validate_Variant | |
692 (Obj_Id => Obj_Id, | |
693 Var => Var, | |
694 Alts => Alts); | |
695 | |
696 Next_Non_Pragma (Var); | |
697 end loop; | |
698 | |
699 -- Even though individual variants may lack eligible components, the | |
700 -- alternatives must still be generated. | |
701 | |
702 pragma Assert (Present (Alts)); | |
703 | |
704 -- Generate: | |
705 -- case Rec_Typ (Obj_Id).Discriminant is | |
706 -- when Discrete_Choices_1 => | |
707 -- Stmts_1 | |
708 -- when Discrete_Choices_N => | |
709 -- Stmts_N | |
710 -- end case; | |
711 | |
712 Append_New_To (Stmts, | |
505 Make_Case_Statement (Loc, | 713 Make_Case_Statement (Loc, |
506 Expression => | 714 Expression => |
507 Make_Selected_Component (Loc, | 715 Make_Selected_Component (Loc, |
508 Prefix => Make_Identifier (Loc, Name_X), | 716 Prefix => |
509 Selector_Name => New_Copy (Name (Variant_Part (CL)))), | 717 Unchecked_Convert_To (Rec_Typ, |
510 Alternatives => Alt_List)); | 718 New_Occurrence_Of (Obj_Id, Loc)), |
511 | 719 Selector_Name => New_Copy_Tree (Name (Var_Part))), |
512 return Result; | 720 Alternatives => Alts)); |
513 end Make_VS_Case; | 721 end Validate_Variant_Part; |
514 | 722 |
515 ---------------- | 723 -- Local variables |
516 -- Make_VS_If -- | 724 |
517 ---------------- | 725 Func_Id : constant Entity_Id := Make_Temporary (Loc, 'V'); |
518 | 726 Obj_Id : constant Entity_Id := Make_Temporary (Loc, 'R'); |
519 -- Generates: | 727 Comps : Node_Id; |
520 | 728 Stmts : List_Id; |
521 -- if | 729 Typ : Entity_Id; |
522 -- not X.C1'Valid_Scalars | 730 Typ_Decl : Node_Id; |
523 -- or else | 731 Typ_Def : Node_Id; |
524 -- not X.C2'Valid_Scalars | 732 Typ_Ext : Node_Id; |
525 -- ... | 733 |
526 -- then | 734 -- Start of processing for Build_Record_VS_Func |
527 -- return False; | 735 |
528 -- end if; | 736 begin |
529 | 737 Typ := Rec_Typ; |
530 -- or a null statement if the list L is empty | 738 |
531 | 739 -- Use the root type when dealing with a class-wide type |
532 function Make_VS_If | 740 |
533 (E : Entity_Id; | 741 if Is_Class_Wide_Type (Typ) then |
534 L : List_Id) return Node_Id | 742 Typ := Root_Type (Typ); |
535 is | 743 end if; |
536 Loc : constant Source_Ptr := Sloc (E); | 744 |
537 C : Node_Id; | 745 Typ_Decl := Declaration_Node (Typ); |
538 Def_Id : Entity_Id; | 746 Typ_Def := Type_Definition (Typ_Decl); |
539 Field_Name : Name_Id; | 747 |
540 Cond : Node_Id; | 748 -- The components of a derived type are located in the extension part |
541 | 749 |
542 begin | 750 if Nkind (Typ_Def) = N_Derived_Type_Definition then |
543 if No (L) then | 751 Typ_Ext := Record_Extension_Part (Typ_Def); |
544 return Make_Null_Statement (Loc); | 752 |
545 | 753 if Present (Typ_Ext) then |
754 Comps := Component_List (Typ_Ext); | |
546 else | 755 else |
547 Cond := Empty; | 756 Comps := Empty; |
548 | 757 end if; |
549 C := First_Non_Pragma (L); | 758 |
550 while Present (C) loop | 759 -- Otherwise the components are available in the definition |
551 Def_Id := Defining_Identifier (C); | 760 |
552 Field_Name := Chars (Def_Id); | 761 else |
553 | 762 Comps := Component_List (Typ_Def); |
554 -- The tags need not be checked since they will always be valid | 763 end if; |
555 | 764 |
556 -- Note also that in the following, we use Make_Identifier for | 765 -- The code generated by this routine is as follows: |
557 -- the component names. Use of New_Occurrence_Of to identify | 766 -- |
558 -- the components would be incorrect because wrong entities for | 767 -- function Func_Id (Obj_Id : Formal_Typ) return Boolean is |
559 -- discriminants could be picked up in the private type case. | 768 -- begin |
560 | 769 -- if not Rec_Typ (Obj_Id).Discriminant_1'Valid[_Scalars] |
561 -- Don't bother with abstract parent in interface case | 770 -- or else not Rec_Typ (Obj_Id).Discriminant_N'Valid[_Scalars] |
562 | 771 -- then |
563 if Field_Name = Name_uParent | 772 -- return False; |
564 and then Is_Interface (Etype (Def_Id)) | 773 -- end if; |
565 then | 774 -- |
566 null; | 775 -- if not Rec_Typ (Obj_Id).Component_1'Valid[_Scalars] |
567 | 776 -- or else not Rec_Typ (Obj_Id).Component_N'Valid[_Scalars] |
568 -- Don't bother with tag, always valid, and not scalar anyway | 777 -- then |
569 | 778 -- return False; |
570 elsif Field_Name = Name_uTag then | 779 -- end if; |
571 null; | 780 -- |
572 | 781 -- case Discriminant_1 is |
573 elsif Ekind (Def_Id) = E_Discriminant | 782 -- when Choice_1 => |
574 and then Is_Unchecked_Union (R_Type) | 783 -- if not Rec_Typ (Obj_Id).Component_1'Valid[_Scalars] |
575 then | 784 -- or else not Rec_Typ (Obj_Id).Component_N'Valid[_Scalars] |
576 null; | 785 -- then |
577 | 786 -- return False; |
578 -- Don't bother with component with no scalar components | 787 -- end if; |
579 | 788 -- |
580 elsif not Scalar_Part_Present (Etype (Def_Id)) then | 789 -- case Discriminant_N is |
581 null; | 790 -- ... |
582 | 791 -- when Choice_N => |
583 -- Normal case, generate Valid_Scalars attribute reference | 792 -- ... |
584 | 793 -- end case; |
585 else | 794 -- |
586 Evolve_Or_Else (Cond, | 795 -- return True; |
587 Make_Op_Not (Loc, | 796 -- end Func_Id; |
588 Right_Opnd => | 797 |
589 Make_Attribute_Reference (Loc, | 798 -- Assume that the record type lacks eligible components, discriminants, |
590 Prefix => | 799 -- and variant parts. |
591 Make_Selected_Component (Loc, | 800 |
592 Prefix => | 801 Stmts := No_List; |
593 Make_Identifier (Loc, Name_X), | 802 |
594 Selector_Name => | 803 -- Validate the discriminants |
595 Make_Identifier (Loc, Field_Name)), | 804 |
596 Attribute_Name => Name_Valid_Scalars))); | 805 if not Is_Unchecked_Union (Rec_Typ) then |
597 end if; | 806 Validate_Fields |
598 | 807 (Obj_Id => Obj_Id, |
599 Next_Non_Pragma (C); | 808 Fields => Discriminant_Specifications (Typ_Decl), |
600 end loop; | 809 Stmts => Stmts); |
601 | 810 end if; |
602 if No (Cond) then | 811 |
603 return Make_Null_Statement (Loc); | 812 -- Validate the components and variant parts |
604 | 813 |
605 else | 814 Validate_Component_List |
606 return | 815 (Obj_Id => Obj_Id, |
607 Make_Implicit_If_Statement (E, | 816 Comp_List => Comps, |
608 Condition => Cond, | 817 Stmts => Stmts); |
609 Then_Statements => New_List ( | 818 |
610 Make_Simple_Return_Statement (Loc, | 819 -- Generate: |
611 Expression => | 820 -- return True; |
612 New_Occurrence_Of (Standard_False, Loc)))); | 821 |
613 end if; | 822 Append_New_To (Stmts, |
614 end if; | |
615 end Make_VS_If; | |
616 | |
617 -- Local variables | |
618 | |
619 Def : constant Node_Id := Parent (R_Type); | |
620 Comps : constant Node_Id := Component_List (Type_Definition (Def)); | |
621 Stmts : constant List_Id := New_List; | |
622 Pspecs : constant List_Id := New_List; | |
623 | |
624 -- Start of processing for Build_Record_VS_Func | |
625 | |
626 begin | |
627 Append_To (Pspecs, | |
628 Make_Parameter_Specification (Loc, | |
629 Defining_Identifier => X, | |
630 Parameter_Type => New_Occurrence_Of (R_Type, Loc))); | |
631 | |
632 Append_To (Stmts, | |
633 Make_VS_If (R_Type, Discriminant_Specifications (Def))); | |
634 Append_List_To (Stmts, Make_VS_Case (R_Type, Comps)); | |
635 | |
636 Append_To (Stmts, | |
637 Make_Simple_Return_Statement (Loc, | 823 Make_Simple_Return_Statement (Loc, |
638 Expression => New_Occurrence_Of (Standard_True, Loc))); | 824 Expression => New_Occurrence_Of (Standard_True, Loc))); |
639 | 825 |
640 Insert_Action (Nod, | 826 -- Generate: |
827 -- function Func_Id (Obj_Id : Formal_Typ) return Boolean is | |
828 -- begin | |
829 -- Stmts | |
830 -- end Func_Id; | |
831 | |
832 Set_Ekind (Func_Id, E_Function); | |
833 Set_Is_Internal (Func_Id); | |
834 Set_Is_Pure (Func_Id); | |
835 | |
836 if not Debug_Generated_Code then | |
837 Set_Debug_Info_Off (Func_Id); | |
838 end if; | |
839 | |
840 Insert_Action (Attr, | |
641 Make_Subprogram_Body (Loc, | 841 Make_Subprogram_Body (Loc, |
642 Specification => | 842 Specification => |
643 Make_Function_Specification (Loc, | 843 Make_Function_Specification (Loc, |
644 Defining_Unit_Name => Func_Id, | 844 Defining_Unit_Name => Func_Id, |
645 Parameter_Specifications => Pspecs, | 845 Parameter_Specifications => New_List ( |
646 Result_Definition => New_Occurrence_Of (Standard_Boolean, Loc)), | 846 Make_Parameter_Specification (Loc, |
847 Defining_Identifier => Obj_Id, | |
848 Parameter_Type => New_Occurrence_Of (Formal_Typ, Loc))), | |
849 Result_Definition => | |
850 New_Occurrence_Of (Standard_Boolean, Loc)), | |
647 Declarations => New_List, | 851 Declarations => New_List, |
648 Handled_Statement_Sequence => | 852 Handled_Statement_Sequence => |
649 Make_Handled_Sequence_Of_Statements (Loc, Statements => Stmts)), | 853 Make_Handled_Sequence_Of_Statements (Loc, |
854 Statements => Stmts)), | |
650 Suppress => Discriminant_Check); | 855 Suppress => Discriminant_Check); |
651 | 856 |
652 if not Debug_Generated_Code then | |
653 Set_Debug_Info_Off (Func_Id); | |
654 end if; | |
655 | |
656 Set_Is_Pure (Func_Id); | |
657 return Func_Id; | 857 return Func_Id; |
658 end Build_Record_VS_Func; | 858 end Build_Record_VS_Func; |
659 | 859 |
660 ---------------------------------- | 860 ---------------------------------- |
661 -- Compile_Stream_Body_In_Scope -- | 861 -- Compile_Stream_Body_In_Scope -- |
1052 | 1252 |
1053 Pref : constant Node_Id := Prefix (N); | 1253 Pref : constant Node_Id := Prefix (N); |
1054 Base_Typ : constant Entity_Id := Base_Type (Etype (Pref)); | 1254 Base_Typ : constant Entity_Id := Base_Type (Etype (Pref)); |
1055 Exprs : constant List_Id := Expressions (N); | 1255 Exprs : constant List_Id := Expressions (N); |
1056 Aux_Decl : Node_Id; | 1256 Aux_Decl : Node_Id; |
1057 Blk : Node_Id; | 1257 Blk : Node_Id := Empty; |
1058 Decls : List_Id; | 1258 Decls : List_Id; |
1059 Installed : Boolean; | 1259 Installed : Boolean; |
1060 Loc : Source_Ptr; | 1260 Loc : Source_Ptr; |
1061 Loop_Id : Entity_Id; | 1261 Loop_Id : Entity_Id; |
1062 Loop_Stmt : Node_Id; | 1262 Loop_Stmt : Node_Id; |
1939 | 2139 |
1940 Extra := New_Formal; | 2140 Extra := New_Formal; |
1941 Next_Formal (Old_Formal); | 2141 Next_Formal (Old_Formal); |
1942 exit when No (Old_Formal); | 2142 exit when No (Old_Formal); |
1943 | 2143 |
1944 Set_Next_Entity (New_Formal, | 2144 Link_Entities (New_Formal, New_Copy (Old_Formal)); |
1945 New_Copy (Old_Formal)); | 2145 Next_Entity (New_Formal); |
1946 Next_Entity (New_Formal); | |
1947 end loop; | 2146 end loop; |
1948 | 2147 |
1949 Set_Next_Entity (New_Formal, Empty); | 2148 Unlink_Next_Entity (New_Formal); |
1950 Set_Last_Entity (Subp_Typ, Extra); | 2149 Set_Last_Entity (Subp_Typ, Extra); |
1951 end if; | 2150 end if; |
1952 | 2151 |
1953 -- Now that the explicit formals have been duplicated, | 2152 -- Now that the explicit formals have been duplicated, |
1954 -- any extra formals needed by the subprogram must be | 2153 -- any extra formals needed by the subprogram must be |
2879 end loop; | 3078 end loop; |
2880 | 3079 |
2881 -- Protected case | 3080 -- Protected case |
2882 | 3081 |
2883 if Is_Protected_Type (Conctyp) then | 3082 if Is_Protected_Type (Conctyp) then |
3083 | |
3084 -- No need to transform 'Count into a function call if the current | |
3085 -- scope has been eliminated. In this case such transformation is | |
3086 -- also not viable because the enclosing protected object is not | |
3087 -- available. | |
3088 | |
3089 if Is_Eliminated (Current_Scope) then | |
3090 return; | |
3091 end if; | |
3092 | |
2884 case Corresponding_Runtime_Package (Conctyp) is | 3093 case Corresponding_Runtime_Package (Conctyp) is |
2885 when System_Tasking_Protected_Objects_Entries => | 3094 when System_Tasking_Protected_Objects_Entries => |
2886 Name := New_Occurrence_Of (RTE (RE_Protected_Count), Loc); | 3095 Name := New_Occurrence_Of (RTE (RE_Protected_Count), Loc); |
2887 | 3096 |
2888 Call := | 3097 Call := |
3428 | 3637 |
3429 -- We do all the required analysis of the conversion here, because we do | 3638 -- We do all the required analysis of the conversion here, because we do |
3430 -- not want this to go through the fixed-point conversion circuits. Note | 3639 -- not want this to go through the fixed-point conversion circuits. Note |
3431 -- that the back end always treats fixed-point as equivalent to the | 3640 -- that the back end always treats fixed-point as equivalent to the |
3432 -- corresponding integer type anyway. | 3641 -- corresponding integer type anyway. |
3642 -- However, in order to remove the handling of Do_Range_Check from the | |
3643 -- backend, we force the generation of a check on the result by | |
3644 -- setting the result type appropriately. Apply_Conversion_Checks | |
3645 -- will generate the required expansion. | |
3433 | 3646 |
3434 when Attribute_Fixed_Value | 3647 when Attribute_Fixed_Value |
3435 | Attribute_Integer_Value | 3648 | Attribute_Integer_Value |
3436 => | 3649 => |
3437 Rewrite (N, | 3650 Rewrite (N, |
3438 Make_Type_Conversion (Loc, | 3651 Make_Type_Conversion (Loc, |
3439 Subtype_Mark => New_Occurrence_Of (Entity (Pref), Loc), | 3652 Subtype_Mark => New_Occurrence_Of (Entity (Pref), Loc), |
3440 Expression => Relocate_Node (First (Exprs)))); | 3653 Expression => Relocate_Node (First (Exprs)))); |
3441 Set_Etype (N, Entity (Pref)); | 3654 |
3655 -- Indicate that the result of the conversion may require a | |
3656 -- range check (see below); | |
3657 | |
3658 Set_Etype (N, Base_Type (Entity (Pref))); | |
3442 Set_Analyzed (N); | 3659 Set_Analyzed (N); |
3443 | 3660 |
3444 -- Note: it might appear that a properly analyzed unchecked | 3661 -- Note: it might appear that a properly analyzed unchecked |
3445 -- conversion would be just fine here, but that's not the case, | 3662 -- conversion would be just fine here, but that's not the case, |
3446 -- since the full range checks performed by the following call | 3663 -- since the full range checks performed by the following code |
3447 -- are critical. | 3664 -- are critical. |
3448 | 3665 -- Given that Fixed-point conversions are not further expanded |
3449 Apply_Type_Conversion_Checks (N); | 3666 -- to prevent the involvement of real type operations we have to |
3667 -- construct two checks explicitly: one on the operand, and one | |
3668 -- on the result. This used to be done in part in the back-end, | |
3669 -- but for other targets (E.g. LLVM) it is preferable to create | |
3670 -- the tests in full in the front-end. | |
3671 | |
3672 if Is_Fixed_Point_Type (Etype (N)) then | |
3673 declare | |
3674 Loc : constant Source_Ptr := Sloc (N); | |
3675 Equiv_T : constant Entity_Id := Make_Temporary (Loc, 'T', N); | |
3676 Expr : constant Node_Id := Expression (N); | |
3677 Fst : constant Entity_Id := Root_Type (Etype (N)); | |
3678 Decl : Node_Id; | |
3679 | |
3680 begin | |
3681 Decl := | |
3682 Make_Full_Type_Declaration (Sloc (N), | |
3683 Defining_Identifier => Equiv_T, | |
3684 Type_Definition => | |
3685 Make_Signed_Integer_Type_Definition (Loc, | |
3686 Low_Bound => | |
3687 Make_Integer_Literal (Loc, | |
3688 Intval => | |
3689 Corresponding_Integer_Value | |
3690 (Type_Low_Bound (Fst))), | |
3691 High_Bound => | |
3692 Make_Integer_Literal (Loc, | |
3693 Intval => | |
3694 Corresponding_Integer_Value | |
3695 (Type_High_Bound (Fst))))); | |
3696 Insert_Action (N, Decl); | |
3697 | |
3698 -- Verify that the conversion is possible | |
3699 | |
3700 Generate_Range_Check (Expr, Equiv_T, CE_Overflow_Check_Failed); | |
3701 | |
3702 -- and verify that the result is in range | |
3703 | |
3704 Generate_Range_Check (N, Etype (N), CE_Range_Check_Failed); | |
3705 end; | |
3706 end if; | |
3450 | 3707 |
3451 ----------- | 3708 ----------- |
3452 -- Floor -- | 3709 -- Floor -- |
3453 ----------- | 3710 ----------- |
3454 | 3711 |
6499 -- The code for valid is dependent on the particular types involved. | 6756 -- The code for valid is dependent on the particular types involved. |
6500 -- See separate sections below for the generated code in each case. | 6757 -- See separate sections below for the generated code in each case. |
6501 | 6758 |
6502 when Attribute_Valid => Valid : declare | 6759 when Attribute_Valid => Valid : declare |
6503 Btyp : Entity_Id := Base_Type (Ptyp); | 6760 Btyp : Entity_Id := Base_Type (Ptyp); |
6504 Tst : Node_Id; | |
6505 | 6761 |
6506 Save_Validity_Checks_On : constant Boolean := Validity_Checks_On; | 6762 Save_Validity_Checks_On : constant Boolean := Validity_Checks_On; |
6507 -- Save the validity checking mode. We always turn off validity | 6763 -- Save the validity checking mode. We always turn off validity |
6508 -- checking during process of 'Valid since this is one place | 6764 -- checking during process of 'Valid since this is one place |
6509 -- where we do not want the implicit validity checks to intefere | 6765 -- where we do not want the implicit validity checks to interfere |
6510 -- with the explicit validity check that the programmer is doing. | 6766 -- with the explicit validity check that the programmer is doing. |
6511 | 6767 |
6512 function Make_Range_Test return Node_Id; | 6768 function Make_Range_Test return Node_Id; |
6513 -- Build the code for a range test of the form | 6769 -- Build the code for a range test of the form |
6514 -- Btyp!(Pref) in Btyp!(Ptyp'First) .. Btyp!(Ptyp'Last) | 6770 -- Btyp!(Pref) in Btyp!(Ptyp'First) .. Btyp!(Ptyp'Last) |
6563 Make_Attribute_Reference (Loc, | 6819 Make_Attribute_Reference (Loc, |
6564 Prefix => New_Occurrence_Of (Ptyp, Loc), | 6820 Prefix => New_Occurrence_Of (Ptyp, Loc), |
6565 Attribute_Name => Name_Last)))); | 6821 Attribute_Name => Name_Last)))); |
6566 end Make_Range_Test; | 6822 end Make_Range_Test; |
6567 | 6823 |
6824 -- Local variables | |
6825 | |
6826 Tst : Node_Id; | |
6827 | |
6568 -- Start of processing for Attribute_Valid | 6828 -- Start of processing for Attribute_Valid |
6569 | 6829 |
6570 begin | 6830 begin |
6571 -- Do not expand sourced code 'Valid reference in CodePeer mode, | 6831 -- Do not expand sourced code 'Valid reference in CodePeer mode, |
6572 -- will be handled by the back-end directly. | 6832 -- will be handled by the back-end directly. |
6891 ------------------- | 7151 ------------------- |
6892 -- Valid_Scalars -- | 7152 -- Valid_Scalars -- |
6893 ------------------- | 7153 ------------------- |
6894 | 7154 |
6895 when Attribute_Valid_Scalars => Valid_Scalars : declare | 7155 when Attribute_Valid_Scalars => Valid_Scalars : declare |
6896 Ftyp : Entity_Id; | 7156 Val_Typ : constant Entity_Id := Validated_View (Ptyp); |
7157 Comp_Typ : Entity_Id; | |
7158 Expr : Node_Id; | |
6897 | 7159 |
6898 begin | 7160 begin |
6899 if Present (Underlying_Type (Ptyp)) then | 7161 -- Assume that the prefix does not need validation |
6900 Ftyp := Underlying_Type (Ptyp); | 7162 |
6901 else | 7163 Expr := Empty; |
6902 Ftyp := Ptyp; | 7164 |
6903 end if; | 7165 -- Attribute 'Valid_Scalars is not supported on private tagged types |
6904 | 7166 |
6905 -- Replace by True if no scalar parts | 7167 if Is_Private_Type (Ptyp) and then Is_Tagged_Type (Ptyp) then |
6906 | 7168 null; |
6907 if not Scalar_Part_Present (Ftyp) then | 7169 |
6908 Rewrite (N, New_Occurrence_Of (Standard_True, Loc)); | 7170 -- Attribute 'Valid_Scalars evaluates to True when the type lacks |
6909 | 7171 -- scalars. |
6910 -- For scalar types, Valid_Scalars is the same as Valid | 7172 |
6911 | 7173 elsif not Scalar_Part_Present (Val_Typ) then |
6912 elsif Is_Scalar_Type (Ftyp) then | 7174 null; |
6913 Rewrite (N, | 7175 |
7176 -- Attribute 'Valid_Scalars is the same as attribute 'Valid when the | |
7177 -- validated type is a scalar type. Generate: | |
7178 | |
7179 -- Val_Typ (Pref)'Valid | |
7180 | |
7181 elsif Is_Scalar_Type (Val_Typ) then | |
7182 Expr := | |
6914 Make_Attribute_Reference (Loc, | 7183 Make_Attribute_Reference (Loc, |
6915 Attribute_Name => Name_Valid, | 7184 Prefix => |
6916 Prefix => Pref)); | 7185 Unchecked_Convert_To (Val_Typ, New_Copy_Tree (Pref)), |
6917 | 7186 Attribute_Name => Name_Valid); |
6918 -- For array types, we construct a function that determines if there | 7187 |
6919 -- are any non-valid scalar subcomponents, and call the function. | 7188 -- Validate the scalar components of an array by iterating over all |
6920 -- We only do this for arrays whose component type needs checking | 7189 -- dimensions of the array while checking individual components. |
6921 | 7190 |
6922 elsif Is_Array_Type (Ftyp) | 7191 elsif Is_Array_Type (Val_Typ) then |
6923 and then Scalar_Part_Present (Component_Type (Ftyp)) | 7192 Comp_Typ := Validated_View (Component_Type (Val_Typ)); |
6924 then | 7193 |
6925 Rewrite (N, | 7194 if Scalar_Part_Present (Comp_Typ) then |
7195 Expr := | |
7196 Make_Function_Call (Loc, | |
7197 Name => | |
7198 New_Occurrence_Of | |
7199 (Build_Array_VS_Func | |
7200 (Attr => N, | |
7201 Formal_Typ => Ptyp, | |
7202 Array_Typ => Val_Typ, | |
7203 Comp_Typ => Comp_Typ), | |
7204 Loc), | |
7205 Parameter_Associations => New_List (Pref)); | |
7206 end if; | |
7207 | |
7208 -- Validate the scalar components, discriminants of a record type by | |
7209 -- examining the structure of a record type. | |
7210 | |
7211 elsif Is_Record_Type (Val_Typ) then | |
7212 Expr := | |
6926 Make_Function_Call (Loc, | 7213 Make_Function_Call (Loc, |
6927 Name => | 7214 Name => |
6928 New_Occurrence_Of (Build_Array_VS_Func (Ftyp, N), Loc), | 7215 New_Occurrence_Of |
6929 Parameter_Associations => New_List (Pref))); | 7216 (Build_Record_VS_Func |
6930 | 7217 (Attr => N, |
6931 -- For record types, we construct a function that determines if there | 7218 Formal_Typ => Ptyp, |
6932 -- are any non-valid scalar subcomponents, and call the function. | 7219 Rec_Typ => Val_Typ), |
6933 | 7220 Loc), |
6934 elsif Is_Record_Type (Ftyp) | 7221 Parameter_Associations => New_List (Pref)); |
6935 and then Present (Declaration_Node (Ftyp)) | 7222 end if; |
6936 and then Nkind (Type_Definition (Declaration_Node (Ftyp))) = | 7223 |
6937 N_Record_Definition | 7224 -- Default the attribute to True when the type of the prefix does not |
6938 then | 7225 -- need validation. |
6939 Rewrite (N, | 7226 |
6940 Make_Function_Call (Loc, | 7227 if No (Expr) then |
6941 Name => | 7228 Expr := New_Occurrence_Of (Standard_True, Loc); |
6942 New_Occurrence_Of (Build_Record_VS_Func (Ftyp, N), Loc), | 7229 end if; |
6943 Parameter_Associations => New_List (Pref))); | 7230 |
6944 | 7231 Rewrite (N, Expr); |
6945 -- Other record types or types with discriminants | |
6946 | |
6947 elsif Is_Record_Type (Ftyp) or else Has_Discriminants (Ptyp) then | |
6948 | |
6949 -- Build expression with list of equality tests | |
6950 | |
6951 declare | |
6952 C : Entity_Id; | |
6953 X : Node_Id; | |
6954 A : Name_Id; | |
6955 | |
6956 begin | |
6957 X := New_Occurrence_Of (Standard_True, Loc); | |
6958 C := First_Component_Or_Discriminant (Ptyp); | |
6959 while Present (C) loop | |
6960 if not Scalar_Part_Present (Etype (C)) then | |
6961 goto Continue; | |
6962 elsif Is_Scalar_Type (Etype (C)) then | |
6963 A := Name_Valid; | |
6964 else | |
6965 A := Name_Valid_Scalars; | |
6966 end if; | |
6967 | |
6968 X := | |
6969 Make_And_Then (Loc, | |
6970 Left_Opnd => X, | |
6971 Right_Opnd => | |
6972 Make_Attribute_Reference (Loc, | |
6973 Attribute_Name => A, | |
6974 Prefix => | |
6975 Make_Selected_Component (Loc, | |
6976 Prefix => | |
6977 Duplicate_Subexpr (Pref, Name_Req => True), | |
6978 Selector_Name => | |
6979 New_Occurrence_Of (C, Loc)))); | |
6980 <<Continue>> | |
6981 Next_Component_Or_Discriminant (C); | |
6982 end loop; | |
6983 | |
6984 Rewrite (N, X); | |
6985 end; | |
6986 | |
6987 -- For all other types, result is True | |
6988 | |
6989 else | |
6990 Rewrite (N, New_Occurrence_Of (Standard_Boolean, Loc)); | |
6991 end if; | |
6992 | |
6993 -- Result is always boolean, but never static | |
6994 | |
6995 Analyze_And_Resolve (N, Standard_Boolean); | 7232 Analyze_And_Resolve (N, Standard_Boolean); |
6996 Set_Is_Static_Expression (N, False); | 7233 Set_Is_Static_Expression (N, False); |
6997 end Valid_Scalars; | 7234 end Valid_Scalars; |
6998 | 7235 |
6999 ----------- | 7236 ----------- |
8272 end Is_GCC_Target; | 8509 end Is_GCC_Target; |
8273 | 8510 |
8274 -- Start of processing for Is_Inline_Floating_Point_Attribute | 8511 -- Start of processing for Is_Inline_Floating_Point_Attribute |
8275 | 8512 |
8276 begin | 8513 begin |
8277 -- Machine and Model can be expanded by the GCC and AAMP back ends only | 8514 -- Machine and Model can be expanded by the GCC back end only |
8278 | 8515 |
8279 if Id = Attribute_Machine or else Id = Attribute_Model then | 8516 if Id = Attribute_Machine or else Id = Attribute_Model then |
8280 return Is_GCC_Target; | 8517 return Is_GCC_Target; |
8281 | 8518 |
8282 -- Remaining cases handled by all back ends are Rounding and Truncation | 8519 -- Remaining cases handled by all back ends are Rounding and Truncation |