1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                               T B U I L D                                --
6--                                                                          --
7--                                 B o d y                                  --
8--                                                                          --
9--          Copyright (C) 1992-2019, 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
26with Atree;    use Atree;
27with Aspects;  use Aspects;
28with Csets;    use Csets;
29with Einfo;    use Einfo;
30with Elists;   use Elists;
31with Lib;      use Lib;
32with Nlists;   use Nlists;
33with Nmake;    use Nmake;
34with Opt;      use Opt;
35with Restrict; use Restrict;
36with Rident;   use Rident;
37with Sem_Aux;  use Sem_Aux;
38with Snames;   use Snames;
39with Stand;    use Stand;
40with Stringt;  use Stringt;
41with Urealp;   use Urealp;
42
43package body Tbuild is
44
45   -----------------------
46   -- Local Subprograms --
47   -----------------------
48
49   procedure Add_Unique_Serial_Number;
50   --  Add a unique serialization to the string in the Name_Buffer. This
51   --  consists of a unit specific serial number, and b/s for body/spec.
52
53   ------------------------------
54   -- Add_Unique_Serial_Number --
55   ------------------------------
56
57   Config_Serial_Number : Nat := 0;
58   --  Counter for use in config pragmas, see comment below
59
60   procedure Add_Unique_Serial_Number is
61   begin
62      --  If we are analyzing configuration pragmas, Cunit (Main_Unit) will
63      --  not be set yet. This happens for example when analyzing static
64      --  string expressions in configuration pragmas. For this case, we
65      --  just maintain a local counter, defined above and we do not need
66      --  to add a b or s indication in this case.
67
68      if No (Cunit (Current_Sem_Unit)) then
69         Config_Serial_Number := Config_Serial_Number + 1;
70         Add_Nat_To_Name_Buffer (Config_Serial_Number);
71         return;
72
73      --  Normal case, within a unit
74
75      else
76         declare
77            Unit_Node : constant Node_Id := Unit (Cunit (Current_Sem_Unit));
78
79         begin
80            Add_Nat_To_Name_Buffer (Increment_Serial_Number);
81
82            --  Add either b or s, depending on whether current unit is a spec
83            --  or a body. This is needed because we may generate the same name
84            --  in a spec and a body otherwise.
85
86            Name_Len := Name_Len + 1;
87
88            if Nkind (Unit_Node) = N_Package_Declaration
89              or else Nkind (Unit_Node) = N_Subprogram_Declaration
90              or else Nkind (Unit_Node) in N_Generic_Declaration
91            then
92               Name_Buffer (Name_Len) := 's';
93            else
94               Name_Buffer (Name_Len) := 'b';
95            end if;
96         end;
97      end if;
98   end Add_Unique_Serial_Number;
99
100   ----------------
101   -- Checks_Off --
102   ----------------
103
104   function Checks_Off (N : Node_Id) return Node_Id is
105   begin
106      return
107        Make_Unchecked_Expression (Sloc (N),
108          Expression => N);
109   end Checks_Off;
110
111   ----------------
112   -- Convert_To --
113   ----------------
114
115   function Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id is
116      Result : Node_Id;
117
118   begin
119      if Present (Etype (Expr))
120        and then (Etype (Expr)) = Typ
121      then
122         return Relocate_Node (Expr);
123      else
124         Result :=
125           Make_Type_Conversion (Sloc (Expr),
126             Subtype_Mark => New_Occurrence_Of (Typ, Sloc (Expr)),
127             Expression => Relocate_Node (Expr));
128
129         Set_Etype (Result, Typ);
130         return Result;
131      end if;
132   end Convert_To;
133
134   ----------------------------
135   -- Convert_To_And_Rewrite --
136   ----------------------------
137
138   procedure Convert_To_And_Rewrite (Typ : Entity_Id; Expr : Node_Id) is
139   begin
140      Rewrite (Expr, Convert_To (Typ, Expr));
141   end Convert_To_And_Rewrite;
142
143   ------------------
144   -- Discard_List --
145   ------------------
146
147   procedure Discard_List (L : List_Id) is
148      pragma Warnings (Off, L);
149   begin
150      null;
151   end Discard_List;
152
153   ------------------
154   -- Discard_Node --
155   ------------------
156
157   procedure Discard_Node (N : Node_Or_Entity_Id) is
158      pragma Warnings (Off, N);
159   begin
160      null;
161   end Discard_Node;
162
163   -------------------------------------------
164   -- Make_Byte_Aligned_Attribute_Reference --
165   -------------------------------------------
166
167   function Make_Byte_Aligned_Attribute_Reference
168     (Sloc           : Source_Ptr;
169      Prefix         : Node_Id;
170      Attribute_Name : Name_Id)
171      return           Node_Id
172   is
173      N : constant Node_Id :=
174            Make_Attribute_Reference (Sloc,
175              Prefix        => Prefix,
176              Attribute_Name => Attribute_Name);
177
178   begin
179      pragma Assert (Nam_In (Attribute_Name, Name_Address,
180                                             Name_Unrestricted_Access));
181      Set_Must_Be_Byte_Aligned (N, True);
182      return N;
183   end Make_Byte_Aligned_Attribute_Reference;
184
185   --------------------
186   -- Make_DT_Access --
187   --------------------
188
189   function Make_DT_Access
190     (Loc : Source_Ptr;
191      Rec : Node_Id;
192      Typ : Entity_Id) return Node_Id
193   is
194      Full_Type : Entity_Id := Typ;
195
196   begin
197      if Is_Private_Type (Typ) then
198         Full_Type := Underlying_Type (Typ);
199      end if;
200
201      return
202        Unchecked_Convert_To (
203          New_Occurrence_Of
204            (Etype (Node (First_Elmt (Access_Disp_Table (Full_Type)))), Loc),
205          Make_Selected_Component (Loc,
206            Prefix => New_Copy (Rec),
207            Selector_Name =>
208              New_Occurrence_Of (First_Tag_Component (Full_Type), Loc)));
209   end Make_DT_Access;
210
211   ------------------------
212   -- Make_Float_Literal --
213   ------------------------
214
215   function Make_Float_Literal
216     (Loc         : Source_Ptr;
217      Radix       : Uint;
218      Significand : Uint;
219      Exponent    : Uint) return Node_Id
220   is
221   begin
222      if Radix = 2 and then abs Significand /= 1 then
223         return
224           Make_Float_Literal
225             (Loc, Uint_16,
226              Significand * Radix**(Exponent mod 4),
227              Exponent / 4);
228
229      else
230         declare
231            N : constant Node_Id := New_Node (N_Real_Literal, Loc);
232
233         begin
234            Set_Realval (N,
235              UR_From_Components
236                (Num      => abs Significand,
237                 Den      => -Exponent,
238                 Rbase    => UI_To_Int (Radix),
239                 Negative => Significand < 0));
240            return N;
241         end;
242      end if;
243   end Make_Float_Literal;
244
245   -------------
246   -- Make_Id --
247   -------------
248
249   function Make_Id (Str : Text_Buffer) return Node_Id is
250   begin
251      Name_Len := 0;
252
253      for J in Str'Range loop
254         Name_Len := Name_Len + 1;
255         Name_Buffer (Name_Len) := Fold_Lower (Str (J));
256      end loop;
257
258      return
259        Make_Identifier (System_Location,
260          Chars => Name_Find);
261   end Make_Id;
262
263   -------------------------------------
264   -- Make_Implicit_Exception_Handler --
265   -------------------------------------
266
267   function Make_Implicit_Exception_Handler
268     (Sloc              : Source_Ptr;
269      Choice_Parameter  : Node_Id := Empty;
270      Exception_Choices : List_Id;
271      Statements        : List_Id) return Node_Id
272   is
273      Handler : Node_Id;
274      Loc     : Source_Ptr;
275
276   begin
277      --  Set the source location only when debugging the expanded code
278
279      --  When debugging the source code directly, we do not want the compiler
280      --  to associate this implicit exception handler with any specific source
281      --  line, because it can potentially confuse the debugger. The most
282      --  damaging situation would arise when the debugger tries to insert a
283      --  breakpoint at a certain line. If the code of the associated implicit
284      --  exception handler is generated before the code of that line, then the
285      --  debugger will end up inserting the breakpoint inside the exception
286      --  handler, rather than the code the user intended to break on. As a
287      --  result, it is likely that the program will not hit the breakpoint
288      --  as expected.
289
290      if Debug_Generated_Code then
291         Loc := Sloc;
292      else
293         Loc := No_Location;
294      end if;
295
296      Handler :=
297        Make_Exception_Handler
298          (Loc, Choice_Parameter, Exception_Choices, Statements);
299      Set_Local_Raise_Statements (Handler, No_Elist);
300      return Handler;
301   end Make_Implicit_Exception_Handler;
302
303   --------------------------------
304   -- Make_Implicit_If_Statement --
305   --------------------------------
306
307   function Make_Implicit_If_Statement
308     (Node            : Node_Id;
309      Condition       : Node_Id;
310      Then_Statements : List_Id;
311      Elsif_Parts     : List_Id := No_List;
312      Else_Statements : List_Id := No_List) return Node_Id
313   is
314   begin
315      Check_Restriction (No_Implicit_Conditionals, Node);
316
317      return Make_If_Statement (Sloc (Node),
318        Condition,
319        Then_Statements,
320        Elsif_Parts,
321        Else_Statements);
322   end Make_Implicit_If_Statement;
323
324   -------------------------------------
325   -- Make_Implicit_Label_Declaration --
326   -------------------------------------
327
328   function Make_Implicit_Label_Declaration
329     (Loc                 : Source_Ptr;
330      Defining_Identifier : Node_Id;
331      Label_Construct     : Node_Id) return Node_Id
332   is
333      N : constant Node_Id :=
334            Make_Implicit_Label_Declaration (Loc, Defining_Identifier);
335   begin
336      Set_Label_Construct (N, Label_Construct);
337      return N;
338   end Make_Implicit_Label_Declaration;
339
340   ----------------------------------
341   -- Make_Implicit_Loop_Statement --
342   ----------------------------------
343
344   function Make_Implicit_Loop_Statement
345     (Node                   : Node_Id;
346      Statements             : List_Id;
347      Identifier             : Node_Id := Empty;
348      Iteration_Scheme       : Node_Id := Empty;
349      Has_Created_Identifier : Boolean := False;
350      End_Label              : Node_Id := Empty) return Node_Id
351   is
352   begin
353      Check_Restriction (No_Implicit_Loops, Node);
354
355      if Present (Iteration_Scheme)
356        and then Present (Condition (Iteration_Scheme))
357      then
358         Check_Restriction (No_Implicit_Conditionals, Node);
359      end if;
360
361      return Make_Loop_Statement (Sloc (Node),
362        Identifier             => Identifier,
363        Iteration_Scheme       => Iteration_Scheme,
364        Statements             => Statements,
365        Has_Created_Identifier => Has_Created_Identifier,
366        End_Label              => End_Label);
367   end Make_Implicit_Loop_Statement;
368
369   --------------------------
370   -- Make_Integer_Literal --
371   ---------------------------
372
373   function Make_Integer_Literal
374     (Loc    : Source_Ptr;
375      Intval : Int) return Node_Id
376   is
377   begin
378      return Make_Integer_Literal (Loc, UI_From_Int (Intval));
379   end Make_Integer_Literal;
380
381   --------------------------------
382   -- Make_Linker_Section_Pragma --
383   --------------------------------
384
385   function Make_Linker_Section_Pragma
386     (Ent : Entity_Id;
387      Loc : Source_Ptr;
388      Sec : String) return Node_Id
389   is
390      LS : Node_Id;
391
392   begin
393      LS :=
394        Make_Pragma
395          (Loc,
396           Name_Linker_Section,
397           New_List
398             (Make_Pragma_Argument_Association
399                (Sloc => Loc,
400                 Expression => New_Occurrence_Of (Ent, Loc)),
401              Make_Pragma_Argument_Association
402                (Sloc => Loc,
403                 Expression =>
404                   Make_String_Literal
405                     (Sloc => Loc,
406                      Strval => Sec))));
407
408      Set_Has_Gigi_Rep_Item (Ent);
409      return LS;
410   end Make_Linker_Section_Pragma;
411
412   -----------------
413   -- Make_Pragma --
414   -----------------
415
416   function Make_Pragma
417     (Sloc                         : Source_Ptr;
418      Chars                        : Name_Id;
419      Pragma_Argument_Associations : List_Id := No_List) return Node_Id
420   is
421   begin
422      return
423        Make_Pragma (Sloc,
424          Pragma_Argument_Associations => Pragma_Argument_Associations,
425          Pragma_Identifier            => Make_Identifier (Sloc, Chars));
426   end Make_Pragma;
427
428   ---------------------------------
429   -- Make_Raise_Constraint_Error --
430   ---------------------------------
431
432   function Make_Raise_Constraint_Error
433     (Sloc      : Source_Ptr;
434      Condition : Node_Id := Empty;
435      Reason    : RT_Exception_Code) return Node_Id
436   is
437   begin
438      pragma Assert (Rkind (Reason) = CE_Reason);
439      return
440        Make_Raise_Constraint_Error (Sloc,
441          Condition => Condition,
442          Reason    => UI_From_Int (RT_Exception_Code'Pos (Reason)));
443   end Make_Raise_Constraint_Error;
444
445   ------------------------------
446   -- Make_Raise_Program_Error --
447   ------------------------------
448
449   function Make_Raise_Program_Error
450     (Sloc      : Source_Ptr;
451      Condition : Node_Id := Empty;
452      Reason    : RT_Exception_Code) return Node_Id
453   is
454   begin
455      pragma Assert (Rkind (Reason) = PE_Reason);
456      return
457        Make_Raise_Program_Error (Sloc,
458          Condition => Condition,
459          Reason    => UI_From_Int (RT_Exception_Code'Pos (Reason)));
460   end Make_Raise_Program_Error;
461
462   ------------------------------
463   -- Make_Raise_Storage_Error --
464   ------------------------------
465
466   function Make_Raise_Storage_Error
467     (Sloc      : Source_Ptr;
468      Condition : Node_Id := Empty;
469      Reason    : RT_Exception_Code) return Node_Id
470   is
471   begin
472      pragma Assert (Rkind (Reason) = SE_Reason);
473      return
474        Make_Raise_Storage_Error (Sloc,
475          Condition => Condition,
476          Reason    => UI_From_Int (RT_Exception_Code'Pos (Reason)));
477   end Make_Raise_Storage_Error;
478
479   -------------
480   -- Make_SC --
481   -------------
482
483   function  Make_SC (Pre, Sel : Node_Id) return Node_Id is
484   begin
485      return
486        Make_Selected_Component (System_Location,
487          Prefix        => Pre,
488          Selector_Name => Sel);
489   end Make_SC;
490
491   -------------------------
492   -- Make_String_Literal --
493   -------------------------
494
495   function Make_String_Literal
496     (Sloc   : Source_Ptr;
497      Strval : String) return Node_Id
498   is
499   begin
500      Start_String;
501      Store_String_Chars (Strval);
502      return Make_String_Literal (Sloc, Strval => End_String);
503   end Make_String_Literal;
504
505   --------------------
506   -- Make_Temporary --
507   --------------------
508
509   function Make_Temporary
510     (Loc          : Source_Ptr;
511      Id           : Character;
512      Related_Node : Node_Id := Empty) return Entity_Id
513   is
514      Temp : constant Entity_Id :=
515               Make_Defining_Identifier (Loc, Chars => New_Internal_Name (Id));
516   begin
517      Set_Related_Expression (Temp, Related_Node);
518      return Temp;
519   end Make_Temporary;
520
521   ---------------------------
522   -- Make_Unsuppress_Block --
523   ---------------------------
524
525   --  Generates the following expansion:
526
527   --    declare
528   --       pragma Suppress (<check>);
529   --    begin
530   --       <stmts>
531   --    end;
532
533   function Make_Unsuppress_Block
534     (Loc   : Source_Ptr;
535      Check : Name_Id;
536      Stmts : List_Id) return Node_Id
537   is
538   begin
539      return
540        Make_Block_Statement (Loc,
541          Declarations => New_List (
542            Make_Pragma (Loc,
543              Chars => Name_Suppress,
544              Pragma_Argument_Associations => New_List (
545                Make_Pragma_Argument_Association (Loc,
546                  Expression => Make_Identifier (Loc, Check))))),
547
548          Handled_Statement_Sequence =>
549            Make_Handled_Sequence_Of_Statements (Loc,
550              Statements => Stmts));
551   end Make_Unsuppress_Block;
552
553   --------------------------
554   -- New_Constraint_Error --
555   --------------------------
556
557   function New_Constraint_Error (Loc : Source_Ptr) return Node_Id is
558      Ident_Node : Node_Id;
559      Raise_Node : Node_Id;
560
561   begin
562      Ident_Node := New_Node (N_Identifier, Loc);
563      Set_Chars (Ident_Node, Chars (Standard_Entity (S_Constraint_Error)));
564      Set_Entity (Ident_Node, Standard_Entity (S_Constraint_Error));
565      Raise_Node := New_Node (N_Raise_Statement, Loc);
566      Set_Name (Raise_Node, Ident_Node);
567      return Raise_Node;
568   end New_Constraint_Error;
569
570   -----------------------
571   -- New_External_Name --
572   -----------------------
573
574   function New_External_Name
575     (Related_Id   : Name_Id;
576      Suffix       : Character := ' ';
577      Suffix_Index : Int       := 0;
578      Prefix       : Character := ' ') return Name_Id
579   is
580   begin
581      Get_Name_String (Related_Id);
582
583      if Prefix /= ' ' then
584         pragma Assert (Is_OK_Internal_Letter (Prefix) or else Prefix = '_');
585
586         for J in reverse 1 .. Name_Len loop
587            Name_Buffer (J + 1) := Name_Buffer (J);
588         end loop;
589
590         Name_Len := Name_Len + 1;
591         Name_Buffer (1) := Prefix;
592      end if;
593
594      if Suffix /= ' ' then
595         pragma Assert (Is_OK_Internal_Letter (Suffix));
596         Add_Char_To_Name_Buffer (Suffix);
597      end if;
598
599      if Suffix_Index /= 0 then
600         if Suffix_Index < 0 then
601            Add_Unique_Serial_Number;
602         else
603            Add_Nat_To_Name_Buffer (Suffix_Index);
604         end if;
605      end if;
606
607      return Name_Find;
608   end New_External_Name;
609
610   function New_External_Name
611     (Related_Id   : Name_Id;
612      Suffix       : String;
613      Suffix_Index : Int       := 0;
614      Prefix       : Character := ' ') return Name_Id
615   is
616   begin
617      Get_Name_String (Related_Id);
618
619      if Prefix /= ' ' then
620         pragma Assert (Is_OK_Internal_Letter (Prefix));
621
622         for J in reverse 1 .. Name_Len loop
623            Name_Buffer (J + 1) := Name_Buffer (J);
624         end loop;
625
626         Name_Len := Name_Len + 1;
627         Name_Buffer (1) := Prefix;
628      end if;
629
630      if Suffix /= "" then
631         Name_Buffer (Name_Len + 1 .. Name_Len + Suffix'Length) := Suffix;
632         Name_Len := Name_Len + Suffix'Length;
633      end if;
634
635      if Suffix_Index /= 0 then
636         if Suffix_Index < 0 then
637            Add_Unique_Serial_Number;
638         else
639            Add_Nat_To_Name_Buffer (Suffix_Index);
640         end if;
641      end if;
642
643      return Name_Find;
644   end New_External_Name;
645
646   function New_External_Name
647     (Suffix       : Character;
648      Suffix_Index : Nat) return Name_Id
649   is
650   begin
651      Name_Buffer (1) := Suffix;
652      Name_Len := 1;
653      Add_Nat_To_Name_Buffer (Suffix_Index);
654      return Name_Find;
655   end New_External_Name;
656
657   -----------------------
658   -- New_Internal_Name --
659   -----------------------
660
661   function New_Internal_Name (Id_Char : Character) return Name_Id is
662   begin
663      pragma Assert (Is_OK_Internal_Letter (Id_Char));
664      Name_Buffer (1) := Id_Char;
665      Name_Len := 1;
666      Add_Unique_Serial_Number;
667      return Name_Enter;
668   end New_Internal_Name;
669
670   -----------------------
671   -- New_Occurrence_Of --
672   -----------------------
673
674   function New_Occurrence_Of
675     (Def_Id : Entity_Id;
676      Loc    : Source_Ptr) return Node_Id
677   is
678      pragma Assert (Present (Def_Id) and then Nkind (Def_Id) in N_Entity);
679      Occurrence : Node_Id;
680
681   begin
682      Occurrence := New_Node (N_Identifier, Loc);
683      Set_Chars (Occurrence, Chars (Def_Id));
684      Set_Entity (Occurrence, Def_Id);
685
686      if Is_Type (Def_Id) then
687         Set_Etype (Occurrence, Def_Id);
688      else
689         Set_Etype (Occurrence, Etype (Def_Id));
690      end if;
691
692      if Ekind (Def_Id) = E_Enumeration_Literal then
693         Set_Is_Static_Expression (Occurrence, True);
694      end if;
695
696      return Occurrence;
697   end New_Occurrence_Of;
698
699   -----------------
700   -- New_Op_Node --
701   -----------------
702
703   function New_Op_Node
704     (New_Node_Kind : Node_Kind;
705      New_Sloc      : Source_Ptr) return Node_Id
706   is
707      type Name_Of_Type is array (N_Op) of Name_Id;
708      Name_Of : constant Name_Of_Type := Name_Of_Type'(
709         N_Op_And                    => Name_Op_And,
710         N_Op_Or                     => Name_Op_Or,
711         N_Op_Xor                    => Name_Op_Xor,
712         N_Op_Eq                     => Name_Op_Eq,
713         N_Op_Ne                     => Name_Op_Ne,
714         N_Op_Lt                     => Name_Op_Lt,
715         N_Op_Le                     => Name_Op_Le,
716         N_Op_Gt                     => Name_Op_Gt,
717         N_Op_Ge                     => Name_Op_Ge,
718         N_Op_Add                    => Name_Op_Add,
719         N_Op_Subtract               => Name_Op_Subtract,
720         N_Op_Concat                 => Name_Op_Concat,
721         N_Op_Multiply               => Name_Op_Multiply,
722         N_Op_Divide                 => Name_Op_Divide,
723         N_Op_Mod                    => Name_Op_Mod,
724         N_Op_Rem                    => Name_Op_Rem,
725         N_Op_Expon                  => Name_Op_Expon,
726         N_Op_Plus                   => Name_Op_Add,
727         N_Op_Minus                  => Name_Op_Subtract,
728         N_Op_Abs                    => Name_Op_Abs,
729         N_Op_Not                    => Name_Op_Not,
730
731         --  We don't really need these shift operators, since they never
732         --  appear as operators in the source, but the path of least
733         --  resistance is to put them in (the aggregate must be complete).
734
735         N_Op_Rotate_Left            => Name_Rotate_Left,
736         N_Op_Rotate_Right           => Name_Rotate_Right,
737         N_Op_Shift_Left             => Name_Shift_Left,
738         N_Op_Shift_Right            => Name_Shift_Right,
739         N_Op_Shift_Right_Arithmetic => Name_Shift_Right_Arithmetic);
740
741      Nod : constant Node_Id := New_Node (New_Node_Kind, New_Sloc);
742
743   begin
744      if New_Node_Kind in Name_Of'Range then
745         Set_Chars (Nod, Name_Of (New_Node_Kind));
746      end if;
747
748      return Nod;
749   end New_Op_Node;
750
751   -----------------------
752   -- New_Suffixed_Name --
753   -----------------------
754
755   function New_Suffixed_Name
756     (Related_Id : Name_Id;
757      Suffix     : String) return Name_Id
758   is
759   begin
760      Get_Name_String (Related_Id);
761      Add_Char_To_Name_Buffer ('_');
762      Add_Str_To_Name_Buffer (Suffix);
763      return Name_Find;
764   end New_Suffixed_Name;
765
766   -------------------
767   -- OK_Convert_To --
768   -------------------
769
770   function OK_Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id is
771      Result : Node_Id;
772   begin
773      Result :=
774        Make_Type_Conversion (Sloc (Expr),
775          Subtype_Mark => New_Occurrence_Of (Typ, Sloc (Expr)),
776          Expression   => Relocate_Node (Expr));
777      Set_Conversion_OK (Result, True);
778      Set_Etype (Result, Typ);
779      return Result;
780   end OK_Convert_To;
781
782   -------------
783   -- Set_NOD --
784   -------------
785
786   procedure Set_NOD (Unit : Node_Id) is
787   begin
788      Set_Restriction_No_Dependence (Unit, Warn => False);
789   end Set_NOD;
790
791   -------------
792   -- Set_NSA --
793   -------------
794
795   procedure Set_NSA (Asp : Name_Id; OK : out Boolean) is
796      Asp_Id : constant Aspect_Id := Get_Aspect_Id (Asp);
797   begin
798      if Asp_Id = No_Aspect then
799         OK := False;
800      else
801         OK := True;
802         Set_Restriction_No_Specification_Of_Aspect (Asp_Id);
803      end if;
804   end Set_NSA;
805
806   -------------
807   -- Set_NUA --
808   -------------
809
810   procedure Set_NUA (Attr : Name_Id; OK : out Boolean) is
811   begin
812      if Is_Attribute_Name (Attr) then
813         OK := True;
814         Set_Restriction_No_Use_Of_Attribute (Get_Attribute_Id (Attr));
815      else
816         OK := False;
817      end if;
818   end Set_NUA;
819
820   -------------
821   -- Set_NUP --
822   -------------
823
824   procedure Set_NUP (Prag : Name_Id; OK : out Boolean) is
825   begin
826      if Is_Pragma_Name (Prag) then
827         OK := True;
828         Set_Restriction_No_Use_Of_Pragma (Get_Pragma_Id (Prag));
829      else
830         OK := False;
831      end if;
832   end Set_NUP;
833
834   --------------------------
835   -- Unchecked_Convert_To --
836   --------------------------
837
838   function Unchecked_Convert_To
839     (Typ  : Entity_Id;
840      Expr : Node_Id) return Node_Id
841   is
842      Loc         : constant Source_Ptr := Sloc (Expr);
843      Result      : Node_Id;
844      Expr_Parent : Node_Id;
845
846   begin
847      --  If the expression is already of the correct type, then nothing
848      --  to do, except for relocating the node in case this is required.
849
850      if Present (Etype (Expr))
851        and then (Base_Type (Etype (Expr)) = Typ
852                   or else Etype (Expr) = Typ)
853      then
854         return Relocate_Node (Expr);
855
856      --  Cases where the inner expression is itself an unchecked conversion
857      --  to the same type, and we can thus eliminate the outer conversion.
858
859      elsif Nkind (Expr) = N_Unchecked_Type_Conversion
860        and then Entity (Subtype_Mark (Expr)) = Typ
861      then
862         Result := Relocate_Node (Expr);
863
864      elsif Nkind (Expr) = N_Null
865        and then Is_Access_Type (Typ)
866      then
867         --  No need for a conversion
868
869         Result := Relocate_Node (Expr);
870
871      --  All other cases
872
873      else
874         --  Capture the parent of the expression before relocating it and
875         --  creating the conversion, so the conversion's parent can be set
876         --  to the original parent below.
877
878         Expr_Parent := Parent (Expr);
879
880         Result :=
881           Make_Unchecked_Type_Conversion (Loc,
882             Subtype_Mark => New_Occurrence_Of (Typ, Loc),
883             Expression   => Relocate_Node (Expr));
884
885         Set_Parent (Result, Expr_Parent);
886      end if;
887
888      Set_Etype (Result, Typ);
889      return Result;
890   end Unchecked_Convert_To;
891
892end Tbuild;
893