1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
11 -- Copyright (C) 1992-2001, Free Software Foundation, Inc. --
13 -- GNAT is free software; you can redistribute it and/or modify it under --
14 -- terms of the GNU General Public License as published by the Free Soft- --
15 -- ware Foundation; either version 2, or (at your option) any later ver- --
16 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
17 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
18 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
19 -- for more details. You should have received a copy of the GNU General --
20 -- Public License distributed with GNAT; see file COPYING. If not, write --
21 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
22 -- MA 02111-1307, USA. --
24 -- GNAT was originally developed by the GNAT team at New York University. --
25 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
27 ------------------------------------------------------------------------------
29 with Atree; use Atree;
30 with Einfo; use Einfo;
32 with Namet; use Namet;
33 with Nlists; use Nlists;
34 with Nmake; use Nmake;
35 with Restrict; use Restrict;
36 with Sinfo; use Sinfo;
37 with Snames; use Snames;
38 with Stand; use Stand;
39 with Uintp; use Uintp;
41 package body Tbuild is
43 -----------------------
44 -- Local Subprograms --
45 -----------------------
47 procedure Add_Unique_Serial_Number;
48 -- Add a unique serialization to the string in the Name_Buffer. This
49 -- consists of a unit specific serial number, and b/s for body/spec.
51 ------------------------------
52 -- Add_Unique_Serial_Number --
53 ------------------------------
55 procedure Add_Unique_Serial_Number is
56 Unit_Node : constant Node_Id := Unit (Cunit (Current_Sem_Unit));
59 Add_Nat_To_Name_Buffer (Increment_Serial_Number);
61 -- Add either b or s, depending on whether current unit is a spec
62 -- or a body. This is needed because we may generate the same name
63 -- in a spec and a body otherwise.
65 Name_Len := Name_Len + 1;
67 if Nkind (Unit_Node) = N_Package_Declaration
68 or else Nkind (Unit_Node) = N_Subprogram_Declaration
69 or else Nkind (Unit_Node) in N_Generic_Declaration
71 Name_Buffer (Name_Len) := 's';
73 Name_Buffer (Name_Len) := 'b';
75 end Add_Unique_Serial_Number;
81 function Checks_Off (N : Node_Id) return Node_Id is
84 Make_Unchecked_Expression (Sloc (N),
92 function Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id is
96 if Present (Etype (Expr))
97 and then (Etype (Expr)) = Typ
99 return Relocate_Node (Expr);
102 Make_Type_Conversion (Sloc (Expr),
103 Subtype_Mark => New_Occurrence_Of (Typ, Sloc (Expr)),
104 Expression => Relocate_Node (Expr));
106 Set_Etype (Result, Typ);
115 function Make_DT_Access
121 Full_Type : Entity_Id := Typ;
124 if Is_Private_Type (Typ) then
125 Full_Type := Underlying_Type (Typ);
129 Unchecked_Convert_To (
130 New_Occurrence_Of (Etype (Access_Disp_Table (Full_Type)), Loc),
131 Make_Selected_Component (Loc,
132 Prefix => New_Copy (Rec),
134 New_Reference_To (Tag_Component (Full_Type), Loc)));
137 -----------------------
138 -- Make_DT_Component --
139 -----------------------
141 function Make_DT_Component
148 Full_Type : Entity_Id := Typ;
151 if Is_Private_Type (Typ) then
152 Full_Type := Underlying_Type (Typ);
155 X := First_Component (
156 Designated_Type (Etype (Access_Disp_Table (Full_Type))));
159 X := Next_Component (X);
162 return New_Reference_To (X, Loc);
163 end Make_DT_Component;
165 --------------------------------
166 -- Make_Implicit_If_Statement --
167 --------------------------------
169 function Make_Implicit_If_Statement
172 Then_Statements : List_Id;
173 Elsif_Parts : List_Id := No_List;
174 Else_Statements : List_Id := No_List)
178 Check_Restriction (No_Implicit_Conditionals, Node);
179 return Make_If_Statement (Sloc (Node),
184 end Make_Implicit_If_Statement;
186 -------------------------------------
187 -- Make_Implicit_Label_Declaration --
188 -------------------------------------
190 function Make_Implicit_Label_Declaration
192 Defining_Identifier : Node_Id;
193 Label_Construct : Node_Id)
196 N : constant Node_Id :=
197 Make_Implicit_Label_Declaration (Loc, Defining_Identifier);
200 Set_Label_Construct (N, Label_Construct);
202 end Make_Implicit_Label_Declaration;
204 ----------------------------------
205 -- Make_Implicit_Loop_Statement --
206 ----------------------------------
208 function Make_Implicit_Loop_Statement
210 Statements : List_Id;
211 Identifier : Node_Id := Empty;
212 Iteration_Scheme : Node_Id := Empty;
213 Has_Created_Identifier : Boolean := False;
214 End_Label : Node_Id := Empty)
218 Check_Restriction (No_Implicit_Loops, Node);
220 if Present (Iteration_Scheme)
221 and then Present (Condition (Iteration_Scheme))
223 Check_Restriction (No_Implicit_Conditionals, Node);
226 return Make_Loop_Statement (Sloc (Node),
227 Identifier => Identifier,
228 Iteration_Scheme => Iteration_Scheme,
229 Statements => Statements,
230 Has_Created_Identifier => Has_Created_Identifier,
231 End_Label => End_Label);
232 end Make_Implicit_Loop_Statement;
234 --------------------------
235 -- Make_Integer_Literal --
236 ---------------------------
238 function Make_Integer_Literal
244 return Make_Integer_Literal (Loc, UI_From_Int (Intval));
245 end Make_Integer_Literal;
247 ---------------------------
248 -- Make_Unsuppress_Block --
249 ---------------------------
251 -- Generates the following expansion:
254 -- pragma Suppress (<check>);
259 function Make_Unsuppress_Block
267 Make_Block_Statement (Loc,
268 Declarations => New_List (
270 Chars => Name_Suppress,
271 Pragma_Argument_Associations => New_List (
272 Make_Pragma_Argument_Association (Loc,
273 Expression => Make_Identifier (Loc, Check))))),
275 Handled_Statement_Sequence =>
276 Make_Handled_Sequence_Of_Statements (Loc,
277 Statements => Stmts));
278 end Make_Unsuppress_Block;
280 --------------------------
281 -- New_Constraint_Error --
282 --------------------------
284 function New_Constraint_Error (Loc : Source_Ptr) return Node_Id is
285 Ident_Node : Node_Id;
286 Raise_Node : Node_Id;
289 Ident_Node := New_Node (N_Identifier, Loc);
290 Set_Chars (Ident_Node, Chars (Standard_Entity (S_Constraint_Error)));
291 Set_Entity (Ident_Node, Standard_Entity (S_Constraint_Error));
292 Raise_Node := New_Node (N_Raise_Statement, Loc);
293 Set_Name (Raise_Node, Ident_Node);
295 end New_Constraint_Error;
297 -----------------------
298 -- New_External_Name --
299 -----------------------
301 function New_External_Name
302 (Related_Id : Name_Id;
303 Suffix : Character := ' ';
304 Suffix_Index : Int := 0;
305 Prefix : Character := ' ')
309 Get_Name_String (Related_Id);
311 if Prefix /= ' ' then
312 pragma Assert (Is_OK_Internal_Letter (Prefix));
314 for J in reverse 1 .. Name_Len loop
315 Name_Buffer (J + 1) := Name_Buffer (J);
318 Name_Len := Name_Len + 1;
319 Name_Buffer (1) := Prefix;
322 if Suffix /= ' ' then
323 pragma Assert (Is_OK_Internal_Letter (Suffix));
324 Name_Len := Name_Len + 1;
325 Name_Buffer (Name_Len) := Suffix;
328 if Suffix_Index /= 0 then
329 if Suffix_Index < 0 then
330 Add_Unique_Serial_Number;
332 Add_Nat_To_Name_Buffer (Suffix_Index);
337 end New_External_Name;
339 function New_External_Name
340 (Related_Id : Name_Id;
342 Suffix_Index : Int := 0;
343 Prefix : Character := ' ')
347 Get_Name_String (Related_Id);
349 if Prefix /= ' ' then
350 pragma Assert (Is_OK_Internal_Letter (Prefix));
352 for J in reverse 1 .. Name_Len loop
353 Name_Buffer (J + 1) := Name_Buffer (J);
356 Name_Len := Name_Len + 1;
357 Name_Buffer (1) := Prefix;
361 Name_Buffer (Name_Len + 1 .. Name_Len + Suffix'Length) := Suffix;
362 Name_Len := Name_Len + Suffix'Length;
365 if Suffix_Index /= 0 then
366 if Suffix_Index < 0 then
367 Add_Unique_Serial_Number;
369 Add_Nat_To_Name_Buffer (Suffix_Index);
374 end New_External_Name;
376 function New_External_Name
382 Name_Buffer (1) := Suffix;
384 Add_Nat_To_Name_Buffer (Suffix_Index);
386 end New_External_Name;
388 -----------------------
389 -- New_Internal_Name --
390 -----------------------
392 function New_Internal_Name (Id_Char : Character) return Name_Id is
394 pragma Assert (Is_OK_Internal_Letter (Id_Char));
395 Name_Buffer (1) := Id_Char;
397 Add_Unique_Serial_Number;
399 end New_Internal_Name;
401 -----------------------
402 -- New_Occurrence_Of --
403 -----------------------
405 function New_Occurrence_Of
410 Occurrence : Node_Id;
413 Occurrence := New_Node (N_Identifier, Loc);
414 Set_Chars (Occurrence, Chars (Def_Id));
415 Set_Entity (Occurrence, Def_Id);
417 if Is_Type (Def_Id) then
418 Set_Etype (Occurrence, Def_Id);
420 Set_Etype (Occurrence, Etype (Def_Id));
424 end New_Occurrence_Of;
426 ----------------------
427 -- New_Reference_To --
428 ----------------------
430 function New_Reference_To
435 Occurrence : Node_Id;
438 Occurrence := New_Node (N_Identifier, Loc);
439 Set_Chars (Occurrence, Chars (Def_Id));
440 Set_Entity (Occurrence, Def_Id);
442 end New_Reference_To;
444 -----------------------
445 -- New_Suffixed_Name --
446 -----------------------
448 function New_Suffixed_Name
449 (Related_Id : Name_Id;
454 Get_Name_String (Related_Id);
455 Name_Len := Name_Len + 1;
456 Name_Buffer (Name_Len) := '_';
457 Name_Buffer (Name_Len + 1 .. Name_Len + Suffix'Length) := Suffix;
458 Name_Len := Name_Len + Suffix'Length;
460 end New_Suffixed_Name;
466 function OK_Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id is
471 Make_Type_Conversion (Sloc (Expr),
472 Subtype_Mark => New_Occurrence_Of (Typ, Sloc (Expr)),
473 Expression => Relocate_Node (Expr));
474 Set_Conversion_OK (Result, True);
475 Set_Etype (Result, Typ);
479 --------------------------
480 -- Unchecked_Convert_To --
481 --------------------------
483 function Unchecked_Convert_To
488 Loc : constant Source_Ptr := Sloc (Expr);
492 -- If the expression is already of the correct type, then nothing
493 -- to do, except for relocating the node in case this is required.
495 if Present (Etype (Expr))
496 and then (Base_Type (Etype (Expr)) = Typ
497 or else Etype (Expr) = Typ)
499 return Relocate_Node (Expr);
501 -- Cases where the inner expression is itself an unchecked conversion
502 -- to the same type, and we can thus eliminate the outer conversion.
504 elsif Nkind (Expr) = N_Unchecked_Type_Conversion
505 and then Entity (Subtype_Mark (Expr)) = Typ
507 Result := Relocate_Node (Expr);
513 Make_Unchecked_Type_Conversion (Loc,
514 Subtype_Mark => New_Occurrence_Of (Typ, Loc),
515 Expression => Relocate_Node (Expr));
518 Set_Etype (Result, Typ);
520 end Unchecked_Convert_To;