OSDN Git Service

2007-08-14 Robert Dewar <dewar@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / tbuild.adb
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-2007, 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 2,  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 COPYING.  If not, write --
19 -- to  the  Free Software Foundation,  51  Franklin  Street,  Fifth  Floor, --
20 -- Boston, MA 02110-1301, USA.                                              --
21 --                                                                          --
22 -- GNAT was originally developed  by the GNAT team at  New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
24 --                                                                          --
25 ------------------------------------------------------------------------------
26
27 with Atree;    use Atree;
28 with Einfo;    use Einfo;
29 with Elists;   use Elists;
30 with Lib;      use Lib;
31 with Nlists;   use Nlists;
32 with Nmake;    use Nmake;
33 with Opt;      use Opt;
34 with Restrict; use Restrict;
35 with Rident;   use Rident;
36 with Sinfo;    use Sinfo;
37 with Snames;   use Snames;
38 with Stand;    use Stand;
39 with Stringt;  use Stringt;
40 with Uintp;    use Uintp;
41
42 package body Tbuild is
43
44    -----------------------
45    -- Local Subprograms --
46    -----------------------
47
48    procedure Add_Unique_Serial_Number;
49    --  Add a unique serialization to the string in the Name_Buffer. This
50    --  consists of a unit specific serial number, and b/s for body/spec.
51
52    ------------------------------
53    -- Add_Unique_Serial_Number --
54    ------------------------------
55
56    Config_Serial_Number : Nat := 0;
57    --  Counter for use in config pragmas, see comment below
58
59    procedure Add_Unique_Serial_Number is
60    begin
61       --  If we are analyzing configuration pragmas, Cunit (Main_Unit) will
62       --  not be set yet. This happens for example when analyzing static
63       --  string expressions in configuration pragmas. For this case, we
64       --  just maintain a local counter, defined above and we do not need
65       --  to add a b or s indication in this case.
66
67       if No (Cunit (Current_Sem_Unit)) then
68          Config_Serial_Number := Config_Serial_Number + 1;
69          Add_Nat_To_Name_Buffer (Config_Serial_Number);
70          return;
71
72       --  Normal case, within a unit
73
74       else
75          declare
76             Unit_Node : constant Node_Id := Unit (Cunit (Current_Sem_Unit));
77
78          begin
79             Add_Nat_To_Name_Buffer (Increment_Serial_Number);
80
81             --  Add either b or s, depending on whether current unit is a spec
82             --  or a body. This is needed because we may generate the same name
83             --  in a spec and a body otherwise.
84
85             Name_Len := Name_Len + 1;
86
87             if Nkind (Unit_Node) = N_Package_Declaration
88               or else Nkind (Unit_Node) = N_Subprogram_Declaration
89               or else Nkind (Unit_Node) in N_Generic_Declaration
90             then
91                Name_Buffer (Name_Len) := 's';
92             else
93                Name_Buffer (Name_Len) := 'b';
94             end if;
95          end;
96       end if;
97    end Add_Unique_Serial_Number;
98
99    ----------------
100    -- Checks_Off --
101    ----------------
102
103    function Checks_Off (N : Node_Id) return Node_Id is
104    begin
105       return
106         Make_Unchecked_Expression (Sloc (N),
107           Expression => N);
108    end Checks_Off;
109
110    ----------------
111    -- Convert_To --
112    ----------------
113
114    function Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id is
115       Result : Node_Id;
116
117    begin
118       if Present (Etype (Expr))
119         and then (Etype (Expr)) = Typ
120       then
121          return Relocate_Node (Expr);
122       else
123          Result :=
124            Make_Type_Conversion (Sloc (Expr),
125              Subtype_Mark => New_Occurrence_Of (Typ, Sloc (Expr)),
126              Expression => Relocate_Node (Expr));
127
128          Set_Etype (Result, Typ);
129          return Result;
130       end if;
131    end Convert_To;
132
133    ------------------
134    -- Discard_List --
135    ------------------
136
137    procedure Discard_List (L : List_Id) is
138       pragma Warnings (Off, L);
139    begin
140       null;
141    end Discard_List;
142
143    ------------------
144    -- Discard_Node --
145    ------------------
146
147    procedure Discard_Node (N : Node_Or_Entity_Id) is
148       pragma Warnings (Off, N);
149    begin
150       null;
151    end Discard_Node;
152
153    -------------------------------------------
154    -- Make_Byte_Aligned_Attribute_Reference --
155    -------------------------------------------
156
157    function Make_Byte_Aligned_Attribute_Reference
158      (Sloc           : Source_Ptr;
159       Prefix         : Node_Id;
160       Attribute_Name : Name_Id)
161       return           Node_Id
162    is
163       N : constant Node_Id :=
164             Make_Attribute_Reference (Sloc,
165               Prefix        => Prefix,
166               Attribute_Name => Attribute_Name);
167
168    begin
169       pragma Assert (Attribute_Name = Name_Address
170                        or else
171                      Attribute_Name = Name_Unrestricted_Access);
172       Set_Must_Be_Byte_Aligned (N, True);
173       return N;
174    end Make_Byte_Aligned_Attribute_Reference;
175
176    --------------------
177    -- Make_DT_Access --
178    --------------------
179
180    function Make_DT_Access
181      (Loc : Source_Ptr;
182       Rec : Node_Id;
183       Typ : Entity_Id) return Node_Id
184    is
185       Full_Type : Entity_Id := Typ;
186
187    begin
188       if Is_Private_Type (Typ) then
189          Full_Type := Underlying_Type (Typ);
190       end if;
191
192       return
193         Unchecked_Convert_To (
194           New_Occurrence_Of
195             (Etype (Node (First_Elmt (Access_Disp_Table (Full_Type)))), Loc),
196           Make_Selected_Component (Loc,
197             Prefix => New_Copy (Rec),
198             Selector_Name =>
199               New_Reference_To (First_Tag_Component (Full_Type), Loc)));
200    end Make_DT_Access;
201
202    -------------------------------------
203    -- Make_Implicit_Exception_Handler --
204    -------------------------------------
205
206    function Make_Implicit_Exception_Handler
207      (Sloc              : Source_Ptr;
208       Choice_Parameter  : Node_Id := Empty;
209       Exception_Choices : List_Id;
210       Statements        : List_Id) return Node_Id
211    is
212       Handler : Node_Id;
213       Loc     : Source_Ptr;
214
215    begin
216       --  Set the source location only when debugging the expanded code
217
218       --  When debugging the source code directly, we do not want the compiler
219       --  to associate this implicit exception handler with any specific source
220       --  line, because it can potentially confuse the debugger. The most
221       --  damaging situation would arise when the debugger tries to insert a
222       --  breakpoint at a certain line. If the code of the associated implicit
223       --  exception handler is generated before the code of that line, then the
224       --  debugger will end up inserting the breakpoint inside the exception
225       --  handler, rather than the code the user intended to break on. As a
226       --  result, it is likely that the program will not hit the breakpoint
227       --  as expected.
228
229       if Debug_Generated_Code then
230          Loc := Sloc;
231       else
232          Loc := No_Location;
233       end if;
234
235       Handler :=
236         Make_Exception_Handler
237           (Loc, Choice_Parameter, Exception_Choices, Statements);
238       Set_Local_Raise_Statements (Handler, No_Elist);
239       return Handler;
240    end Make_Implicit_Exception_Handler;
241
242    --------------------------------
243    -- Make_Implicit_If_Statement --
244    --------------------------------
245
246    function Make_Implicit_If_Statement
247      (Node            : Node_Id;
248       Condition       : Node_Id;
249       Then_Statements : List_Id;
250       Elsif_Parts     : List_Id := No_List;
251       Else_Statements : List_Id := No_List) return Node_Id
252    is
253    begin
254       Check_Restriction (No_Implicit_Conditionals, Node);
255
256       return Make_If_Statement (Sloc (Node),
257         Condition,
258         Then_Statements,
259         Elsif_Parts,
260         Else_Statements);
261    end Make_Implicit_If_Statement;
262
263    -------------------------------------
264    -- Make_Implicit_Label_Declaration --
265    -------------------------------------
266
267    function Make_Implicit_Label_Declaration
268      (Loc                 : Source_Ptr;
269       Defining_Identifier : Node_Id;
270       Label_Construct     : Node_Id) return Node_Id
271    is
272       N : constant Node_Id :=
273             Make_Implicit_Label_Declaration (Loc, Defining_Identifier);
274    begin
275       Set_Label_Construct (N, Label_Construct);
276       return N;
277    end Make_Implicit_Label_Declaration;
278
279    ----------------------------------
280    -- Make_Implicit_Loop_Statement --
281    ----------------------------------
282
283    function Make_Implicit_Loop_Statement
284      (Node                   : Node_Id;
285       Statements             : List_Id;
286       Identifier             : Node_Id := Empty;
287       Iteration_Scheme       : Node_Id := Empty;
288       Has_Created_Identifier : Boolean := False;
289       End_Label              : Node_Id := Empty) return Node_Id
290    is
291    begin
292       Check_Restriction (No_Implicit_Loops, Node);
293
294       if Present (Iteration_Scheme)
295         and then Present (Condition (Iteration_Scheme))
296       then
297          Check_Restriction (No_Implicit_Conditionals, Node);
298       end if;
299
300       return Make_Loop_Statement (Sloc (Node),
301         Identifier             => Identifier,
302         Iteration_Scheme       => Iteration_Scheme,
303         Statements             => Statements,
304         Has_Created_Identifier => Has_Created_Identifier,
305         End_Label              => End_Label);
306    end Make_Implicit_Loop_Statement;
307
308    --------------------------
309    -- Make_Integer_Literal --
310    ---------------------------
311
312    function Make_Integer_Literal
313      (Loc    : Source_Ptr;
314       Intval : Int) return Node_Id
315    is
316    begin
317       return Make_Integer_Literal (Loc, UI_From_Int (Intval));
318    end Make_Integer_Literal;
319
320    --------------------------------
321    -- Make_Linker_Section_Pragma --
322    --------------------------------
323
324    function Make_Linker_Section_Pragma
325      (Ent : Entity_Id;
326       Loc : Source_Ptr;
327       Sec : String) return Node_Id
328    is
329       LS : Node_Id;
330
331    begin
332       LS :=
333         Make_Pragma
334           (Loc,
335            Name_Linker_Section,
336            New_List
337              (Make_Pragma_Argument_Association
338                 (Sloc => Loc,
339                  Expression => New_Occurrence_Of (Ent, Loc)),
340               Make_Pragma_Argument_Association
341                 (Sloc => Loc,
342                  Expression =>
343                    Make_String_Literal
344                      (Sloc => Loc,
345                       Strval => Sec))));
346
347       Set_Has_Gigi_Rep_Item (Ent);
348       return LS;
349    end Make_Linker_Section_Pragma;
350
351    ---------------------------------
352    -- Make_Raise_Constraint_Error --
353    ---------------------------------
354
355    function Make_Raise_Constraint_Error
356      (Sloc      : Source_Ptr;
357       Condition : Node_Id := Empty;
358       Reason    : RT_Exception_Code) return Node_Id
359    is
360    begin
361       pragma Assert (Reason in RT_CE_Exceptions);
362       return
363         Make_Raise_Constraint_Error (Sloc,
364           Condition => Condition,
365           Reason =>
366             UI_From_Int (RT_Exception_Code'Pos (Reason)));
367    end Make_Raise_Constraint_Error;
368
369    ------------------------------
370    -- Make_Raise_Program_Error --
371    ------------------------------
372
373    function Make_Raise_Program_Error
374      (Sloc      : Source_Ptr;
375       Condition : Node_Id := Empty;
376       Reason    : RT_Exception_Code) return Node_Id
377    is
378    begin
379       pragma Assert (Reason in RT_PE_Exceptions);
380       return
381         Make_Raise_Program_Error (Sloc,
382           Condition => Condition,
383           Reason =>
384             UI_From_Int (RT_Exception_Code'Pos (Reason)));
385    end Make_Raise_Program_Error;
386
387    ------------------------------
388    -- Make_Raise_Storage_Error --
389    ------------------------------
390
391    function Make_Raise_Storage_Error
392      (Sloc      : Source_Ptr;
393       Condition : Node_Id := Empty;
394       Reason    : RT_Exception_Code) return Node_Id
395    is
396    begin
397       pragma Assert (Reason in RT_SE_Exceptions);
398       return
399         Make_Raise_Storage_Error (Sloc,
400           Condition => Condition,
401           Reason =>
402             UI_From_Int (RT_Exception_Code'Pos (Reason)));
403    end Make_Raise_Storage_Error;
404
405    -------------------------
406    -- Make_String_Literal --
407    -------------------------
408
409    function Make_String_Literal
410      (Sloc   : Source_Ptr;
411       Strval : String) return Node_Id
412    is
413    begin
414       Start_String;
415       Store_String_Chars (Strval);
416       return
417         Make_String_Literal (Sloc,
418           Strval => End_String);
419    end Make_String_Literal;
420
421    ---------------------------
422    -- Make_Unsuppress_Block --
423    ---------------------------
424
425    --  Generates the following expansion:
426
427    --    declare
428    --       pragma Suppress (<check>);
429    --    begin
430    --       <stmts>
431    --    end;
432
433    function Make_Unsuppress_Block
434      (Loc   : Source_Ptr;
435       Check : Name_Id;
436       Stmts : List_Id) return Node_Id
437    is
438    begin
439       return
440         Make_Block_Statement (Loc,
441           Declarations => New_List (
442             Make_Pragma (Loc,
443               Chars => Name_Suppress,
444               Pragma_Argument_Associations => New_List (
445                 Make_Pragma_Argument_Association (Loc,
446                   Expression => Make_Identifier (Loc, Check))))),
447
448           Handled_Statement_Sequence =>
449             Make_Handled_Sequence_Of_Statements (Loc,
450               Statements => Stmts));
451    end Make_Unsuppress_Block;
452
453    --------------------------
454    -- New_Constraint_Error --
455    --------------------------
456
457    function New_Constraint_Error (Loc : Source_Ptr) return Node_Id is
458       Ident_Node : Node_Id;
459       Raise_Node : Node_Id;
460
461    begin
462       Ident_Node := New_Node (N_Identifier, Loc);
463       Set_Chars (Ident_Node, Chars (Standard_Entity (S_Constraint_Error)));
464       Set_Entity (Ident_Node, Standard_Entity (S_Constraint_Error));
465       Raise_Node := New_Node (N_Raise_Statement, Loc);
466       Set_Name (Raise_Node, Ident_Node);
467       return Raise_Node;
468    end New_Constraint_Error;
469
470    -----------------------
471    -- New_External_Name --
472    -----------------------
473
474    function New_External_Name
475      (Related_Id   : Name_Id;
476       Suffix       : Character := ' ';
477       Suffix_Index : Int       := 0;
478       Prefix       : Character := ' ') return Name_Id
479    is
480    begin
481       Get_Name_String (Related_Id);
482
483       if Prefix /= ' ' then
484          pragma Assert (Is_OK_Internal_Letter (Prefix));
485
486          for J in reverse 1 .. Name_Len loop
487             Name_Buffer (J + 1) := Name_Buffer (J);
488          end loop;
489
490          Name_Len := Name_Len + 1;
491          Name_Buffer (1) := Prefix;
492       end if;
493
494       if Suffix /= ' ' then
495          pragma Assert (Is_OK_Internal_Letter (Suffix));
496          Name_Len := Name_Len + 1;
497          Name_Buffer (Name_Len) := Suffix;
498       end if;
499
500       if Suffix_Index /= 0 then
501          if Suffix_Index < 0 then
502             Add_Unique_Serial_Number;
503          else
504             Add_Nat_To_Name_Buffer (Suffix_Index);
505          end if;
506       end if;
507
508       return Name_Find;
509    end New_External_Name;
510
511    function New_External_Name
512      (Related_Id   : Name_Id;
513       Suffix       : String;
514       Suffix_Index : Int       := 0;
515       Prefix       : Character := ' ') return Name_Id
516    is
517    begin
518       Get_Name_String (Related_Id);
519
520       if Prefix /= ' ' then
521          pragma Assert (Is_OK_Internal_Letter (Prefix));
522
523          for J in reverse 1 .. Name_Len loop
524             Name_Buffer (J + 1) := Name_Buffer (J);
525          end loop;
526
527          Name_Len := Name_Len + 1;
528          Name_Buffer (1) := Prefix;
529       end if;
530
531       if Suffix /= "" then
532          Name_Buffer (Name_Len + 1 .. Name_Len + Suffix'Length) := Suffix;
533          Name_Len := Name_Len + Suffix'Length;
534       end if;
535
536       if Suffix_Index /= 0 then
537          if Suffix_Index < 0 then
538             Add_Unique_Serial_Number;
539          else
540             Add_Nat_To_Name_Buffer (Suffix_Index);
541          end if;
542       end if;
543
544       return Name_Find;
545    end New_External_Name;
546
547    function New_External_Name
548      (Suffix       : Character;
549       Suffix_Index : Nat) return Name_Id
550    is
551    begin
552       Name_Buffer (1) := Suffix;
553       Name_Len := 1;
554       Add_Nat_To_Name_Buffer (Suffix_Index);
555       return Name_Find;
556    end New_External_Name;
557
558    -----------------------
559    -- New_Internal_Name --
560    -----------------------
561
562    function New_Internal_Name (Id_Char : Character) return Name_Id is
563    begin
564       pragma Assert (Is_OK_Internal_Letter (Id_Char));
565       Name_Buffer (1) := Id_Char;
566       Name_Len := 1;
567       Add_Unique_Serial_Number;
568       return Name_Enter;
569    end New_Internal_Name;
570
571    -----------------------
572    -- New_Occurrence_Of --
573    -----------------------
574
575    function New_Occurrence_Of
576      (Def_Id : Entity_Id;
577       Loc    : Source_Ptr) return Node_Id
578    is
579       Occurrence : Node_Id;
580
581    begin
582       Occurrence := New_Node (N_Identifier, Loc);
583       Set_Chars (Occurrence, Chars (Def_Id));
584       Set_Entity (Occurrence, Def_Id);
585
586       if Is_Type (Def_Id) then
587          Set_Etype (Occurrence, Def_Id);
588       else
589          Set_Etype (Occurrence, Etype (Def_Id));
590       end if;
591
592       return Occurrence;
593    end New_Occurrence_Of;
594
595    ----------------------
596    -- New_Reference_To --
597    ----------------------
598
599    function New_Reference_To
600      (Def_Id : Entity_Id;
601       Loc    : Source_Ptr) return Node_Id
602    is
603       Occurrence : Node_Id;
604
605    begin
606       Occurrence := New_Node (N_Identifier, Loc);
607       Set_Chars (Occurrence, Chars (Def_Id));
608       Set_Entity (Occurrence, Def_Id);
609       return Occurrence;
610    end New_Reference_To;
611
612    -----------------------
613    -- New_Suffixed_Name --
614    -----------------------
615
616    function New_Suffixed_Name
617      (Related_Id : Name_Id;
618       Suffix     : String) return Name_Id
619    is
620    begin
621       Get_Name_String (Related_Id);
622       Name_Len := Name_Len + 1;
623       Name_Buffer (Name_Len) := '_';
624       Name_Buffer (Name_Len + 1 .. Name_Len + Suffix'Length) := Suffix;
625       Name_Len := Name_Len + Suffix'Length;
626       return Name_Find;
627    end New_Suffixed_Name;
628
629    -------------------
630    -- OK_Convert_To --
631    -------------------
632
633    function OK_Convert_To (Typ : Entity_Id; Expr : Node_Id) return Node_Id is
634       Result : Node_Id;
635    begin
636       Result :=
637         Make_Type_Conversion (Sloc (Expr),
638           Subtype_Mark => New_Occurrence_Of (Typ, Sloc (Expr)),
639           Expression   => Relocate_Node (Expr));
640       Set_Conversion_OK (Result, True);
641       Set_Etype (Result, Typ);
642       return Result;
643    end OK_Convert_To;
644
645    --------------------------
646    -- Unchecked_Convert_To --
647    --------------------------
648
649    function Unchecked_Convert_To
650      (Typ  : Entity_Id;
651       Expr : Node_Id) return Node_Id
652    is
653       Loc    : constant Source_Ptr := Sloc (Expr);
654       Result : Node_Id;
655
656    begin
657       --  If the expression is already of the correct type, then nothing
658       --  to do, except for relocating the node in case this is required.
659
660       if Present (Etype (Expr))
661         and then (Base_Type (Etype (Expr)) = Typ
662                    or else Etype (Expr) = Typ)
663       then
664          return Relocate_Node (Expr);
665
666       --  Cases where the inner expression is itself an unchecked conversion
667       --  to the same type, and we can thus eliminate the outer conversion.
668
669       elsif Nkind (Expr) = N_Unchecked_Type_Conversion
670         and then Entity (Subtype_Mark (Expr)) = Typ
671       then
672          Result := Relocate_Node (Expr);
673
674       elsif Nkind (Expr) = N_Null
675         and then Is_Access_Type (Typ)
676       then
677          --  No need for a conversion
678
679          Result := Relocate_Node (Expr);
680
681       --  All other cases
682
683       else
684          Result :=
685            Make_Unchecked_Type_Conversion (Loc,
686              Subtype_Mark => New_Occurrence_Of (Typ, Loc),
687              Expression   => Relocate_Node (Expr));
688       end if;
689
690       Set_Etype (Result, Typ);
691       return Result;
692    end Unchecked_Convert_To;
693
694 end Tbuild;