OSDN Git Service

* sem_ch3.adb (Find_Type_Of_Subtype_Indic): If subtype indication
[pf3gnuchains/gcc-fork.git] / gcc / ada / sem_dist.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             S E M _ D I S T                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --                            $Revision: 1.182 $
10 --                                                                          --
11 --          Copyright (C) 1992-2001, Free Software Foundation, Inc.         --
12 --                                                                          --
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.                                                      --
23 --                                                                          --
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). --
26 --                                                                          --
27 ------------------------------------------------------------------------------
28
29 with Atree;    use Atree;
30 with Casing;   use Casing;
31 with Einfo;    use Einfo;
32 with Errout;   use Errout;
33 with Exp_Dist; use Exp_Dist;
34 with Exp_Tss;  use Exp_Tss;
35 with Nlists;   use Nlists;
36 with Nmake;    use Nmake;
37 with Namet;    use Namet;
38 with Opt;      use Opt;
39 with Rtsfind;  use Rtsfind;
40 with Sem;      use Sem;
41 with Sem_Res;  use Sem_Res;
42 with Sem_Util; use Sem_Util;
43 with Sinfo;    use Sinfo;
44 with Snames;   use Snames;
45 with Stand;    use Stand;
46 with Stringt;  use Stringt;
47 with Tbuild;   use Tbuild;
48 with Uname;    use Uname;
49
50 package body Sem_Dist is
51
52    -----------------------
53    -- Local Subprograms --
54    -----------------------
55
56    procedure RAS_E_Dereference (Pref : Node_Id);
57    --  Handles explicit dereference of Remote Access to Subprograms.
58
59    function Full_Qualified_Name (E : Entity_Id) return String_Id;
60    --  returns the full qualified name of the entity in lower case.
61
62    -------------------------
63    -- Add_Stub_Constructs --
64    -------------------------
65
66    procedure Add_Stub_Constructs (N : Node_Id) is
67       U    : constant Node_Id := Unit (N);
68       Spec : Entity_Id        := Empty;
69       Exp  : Node_Id          := U;         --  Unit that will be expanded
70
71    begin
72       pragma Assert (Distribution_Stub_Mode /= No_Stubs);
73
74       if Nkind (U) = N_Package_Declaration then
75          Spec := Defining_Entity (Specification (U));
76
77       elsif Nkind (U) = N_Package_Body then
78          Spec := Corresponding_Spec (U);
79
80       else pragma Assert (Nkind (U) = N_Package_Instantiation);
81          Exp  := Instance_Spec (U);
82          Spec := Defining_Entity (Specification (Exp));
83       end if;
84
85       pragma Assert (Is_Shared_Passive (Spec)
86         or else Is_Remote_Call_Interface (Spec));
87
88       if Distribution_Stub_Mode = Generate_Caller_Stub_Body then
89
90          if Is_Shared_Passive (Spec) then
91             null;
92          elsif Nkind (U) = N_Package_Body then
93             Error_Msg_N
94               ("Specification file expected from command line", U);
95          else
96             Expand_Calling_Stubs_Bodies (Exp);
97          end if;
98
99       else
100
101          if Is_Shared_Passive (Spec) then
102             Build_Passive_Partition_Stub (Exp);
103          else
104             Expand_Receiving_Stubs_Bodies (Exp);
105          end if;
106
107       end if;
108    end Add_Stub_Constructs;
109
110    -------------------------
111    -- Full_Qualified_Name --
112    -------------------------
113
114    function Full_Qualified_Name (E : Entity_Id) return String_Id is
115       Ent         : Entity_Id := E;
116       Parent_Name : String_Id := No_String;
117
118    begin
119       --  Deals properly with child units
120
121       if Nkind (Ent) = N_Defining_Program_Unit_Name then
122          Ent := Defining_Identifier (Ent);
123       end if;
124
125       --  Compute recursively the qualification. Only "Standard" has no scope.
126
127       if Present (Scope (Scope (Ent))) then
128          Parent_Name := Full_Qualified_Name (Scope (Ent));
129       end if;
130
131       --  Every entity should have a name except some expanded blocks
132       --  don't bother about those.
133
134       if Chars (Ent) = No_Name then
135          return Parent_Name;
136       end if;
137
138       --  Add a period between Name and qualification
139
140       if Parent_Name /= No_String then
141          Start_String (Parent_Name);
142          Store_String_Char (Get_Char_Code ('.'));
143
144       else
145          Start_String;
146       end if;
147
148       --  Generates the entity name in upper case
149
150       Get_Name_String (Chars (Ent));
151       Set_Casing (All_Lower_Case);
152       Store_String_Chars (Name_Buffer (1 .. Name_Len));
153       return End_String;
154    end Full_Qualified_Name;
155
156    -----------------------
157    -- Get_Subprogram_Id --
158    -----------------------
159
160    function Get_Subprogram_Id (E : Entity_Id) return Int is
161       Current_Declaration : Node_Id;
162       Result              : Int := 0;
163
164    begin
165       pragma Assert
166         (Is_Remote_Call_Interface (Scope (E))
167            and then
168              (Nkind (Parent (E)) = N_Procedure_Specification
169                 or else
170               Nkind (Parent (E)) = N_Function_Specification));
171
172       Current_Declaration :=
173         First (Visible_Declarations
174           (Package_Specification_Of_Scope (Scope (E))));
175
176       while Current_Declaration /= Empty loop
177          if Nkind (Current_Declaration) = N_Subprogram_Declaration
178            and then Comes_From_Source (Current_Declaration)
179          then
180             if Defining_Unit_Name
181                  (Specification (Current_Declaration)) = E
182             then
183                return Result;
184             end if;
185
186             Result := Result + 1;
187          end if;
188
189          Next (Current_Declaration);
190       end loop;
191
192       --  Error if we do not find it
193
194       raise Program_Error;
195    end Get_Subprogram_Id;
196
197    ------------------------
198    -- Is_All_Remote_Call --
199    ------------------------
200
201    function Is_All_Remote_Call (N : Node_Id) return Boolean is
202       Par : Node_Id;
203
204    begin
205       if (Nkind (N) = N_Function_Call
206               or else Nkind (N) = N_Procedure_Call_Statement)
207         and then Nkind (Name (N)) in N_Has_Entity
208         and then Is_Remote_Call_Interface (Entity (Name (N)))
209         and then Has_All_Calls_Remote (Scope (Entity (Name (N))))
210         and then Comes_From_Source (N)
211       then
212          Par := Parent (Entity (Name (N)));
213
214          while Present (Par)
215            and then (Nkind (Par) /= N_Package_Specification
216                        or else Is_Wrapper_Package (Defining_Entity (Par)))
217          loop
218             Par := Parent (Par);
219          end loop;
220
221          if Present (Par) then
222             return
223               not Scope_Within_Or_Same (Current_Scope, Defining_Entity (Par));
224          else
225             return False;
226          end if;
227       else
228          return False;
229       end if;
230    end Is_All_Remote_Call;
231
232    ------------------------------------
233    -- Package_Specification_Of_Scope --
234    ------------------------------------
235
236    function Package_Specification_Of_Scope (E : Entity_Id) return Node_Id is
237       N : Node_Id := Parent (E);
238    begin
239       while Nkind (N) /= N_Package_Specification loop
240          N := Parent (N);
241       end loop;
242
243       return N;
244    end Package_Specification_Of_Scope;
245
246    --------------------------
247    -- Process_Partition_ID --
248    --------------------------
249
250    procedure Process_Partition_Id (N : Node_Id) is
251       Loc            : constant Source_Ptr := Sloc (N);
252       Ety            : Entity_Id;
253       Nd             : Node_Id;
254       Get_Pt_Id      : Node_Id;
255       Get_Pt_Id_Call : Node_Id;
256       Prefix_String  : String_Id;
257       Typ            : constant Entity_Id := Etype (N);
258
259    begin
260       Ety := Entity (Prefix (N));
261
262       --  In case prefix is not a library unit entity, get the entity
263       --  of library unit.
264
265       while (Present (Scope (Ety))
266         and then Scope (Ety) /= Standard_Standard)
267         and not Is_Child_Unit (Ety)
268       loop
269          Ety := Scope (Ety);
270       end loop;
271
272       Nd := Enclosing_Lib_Unit_Node (N);
273
274       --  Retrieve the proper function to call.
275
276       if Is_Remote_Call_Interface (Ety) then
277          Get_Pt_Id := New_Occurrence_Of
278            (RTE (RE_Get_Active_Partition_Id), Loc);
279
280       elsif Is_Shared_Passive (Ety) then
281          Get_Pt_Id := New_Occurrence_Of
282            (RTE (RE_Get_Passive_Partition_Id), Loc);
283
284       else
285          Get_Pt_Id := New_Occurrence_Of
286            (RTE (RE_Get_Local_Partition_Id), Loc);
287       end if;
288
289       --  Get and store the String_Id corresponding to the name of the
290       --  library unit whose Partition_Id is needed
291
292       Get_Unit_Name_String (Get_Unit_Name (Unit_Declaration_Node (Ety)));
293
294       --  Remove seven last character ("(spec)" or " (body)").
295       --  (this is a bit nasty, should have interface for this ???)
296
297       Name_Len := Name_Len - 7;
298
299       Start_String;
300       Store_String_Chars (Name_Buffer (1 .. Name_Len));
301       Prefix_String := End_String;
302
303       --  Build the function call which will replace the attribute
304
305       if Is_Remote_Call_Interface (Ety)
306         or else Is_Shared_Passive (Ety)
307       then
308          Get_Pt_Id_Call :=
309            Make_Function_Call (Loc,
310              Name => Get_Pt_Id,
311              Parameter_Associations =>
312                New_List (Make_String_Literal (Loc, Prefix_String)));
313
314       else
315          Get_Pt_Id_Call := Make_Function_Call (Loc, Get_Pt_Id);
316
317       end if;
318
319       --  Replace the attribute node by a conversion of the function call
320       --  to the target type.
321
322       Rewrite (N, Convert_To (Typ, Get_Pt_Id_Call));
323       Analyze_And_Resolve (N, Typ);
324
325    end Process_Partition_Id;
326
327    ----------------------------------
328    -- Process_Remote_AST_Attribute --
329    ----------------------------------
330
331    procedure Process_Remote_AST_Attribute
332      (N        : Node_Id;
333       New_Type : Entity_Id)
334    is
335       Loc                   : constant Source_Ptr := Sloc (N);
336       Remote_Subp           : Entity_Id;
337       Tick_Access_Conv_Call : Node_Id;
338       Remote_Subp_Decl      : Node_Id;
339       RAS_Decl              : Node_Id;
340       RS_Pkg_Specif         : Node_Id;
341       RS_Pkg_E              : Entity_Id;
342       RAS_Pkg_E             : Entity_Id;
343       RAS_Type              : Entity_Id;
344       RAS_Name              : Name_Id;
345       Async_E               : Entity_Id;
346       Subp_Id               : Int;
347       Attribute_Subp        : Entity_Id;
348       Parameter             : Node_Id;
349
350    begin
351       --  Check if we have to expand the access attribute
352
353       Remote_Subp := Entity (Prefix (N));
354
355       if not Expander_Active then
356          return;
357
358       elsif Ekind (New_Type) = E_Record_Type then
359          RAS_Type := New_Type;
360
361       else
362          --  If the remote type has not been constructed yet, create
363          --  it and its attributes now.
364
365          Attribute_Subp := TSS (New_Type, Name_uRAS_Access);
366
367          if No (Attribute_Subp) then
368             Add_RAST_Features (Parent (New_Type));
369          end if;
370
371          RAS_Type := Equivalent_Type (New_Type);
372       end if;
373
374       RAS_Name  := Chars (RAS_Type);
375       RAS_Decl := Parent (RAS_Type);
376       Attribute_Subp := TSS (RAS_Type, Name_uRAS_Access);
377
378       RAS_Pkg_E  := Defining_Entity (Parent (RAS_Decl));
379       Remote_Subp_Decl := Unit_Declaration_Node (Remote_Subp);
380
381       if Nkind (Remote_Subp_Decl) = N_Subprogram_Body then
382          Remote_Subp := Corresponding_Spec (Remote_Subp_Decl);
383          Remote_Subp_Decl := Unit_Declaration_Node (Remote_Subp);
384       end if;
385
386       RS_Pkg_Specif := Parent (Remote_Subp_Decl);
387       RS_Pkg_E := Defining_Entity (RS_Pkg_Specif);
388
389       Subp_Id := Get_Subprogram_Id (Remote_Subp);
390
391       if Ekind (Remote_Subp) = E_Procedure
392         and then Is_Asynchronous (Remote_Subp)
393       then
394          Async_E := Standard_True;
395       else
396          Async_E := Standard_False;
397       end if;
398
399       --  Right now, we do not call the Name_uAddress_Resolver subprogram,
400       --  which means that we end up with a Null_Address value in the ras
401       --  field: each dereference of an RAS will go through the PCS, which
402       --  is authorized but potentially not very efficient ???
403
404       Parameter := New_Occurrence_Of (RTE (RE_Null_Address), Loc);
405
406       Tick_Access_Conv_Call :=
407         Make_Function_Call (Loc,
408           Name => New_Occurrence_Of (Attribute_Subp, Loc),
409           Parameter_Associations =>
410             New_List (
411               Parameter,
412               Make_String_Literal (Loc, Full_Qualified_Name (RS_Pkg_E)),
413               Make_Integer_Literal (Loc, Subp_Id),
414               New_Occurrence_Of (Async_E, Loc)));
415
416       Rewrite (N, Tick_Access_Conv_Call);
417       Analyze_And_Resolve (N, RAS_Type);
418
419    end Process_Remote_AST_Attribute;
420
421    ------------------------------------
422    -- Process_Remote_AST_Declaration --
423    ------------------------------------
424
425    procedure Process_Remote_AST_Declaration (N : Node_Id) is
426       Loc           : constant Source_Ptr := Sloc (N);
427       User_Type     : constant Node_Id := Defining_Identifier (N);
428       Fat_Type      : constant Entity_Id :=
429                         Make_Defining_Identifier
430                           (Loc, Chars (User_Type));
431       New_Type_Decl : Node_Id;
432
433    begin
434       --  We add a record type declaration for the equivalent fat pointer type
435
436       New_Type_Decl :=
437         Make_Full_Type_Declaration (Loc,
438           Defining_Identifier => Fat_Type,
439           Type_Definition =>
440             Make_Record_Definition (Loc,
441               Component_List =>
442                 Make_Component_List (Loc,
443                   Component_Items => New_List (
444
445                     Make_Component_Declaration (Loc,
446                       Defining_Identifier =>
447                         Make_Defining_Identifier (Loc,
448                           Chars => Name_Ras),
449                       Subtype_Indication =>
450                         New_Occurrence_Of
451                           (RTE (RE_Unsigned_64), Loc)),
452
453                     Make_Component_Declaration (Loc,
454                       Defining_Identifier =>
455                         Make_Defining_Identifier (Loc,
456                           Chars => Name_Origin),
457                       Subtype_Indication =>
458                         New_Reference_To
459                           (Standard_Integer,
460                            Loc)),
461
462                     Make_Component_Declaration (Loc,
463                       Defining_Identifier =>
464                         Make_Defining_Identifier (Loc,
465                           Chars => Name_Receiver),
466                       Subtype_Indication =>
467                         New_Reference_To
468                           (RTE (RE_Unsigned_64), Loc)),
469
470                     Make_Component_Declaration (Loc,
471                       Defining_Identifier =>
472                         Make_Defining_Identifier (Loc,
473                           Chars => Name_Subp_Id),
474                       Subtype_Indication =>
475                         New_Reference_To
476                           (Standard_Natural,
477                            Loc)),
478
479                     Make_Component_Declaration (Loc,
480                       Defining_Identifier =>
481                         Make_Defining_Identifier (Loc,
482                           Chars => Name_Async),
483                       Subtype_Indication =>
484                         New_Reference_To
485                           (Standard_Boolean,
486                            Loc))))));
487
488       Insert_After (N, New_Type_Decl);
489       Set_Equivalent_Type (User_Type, Fat_Type);
490       Set_Corresponding_Remote_Type (Fat_Type, User_Type);
491
492       --  The reason we suppress the initialization procedure is that we know
493       --  that no initialization is required (even if Initialize_Scalars mode
494       --  is active), and there are order of elaboration problems if we do try
495       --  to generate an Init_Proc for this created record type.
496
497       Set_Suppress_Init_Proc (Fat_Type);
498
499       if Expander_Active then
500          Add_RAST_Features (Parent (User_Type));
501       end if;
502
503    end Process_Remote_AST_Declaration;
504
505    -----------------------
506    -- RAS_E_Dereference --
507    -----------------------
508
509    procedure RAS_E_Dereference (Pref : Node_Id) is
510       Loc             : constant Source_Ptr := Sloc (Pref);
511       Call_Node       : Node_Id;
512       New_Type        : constant Entity_Id := Etype (Pref);
513       RAS             : constant Entity_Id :=
514                           Corresponding_Remote_Type (New_Type);
515       RAS_Decl        : constant Node_Id   := Parent (RAS);
516       Explicit_Deref  : constant Node_Id   := Parent (Pref);
517       Deref_Subp_Call : constant Node_Id   := Parent (Explicit_Deref);
518       Deref_Proc      : Entity_Id;
519       Params          : List_Id;
520
521    begin
522       if Nkind (Deref_Subp_Call) = N_Procedure_Call_Statement then
523          Params := Parameter_Associations (Deref_Subp_Call);
524
525          if Present (Params) then
526             Prepend (Pref, Params);
527          else
528             Params := New_List (Pref);
529          end if;
530
531       elsif Nkind (Deref_Subp_Call) = N_Indexed_Component then
532
533          Params := Expressions (Deref_Subp_Call);
534
535          if Present (Params) then
536             Prepend (Pref, Params);
537          else
538             Params := New_List (Pref);
539          end if;
540
541       else
542          --  Context is not a call.
543
544          return;
545       end if;
546
547       Deref_Proc := TSS (New_Type, Name_uRAS_Dereference);
548
549       if not Expander_Active then
550          return;
551
552       elsif No (Deref_Proc) then
553          Add_RAST_Features (RAS_Decl);
554          Deref_Proc := TSS (New_Type, Name_uRAS_Dereference);
555       end if;
556
557       if Ekind (Deref_Proc) = E_Function then
558          Call_Node :=
559            Make_Function_Call (Loc,
560               Name => New_Occurrence_Of (Deref_Proc, Loc),
561               Parameter_Associations => Params);
562
563       else
564          Call_Node :=
565            Make_Procedure_Call_Statement (Loc,
566               Name => New_Occurrence_Of (Deref_Proc, Loc),
567               Parameter_Associations => Params);
568       end if;
569
570       Rewrite (Deref_Subp_Call, Call_Node);
571       Analyze (Deref_Subp_Call);
572    end RAS_E_Dereference;
573
574    ------------------------------
575    -- Remote_AST_E_Dereference --
576    ------------------------------
577
578    function Remote_AST_E_Dereference (P : Node_Id) return Boolean
579    is
580       ET : constant Entity_Id  := Etype (P);
581
582    begin
583       --  Perform the changes only on original dereferences, and only if
584       --  we are generating code.
585
586       if Comes_From_Source (P)
587         and then Is_Record_Type (ET)
588         and then (Is_Remote_Call_Interface (ET)
589                    or else Is_Remote_Types (ET))
590         and then Present (Corresponding_Remote_Type (ET))
591         and then (Nkind (Parent (Parent (P))) = N_Procedure_Call_Statement
592                    or else Nkind (Parent (Parent (P))) = N_Indexed_Component)
593         and then Expander_Active
594       then
595          RAS_E_Dereference (P);
596          return True;
597       else
598          return False;
599       end if;
600    end Remote_AST_E_Dereference;
601
602    ------------------------------
603    -- Remote_AST_I_Dereference --
604    ------------------------------
605
606    function Remote_AST_I_Dereference (P : Node_Id) return Boolean
607    is
608       ET     : constant Entity_Id  := Etype (P);
609       Deref  : Node_Id;
610    begin
611
612       if Comes_From_Source (P)
613         and then (Is_Remote_Call_Interface (ET)
614                    or else Is_Remote_Types (ET))
615         and then Present (Corresponding_Remote_Type (ET))
616         and then Ekind (Entity (P)) /= E_Function
617       then
618          Deref :=
619            Make_Explicit_Dereference (Sloc (P),
620              Prefix => Relocate_Node (P));
621          Rewrite (P, Deref);
622          Set_Etype (P, ET);
623          RAS_E_Dereference (Prefix (P));
624          return True;
625       end if;
626
627       return False;
628    end Remote_AST_I_Dereference;
629
630    ---------------------------
631    -- Remote_AST_Null_Value --
632    ---------------------------
633
634    function Remote_AST_Null_Value
635      (N    : Node_Id;
636       Typ  : Entity_Id)
637       return Boolean
638    is
639       Loc         : constant Source_Ptr := Sloc (N);
640       Target_Type : Entity_Id;
641
642    begin
643       if not Expander_Active then
644          return False;
645
646       elsif Ekind (Typ) = E_Access_Subprogram_Type
647         and then (Is_Remote_Call_Interface (Typ)
648                     or else Is_Remote_Types (Typ))
649         and then Comes_From_Source (N)
650         and then Expander_Active
651       then
652          --  Any null that comes from source and is of the RAS type must
653          --  be expanded, except if expansion is not active (nothing
654          --  gets expanded into the equivalent record type).
655
656          Target_Type := Equivalent_Type (Typ);
657
658       elsif Ekind (Typ) = E_Record_Type
659         and then Present (Corresponding_Remote_Type (Typ))
660       then
661
662          --  This is a record type representing a RAS type, this must be
663          --  expanded.
664
665          Target_Type := Typ;
666
667       else
668          --  We do not have to handle this case
669
670          return False;
671
672       end if;
673
674       Rewrite (N,
675         Make_Aggregate (Loc,
676           Expressions => New_List (
677             Make_Integer_Literal (Loc, 0),                  -- Ras
678             Make_Integer_Literal (Loc, 0),                  -- Origin
679             Make_Integer_Literal (Loc, 0),                  -- Receiver
680             Make_Integer_Literal (Loc, 0),                  -- Subp_Id
681             New_Occurrence_Of (Standard_False, Loc))));     -- Asyn
682       Analyze_And_Resolve (N, Target_Type);
683       return True;
684    end Remote_AST_Null_Value;
685
686 end Sem_Dist;