OSDN Git Service

2008-04-08 Hristian Kirtchev <kirtchev@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / sem_intr.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT COMPILER COMPONENTS                         --
4 --                                                                          --
5 --                             S E M _ I N T R                              --
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 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 --  Processing for intrinsic subprogram declarations
27
28 with Atree;    use Atree;
29 with Einfo;    use Einfo;
30 with Errout;   use Errout;
31 with Fname;    use Fname;
32 with Lib;      use Lib;
33 with Namet;    use Namet;
34 with Sem_Eval; use Sem_Eval;
35 with Sem_Util; use Sem_Util;
36 with Sinfo;    use Sinfo;
37 with Snames;   use Snames;
38 with Stand;    use Stand;
39 with Stringt;  use Stringt;
40 with Targparm; use Targparm;
41 with Uintp;    use Uintp;
42
43 package body Sem_Intr is
44
45    -----------------------
46    -- Local Subprograms --
47    -----------------------
48
49    procedure Check_Exception_Function (E : Entity_Id; N : Node_Id);
50    --  Check use of intrinsic Exception_Message, Exception_Info or
51    --  Exception_Name, as used in the DEC compatible Current_Exceptions
52    --  package. In each case we must have a parameterless function that
53    --  returns type String.
54
55    procedure Check_Intrinsic_Operator (E : Entity_Id; N : Node_Id);
56    --  Check that operator is one of the binary arithmetic operators, and
57    --  that the types involved have the same size.
58
59    procedure Check_Shift (E : Entity_Id; N : Node_Id);
60    --  Check intrinsic shift subprogram, the two arguments are the same
61    --  as for Check_Intrinsic_Subprogram (i.e. the entity of the subprogram
62    --  declaration, and the node for the pragma argument, used for messages)
63
64    procedure Errint (Msg : String; S : Node_Id; N : Node_Id);
65    --  Post error message for bad intrinsic, the message itself is posted
66    --  on the appropriate spec node and another message is placed on the
67    --  pragma itself, referring to the spec. S is the node in the spec on
68    --  which the message is to be placed, and N is the pragma argument node.
69
70    ------------------------------
71    -- Check_Exception_Function --
72    ------------------------------
73
74    procedure Check_Exception_Function (E : Entity_Id; N : Node_Id) is
75    begin
76       if Ekind (E) /= E_Function
77         and then Ekind (E) /= E_Generic_Function
78       then
79          Errint
80            ("intrinsic exception subprogram must be a function", E, N);
81
82       elsif Present (First_Formal (E)) then
83          Errint
84            ("intrinsic exception subprogram may not have parameters",
85             E, First_Formal (E));
86          return;
87
88       elsif Etype (E) /= Standard_String then
89          Errint
90            ("return type of exception subprogram must be String", E, N);
91          return;
92       end if;
93    end Check_Exception_Function;
94
95    --------------------------
96    -- Check_Intrinsic_Call --
97    --------------------------
98
99    procedure Check_Intrinsic_Call (N : Node_Id) is
100       Nam  : constant Entity_Id := Entity (Name (N));
101       Cnam : constant Name_Id   := Chars (Nam);
102       Arg1 : constant Node_Id   := First_Actual (N);
103
104    begin
105       --  For Import_xxx calls, argument must be static string
106
107       if Cnam = Name_Import_Address
108            or else
109          Cnam = Name_Import_Largest_Value
110            or else
111          Cnam = Name_Import_Value
112       then
113          if Etype (Arg1) = Any_Type
114            or else Raises_Constraint_Error (Arg1)
115          then
116             null;
117
118          elsif not Is_Static_Expression (Arg1) then
119             Error_Msg_FE
120               ("call to & requires static string argument!", N, Nam);
121             Why_Not_Static (Arg1);
122
123          elsif String_Length (Strval (Expr_Value_S (Arg1))) = 0 then
124             Error_Msg_NE
125               ("call to & does not permit null string", N, Nam);
126
127          elsif OpenVMS_On_Target
128            and then String_Length (Strval (Expr_Value_S (Arg1))) > 31
129          then
130             Error_Msg_NE
131               ("argument in call to & must be 31 characters or less", N, Nam);
132          end if;
133
134       --  Check for the case of freeing a non-null object which will raise
135       --  Constaint_Error. Issue warning here, do the expansion in Exp_Intr.
136
137       elsif Cnam = Name_Free
138         and then Can_Never_Be_Null (Etype (Arg1))
139       then
140          Error_Msg_N
141            ("freeing `NOT NULL` object will raise Constraint_Error?", N);
142
143       --  For now, no other special checks are required
144
145       else
146          return;
147       end if;
148    end Check_Intrinsic_Call;
149
150    ------------------------------
151    -- Check_Intrinsic_Operator --
152    ------------------------------
153
154    procedure Check_Intrinsic_Operator (E : Entity_Id; N : Node_Id) is
155       Ret : constant Entity_Id := Etype (E);
156       Nam : constant Name_Id   := Chars (E);
157       T1  : Entity_Id;
158       T2  : Entity_Id;
159
160    begin
161       --  Aritnmetic operators
162
163       if Nam = Name_Op_Add
164            or else
165          Nam = Name_Op_Subtract
166            or else
167          Nam = Name_Op_Multiply
168            or else
169          Nam = Name_Op_Divide
170            or else
171          Nam = Name_Op_Rem
172            or else
173          Nam = Name_Op_Mod
174            or else
175          Nam = Name_Op_Abs
176       then
177          T1 := Etype (First_Formal (E));
178
179          if No (Next_Formal (First_Formal (E))) then
180
181             if Nam = Name_Op_Add
182                  or else
183                Nam = Name_Op_Subtract
184                  or else
185                Nam = Name_Op_Abs
186             then
187                T2 := T1;
188
189             else
190                --  Previous error in declaration
191
192                return;
193             end if;
194
195          else
196             T2 := Etype (Next_Formal (First_Formal (E)));
197          end if;
198
199          if Root_Type (T1) /= Root_Type (T2)
200            or else Root_Type (T1) /= Root_Type (Ret)
201          then
202             Errint
203               ("types of intrinsic operator must have the same size", E, N);
204          end if;
205
206       --  Comparison operators
207
208       elsif Nam = Name_Op_Eq
209               or else
210             Nam = Name_Op_Ge
211               or else
212             Nam = Name_Op_Gt
213               or else
214             Nam = Name_Op_Le
215               or else
216             Nam = Name_Op_Lt
217               or else
218             Nam = Name_Op_Ne
219       then
220          T1 := Etype (First_Formal (E));
221
222          if No (Next_Formal (First_Formal (E))) then
223
224             --  Previous error in declaration
225
226             return;
227
228          else
229             T2 := Etype (Next_Formal (First_Formal (E)));
230          end if;
231
232          if Root_Type (T1) /= Root_Type (T2) then
233             Errint
234               ("types of intrinsic operator must have the same size", E, N);
235          end if;
236
237          if Root_Type (Ret) /= Standard_Boolean then
238             Errint
239               ("result type of intrinsic comparison must be boolean", E, N);
240          end if;
241
242       --  Exponentiation
243
244       elsif Nam = Name_Op_Expon then
245          T1 := Etype (First_Formal (E));
246
247          if No (Next_Formal (First_Formal (E))) then
248
249             --  Previous error in declaration
250
251             return;
252
253          else
254             T2 := Etype (Next_Formal (First_Formal (E)));
255          end if;
256
257          if not (Is_Integer_Type (T1)
258                    or else
259                  Is_Floating_Point_Type (T1))
260            or else Root_Type (T1) /= Root_Type (Ret)
261            or else Root_Type (T2) /= Root_Type (Standard_Integer)
262          then
263             Errint ("incorrect operands for intrinsic operator", N, E);
264          end if;
265
266       --  All other operators (are there any?) are not handled
267
268       else
269          Errint ("incorrect context for ""Intrinsic"" convention", E, N);
270          return;
271       end if;
272
273       if not Is_Numeric_Type (T1) then
274          Errint ("intrinsic operator can only apply to numeric types", E, N);
275       end if;
276    end Check_Intrinsic_Operator;
277
278    --------------------------------
279    -- Check_Intrinsic_Subprogram --
280    --------------------------------
281
282    procedure Check_Intrinsic_Subprogram (E : Entity_Id; N : Node_Id) is
283       Spec : constant Node_Id := Specification (Unit_Declaration_Node (E));
284       Nam  : Name_Id;
285
286    begin
287       if Present (Spec)
288         and then Present (Generic_Parent (Spec))
289       then
290          Nam := Chars (Generic_Parent (Spec));
291       else
292          Nam := Chars (E);
293       end if;
294
295       --  Check name is valid intrinsic name
296
297       Get_Name_String (Nam);
298
299       if Name_Buffer (1) /= 'O'
300         and then Nam /= Name_Asm
301         and then Nam /= Name_To_Address
302         and then Nam not in First_Intrinsic_Name .. Last_Intrinsic_Name
303       then
304          Errint ("unrecognized intrinsic subprogram", E, N);
305
306       --  We always allow intrinsic specifications in language defined units
307       --  and in expanded code. We assume that the GNAT implemetors know what
308       --  they are doing, and do not write or generate junk use of intrinsic!
309
310       elsif not Comes_From_Source (E)
311         or else not Comes_From_Source (N)
312         or else Is_Predefined_File_Name
313                   (Unit_File_Name (Get_Source_Unit (N)))
314       then
315          null;
316
317       --  Shift cases. We allow user specification of intrinsic shift
318       --  operators for any numeric types.
319
320       elsif
321         Nam = Name_Rotate_Left
322           or else
323         Nam = Name_Rotate_Right
324           or else
325         Nam = Name_Shift_Left
326           or else
327         Nam = Name_Shift_Right
328           or else
329         Nam = Name_Shift_Right_Arithmetic
330       then
331          Check_Shift (E, N);
332
333       elsif
334         Nam = Name_Exception_Information
335           or else
336         Nam = Name_Exception_Message
337           or else
338         Nam = Name_Exception_Name
339       then
340          Check_Exception_Function (E, N);
341
342       elsif Nkind (E) = N_Defining_Operator_Symbol then
343          Check_Intrinsic_Operator (E, N);
344
345       elsif Nam = Name_File
346         or else Nam = Name_Line
347         or else Nam = Name_Source_Location
348         or else Nam = Name_Enclosing_Entity
349       then
350          null;
351
352       --  For now, no other intrinsic subprograms are recognized in user code
353
354       else
355          Errint ("incorrect context for ""Intrinsic"" convention", E, N);
356       end if;
357    end Check_Intrinsic_Subprogram;
358
359    -----------------
360    -- Check_Shift --
361    -----------------
362
363    procedure Check_Shift (E : Entity_Id; N : Node_Id) is
364       Arg1  : Node_Id;
365       Arg2  : Node_Id;
366       Size  : Nat;
367       Typ1  : Entity_Id;
368       Typ2  : Entity_Id;
369       Ptyp1 : Node_Id;
370       Ptyp2 : Node_Id;
371
372    begin
373       if Ekind (E) /= E_Function
374         and then Ekind (E) /= E_Generic_Function
375       then
376          Errint ("intrinsic shift subprogram must be a function", E, N);
377          return;
378       end if;
379
380       Arg1 := First_Formal (E);
381
382       if Present (Arg1) then
383          Arg2 := Next_Formal (Arg1);
384       else
385          Arg2 := Empty;
386       end if;
387
388       if Arg1 = Empty or else Arg2 = Empty then
389          Errint ("intrinsic shift function must have two arguments", E, N);
390          return;
391       end if;
392
393       Typ1 := Etype (Arg1);
394       Typ2 := Etype (Arg2);
395
396       Ptyp1 := Parameter_Type (Parent (Arg1));
397       Ptyp2 := Parameter_Type (Parent (Arg2));
398
399       if not Is_Integer_Type (Typ1) then
400          Errint ("first argument to shift must be integer type", Ptyp1, N);
401          return;
402       end if;
403
404       if Typ2 /= Standard_Natural then
405          Errint ("second argument to shift must be type Natural", Ptyp2, N);
406          return;
407       end if;
408
409       Size := UI_To_Int (Esize (Typ1));
410
411       if Size /= 8
412         and then Size /= 16
413         and then Size /= 32
414         and then Size /= 64
415       then
416          Errint
417            ("first argument for shift must have size 8, 16, 32 or 64",
418              Ptyp1, N);
419          return;
420
421       elsif Is_Modular_Integer_Type (Typ1)
422         and then Non_Binary_Modulus (Typ1)
423       then
424          Errint
425            ("shifts not allowed for non-binary modular types",
426             Ptyp1, N);
427
428       elsif Etype (Arg1) /= Etype (E) then
429          Errint
430            ("first argument of shift must match return type", Ptyp1, N);
431          return;
432       end if;
433    end Check_Shift;
434
435    ------------
436    -- Errint --
437    ------------
438
439    procedure Errint (Msg : String; S : Node_Id; N : Node_Id) is
440    begin
441       Error_Msg_N (Msg, S);
442       Error_Msg_N ("incorrect intrinsic subprogram, see spec", N);
443    end Errint;
444
445 end Sem_Intr;