Allow returning something of type void in a function that returns void
[delight/core.git] / d-builtins.c
blobecafc4515a34cbb2a76c228337d72e8888c342d2
1 /* GDC -- D front-end for GCC
2 Copyright (C) 2004 David Friedman
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 /* This file is mostly a copy of gcc/c-common.c */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "intl.h"
26 #include "tree.h"
27 #include "flags.h"
28 #include "output.h"
29 #include "rtl.h"
30 #include "ggc.h"
31 #include "varray.h"
32 #include "expr.h"
33 #include "diagnostic.h"
34 #include "tm_p.h"
35 #include "target.h"
36 #include "langhooks.h"
37 #include "tree-inline.h"
38 #include "toplev.h"
39 #if D_GCC_VER >= 40
40 /* Only used in >= 4.1.x */
41 #include "cgraph.h"
42 #endif
44 #include "d-lang.h"
46 tree intmax_type_node;
47 tree uintmax_type_node;
48 tree signed_size_type_node;
49 tree string_type_node;
50 tree const_string_type_node;
52 #if D_GCC_VER >= 41
53 tree null_node;
54 extern void dkeep(tree t);
55 #endif
58 #if D_GCC_VER < 40
59 # ifdef D_GCC_VER341
60 # include "d-bi-attrs-341.h"
61 # else
62 # include "d-bi-attrs-34.h"
63 # endif
64 #elif D_GCC_VER < 41
65 #include "d-bi-attrs-40.h"
66 #else
67 #include "d-bi-attrs-41.h"
68 #endif
70 #if D_GCC_VER >= 41
71 /* Nonzero means enable C89 Amendment 1 features. */
73 /*extern*/ int flag_isoc94;
75 /* Nonzero means use the ISO C99 dialect of C. */
77 /*extern*/ int flag_isoc99;
78 #endif
80 /* Used to help initialize the builtin-types.def table. When a type of
81 the correct size doesn't exist, use error_mark_node instead of NULL.
82 The later results in segfaults even when a decl using the type doesn't
83 get invoked. */
85 tree
86 builtin_type_for_size (int size, bool unsignedp)
88 tree type = lang_hooks.types.type_for_size (size, unsignedp);
89 return type ? type : error_mark_node;
92 enum built_in_attribute
94 #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
95 #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
96 #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
97 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
98 #include "builtin-attrs.def"
99 #undef DEF_ATTR_NULL_TREE
100 #undef DEF_ATTR_INT
101 #undef DEF_ATTR_IDENT
102 #undef DEF_ATTR_TREE_LIST
103 ATTR_LAST
106 static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
108 static void
109 d_init_attributes (void)
111 /* Fill in the built_in_attributes array. */
112 #define DEF_ATTR_NULL_TREE(ENUM) \
113 built_in_attributes[(int) ENUM] = NULL_TREE;
114 #if D_GCC_VER < 40
115 # define DEF_ATTR_INT(ENUM, VALUE) \
116 built_in_attributes[(int) ENUM] = build_int_2 (VALUE, VALUE < 0 ? -1 : 0);
117 #else
118 # define DEF_ATTR_INT(ENUM, VALUE) \
119 built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
120 #endif
121 #define DEF_ATTR_IDENT(ENUM, STRING) \
122 built_in_attributes[(int) ENUM] = get_identifier (STRING);
123 #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
124 built_in_attributes[(int) ENUM] \
125 = tree_cons (built_in_attributes[(int) PURPOSE], \
126 built_in_attributes[(int) VALUE], \
127 built_in_attributes[(int) CHAIN]);
128 #include "builtin-attrs.def"
129 #undef DEF_ATTR_NULL_TREE
130 #undef DEF_ATTR_INT
131 #undef DEF_ATTR_IDENT
132 #undef DEF_ATTR_TREE_LIST
136 #if D_GCC_VER >= 40
137 #ifndef WINT_TYPE
138 #define WINT_TYPE "unsigned int"
139 #endif
140 #ifndef PID_TYPE
141 #define PID_TYPE "int"
142 #endif
144 static tree
145 lookup_C_type_name(const char * p)
147 // These are the names used in c_common_nodes_and_builtins
148 if (strcmp(p,"char")) return char_type_node;
149 else if (strcmp(p,"signed char")) return signed_char_type_node;
150 else if (strcmp(p,"unsigned char")) return unsigned_char_type_node;
151 else if (strcmp(p,"short int")) return short_integer_type_node;
152 else if (strcmp(p,"short unsigned int ")) return short_unsigned_type_node;//cxx! -- affects ming/c++?
153 else if (strcmp(p,"int")) return integer_type_node;
154 else if (strcmp(p,"unsigned int")) return unsigned_type_node;
155 else if (strcmp(p,"long int")) return long_integer_type_node;
156 else if (strcmp(p,"long unsigned int")) return long_unsigned_type_node; // cxx!
157 else if (strcmp(p,"long long int")) return long_integer_type_node;
158 else if (strcmp(p,"long long unsigned int")) return long_unsigned_type_node; // cxx!
159 internal_error("unsigned C type '%s'", p);
161 #endif
163 #if D_GCC_VER >= 41
164 tree do_build_builtin_fn(enum built_in_function fncode,
165 const char *name,
166 enum built_in_class fnclass,
167 int fntype_index, tree fntype, int libtype_index,
168 bool both_p, bool fallback_p, bool nonansi_p,
169 tree fnattrs, bool implicit_p)
171 tree decl;
173 const char *libname;
175 gcc_assert ((!(both_p) && !(fallback_p))
176 || !strncmp (name, "__builtin_",
177 strlen ("__builtin_")));
178 libname = name + strlen ("__builtin_");
181 /*if (!BOTH_P)*/
182 decl = lang_hooks.builtin_function (name, fntype,
183 fncode,
184 fnclass,
185 fallback_p ?libname : NULL,
186 fnattrs);
188 built_in_decls[(int) fncode] = decl;
189 if (implicit_p)
190 implicit_built_in_decls[(int) fncode] = decl;
192 #endif
194 void d_init_builtins(void)
196 enum builtin_type
198 #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
199 #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
200 #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
201 #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
202 #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
203 #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
204 #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
205 #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) NAME,
206 #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
207 #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
208 #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
209 #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
210 #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
211 #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) NAME,
212 #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
213 #include "builtin-types.def"
214 #undef DEF_PRIMITIVE_TYPE
215 #undef DEF_FUNCTION_TYPE_0
216 #undef DEF_FUNCTION_TYPE_1
217 #undef DEF_FUNCTION_TYPE_2
218 #undef DEF_FUNCTION_TYPE_3
219 #undef DEF_FUNCTION_TYPE_4
220 #undef DEF_FUNCTION_TYPE_5
221 #undef DEF_FUNCTION_TYPE_6
222 #undef DEF_FUNCTION_TYPE_VAR_0
223 #undef DEF_FUNCTION_TYPE_VAR_1
224 #undef DEF_FUNCTION_TYPE_VAR_2
225 #undef DEF_FUNCTION_TYPE_VAR_3
226 #undef DEF_FUNCTION_TYPE_VAR_4
227 #undef DEF_FUNCTION_TYPE_VAR_5
228 #undef DEF_POINTER_TYPE
229 BT_LAST
231 typedef enum builtin_type builtin_type;
233 tree builtin_types[(int) BT_LAST];
235 tree va_list_ref_type_node;
236 tree va_list_arg_type_node;
238 d_bi_init((int) BT_LAST, (int) END_BUILTINS);
241 if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
243 /* It might seem natural to make the reference type a pointer,
244 but this will not work in D: There is no implicit casting from
245 an array to a pointer. */
246 va_list_arg_type_node = va_list_ref_type_node = va_list_type_node;
248 else
250 va_list_arg_type_node = va_list_type_node;
251 va_list_ref_type_node = build_reference_type (va_list_type_node);
255 intmax_type_node = intDI_type_node;
256 uintmax_type_node = unsigned_intDI_type_node;
257 signed_size_type_node = (* lang_hooks.types.signed_type)(size_type_node);
258 string_type_node = build_pointer_type (char_type_node);
259 const_string_type_node = build_pointer_type (build_qualified_type
260 (char_type_node, TYPE_QUAL_CONST));
262 void_list_node = tree_cons(NULL_TREE, void_type_node, NULL_TREE);
264 #if D_GCC_VER >= 40
265 /* WINT_TYPE is a C type name, not an itk_ constant or something useful
266 like that... */
267 tree wint_type_node = lookup_C_type_name(WINT_TYPE);
268 pid_type_node = lookup_C_type_name(PID_TYPE);
269 #endif
271 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
272 builtin_types[(int) ENUM] = VALUE;
273 #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
274 builtin_types[(int) ENUM] \
275 = build_function_type (builtin_types[(int) RETURN], \
276 void_list_node);
277 #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
278 builtin_types[(int) ENUM] \
279 = build_function_type (builtin_types[(int) RETURN], \
280 tree_cons (NULL_TREE, \
281 builtin_types[(int) ARG1], \
282 void_list_node));
283 #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
284 builtin_types[(int) ENUM] \
285 = build_function_type \
286 (builtin_types[(int) RETURN], \
287 tree_cons (NULL_TREE, \
288 builtin_types[(int) ARG1], \
289 tree_cons (NULL_TREE, \
290 builtin_types[(int) ARG2], \
291 void_list_node)));
292 #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
293 builtin_types[(int) ENUM] \
294 = build_function_type \
295 (builtin_types[(int) RETURN], \
296 tree_cons (NULL_TREE, \
297 builtin_types[(int) ARG1], \
298 tree_cons (NULL_TREE, \
299 builtin_types[(int) ARG2], \
300 tree_cons (NULL_TREE, \
301 builtin_types[(int) ARG3], \
302 void_list_node))));
303 #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
304 builtin_types[(int) ENUM] \
305 = build_function_type \
306 (builtin_types[(int) RETURN], \
307 tree_cons (NULL_TREE, \
308 builtin_types[(int) ARG1], \
309 tree_cons (NULL_TREE, \
310 builtin_types[(int) ARG2], \
311 tree_cons \
312 (NULL_TREE, \
313 builtin_types[(int) ARG3], \
314 tree_cons (NULL_TREE, \
315 builtin_types[(int) ARG4], \
316 void_list_node)))));
317 #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
318 builtin_types[(int) ENUM] \
319 = build_function_type \
320 (builtin_types[(int) RETURN], \
321 tree_cons (NULL_TREE, \
322 builtin_types[(int) ARG1], \
323 tree_cons (NULL_TREE, \
324 builtin_types[(int) ARG2], \
325 tree_cons \
326 (NULL_TREE, \
327 builtin_types[(int) ARG3], \
328 tree_cons (NULL_TREE, \
329 builtin_types[(int) ARG4], \
330 tree_cons (NULL_TREE, \
331 builtin_types[(int) ARG5],\
332 void_list_node))))));
333 #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
334 ARG6) \
335 builtin_types[(int) ENUM] \
336 = build_function_type \
337 (builtin_types[(int) RETURN], \
338 tree_cons (NULL_TREE, \
339 builtin_types[(int) ARG1], \
340 tree_cons (NULL_TREE, \
341 builtin_types[(int) ARG2], \
342 tree_cons \
343 (NULL_TREE, \
344 builtin_types[(int) ARG3], \
345 tree_cons \
346 (NULL_TREE, \
347 builtin_types[(int) ARG4], \
348 tree_cons (NULL_TREE, \
349 builtin_types[(int) ARG5], \
350 tree_cons (NULL_TREE, \
351 builtin_types[(int) ARG6],\
352 void_list_node)))))));
353 #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
354 builtin_types[(int) ENUM] \
355 = build_function_type (builtin_types[(int) RETURN], NULL_TREE);
356 #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
357 builtin_types[(int) ENUM] \
358 = build_function_type (builtin_types[(int) RETURN], \
359 tree_cons (NULL_TREE, \
360 builtin_types[(int) ARG1], \
361 NULL_TREE));
363 #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
364 builtin_types[(int) ENUM] \
365 = build_function_type \
366 (builtin_types[(int) RETURN], \
367 tree_cons (NULL_TREE, \
368 builtin_types[(int) ARG1], \
369 tree_cons (NULL_TREE, \
370 builtin_types[(int) ARG2], \
371 NULL_TREE)));
373 #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
374 builtin_types[(int) ENUM] \
375 = build_function_type \
376 (builtin_types[(int) RETURN], \
377 tree_cons (NULL_TREE, \
378 builtin_types[(int) ARG1], \
379 tree_cons (NULL_TREE, \
380 builtin_types[(int) ARG2], \
381 tree_cons (NULL_TREE, \
382 builtin_types[(int) ARG3], \
383 NULL_TREE))));
384 #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
385 builtin_types[(int) ENUM] \
386 = build_function_type \
387 (builtin_types[(int) RETURN], \
388 tree_cons (NULL_TREE, \
389 builtin_types[(int) ARG1], \
390 tree_cons (NULL_TREE, \
391 builtin_types[(int) ARG2], \
392 tree_cons (NULL_TREE, \
393 builtin_types[(int) ARG3], \
394 tree_cons (NULL_TREE, \
395 builtin_types[(int) ARG4],\
396 NULL_TREE)))));
398 #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, \
399 ARG5) \
400 builtin_types[(int) ENUM] \
401 = build_function_type \
402 (builtin_types[(int) RETURN], \
403 tree_cons (NULL_TREE, \
404 builtin_types[(int) ARG1], \
405 tree_cons (NULL_TREE, \
406 builtin_types[(int) ARG2], \
407 tree_cons \
408 (NULL_TREE, \
409 builtin_types[(int) ARG3], \
410 tree_cons (NULL_TREE, \
411 builtin_types[(int) ARG4], \
412 tree_cons (NULL_TREE, \
413 builtin_types[(int) ARG5],\
414 NULL_TREE))))));
417 #define DEF_POINTER_TYPE(ENUM, TYPE) \
418 builtin_types[(int) ENUM] \
419 = build_pointer_type (builtin_types[(int) TYPE]);
420 #include "builtin-types.def"
421 #undef DEF_PRIMITIVE_TYPE
422 #undef DEF_FUNCTION_TYPE_1
423 #undef DEF_FUNCTION_TYPE_2
424 #undef DEF_FUNCTION_TYPE_3
425 #undef DEF_FUNCTION_TYPE_4
426 #undef DEF_FUNCTION_TYPE_5
427 #undef DEF_FUNCTION_TYPE_6
428 #undef DEF_FUNCTION_TYPE_VAR_0
429 #undef DEF_FUNCTION_TYPE_VAR_1
430 #undef DEF_FUNCTION_TYPE_VAR_2
431 #undef DEF_FUNCTION_TYPE_VAR_3
432 #undef DEF_FUNCTION_TYPE_VAR_4
433 #undef DEF_FUNCTION_TYPE_VAR_5
434 #undef DEF_POINTER_TYPE
436 d_init_attributes ();
438 #if D_GCC_VER == 34
439 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, \
440 BOTH_P, FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT) \
441 if (NAME) \
443 tree decl; \
445 if (strncmp (NAME, "__builtin_", strlen ("__builtin_")) != 0) \
446 abort (); \
448 /*if (!BOTH_P)*/ \
449 decl = builtin_function (NAME, builtin_types[TYPE], ENUM, \
450 CLASS, \
451 (FALLBACK_P \
452 ? (NAME + strlen ("__builtin_")) \
453 : NULL), \
454 built_in_attributes[(int) ATTRS]); \
455 /*else*/ \
456 /*decl = builtin_function_2 (NAME,*/ \
457 /* NAME + strlen ("__builtin_"),*/ \
458 /* builtin_types[TYPE],*/ \
459 /* builtin_types[LIBTYPE],*/ \
460 /* ENUM,*/ \
461 /* CLASS,*/ \
462 /* FALLBACK_P,*/ \
463 /* NONANSI_P,*/ \
464 /* built_in_attributes[(int) ATTRS]);*/ \
466 built_in_decls[(int) ENUM] = decl; \
467 if (IMPLICIT) \
468 implicit_built_in_decls[(int) ENUM] = decl; \
470 #elif D_GCC_VER == 40
471 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
472 NONANSI_P, ATTRS, IMPLICIT, COND) \
473 if (NAME && COND) \
475 tree decl; \
477 gcc_assert (!strncmp (NAME, "__builtin_", \
478 strlen ("__builtin_"))); \
480 /*if (!BOTH_P)*/ \
481 decl = lang_hooks.builtin_function (NAME, builtin_types[TYPE], \
482 ENUM, \
483 CLASS, \
484 (FALLBACK_P \
485 ? (NAME + strlen ("__builtin_")) \
486 : NULL), \
487 built_in_attributes[(int) ATTRS]); \
488 /*else*/ \
489 /*decl = builtin_function_2 (NAME,*/ \
490 /* NAME + strlen ("__builtin_"),*/ \
491 /* builtin_types[TYPE],*/ \
492 /* builtin_types[LIBTYPE],*/ \
493 /* ENUM,*/ \
494 /* CLASS,*/ \
495 /* FALLBACK_P,*/ \
496 /* NONANSI_P,*/ \
497 /* built_in_attributes[(int) ATTRS]);*/ \
499 built_in_decls[(int) ENUM] = decl; \
500 if (IMPLICIT) \
501 implicit_built_in_decls[(int) ENUM] = decl; \
503 #elif D_GCC_VER >= 41
504 #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
505 NONANSI_P, ATTRS, IMPLICIT, COND) \
506 if (NAME && COND) \
507 do_build_builtin_fn(ENUM, NAME, CLASS, TYPE, builtin_types[TYPE], LIBTYPE, BOTH_P, \
508 FALLBACK_P, NONANSI_P, built_in_attributes[(int) ATTRS], IMPLICIT);
509 #endif
511 #include "builtins.def"
512 #undef DEF_BUILTIN
514 #if D_GCC_VER >= 40
515 build_common_builtin_nodes ();
516 #endif
518 (*targetm.init_builtins) ();
520 main_identifier_node = get_identifier ("main");
522 #if D_GCC_VER >= 41
523 /* Create the built-in __null node. It is important that this is
524 not shared. */
525 null_node = make_node (INTEGER_CST);
526 TREE_TYPE (null_node) = d_type_for_size (POINTER_SIZE, 0);
527 dkeep(null_node);
528 #endif
531 /* Return a definition for a builtin function named NAME and whose data type
532 is TYPE. TYPE should be a function type with argument types.
533 FUNCTION_CODE tells later passes how to compile calls to this function.
534 See tree.h for its possible values.
536 If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME,
537 the name to be called if we can't opencode the function. If
538 ATTRS is nonzero, use that for the function's attribute list. */
540 tree
541 builtin_function (const char *name, tree type, int function_code,
542 enum built_in_class klass, const char *library_name,
543 tree attrs)
545 //%% for D, just use library_name?
546 tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type);
547 DECL_EXTERNAL (decl) = 1;
548 TREE_PUBLIC (decl) = 1;
549 if (library_name)
550 SET_DECL_ASSEMBLER_NAME (decl, get_identifier (library_name));
551 #if D_GCC_VER < 40
552 make_decl_rtl (decl, NULL);
553 #endif
554 // %% gcc4 -- is make_decl_rtl needed? why are we doing it in gcc3?
555 // shouldn't it go after attributes?
557 pushdecl (decl);
558 DECL_BUILT_IN_CLASS (decl) = klass;
559 DECL_FUNCTION_CODE (decl) = function_code;
561 /* Warn if a function in the namespace for users
562 is used without an occasion to consider it declared. */
564 if (name[0] != '_' || name[1] != '_')
565 C_DECL_INVISIBLE (decl) = 1;
568 /* Possibly apply some default attributes to this built-in function. */
569 if (attrs)
570 decl_attributes (&decl, attrs, ATTR_FLAG_BUILT_IN);
571 else
572 decl_attributes (&decl, NULL_TREE, 0);
574 d_bi_builtin_func(decl);
576 return decl;
579 #include "gt-dlt-d-builtins.h"