OSDN Git Service

* gcc-interface/trans.c (Call_to_gnu): Robustify test for function case
[pf3gnuchains/gcc-fork.git] / gcc / ada / exp_alfa.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             E X P _ A L F A                              --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --          Copyright (C) 1992-2011, 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 Einfo;    use Einfo;
28 with Exp_Attr; use Exp_Attr;
29 with Exp_Ch4;  use Exp_Ch4;
30 with Exp_Ch6;  use Exp_Ch6;
31 with Exp_Dbug; use Exp_Dbug;
32 with Exp_Util; use Exp_Util;
33 with Nlists;   use Nlists;
34 with Rtsfind;  use Rtsfind;
35 with Sem_Aux;  use Sem_Aux;
36 with Sem_Res;  use Sem_Res;
37 with Sem_Util; use Sem_Util;
38 with Sinfo;    use Sinfo;
39 with Snames;   use Snames;
40 with Stand;    use Stand;
41 with Tbuild;   use Tbuild;
42
43 package body Exp_Alfa is
44
45    -----------------------
46    -- Local Subprograms --
47    -----------------------
48
49    procedure Expand_Alfa_Call (N : Node_Id);
50    --  This procedure contains common processing for function and procedure
51    --  calls:
52    --    * expansion of actuals to introduce necessary temporaries
53    --    * replacement of renaming by subprogram renamed
54
55    procedure Expand_Alfa_N_Attribute_Reference (N : Node_Id);
56    --  Expand attributes 'Old and 'Result only
57
58    procedure Expand_Alfa_N_In (N : Node_Id);
59    --  Expand set membership into individual ones
60
61    procedure Expand_Alfa_N_Object_Renaming_Declaration (N : Node_Id);
62    --  Perform name evaluation for a renamed object
63
64    procedure Expand_Alfa_N_Simple_Return_Statement (N : Node_Id);
65    --  Insert conversion on function return if necessary
66
67    procedure Expand_Alfa_Simple_Function_Return (N : Node_Id);
68    --  Expand simple return from function
69
70    procedure Expand_Potential_Renaming (N : Node_Id);
71    --  N denotes a N_Identifier or N_Expanded_Name. If N references a renaming,
72    --  replace N with the renamed object.
73
74    -----------------
75    -- Expand_Alfa --
76    -----------------
77
78    procedure Expand_Alfa (N : Node_Id) is
79    begin
80       case Nkind (N) is
81          when N_Attribute_Reference =>
82             Expand_Alfa_N_Attribute_Reference (N);
83
84          when N_Block_Statement     |
85               N_Package_Body        |
86               N_Package_Declaration |
87               N_Subprogram_Body     =>
88             Qualify_Entity_Names (N);
89
90          when N_Function_Call            |
91               N_Procedure_Call_Statement =>
92             Expand_Alfa_Call (N);
93
94          when N_Expanded_Name |
95               N_Identifier    =>
96             Expand_Potential_Renaming (N);
97
98          when N_In =>
99             Expand_Alfa_N_In (N);
100
101          when N_Not_In =>
102             Expand_N_Not_In (N);
103
104          when N_Object_Renaming_Declaration =>
105             Expand_Alfa_N_Object_Renaming_Declaration (N);
106
107          when N_Simple_Return_Statement =>
108             Expand_Alfa_N_Simple_Return_Statement (N);
109
110          when others =>
111             null;
112       end case;
113    end Expand_Alfa;
114
115    ----------------------
116    -- Expand_Alfa_Call --
117    ----------------------
118
119    procedure Expand_Alfa_Call (N : Node_Id) is
120       Call_Node   : constant Node_Id := N;
121       Parent_Subp : Entity_Id;
122       Subp        : Entity_Id;
123
124    begin
125       --  Ignore if previous error
126
127       if Nkind (Call_Node) in N_Has_Etype
128         and then Etype (Call_Node) = Any_Type
129       then
130          return;
131       end if;
132
133       --  Call using access to subprogram with explicit dereference
134
135       if Nkind (Name (Call_Node)) = N_Explicit_Dereference then
136          Subp        := Etype (Name (Call_Node));
137          Parent_Subp := Empty;
138
139       --  Case of call to simple entry, where the Name is a selected component
140       --  whose prefix is the task, and whose selector name is the entry name
141
142       elsif Nkind (Name (Call_Node)) = N_Selected_Component then
143          Subp        := Entity (Selector_Name (Name (Call_Node)));
144          Parent_Subp := Empty;
145
146       --  Case of call to member of entry family, where Name is an indexed
147       --  component, with the prefix being a selected component giving the
148       --  task and entry family name, and the index being the entry index.
149
150       elsif Nkind (Name (Call_Node)) = N_Indexed_Component then
151          Subp        := Entity (Selector_Name (Prefix (Name (Call_Node))));
152          Parent_Subp := Empty;
153
154       --  Normal case
155
156       else
157          Subp        := Entity (Name (Call_Node));
158          Parent_Subp := Alias (Subp);
159       end if;
160
161       --  Various expansion activities for actuals are carried out
162
163       Expand_Actuals (N, Subp);
164
165       --  If the subprogram is a renaming, replace it in the call with the name
166       --  of the actual subprogram being called.
167
168       if Present (Parent_Subp) then
169          Parent_Subp := Ultimate_Alias (Parent_Subp);
170
171          --  The below setting of Entity is suspect, see F109-018 discussion???
172
173          Set_Entity (Name (Call_Node), Parent_Subp);
174       end if;
175    end Expand_Alfa_Call;
176
177    ---------------------------------------
178    -- Expand_Alfa_N_Attribute_Reference --
179    ---------------------------------------
180
181    procedure Expand_Alfa_N_Attribute_Reference (N : Node_Id) is
182       Id : constant Attribute_Id := Get_Attribute_Id (Attribute_Name (N));
183
184    begin
185       case Id is
186          when Attribute_Old    |
187               Attribute_Result =>
188             Expand_N_Attribute_Reference (N);
189
190          when others =>
191             null;
192       end case;
193    end Expand_Alfa_N_Attribute_Reference;
194
195    ----------------------
196    -- Expand_Alfa_N_In --
197    ----------------------
198
199    procedure Expand_Alfa_N_In (N : Node_Id) is
200    begin
201       if Present (Alternatives (N)) then
202          Expand_Set_Membership (N);
203       end if;
204    end Expand_Alfa_N_In;
205
206    -----------------------------------------------
207    -- Expand_Alfa_N_Object_Renaming_Declaration --
208    -----------------------------------------------
209
210    procedure Expand_Alfa_N_Object_Renaming_Declaration (N : Node_Id) is
211    begin
212       --  Unconditionally remove all side effects from the name
213
214       Evaluate_Name (Name (N));
215    end Expand_Alfa_N_Object_Renaming_Declaration;
216
217    -------------------------------------------
218    -- Expand_Alfa_N_Simple_Return_Statement --
219    -------------------------------------------
220
221    procedure Expand_Alfa_N_Simple_Return_Statement (N : Node_Id) is
222    begin
223       --  Defend against previous errors (i.e. the return statement calls a
224       --  function that is not available in configurable runtime).
225
226       if Present (Expression (N))
227         and then Nkind (Expression (N)) = N_Empty
228       then
229          return;
230       end if;
231
232       --  Distinguish the function and non-function cases:
233
234       case Ekind (Return_Applies_To (Return_Statement_Entity (N))) is
235
236          when E_Function          |
237               E_Generic_Function  =>
238             Expand_Alfa_Simple_Function_Return (N);
239
240          when E_Procedure         |
241               E_Generic_Procedure |
242               E_Entry             |
243               E_Entry_Family      |
244               E_Return_Statement =>
245             null;
246
247          when others =>
248             raise Program_Error;
249       end case;
250
251    exception
252       when RE_Not_Available =>
253          return;
254    end Expand_Alfa_N_Simple_Return_Statement;
255
256    ----------------------------------------
257    -- Expand_Alfa_Simple_Function_Return --
258    ----------------------------------------
259
260    procedure Expand_Alfa_Simple_Function_Return (N : Node_Id) is
261       Scope_Id : constant Entity_Id :=
262                    Return_Applies_To (Return_Statement_Entity (N));
263       --  The function we are returning from
264
265       R_Type : constant Entity_Id := Etype (Scope_Id);
266       --  The result type of the function
267
268       Exp : constant Node_Id := Expression (N);
269       pragma Assert (Present (Exp));
270
271       Exptyp : constant Entity_Id := Etype (Exp);
272       --  The type of the expression (not necessarily the same as R_Type)
273
274    begin
275       --  Check the result expression of a scalar function against the subtype
276       --  of the function by inserting a conversion. This conversion must
277       --  eventually be performed for other classes of types, but for now it's
278       --  only done for scalars.
279       --  ???
280
281       if Is_Scalar_Type (Exptyp) then
282          Rewrite (Exp, Convert_To (R_Type, Exp));
283
284          --  The expression is resolved to ensure that the conversion gets
285          --  expanded to generate a possible constraint check.
286
287          Analyze_And_Resolve (Exp, R_Type);
288       end if;
289    end Expand_Alfa_Simple_Function_Return;
290
291    -------------------------------
292    -- Expand_Potential_Renaming --
293    -------------------------------
294
295    procedure Expand_Potential_Renaming (N : Node_Id) is
296       E : constant Entity_Id := Entity (N);
297       T : constant Entity_Id := Etype (N);
298
299    begin
300       --  Replace a reference to a renaming with the actual renamed object
301
302       if Ekind (E) in Object_Kind and then Present (Renamed_Object (E)) then
303          Rewrite (N, New_Copy_Tree (Renamed_Object (E)));
304          Reset_Analyzed_Flags (N);
305          Analyze_And_Resolve (N, T);
306       end if;
307    end Expand_Potential_Renaming;
308
309 end Exp_Alfa;