]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/ada/exp_ch13.adb
[Ada] Variable-sized node types
[thirdparty/gcc.git] / gcc / ada / exp_ch13.adb
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- E X P _ C H 1 3 --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2021, Free Software Foundation, Inc. --
10 -- --
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- --
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- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
20 -- --
21 -- GNAT was originally developed by the GNAT team at New York University. --
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
23 -- --
24 ------------------------------------------------------------------------------
25
26 with Atree; use Atree;
27 with Checks; use Checks;
28 with Einfo; use Einfo;
29 with Einfo.Entities; use Einfo.Entities;
30 with Einfo.Utils; use Einfo.Utils;
31 with Exp_Ch3; use Exp_Ch3;
32 with Exp_Ch6;
33 with Exp_Imgv; use Exp_Imgv;
34 with Exp_Tss; use Exp_Tss;
35 with Exp_Util; use Exp_Util;
36 with Freeze; use Freeze;
37 with Namet; use Namet;
38 with Nlists; use Nlists;
39 with Nmake; use Nmake;
40 with Opt; use Opt;
41 with Restrict; use Restrict;
42 with Rident; use Rident;
43 with Rtsfind; use Rtsfind;
44 with Sem; use Sem;
45 with Sem_Aux; use Sem_Aux;
46 with Sem_Ch7; use Sem_Ch7;
47 with Sem_Ch8; use Sem_Ch8;
48 with Sem_Eval; use Sem_Eval;
49 with Sem_Util; use Sem_Util;
50 with Sinfo; use Sinfo;
51 with Sinfo.Nodes; use Sinfo.Nodes;
52 with Sinfo.Utils; use Sinfo.Utils;
53 with Snames; use Snames;
54 with Tbuild; use Tbuild;
55 with Uintp; use Uintp;
56 with Validsw; use Validsw;
57
58 package body Exp_Ch13 is
59
60 ------------------------------------------
61 -- Expand_N_Attribute_Definition_Clause --
62 ------------------------------------------
63
64 -- Expansion action depends on attribute involved
65
66 procedure Expand_N_Attribute_Definition_Clause (N : Node_Id) is
67 Loc : constant Source_Ptr := Sloc (N);
68 Exp : constant Node_Id := Expression (N);
69 Ent : Entity_Id;
70 V : Node_Id;
71
72 begin
73 Ent := Entity (Name (N));
74
75 if Is_Type (Ent) then
76 Ent := Underlying_Type (Ent);
77 end if;
78
79 case Get_Attribute_Id (Chars (N)) is
80
81 -------------
82 -- Address --
83 -------------
84
85 when Attribute_Address =>
86
87 -- If there is an initialization which did not come from the
88 -- source program, then it is an artifact of our expansion, and we
89 -- suppress it. The case we are most concerned about here is the
90 -- initialization of a packed array to all false, which seems
91 -- inappropriate for variable to which an address clause is
92 -- applied. The expression may itself have been rewritten if the
93 -- type is packed array, so we need to examine whether the
94 -- original node is in the source. An exception though is the case
95 -- of an access variable which is default initialized to null, and
96 -- such initialization is retained.
97
98 -- Furthermore, if the initialization is the equivalent aggregate
99 -- of the type initialization procedure, it replaces an implicit
100 -- call to the init proc, and must be respected. Note that for
101 -- packed types we do not build equivalent aggregates.
102
103 -- Also, if Init_Or_Norm_Scalars applies, then we need to retain
104 -- any default initialization for objects of scalar types and
105 -- types with scalar components. Normally a composite type will
106 -- have an init_proc in the presence of Init_Or_Norm_Scalars,
107 -- so when that flag is set we have just have to do a test for
108 -- scalar and string types (the predefined string types such as
109 -- String and Wide_String don't have an init_proc).
110
111 declare
112 Decl : constant Node_Id := Declaration_Node (Ent);
113 Typ : constant Entity_Id := Etype (Ent);
114
115 begin
116 if Nkind (Decl) = N_Object_Declaration
117 and then Present (Expression (Decl))
118 and then Nkind (Expression (Decl)) /= N_Null
119 and then
120 not Comes_From_Source (Original_Node (Expression (Decl)))
121 then
122 if Present (Base_Init_Proc (Typ))
123 and then
124 Present (Static_Initialization (Base_Init_Proc (Typ)))
125 then
126 null;
127
128 elsif Init_Or_Norm_Scalars
129 and then (Is_Scalar_Type (Typ)
130 or else Is_String_Type (Typ))
131 then
132 null;
133
134 else
135 Set_Expression (Decl, Empty);
136 end if;
137
138 -- An object declaration to which an address clause applies
139 -- has a delayed freeze, but the address expression itself
140 -- must be elaborated at the point it appears. If the object
141 -- is controlled, additional checks apply elsewhere.
142 -- If the attribute comes from an aspect specification it
143 -- is being elaborated at the freeze point and side effects
144 -- need not be removed (and shouldn't, if the expression
145 -- depends on other entities that have delayed freeze).
146 -- This is another consequence of the delayed analysis of
147 -- aspects, and a real semantic difference.
148
149 elsif Nkind (Decl) = N_Object_Declaration
150 and then not Needs_Constant_Address (Decl, Typ)
151 and then not From_Aspect_Specification (N)
152 then
153 Remove_Side_Effects (Exp);
154 end if;
155 end;
156
157 ---------------
158 -- Alignment --
159 ---------------
160
161 when Attribute_Alignment =>
162
163 -- As required by Gigi, we guarantee that the operand is an
164 -- integer literal (this simplifies things in Gigi).
165
166 if Nkind (Exp) /= N_Integer_Literal then
167 Rewrite (Exp, Make_Integer_Literal (Loc, Expr_Value (Exp)));
168 end if;
169
170 -- A complex case arises if the alignment clause applies to an
171 -- unconstrained object initialized with a function call. The
172 -- result of the call is placed on the secondary stack, and the
173 -- declaration is rewritten as a renaming of a dereference, which
174 -- fails expansion. We must introduce a temporary and assign its
175 -- value to the existing entity.
176
177 if Nkind (Parent (Ent)) = N_Object_Renaming_Declaration
178 and then not Is_Entity_Name (Renamed_Object (Ent))
179 then
180 declare
181 Decl : constant Node_Id := Parent (Ent);
182 Loc : constant Source_Ptr := Sloc (N);
183 Temp : constant Entity_Id := Make_Temporary (Loc, 'T');
184
185 New_Decl : Node_Id;
186
187 begin
188 -- Replace entity with temporary and reanalyze
189
190 Set_Defining_Identifier (Decl, Temp);
191 Set_Analyzed (Decl, False);
192 Analyze (Decl);
193
194 -- Introduce new declaration for entity but do not reanalyze
195 -- because entity is already in scope. Type and expression
196 -- are already resolved.
197
198 New_Decl :=
199 Make_Object_Declaration (Loc,
200 Defining_Identifier => Ent,
201 Object_Definition =>
202 New_Occurrence_Of (Etype (Ent), Loc),
203 Expression => New_Occurrence_Of (Temp, Loc));
204
205 Set_Renamed_Object (Ent, Empty);
206 Insert_After (Decl, New_Decl);
207 Set_Analyzed (Decl);
208 end;
209 end if;
210
211 ------------------
212 -- Storage_Size --
213 ------------------
214
215 when Attribute_Storage_Size =>
216
217 -- If the type is a task type, then assign the value of the
218 -- storage size to the Size variable associated with the task.
219 -- Insert the assignment right after the declaration of the Size
220 -- variable.
221
222 -- Generate:
223
224 -- task_typeZ := expression
225
226 if Ekind (Ent) = E_Task_Type then
227
228 declare
229 Assign : Node_Id;
230 begin
231 Assign :=
232 Make_Assignment_Statement (Loc,
233 Name =>
234 New_Occurrence_Of (Storage_Size_Variable (Ent), Loc),
235 Expression =>
236 Convert_To (RTE (RE_Size_Type), Expression (N)));
237
238 -- If the clause is not generated by an aspect, insert
239 -- the assignment here. Freezing rules ensure that this
240 -- is safe, or clause will have been rejected already.
241
242 if Is_List_Member (N) then
243 Insert_After (N, Assign);
244
245 -- Otherwise, insert assignment after task declaration.
246
247 else
248 Insert_After
249 (Parent (Storage_Size_Variable (Entity (N))), Assign);
250 end if;
251
252 Analyze (Assign);
253 end;
254
255 -- For Storage_Size for an access type, create a variable to hold
256 -- the value of the specified size with name typeV and expand an
257 -- assignment statement to initialize this value.
258
259 elsif Is_Access_Type (Ent) then
260
261 -- We don't need the variable for a storage size of zero
262
263 if not No_Pool_Assigned (Ent) then
264 V :=
265 Make_Defining_Identifier (Loc,
266 Chars => New_External_Name (Chars (Ent), 'V'));
267
268 -- Insert the declaration of the object. If the expression
269 -- is not static it may depend on some other type that is
270 -- not frozen yet, so attach the declaration that captures
271 -- the value of the expression to the actions of the freeze
272 -- node of the current type.
273
274 declare
275 Decl : constant Node_Id :=
276 Make_Object_Declaration (Loc,
277 Defining_Identifier => V,
278 Object_Definition =>
279 New_Occurrence_Of (RTE (RE_Storage_Offset), Loc),
280 Expression =>
281 Convert_To
282 (RTE (RE_Storage_Offset), Expression (N)));
283 begin
284 if not Is_OK_Static_Expression (Expression (N))
285 and then Present (Freeze_Node (Ent))
286 then
287 if No (Actions (Freeze_Node (Ent))) then
288 Set_Actions (Freeze_Node (Ent), New_List (Decl));
289 else
290 Append (Decl, Actions (Freeze_Node (Ent)));
291 end if;
292
293 else
294 Insert_Action (N, Decl);
295 end if;
296 end;
297
298 Set_Storage_Size_Variable (Ent, Entity_Id (V));
299 end if;
300 end if;
301
302 -- Other attributes require no expansion
303
304 when others =>
305 null;
306 end case;
307 end Expand_N_Attribute_Definition_Clause;
308
309 -----------------------------
310 -- Expand_N_Free_Statement --
311 -----------------------------
312
313 procedure Expand_N_Free_Statement (N : Node_Id) is
314 Expr : constant Node_Id := Expression (N);
315 Typ : Entity_Id;
316
317 begin
318 -- Certain run-time configurations and targets do not provide support
319 -- for controlled types.
320
321 if Restriction_Active (No_Finalization) then
322 return;
323 end if;
324
325 -- Use the base type to perform the check for finalization master
326
327 Typ := Etype (Expr);
328
329 if Ekind (Typ) = E_Access_Subtype then
330 Typ := Etype (Typ);
331 end if;
332
333 -- Handle private access types
334
335 if Is_Private_Type (Typ)
336 and then Present (Full_View (Typ))
337 then
338 Typ := Full_View (Typ);
339 end if;
340
341 -- Do not create a custom Deallocate when freeing an object with
342 -- suppressed finalization. In such cases the object is never attached
343 -- to a master, so it does not need to be detached. Use a regular free
344 -- statement instead.
345
346 if No (Finalization_Master (Typ)) then
347 return;
348 end if;
349
350 -- Use a temporary to store the result of a complex expression. Perform
351 -- the following transformation:
352 --
353 -- Free (Complex_Expression);
354 --
355 -- Temp : constant Type_Of_Expression := Complex_Expression;
356 -- Free (Temp);
357
358 if Nkind (Expr) /= N_Identifier then
359 declare
360 Expr_Typ : constant Entity_Id := Etype (Expr);
361 Loc : constant Source_Ptr := Sloc (N);
362 New_Expr : Node_Id;
363 Temp_Id : Entity_Id;
364
365 begin
366 Temp_Id := Make_Temporary (Loc, 'T');
367 Insert_Action (N,
368 Make_Object_Declaration (Loc,
369 Defining_Identifier => Temp_Id,
370 Object_Definition => New_Occurrence_Of (Expr_Typ, Loc),
371 Expression => Relocate_Node (Expr)));
372
373 New_Expr := New_Occurrence_Of (Temp_Id, Loc);
374 Set_Etype (New_Expr, Expr_Typ);
375
376 Set_Expression (N, New_Expr);
377 end;
378 end if;
379
380 -- Create a custom Deallocate for a controlled object. This routine
381 -- ensures that the hidden list header will be deallocated along with
382 -- the actual object.
383
384 Build_Allocate_Deallocate_Proc (N, Is_Allocate => False);
385 end Expand_N_Free_Statement;
386
387 ----------------------------
388 -- Expand_N_Freeze_Entity --
389 ----------------------------
390
391 procedure Expand_N_Freeze_Entity (N : Node_Id) is
392 E : constant Entity_Id := Entity (N);
393
394 Decl : Node_Id;
395 Delete : Boolean := False;
396 E_Scope : Entity_Id;
397 In_Other_Scope : Boolean;
398 In_Outer_Scope : Boolean;
399
400 begin
401 -- If there are delayed aspect specifications, we insert them just
402 -- before the freeze node. They are already analyzed so we don't need
403 -- to reanalyze them (they were analyzed before the type was frozen),
404 -- but we want them in the tree for the back end, and so that the
405 -- listing from sprint is clearer on where these occur logically.
406
407 if Has_Delayed_Aspects (E) then
408 declare
409 Aitem : Node_Id;
410 Ritem : Node_Id;
411
412 begin
413 -- Look for aspect specs for this entity
414
415 Ritem := First_Rep_Item (E);
416 while Present (Ritem) loop
417 if Nkind (Ritem) = N_Aspect_Specification
418 and then Entity (Ritem) = E
419 then
420 Aitem := Aspect_Rep_Item (Ritem);
421
422 -- Skip this for aspects (e.g. Current_Value) for which
423 -- there is no corresponding pragma or attribute.
424
425 if Present (Aitem)
426
427 -- Also skip if we have a null statement rather than a
428 -- delayed aspect (this happens when we are ignoring rep
429 -- items from use of the -gnatI switch).
430
431 and then Nkind (Aitem) /= N_Null_Statement
432 then
433 pragma Assert (Is_Delayed_Aspect (Aitem));
434 Insert_Before (N, Aitem);
435 end if;
436 end if;
437
438 Next_Rep_Item (Ritem);
439 end loop;
440 end;
441 end if;
442
443 -- Processing for objects
444
445 if Is_Object (E) then
446 if Present (Address_Clause (E)) then
447 Apply_Address_Clause_Check (E, N);
448 end if;
449
450 -- Analyze actions in freeze node, if any
451
452 if Present (Actions (N)) then
453 declare
454 Act : Node_Id;
455 begin
456 Act := First (Actions (N));
457 while Present (Act) loop
458 Analyze (Act);
459 Next (Act);
460 end loop;
461 end;
462 end if;
463
464 -- If initialization statements have been captured in a compound
465 -- statement, insert them back into the tree now.
466
467 Explode_Initialization_Compound_Statement (E);
468 return;
469
470 -- Only other items requiring any front end action are types and
471 -- subprograms.
472
473 elsif not Is_Type (E) and then not Is_Subprogram (E) then
474 return;
475 end if;
476
477 -- Here E is a type or a subprogram
478
479 E_Scope := Scope (E);
480
481 -- This is an error protection against previous errors
482
483 if No (E_Scope) then
484 Check_Error_Detected;
485 return;
486 end if;
487
488 -- The entity may be a subtype declared for a constrained record
489 -- component, in which case the relevant scope is the scope of
490 -- the record. This happens for class-wide subtypes created for
491 -- a constrained type extension with inherited discriminants.
492
493 if Is_Type (E_Scope)
494 and then Ekind (E_Scope) not in Concurrent_Kind
495 then
496 E_Scope := Scope (E_Scope);
497
498 -- The entity may be a subtype declared for an iterator
499
500 elsif Ekind (E_Scope) = E_Loop then
501 E_Scope := Scope (E_Scope);
502 end if;
503
504 -- Remember that we are processing a freezing entity and its freezing
505 -- nodes. This flag (non-zero = set) is used to avoid the need of
506 -- climbing through the tree while processing the freezing actions (ie.
507 -- to avoid generating spurious warnings or to avoid killing constant
508 -- indications while processing the code associated with freezing
509 -- actions). We use a counter to deal with nesting.
510
511 Inside_Freezing_Actions := Inside_Freezing_Actions + 1;
512
513 -- If we are freezing entities defined in protected types, they belong
514 -- in the enclosing scope, given that the original type has been
515 -- expanded away. The same is true for entities in task types, in
516 -- particular the parameter records of entries (Entities in bodies are
517 -- all frozen within the body). If we are in the task body, this is a
518 -- proper scope. If we are within a subprogram body, the proper scope
519 -- is the corresponding spec. This may happen for itypes generated in
520 -- the bodies of protected operations.
521
522 if Ekind (E_Scope) = E_Protected_Type
523 or else (Ekind (E_Scope) = E_Task_Type
524 and then not Has_Completion (E_Scope))
525 then
526 E_Scope := Scope (E_Scope);
527
528 elsif Ekind (E_Scope) = E_Subprogram_Body then
529 E_Scope := Corresponding_Spec (Unit_Declaration_Node (E_Scope));
530 end if;
531
532 -- If the scope of the entity is in open scopes, it is the current one
533 -- or an enclosing one, including a loop, a block, or a subprogram.
534
535 if In_Open_Scopes (E_Scope) then
536 In_Other_Scope := False;
537 In_Outer_Scope := E_Scope /= Current_Scope;
538
539 -- Otherwise it is a local package or a different compilation unit
540
541 else
542 In_Other_Scope := True;
543 In_Outer_Scope := False;
544 end if;
545
546 -- If the entity being frozen is defined in a scope that is not
547 -- currently on the scope stack, we must establish the proper
548 -- visibility before freezing the entity and related subprograms.
549
550 if In_Other_Scope then
551 Push_Scope (E_Scope);
552
553 -- Finalizers are little odd in terms of freezing. The spec of the
554 -- procedure appears in the declarations while the body appears in
555 -- the statement part of a single construct. Since the finalizer must
556 -- be called by the At_End handler of the construct, the spec is
557 -- manually frozen right after its declaration. The only side effect
558 -- of this action appears in contexts where the construct is not in
559 -- its final resting place. These contexts are:
560
561 -- * Entry bodies - The declarations and statements are moved to
562 -- the procedure equivalen of the entry.
563 -- * Protected subprograms - The declarations and statements are
564 -- moved to the non-protected version of the subprogram.
565 -- * Task bodies - The declarations and statements are moved to the
566 -- task body procedure.
567 -- * Blocks that will be rewritten as subprograms when unnesting
568 -- is in effect.
569
570 -- Visible declarations do not need to be installed in these three
571 -- cases since it does not make semantic sense to do so. All entities
572 -- referenced by a finalizer are visible and already resolved, plus
573 -- the enclosing scope may not have visible declarations at all.
574
575 if Ekind (E) = E_Procedure
576 and then Is_Finalizer (E)
577 and then
578 (Is_Entry (E_Scope)
579 or else (Is_Subprogram (E_Scope)
580 and then Is_Protected_Type (Scope (E_Scope)))
581 or else Is_Task_Type (E_Scope)
582 or else Ekind (E_Scope) = E_Block)
583 then
584 null;
585 else
586 Install_Visible_Declarations (E_Scope);
587 end if;
588
589 if Is_Concurrent_Type (E_Scope)
590 or else Is_Package_Or_Generic_Package (E_Scope)
591 then
592 Install_Private_Declarations (E_Scope);
593 end if;
594
595 -- If the entity is in an outer scope, then that scope needs to
596 -- temporarily become the current scope so that operations created
597 -- during type freezing will be declared in the right scope and
598 -- can properly override any corresponding inherited operations.
599
600 elsif In_Outer_Scope then
601 Push_Scope (E_Scope);
602 end if;
603
604 -- If type, freeze the type
605
606 if Is_Type (E) then
607 Delete := Freeze_Type (N);
608
609 -- And for enumeration type, build the enumeration tables
610
611 if Is_Enumeration_Type (E) then
612 Build_Enumeration_Image_Tables (E, N);
613 end if;
614
615 -- If subprogram, freeze the subprogram
616
617 elsif Is_Subprogram (E) then
618 Exp_Ch6.Freeze_Subprogram (N);
619
620 -- Ada 2005 (AI-251): Remove the freezing node associated with the
621 -- entities internally used by the frontend to register primitives
622 -- covering abstract interfaces. The call to Freeze_Subprogram has
623 -- already expanded the code that fills the corresponding entry in
624 -- its secondary dispatch table and therefore the code generator
625 -- has nothing else to do with this freezing node.
626
627 Delete := Present (Interface_Alias (E));
628 end if;
629
630 -- Analyze actions generated by freezing. The init_proc contains source
631 -- expressions that may raise Constraint_Error, and the assignment
632 -- procedure for complex types needs checks on individual component
633 -- assignments, but all other freezing actions should be compiled with
634 -- all checks off.
635
636 if Present (Actions (N)) then
637 Decl := First (Actions (N));
638 while Present (Decl) loop
639 if Nkind (Decl) = N_Subprogram_Body
640 and then (Is_Init_Proc (Defining_Entity (Decl))
641 or else
642 Chars (Defining_Entity (Decl)) = Name_uAssign)
643 then
644 Analyze (Decl);
645
646 -- A subprogram body created for a renaming_as_body completes
647 -- a previous declaration, which may be in a different scope.
648 -- Establish the proper scope before analysis.
649
650 elsif Nkind (Decl) = N_Subprogram_Body
651 and then Present (Corresponding_Spec (Decl))
652 and then Scope (Corresponding_Spec (Decl)) /= Current_Scope
653 then
654 Push_Scope (Scope (Corresponding_Spec (Decl)));
655 Analyze (Decl, Suppress => All_Checks);
656 Pop_Scope;
657
658 -- We treat generated equality specially, if validity checks are
659 -- enabled, in order to detect components default-initialized
660 -- with invalid values.
661
662 elsif Nkind (Decl) = N_Subprogram_Body
663 and then Chars (Defining_Entity (Decl)) = Name_Op_Eq
664 and then Validity_Checks_On
665 and then Initialize_Scalars
666 then
667 declare
668 Save_Force : constant Boolean := Force_Validity_Checks;
669 begin
670 Force_Validity_Checks := True;
671 Analyze (Decl);
672 Force_Validity_Checks := Save_Force;
673 end;
674
675 -- All other freezing actions
676
677 else
678 Analyze (Decl, Suppress => All_Checks);
679 end if;
680
681 Next (Decl);
682 end loop;
683 end if;
684
685 -- If we are to delete this N_Freeze_Entity, do so by rewriting so that
686 -- a loop on all nodes being inserted will work propertly.
687
688 if Delete then
689 Rewrite (N, Make_Null_Statement (Sloc (N)));
690 end if;
691
692 -- Pop scope if we installed one for the analysis
693
694 if In_Other_Scope then
695 if Ekind (Current_Scope) = E_Package then
696 End_Package_Scope (E_Scope);
697 else
698 End_Scope;
699 end if;
700
701 elsif In_Outer_Scope then
702 Pop_Scope;
703 end if;
704
705 -- Restore previous value of the nesting-level counter that records
706 -- whether we are inside a (possibly nested) call to this procedure.
707
708 Inside_Freezing_Actions := Inside_Freezing_Actions - 1;
709 end Expand_N_Freeze_Entity;
710
711 -------------------------------------------
712 -- Expand_N_Record_Representation_Clause --
713 -------------------------------------------
714
715 -- The only expansion required is for the case of a mod clause present,
716 -- which is removed, and translated into an alignment representation
717 -- clause inserted immediately after the record rep clause with any
718 -- initial pragmas inserted at the start of the component clause list.
719
720 procedure Expand_N_Record_Representation_Clause (N : Node_Id) is
721 Loc : constant Source_Ptr := Sloc (N);
722 Rectype : constant Entity_Id := Entity (Identifier (N));
723 Mod_Val : Uint;
724 Citems : List_Id;
725 Repitem : Node_Id;
726 AtM_Nod : Node_Id;
727
728 begin
729 if Present (Mod_Clause (N)) and then not Ignore_Rep_Clauses then
730 Mod_Val := Expr_Value (Expression (Mod_Clause (N)));
731 Citems := Pragmas_Before (Mod_Clause (N));
732
733 if Present (Citems) then
734 Append_List_To (Citems, Component_Clauses (N));
735 Set_Component_Clauses (N, Citems);
736 end if;
737
738 AtM_Nod :=
739 Make_Attribute_Definition_Clause (Loc,
740 Name => New_Occurrence_Of (Base_Type (Rectype), Loc),
741 Chars => Name_Alignment,
742 Expression => Make_Integer_Literal (Loc, Mod_Val));
743
744 Set_From_At_Mod (AtM_Nod);
745 Insert_After (N, AtM_Nod);
746 Set_Mod_Clause (N, Empty);
747 end if;
748
749 -- If the record representation clause has no components, then
750 -- completely remove it. Note that we also have to remove
751 -- ourself from the Rep Item list.
752
753 if Is_Empty_List (Component_Clauses (N)) then
754 if First_Rep_Item (Rectype) = N then
755 Set_First_Rep_Item (Rectype, Next_Rep_Item (N));
756 else
757 Repitem := First_Rep_Item (Rectype);
758 while Present (Next_Rep_Item (Repitem)) loop
759 if Next_Rep_Item (Repitem) = N then
760 Set_Next_Rep_Item (Repitem, Next_Rep_Item (N));
761 exit;
762 end if;
763
764 Next_Rep_Item (Repitem);
765 end loop;
766 end if;
767
768 Rewrite (N,
769 Make_Null_Statement (Loc));
770 end if;
771 end Expand_N_Record_Representation_Clause;
772
773 end Exp_Ch13;