1 ------------------------------------------------------------------------------
3 -- GNAT COMPILER COMPONENTS --
9 -- Copyright (C) 1992-2003 Free Software Foundation, Inc. --
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. --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
25 ------------------------------------------------------------------------------
27 -- Processing for intrinsic subprogram declarations
29 with Atree
; use Atree
;
30 with Einfo
; use Einfo
;
31 with Errout
; use Errout
;
32 with Fname
; use Fname
;
34 with Namet
; use Namet
;
35 with Sem_Eval
; use Sem_Eval
;
36 with Sem_Util
; use Sem_Util
;
37 with Sinfo
; use Sinfo
;
38 with Snames
; use Snames
;
39 with Stand
; use Stand
;
40 with Stringt
; use Stringt
;
41 with Targparm
; use Targparm
;
42 with Uintp
; use Uintp
;
44 package body Sem_Intr
is
46 -----------------------
47 -- Local Subprograms --
48 -----------------------
50 procedure Check_Exception_Function
(E
: Entity_Id
; N
: Node_Id
);
51 -- Check use of intrinsic Exception_Message, Exception_Info or
52 -- Exception_Name, as used in the DEC compatible Current_Exceptions
53 -- package. In each case we must have a parameterless function that
54 -- returns type String.
56 procedure Check_Intrinsic_Operator
(E
: Entity_Id
; N
: Node_Id
);
57 -- Check that operator is one of the binary arithmetic operators, and
58 -- that the types involved have the same size.
60 procedure Check_Shift
(E
: Entity_Id
; N
: Node_Id
);
61 -- Check intrinsic shift subprogram, the two arguments are the same
62 -- as for Check_Intrinsic_Subprogram (i.e. the entity of the subprogram
63 -- declaration, and the node for the pragma argument, used for messages)
65 procedure Errint
(Msg
: String; S
: Node_Id
; N
: Node_Id
);
66 -- Post error message for bad intrinsic, the message itself is posted
67 -- on the appropriate spec node and another message is placed on the
68 -- pragma itself, referring to the spec. S is the node in the spec on
69 -- which the message is to be placed, and N is the pragma argument node.
71 ------------------------------
72 -- Check_Exception_Function --
73 ------------------------------
75 procedure Check_Exception_Function
(E
: Entity_Id
; N
: Node_Id
) is
77 if Ekind
(E
) /= E_Function
78 and then Ekind
(E
) /= E_Generic_Function
81 ("intrinsic exception subprogram must be a function", E
, N
);
83 elsif Present
(First_Formal
(E
)) then
85 ("intrinsic exception subprogram may not have parameters",
89 elsif Etype
(E
) /= Standard_String
then
91 ("return type of exception subprogram must be String", E
, N
);
94 end Check_Exception_Function
;
96 --------------------------
97 -- Check_Intrinsic_Call --
98 --------------------------
100 procedure Check_Intrinsic_Call
(N
: Node_Id
) is
101 Nam
: constant Entity_Id
:= Entity
(Name
(N
));
102 Cnam
: constant Name_Id
:= Chars
(Nam
);
103 Arg1
: constant Node_Id
:= First_Actual
(N
);
106 -- For Import_xxx calls, argument must be static string
108 if Cnam
= Name_Import_Address
110 Cnam
= Name_Import_Largest_Value
112 Cnam
= Name_Import_Value
114 if Etype
(Arg1
) = Any_Type
115 or else Raises_Constraint_Error
(Arg1
)
119 elsif not Is_Static_Expression
(Arg1
) then
121 ("call to & requires static string argument!", N
, Nam
);
122 Why_Not_Static
(Arg1
);
124 elsif String_Length
(Strval
(Expr_Value_S
(Arg1
))) = 0 then
126 ("call to & does not permit null string", N
, Nam
);
128 elsif OpenVMS_On_Target
129 and then String_Length
(Strval
(Expr_Value_S
(Arg1
))) > 31
132 ("argument in call to & must be 31 characters or less", N
, Nam
);
135 -- For now, no other special checks are required
140 end Check_Intrinsic_Call
;
142 ------------------------------
143 -- Check_Intrinsic_Operator --
144 ------------------------------
146 procedure Check_Intrinsic_Operator
(E
: Entity_Id
; N
: Node_Id
) is
147 Ret
: constant Entity_Id
:= Etype
(E
);
148 Nam
: constant Name_Id
:= Chars
(E
);
153 -- Aritnmetic operators
157 Nam
= Name_Op_Subtract
159 Nam
= Name_Op_Multiply
169 T1
:= Etype
(First_Formal
(E
));
171 if No
(Next_Formal
(First_Formal
(E
))) then
175 Nam
= Name_Op_Subtract
182 -- Previous error in declaration
188 T2
:= Etype
(Next_Formal
(First_Formal
(E
)));
191 if Root_Type
(T1
) /= Root_Type
(T2
)
192 or else Root_Type
(T1
) /= Root_Type
(Ret
)
195 ("types of intrinsic operator must have the same size", E
, N
);
198 -- Comparison operators
200 elsif Nam
= Name_Op_Eq
212 T1
:= Etype
(First_Formal
(E
));
214 if No
(Next_Formal
(First_Formal
(E
))) then
216 -- Previous error in declaration
221 T2
:= Etype
(Next_Formal
(First_Formal
(E
)));
224 if Root_Type
(T1
) /= Root_Type
(T2
) then
226 ("types of intrinsic operator must have the same size", E
, N
);
229 if Root_Type
(Ret
) /= Standard_Boolean
then
231 ("result type of intrinsic comparison must be boolean", E
, N
);
236 elsif Nam
= Name_Op_Expon
then
237 T1
:= Etype
(First_Formal
(E
));
239 if No
(Next_Formal
(First_Formal
(E
))) then
241 -- Previous error in declaration
246 T2
:= Etype
(Next_Formal
(First_Formal
(E
)));
249 if not (Is_Integer_Type
(T1
)
251 Is_Floating_Point_Type
(T1
))
252 or else Root_Type
(T1
) /= Root_Type
(Ret
)
253 or else Root_Type
(T2
) /= Root_Type
(Standard_Integer
)
255 Errint
("incorrect operands for intrinsic operator", N
, E
);
258 -- All other operators (are there any?) are not handled
261 Errint
("incorrect context for ""Intrinsic"" convention", E
, N
);
265 if not Is_Numeric_Type
(T1
) then
266 Errint
("intrinsic operator can only apply to numeric types", E
, N
);
268 end Check_Intrinsic_Operator
;
270 --------------------------------
271 -- Check_Intrinsic_Subprogram --
272 --------------------------------
274 procedure Check_Intrinsic_Subprogram
(E
: Entity_Id
; N
: Node_Id
) is
275 Spec
: constant Node_Id
:= Specification
(Unit_Declaration_Node
(E
));
280 and then Present
(Generic_Parent
(Spec
))
282 Nam
:= Chars
(Generic_Parent
(Spec
));
287 -- Check name is valid intrinsic name
289 Get_Name_String
(Nam
);
291 if Name_Buffer
(1) /= 'O'
292 and then Nam
/= Name_Asm
293 and then Nam
/= Name_To_Address
294 and then Nam
not in First_Intrinsic_Name
.. Last_Intrinsic_Name
296 Errint
("unrecognized intrinsic subprogram", E
, N
);
298 -- We always allow intrinsic specifications in language defined units
299 -- and in expanded code. We assume that the GNAT implemetors know what
300 -- they are doing, and do not write or generate junk use of intrinsic!
302 elsif not Comes_From_Source
(E
)
303 or else not Comes_From_Source
(N
)
304 or else Is_Predefined_File_Name
305 (Unit_File_Name
(Get_Source_Unit
(N
)))
309 -- Shift cases. We allow user specification of intrinsic shift
310 -- operators for any numeric types.
313 Nam
= Name_Rotate_Left
315 Nam
= Name_Rotate_Right
317 Nam
= Name_Shift_Left
319 Nam
= Name_Shift_Right
321 Nam
= Name_Shift_Right_Arithmetic
326 Nam
= Name_Exception_Information
328 Nam
= Name_Exception_Message
330 Nam
= Name_Exception_Name
332 Check_Exception_Function
(E
, N
);
334 elsif Nkind
(E
) = N_Defining_Operator_Symbol
then
335 Check_Intrinsic_Operator
(E
, N
);
337 elsif Nam
= Name_File
338 or else Nam
= Name_Line
339 or else Nam
= Name_Source_Location
340 or else Nam
= Name_Enclosing_Entity
344 -- For now, no other intrinsic subprograms are recognized in user code
347 Errint
("incorrect context for ""Intrinsic"" convention", E
, N
);
349 end Check_Intrinsic_Subprogram
;
355 procedure Check_Shift
(E
: Entity_Id
; N
: Node_Id
) is
365 if Ekind
(E
) /= E_Function
366 and then Ekind
(E
) /= E_Generic_Function
368 Errint
("intrinsic shift subprogram must be a function", E
, N
);
372 Arg1
:= First_Formal
(E
);
374 if Present
(Arg1
) then
375 Arg2
:= Next_Formal
(Arg1
);
380 if Arg1
= Empty
or else Arg2
= Empty
then
381 Errint
("intrinsic shift function must have two arguments", E
, N
);
385 Typ1
:= Etype
(Arg1
);
386 Typ2
:= Etype
(Arg2
);
388 Ptyp1
:= Parameter_Type
(Parent
(Arg1
));
389 Ptyp2
:= Parameter_Type
(Parent
(Arg2
));
391 if not Is_Integer_Type
(Typ1
) then
392 Errint
("first argument to shift must be integer type", Ptyp1
, N
);
396 if Typ2
/= Standard_Natural
then
397 Errint
("second argument to shift must be type Natural", Ptyp2
, N
);
401 Size
:= UI_To_Int
(Esize
(Typ1
));
409 ("first argument for shift must have size 8, 16, 32 or 64",
413 elsif Is_Modular_Integer_Type
(Typ1
)
414 and then Non_Binary_Modulus
(Typ1
)
417 ("shifts not allowed for non-binary modular types",
420 elsif Etype
(Arg1
) /= Etype
(E
) then
422 ("first argument of shift must match return type", Ptyp1
, N
);
431 procedure Errint
(Msg
: String; S
: Node_Id
; N
: Node_Id
) is
433 Error_Msg_N
(Msg
, S
);
434 Error_Msg_N
("incorrect intrinsic subprogram, see spec", N
);