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