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