d-builtins.cc revision 1.1 1 1.1 mrg /* d-builtins.cc -- GCC builtins support for D.
2 1.1 mrg Copyright (C) 2006-2019 Free Software Foundation, Inc.
3 1.1 mrg
4 1.1 mrg GCC is free software; you can redistribute it and/or modify
5 1.1 mrg it under the terms of the GNU General Public License as published by
6 1.1 mrg the Free Software Foundation; either version 3, or (at your option)
7 1.1 mrg any later version.
8 1.1 mrg
9 1.1 mrg GCC is distributed in the hope that it will be useful,
10 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
11 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 1.1 mrg GNU General Public License for more details.
13 1.1 mrg
14 1.1 mrg You should have received a copy of the GNU General Public License
15 1.1 mrg along with GCC; see the file COPYING3. If not see
16 1.1 mrg <http://www.gnu.org/licenses/>. */
17 1.1 mrg
18 1.1 mrg #include "config.h"
19 1.1 mrg #include "system.h"
20 1.1 mrg #include "coretypes.h"
21 1.1 mrg
22 1.1 mrg #include "dmd/attrib.h"
23 1.1 mrg #include "dmd/aggregate.h"
24 1.1 mrg #include "dmd/cond.h"
25 1.1 mrg #include "dmd/declaration.h"
26 1.1 mrg #include "dmd/expression.h"
27 1.1 mrg #include "dmd/identifier.h"
28 1.1 mrg #include "dmd/module.h"
29 1.1 mrg #include "dmd/mtype.h"
30 1.1 mrg
31 1.1 mrg #include "tree.h"
32 1.1 mrg #include "fold-const.h"
33 1.1 mrg #include "diagnostic.h"
34 1.1 mrg #include "langhooks.h"
35 1.1 mrg #include "target.h"
36 1.1 mrg #include "common/common-target.h"
37 1.1 mrg #include "stringpool.h"
38 1.1 mrg #include "stor-layout.h"
39 1.1 mrg
40 1.1 mrg #include "d-tree.h"
41 1.1 mrg #include "d-target.h"
42 1.1 mrg
43 1.1 mrg
44 1.1 mrg static GTY(()) vec<tree, va_gc> *gcc_builtins_functions = NULL;
45 1.1 mrg static GTY(()) vec<tree, va_gc> *gcc_builtins_libfuncs = NULL;
46 1.1 mrg static GTY(()) vec<tree, va_gc> *gcc_builtins_types = NULL;
47 1.1 mrg
48 1.1 mrg /* Record built-in types and their associated decls for re-use when
49 1.1 mrg generating the `gcc.builtins' module. */
50 1.1 mrg
51 1.1 mrg struct builtin_data
52 1.1 mrg {
53 1.1 mrg Type *dtype;
54 1.1 mrg tree ctype;
55 1.1 mrg Dsymbol *dsym;
56 1.1 mrg
57 1.1 mrg builtin_data (Type *t, tree c, Dsymbol *d = NULL)
58 1.1 mrg : dtype(t), ctype(c), dsym(d)
59 1.1 mrg { }
60 1.1 mrg };
61 1.1 mrg
62 1.1 mrg static vec<builtin_data> builtin_converted_decls;
63 1.1 mrg
64 1.1 mrg /* Build D frontend type from tree TYPE type given. This will set the
65 1.1 mrg back-end type symbol directly for complex types to save build_ctype()
66 1.1 mrg the work. For other types, it is not useful or will cause errors, such
67 1.1 mrg as casting from `C char' to `D char', which also means that `char *`
68 1.1 mrg needs to be specially handled. */
69 1.1 mrg
70 1.1 mrg static Type *
71 1.1 mrg build_frontend_type (tree type)
72 1.1 mrg {
73 1.1 mrg Type *dtype;
74 1.1 mrg MOD mod = 0;
75 1.1 mrg
76 1.1 mrg if (TYPE_READONLY (type))
77 1.1 mrg mod |= MODconst;
78 1.1 mrg if (TYPE_VOLATILE (type))
79 1.1 mrg mod |= MODshared;
80 1.1 mrg
81 1.1 mrg /* If we've seen the type before, re-use the converted decl. */
82 1.1 mrg for (size_t i = 0; i < builtin_converted_decls.length (); ++i)
83 1.1 mrg {
84 1.1 mrg tree t = builtin_converted_decls[i].ctype;
85 1.1 mrg if (TYPE_MAIN_VARIANT (t) == TYPE_MAIN_VARIANT (type))
86 1.1 mrg return builtin_converted_decls[i].dtype;
87 1.1 mrg }
88 1.1 mrg
89 1.1 mrg switch (TREE_CODE (type))
90 1.1 mrg {
91 1.1 mrg case POINTER_TYPE:
92 1.1 mrg dtype = build_frontend_type (TREE_TYPE (type));
93 1.1 mrg if (dtype)
94 1.1 mrg {
95 1.1 mrg /* Check for char * first. Needs to be done for chars/string. */
96 1.1 mrg if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == char_type_node)
97 1.1 mrg return Type::tchar->addMod (dtype->mod)->pointerTo ()->addMod (mod);
98 1.1 mrg
99 1.1 mrg if (dtype->ty == Tfunction)
100 1.1 mrg return (TypePointer::create (dtype))->addMod (mod);
101 1.1 mrg
102 1.1 mrg return dtype->pointerTo ()->addMod (mod);
103 1.1 mrg }
104 1.1 mrg break;
105 1.1 mrg
106 1.1 mrg case REFERENCE_TYPE:
107 1.1 mrg dtype = build_frontend_type (TREE_TYPE (type));
108 1.1 mrg if (dtype)
109 1.1 mrg {
110 1.1 mrg /* Want to assign ctype directly so that the REFERENCE_TYPE code
111 1.1 mrg can be turned into as an `inout' argument. Can't use pointerTo(),
112 1.1 mrg because the returned Type is shared. */
113 1.1 mrg dtype = (TypePointer::create (dtype))->addMod (mod);
114 1.1 mrg dtype->ctype = type;
115 1.1 mrg builtin_converted_decls.safe_push (builtin_data (dtype, type));
116 1.1 mrg return dtype;
117 1.1 mrg }
118 1.1 mrg break;
119 1.1 mrg
120 1.1 mrg case BOOLEAN_TYPE:
121 1.1 mrg /* Should be no need for size checking. */
122 1.1 mrg return Type::tbool->addMod (mod);
123 1.1 mrg
124 1.1 mrg case INTEGER_TYPE:
125 1.1 mrg {
126 1.1 mrg unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
127 1.1 mrg bool unsignedp = TYPE_UNSIGNED (type);
128 1.1 mrg
129 1.1 mrg /* For now, skip support for cent/ucent until the frontend
130 1.1 mrg has better support for handling it. */
131 1.1 mrg for (size_t i = Tint8; i <= Tuns64; i++)
132 1.1 mrg {
133 1.1 mrg dtype = Type::basic[i];
134 1.1 mrg
135 1.1 mrg /* Search for type matching size and signedness. */
136 1.1 mrg if (unsignedp != dtype->isunsigned ()
137 1.1 mrg || size != dtype->size ())
138 1.1 mrg continue;
139 1.1 mrg
140 1.1 mrg return dtype->addMod (mod);
141 1.1 mrg }
142 1.1 mrg break;
143 1.1 mrg }
144 1.1 mrg
145 1.1 mrg case REAL_TYPE:
146 1.1 mrg {
147 1.1 mrg unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
148 1.1 mrg
149 1.1 mrg for (size_t i = Tfloat32; i <= Tfloat80; i++)
150 1.1 mrg {
151 1.1 mrg dtype = Type::basic[i];
152 1.1 mrg
153 1.1 mrg /* Search for type matching size. */
154 1.1 mrg if (dtype->size () != size)
155 1.1 mrg continue;
156 1.1 mrg
157 1.1 mrg return dtype->addMod (mod);
158 1.1 mrg }
159 1.1 mrg break;
160 1.1 mrg }
161 1.1 mrg
162 1.1 mrg case COMPLEX_TYPE:
163 1.1 mrg {
164 1.1 mrg unsigned size = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
165 1.1 mrg for (size_t i = Tcomplex32; i <= Tcomplex80; i++)
166 1.1 mrg {
167 1.1 mrg dtype = Type::basic[i];
168 1.1 mrg
169 1.1 mrg /* Search for type matching size. */
170 1.1 mrg if (dtype->size () != size)
171 1.1 mrg continue;
172 1.1 mrg
173 1.1 mrg return dtype->addMod (mod);
174 1.1 mrg }
175 1.1 mrg break;
176 1.1 mrg }
177 1.1 mrg
178 1.1 mrg case VOID_TYPE:
179 1.1 mrg return Type::tvoid->addMod (mod);
180 1.1 mrg
181 1.1 mrg case ARRAY_TYPE:
182 1.1 mrg dtype = build_frontend_type (TREE_TYPE (type));
183 1.1 mrg if (dtype)
184 1.1 mrg {
185 1.1 mrg tree index = TYPE_DOMAIN (type);
186 1.1 mrg tree ub = TYPE_MAX_VALUE (index);
187 1.1 mrg tree lb = TYPE_MIN_VALUE (index);
188 1.1 mrg
189 1.1 mrg tree length = fold_build2 (MINUS_EXPR, TREE_TYPE (lb), ub, lb);
190 1.1 mrg length = size_binop (PLUS_EXPR, size_one_node,
191 1.1 mrg convert (sizetype, length));
192 1.1 mrg
193 1.1 mrg dtype = dtype->sarrayOf (TREE_INT_CST_LOW (length))->addMod (mod);
194 1.1 mrg builtin_converted_decls.safe_push (builtin_data (dtype, type));
195 1.1 mrg return dtype;
196 1.1 mrg }
197 1.1 mrg break;
198 1.1 mrg
199 1.1 mrg case VECTOR_TYPE:
200 1.1 mrg dtype = build_frontend_type (TREE_TYPE (type));
201 1.1 mrg if (dtype)
202 1.1 mrg {
203 1.1 mrg poly_uint64 nunits = TYPE_VECTOR_SUBPARTS (type);
204 1.1 mrg dtype = dtype->sarrayOf (nunits.to_constant ())->addMod (mod);
205 1.1 mrg
206 1.1 mrg if (dtype->nextOf ()->isTypeBasic () == NULL)
207 1.1 mrg break;
208 1.1 mrg
209 1.1 mrg dtype = (TypeVector::create (Loc (), dtype))->addMod (mod);
210 1.1 mrg builtin_converted_decls.safe_push (builtin_data (dtype, type));
211 1.1 mrg return dtype;
212 1.1 mrg }
213 1.1 mrg break;
214 1.1 mrg
215 1.1 mrg case RECORD_TYPE:
216 1.1 mrg if (TYPE_NAME (type))
217 1.1 mrg {
218 1.1 mrg tree structname = DECL_NAME (TYPE_NAME (type));
219 1.1 mrg Identifier *ident
220 1.1 mrg = Identifier::idPool (IDENTIFIER_POINTER (structname));
221 1.1 mrg
222 1.1 mrg /* Neither the `object' and `gcc.builtins' modules will not exist when
223 1.1 mrg this is called. Use a stub 'object' module parent in the meantime.
224 1.1 mrg If `gcc.builtins' is later imported, the parent will be overridden
225 1.1 mrg with the correct module symbol. */
226 1.1 mrg static Identifier *object = Identifier::idPool ("object");
227 1.1 mrg static Module *stubmod = Module::create ("object.d", object, 0, 0);
228 1.1 mrg
229 1.1 mrg StructDeclaration *sdecl = StructDeclaration::create (Loc (), ident,
230 1.1 mrg false);
231 1.1 mrg sdecl->parent = stubmod;
232 1.1 mrg sdecl->structsize = int_size_in_bytes (type);
233 1.1 mrg sdecl->alignsize = TYPE_ALIGN_UNIT (type);
234 1.1 mrg sdecl->alignment = STRUCTALIGN_DEFAULT;
235 1.1 mrg sdecl->sizeok = SIZEOKdone;
236 1.1 mrg sdecl->type = (TypeStruct::create (sdecl))->addMod (mod);
237 1.1 mrg sdecl->type->ctype = type;
238 1.1 mrg sdecl->type->merge2 ();
239 1.1 mrg
240 1.1 mrg /* Does not seem necessary to convert fields, but the members field
241 1.1 mrg must be non-null for the above size setting to stick. */
242 1.1 mrg sdecl->members = new Dsymbols;
243 1.1 mrg dtype = sdecl->type;
244 1.1 mrg builtin_converted_decls.safe_push (builtin_data (dtype, type, sdecl));
245 1.1 mrg return dtype;
246 1.1 mrg }
247 1.1 mrg break;
248 1.1 mrg
249 1.1 mrg case FUNCTION_TYPE:
250 1.1 mrg dtype = build_frontend_type (TREE_TYPE (type));
251 1.1 mrg if (dtype)
252 1.1 mrg {
253 1.1 mrg tree parms = TYPE_ARG_TYPES (type);
254 1.1 mrg int varargs_p = 1;
255 1.1 mrg
256 1.1 mrg Parameters *args = new Parameters;
257 1.1 mrg args->reserve (list_length (parms));
258 1.1 mrg
259 1.1 mrg /* Attempt to convert all parameter types. */
260 1.1 mrg for (tree parm = parms; parm != NULL_TREE; parm = TREE_CHAIN (parm))
261 1.1 mrg {
262 1.1 mrg tree argtype = TREE_VALUE (parm);
263 1.1 mrg if (argtype == void_type_node)
264 1.1 mrg {
265 1.1 mrg varargs_p = 0;
266 1.1 mrg break;
267 1.1 mrg }
268 1.1 mrg
269 1.1 mrg StorageClass sc = STCundefined;
270 1.1 mrg if (TREE_CODE (argtype) == REFERENCE_TYPE)
271 1.1 mrg {
272 1.1 mrg argtype = TREE_TYPE (argtype);
273 1.1 mrg sc |= STCref;
274 1.1 mrg }
275 1.1 mrg
276 1.1 mrg Type *targ = build_frontend_type (argtype);
277 1.1 mrg if (!targ)
278 1.1 mrg {
279 1.1 mrg delete args;
280 1.1 mrg return NULL;
281 1.1 mrg }
282 1.1 mrg
283 1.1 mrg args->push (Parameter::create (sc, targ, NULL, NULL));
284 1.1 mrg }
285 1.1 mrg
286 1.1 mrg /* GCC generic and placeholder built-ins are marked as variadic, yet
287 1.1 mrg have no named parameters, and so can't be represented in D. */
288 1.1 mrg if (args->dim != 0 || !varargs_p)
289 1.1 mrg {
290 1.1 mrg dtype = TypeFunction::create (args, dtype, varargs_p, LINKc);
291 1.1 mrg return dtype->addMod (mod);
292 1.1 mrg }
293 1.1 mrg }
294 1.1 mrg break;
295 1.1 mrg
296 1.1 mrg default:
297 1.1 mrg break;
298 1.1 mrg }
299 1.1 mrg
300 1.1 mrg return NULL;
301 1.1 mrg }
302 1.1 mrg
303 1.1 mrg /* Attempt to convert GCC evaluated CST to a D Frontend Expression.
304 1.1 mrg This is used for getting the CTFE value out of a const-folded builtin,
305 1.1 mrg returns NULL if it cannot convert CST. */
306 1.1 mrg
307 1.1 mrg Expression *
308 1.1 mrg d_eval_constant_expression (tree cst)
309 1.1 mrg {
310 1.1 mrg STRIP_TYPE_NOPS (cst);
311 1.1 mrg Type *type = build_frontend_type (TREE_TYPE (cst));
312 1.1 mrg
313 1.1 mrg if (type)
314 1.1 mrg {
315 1.1 mrg /* Convert our GCC CST tree into a D Expression. This seems like we are
316 1.1 mrg trying too hard, as these will only be converted back to a tree again
317 1.1 mrg later in the codegen pass, but satisfies the need to have GCC built-ins
318 1.1 mrg CTFE-able in the frontend. */
319 1.1 mrg tree_code code = TREE_CODE (cst);
320 1.1 mrg if (code == COMPLEX_CST)
321 1.1 mrg {
322 1.1 mrg real_value re = TREE_REAL_CST (TREE_REALPART (cst));
323 1.1 mrg real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
324 1.1 mrg complex_t value = complex_t (ldouble (re), ldouble (im));
325 1.1 mrg return ComplexExp::create (Loc (), value, type);
326 1.1 mrg }
327 1.1 mrg else if (code == INTEGER_CST)
328 1.1 mrg {
329 1.1 mrg dinteger_t value = TREE_INT_CST_LOW (cst);
330 1.1 mrg return IntegerExp::create (Loc (), value, type);
331 1.1 mrg }
332 1.1 mrg else if (code == REAL_CST)
333 1.1 mrg {
334 1.1 mrg real_value value = TREE_REAL_CST (cst);
335 1.1 mrg return RealExp::create (Loc (), ldouble (value), type);
336 1.1 mrg }
337 1.1 mrg else if (code == STRING_CST)
338 1.1 mrg {
339 1.1 mrg const void *string = TREE_STRING_POINTER (cst);
340 1.1 mrg size_t len = TREE_STRING_LENGTH (cst);
341 1.1 mrg return StringExp::create (Loc (), CONST_CAST (void *, string), len);
342 1.1 mrg }
343 1.1 mrg else if (code == VECTOR_CST)
344 1.1 mrg {
345 1.1 mrg dinteger_t nunits = VECTOR_CST_NELTS (cst).to_constant ();
346 1.1 mrg Expressions *elements = new Expressions;
347 1.1 mrg elements->setDim (nunits);
348 1.1 mrg
349 1.1 mrg for (size_t i = 0; i < nunits; i++)
350 1.1 mrg {
351 1.1 mrg Expression *elem
352 1.1 mrg = d_eval_constant_expression (VECTOR_CST_ELT (cst, i));
353 1.1 mrg if (elem == NULL)
354 1.1 mrg return NULL;
355 1.1 mrg
356 1.1 mrg (*elements)[i] = elem;
357 1.1 mrg }
358 1.1 mrg
359 1.1 mrg Expression *e = ArrayLiteralExp::create (Loc (), elements);
360 1.1 mrg e->type = ((TypeVector *) type)->basetype;
361 1.1 mrg
362 1.1 mrg return VectorExp::create (Loc (), e, type);
363 1.1 mrg }
364 1.1 mrg }
365 1.1 mrg
366 1.1 mrg return NULL;
367 1.1 mrg }
368 1.1 mrg
369 1.1 mrg /* Callback for TARGET_D_CPU_VERSIONS and TARGET_D_OS_VERSIONS.
370 1.1 mrg Adds IDENT to the list of predefined version identifiers. */
371 1.1 mrg
372 1.1 mrg void
373 1.1 mrg d_add_builtin_version (const char* ident)
374 1.1 mrg {
375 1.1 mrg /* For now, we need to tell the D frontend what platform is being targeted.
376 1.1 mrg This should be removed once the frontend has been fixed. */
377 1.1 mrg if (strcmp (ident, "linux") == 0)
378 1.1 mrg global.params.isLinux = true;
379 1.1 mrg else if (strcmp (ident, "OSX") == 0)
380 1.1 mrg global.params.isOSX = true;
381 1.1 mrg else if (strcmp (ident, "Windows") == 0)
382 1.1 mrg global.params.isWindows = true;
383 1.1 mrg else if (strcmp (ident, "FreeBSD") == 0)
384 1.1 mrg global.params.isFreeBSD = true;
385 1.1 mrg else if (strcmp (ident, "OpenBSD") == 0)
386 1.1 mrg global.params.isOpenBSD = true;
387 1.1 mrg else if (strcmp (ident, "Solaris") == 0)
388 1.1 mrg global.params.isSolaris = true;
389 1.1 mrg /* The is64bit field only refers to x86_64 target. */
390 1.1 mrg else if (strcmp (ident, "X86_64") == 0)
391 1.1 mrg global.params.is64bit = true;
392 1.1 mrg /* No other fields are required to be set for the frontend. */
393 1.1 mrg
394 1.1 mrg VersionCondition::addPredefinedGlobalIdent (ident);
395 1.1 mrg }
396 1.1 mrg
397 1.1 mrg /* Initialize the list of all the predefined version identifiers. */
398 1.1 mrg
399 1.1 mrg void
400 1.1 mrg d_init_versions (void)
401 1.1 mrg {
402 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("GNU");
403 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_Version2");
404 1.1 mrg
405 1.1 mrg if (BYTES_BIG_ENDIAN)
406 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("BigEndian");
407 1.1 mrg else
408 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("LittleEndian");
409 1.1 mrg
410 1.1 mrg if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ)
411 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("GNU_SjLj_Exceptions");
412 1.1 mrg else if (targetm_common.except_unwind_info (&global_options) == UI_SEH)
413 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("GNU_SEH_Exceptions");
414 1.1 mrg else if (targetm_common.except_unwind_info (&global_options) == UI_DWARF2)
415 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("GNU_DWARF2_Exceptions");
416 1.1 mrg
417 1.1 mrg if (!targetm.have_tls)
418 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("GNU_EMUTLS");
419 1.1 mrg
420 1.1 mrg if (STACK_GROWS_DOWNWARD)
421 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("GNU_StackGrowsDown");
422 1.1 mrg
423 1.1 mrg /* Should define this anyway to set us apart from the competition. */
424 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("GNU_InlineAsm");
425 1.1 mrg
426 1.1 mrg /* LP64 only means 64bit pointers in D. */
427 1.1 mrg if (global.params.isLP64)
428 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_LP64");
429 1.1 mrg
430 1.1 mrg /* Setting `global.params.cov' forces module info generation which is
431 1.1 mrg not needed for the GCC coverage implementation. Instead, just
432 1.1 mrg test flag_test_coverage while leaving `global.params.cov' unset. */
433 1.1 mrg if (flag_test_coverage)
434 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_Coverage");
435 1.1 mrg if (flag_pic)
436 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_PIC");
437 1.1 mrg
438 1.1 mrg if (global.params.doDocComments)
439 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_Ddoc");
440 1.1 mrg
441 1.1 mrg if (global.params.useUnitTests)
442 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("unittest");
443 1.1 mrg
444 1.1 mrg if (global.params.useAssert)
445 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("assert");
446 1.1 mrg
447 1.1 mrg if (global.params.useArrayBounds == BOUNDSCHECKoff)
448 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_NoBoundsChecks");
449 1.1 mrg
450 1.1 mrg if (global.params.betterC)
451 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_BetterC");
452 1.1 mrg else
453 1.1 mrg {
454 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
455 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
456 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
457 1.1 mrg }
458 1.1 mrg
459 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("all");
460 1.1 mrg
461 1.1 mrg /* Emit all target-specific version identifiers. */
462 1.1 mrg targetdm.d_cpu_versions ();
463 1.1 mrg targetdm.d_os_versions ();
464 1.1 mrg
465 1.1 mrg VersionCondition::addPredefinedGlobalIdent ("CppRuntime_Gcc");
466 1.1 mrg }
467 1.1 mrg
468 1.1 mrg /* A helper for d_build_builtins_module. Return a new ALIAS for TYPE.
469 1.1 mrg Analogous to `alias ALIAS = TYPE' in D code. */
470 1.1 mrg
471 1.1 mrg static AliasDeclaration *
472 1.1 mrg build_alias_declaration (const char *alias, Type *type)
473 1.1 mrg {
474 1.1 mrg return AliasDeclaration::create (Loc (), Identifier::idPool (alias), type);
475 1.1 mrg }
476 1.1 mrg
477 1.1 mrg /* A helper function for Target::loadModule. Generates all code for the
478 1.1 mrg `gcc.builtins' module, whose frontend symbol should be M. */
479 1.1 mrg
480 1.1 mrg void
481 1.1 mrg d_build_builtins_module (Module *m)
482 1.1 mrg {
483 1.1 mrg Dsymbols *members = new Dsymbols;
484 1.1 mrg tree decl;
485 1.1 mrg
486 1.1 mrg for (size_t i = 0; vec_safe_iterate (gcc_builtins_functions, i, &decl); ++i)
487 1.1 mrg {
488 1.1 mrg const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
489 1.1 mrg TypeFunction *tf
490 1.1 mrg = (TypeFunction *) build_frontend_type (TREE_TYPE (decl));
491 1.1 mrg
492 1.1 mrg /* Cannot create built-in function type for DECL. */
493 1.1 mrg if (!tf)
494 1.1 mrg continue;
495 1.1 mrg
496 1.1 mrg /* A few notes on D2 attributes applied to builtin functions:
497 1.1 mrg - It is assumed that built-ins solely provided by the compiler are
498 1.1 mrg considered @safe and pure.
499 1.1 mrg - Built-ins that correspond to `extern(C)' functions in the standard
500 1.1 mrg library that have `__attribute__(nothrow)' are considered `@trusted'.
501 1.1 mrg - The purity of a built-in can vary depending on compiler flags set
502 1.1 mrg upon initialization, or by the `-foptions' passed, such as
503 1.1 mrg flag_unsafe_math_optimizations.
504 1.1 mrg - Built-ins never use the GC or raise a D exception, and so are always
505 1.1 mrg marked as `nothrow' and `@nogc'. */
506 1.1 mrg tf->purity = DECL_PURE_P (decl) ? PUREstrong
507 1.1 mrg : TREE_READONLY (decl) ? PUREconst
508 1.1 mrg : DECL_IS_NOVOPS (decl) ? PUREweak
509 1.1 mrg : !DECL_ASSEMBLER_NAME_SET_P (decl) ? PUREweak
510 1.1 mrg : PUREimpure;
511 1.1 mrg tf->trust = !DECL_ASSEMBLER_NAME_SET_P (decl) ? TRUSTsafe
512 1.1 mrg : TREE_NOTHROW (decl) ? TRUSTtrusted
513 1.1 mrg : TRUSTsystem;
514 1.1 mrg tf->isnothrow = true;
515 1.1 mrg tf->isnogc = true;
516 1.1 mrg
517 1.1 mrg FuncDeclaration *func
518 1.1 mrg = FuncDeclaration::create (Loc (), Loc (),
519 1.1 mrg Identifier::idPool (name),
520 1.1 mrg STCextern, tf);
521 1.1 mrg DECL_LANG_SPECIFIC (decl) = build_lang_decl (func);
522 1.1 mrg func->csym = decl;
523 1.1 mrg func->builtin = BUILTINyes;
524 1.1 mrg
525 1.1 mrg members->push (func);
526 1.1 mrg }
527 1.1 mrg
528 1.1 mrg for (size_t i = 0; vec_safe_iterate (gcc_builtins_types, i, &decl); ++i)
529 1.1 mrg {
530 1.1 mrg const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
531 1.1 mrg Type *t = build_frontend_type (TREE_TYPE (decl));
532 1.1 mrg
533 1.1 mrg /* Cannot create built-in type for DECL. */
534 1.1 mrg if (!t)
535 1.1 mrg continue;
536 1.1 mrg
537 1.1 mrg members->push (build_alias_declaration (name, t));
538 1.1 mrg }
539 1.1 mrg
540 1.1 mrg /* Iterate through the target-specific builtin types for va_list. */
541 1.1 mrg if (targetm.enum_va_list_p)
542 1.1 mrg {
543 1.1 mrg const char *name;
544 1.1 mrg tree type;
545 1.1 mrg
546 1.1 mrg for (int i = 0; targetm.enum_va_list_p (i, &name, &type); ++i)
547 1.1 mrg {
548 1.1 mrg Type *t = build_frontend_type (type);
549 1.1 mrg /* Cannot create built-in type. */
550 1.1 mrg if (!t)
551 1.1 mrg continue;
552 1.1 mrg
553 1.1 mrg members->push (build_alias_declaration (name, t));
554 1.1 mrg }
555 1.1 mrg }
556 1.1 mrg
557 1.1 mrg /* Push out declarations for any RECORD_TYPE types encountered when building
558 1.1 mrg all builtin functions and types. */
559 1.1 mrg for (size_t i = 0; i < builtin_converted_decls.length (); ++i)
560 1.1 mrg {
561 1.1 mrg /* Currently, there is no need to run semantic, but we do want to output
562 1.1 mrg initializers, typeinfo, and others on demand. */
563 1.1 mrg Dsymbol *dsym = builtin_converted_decls[i].dsym;
564 1.1 mrg if (dsym != NULL)
565 1.1 mrg {
566 1.1 mrg dsym->parent = m;
567 1.1 mrg members->push (dsym);
568 1.1 mrg }
569 1.1 mrg }
570 1.1 mrg
571 1.1 mrg /* va_list should already be built, so no need to convert to D type again. */
572 1.1 mrg members->push (build_alias_declaration ("__builtin_va_list", Type::tvalist));
573 1.1 mrg
574 1.1 mrg /* Expose target-specific integer types to the builtins module. */
575 1.1 mrg {
576 1.1 mrg Type *t = build_frontend_type (long_integer_type_node);
577 1.1 mrg members->push (build_alias_declaration ("__builtin_clong", t));
578 1.1 mrg
579 1.1 mrg t = build_frontend_type (long_unsigned_type_node);
580 1.1 mrg members->push (build_alias_declaration ("__builtin_culong", t));
581 1.1 mrg
582 1.1 mrg t = build_frontend_type (long_long_integer_type_node);
583 1.1 mrg members->push (build_alias_declaration ("__builtin_clonglong", t));
584 1.1 mrg
585 1.1 mrg t = build_frontend_type (long_long_unsigned_type_node);
586 1.1 mrg members->push (build_alias_declaration ("__builtin_culonglong", t));
587 1.1 mrg
588 1.1 mrg t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 0));
589 1.1 mrg members->push (build_alias_declaration ("__builtin_machine_byte", t));
590 1.1 mrg
591 1.1 mrg t = build_frontend_type (lang_hooks.types.type_for_mode (byte_mode, 1));
592 1.1 mrg members->push (build_alias_declaration ("__builtin_machine_ubyte", t));
593 1.1 mrg
594 1.1 mrg t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 0));
595 1.1 mrg members->push (build_alias_declaration ("__builtin_machine_int", t));
596 1.1 mrg
597 1.1 mrg t = build_frontend_type (lang_hooks.types.type_for_mode (word_mode, 1));
598 1.1 mrg members->push (build_alias_declaration ("__builtin_machine_uint", t));
599 1.1 mrg
600 1.1 mrg t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 0));
601 1.1 mrg members->push (build_alias_declaration ("__builtin_pointer_int", t));
602 1.1 mrg
603 1.1 mrg t = build_frontend_type (lang_hooks.types.type_for_mode (ptr_mode, 1));
604 1.1 mrg members->push (build_alias_declaration ("__builtin_pointer_uint", t));
605 1.1 mrg
606 1.1 mrg /* _Unwind_Word has its own target specific mode. */
607 1.1 mrg machine_mode mode = targetm.unwind_word_mode ();
608 1.1 mrg t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 0));
609 1.1 mrg members->push (build_alias_declaration ("__builtin_unwind_int", t));
610 1.1 mrg
611 1.1 mrg t = build_frontend_type (lang_hooks.types.type_for_mode (mode, 1));
612 1.1 mrg members->push (build_alias_declaration ("__builtin_unwind_uint", t));
613 1.1 mrg }
614 1.1 mrg
615 1.1 mrg m->members->push (LinkDeclaration::create (LINKc, members));
616 1.1 mrg }
617 1.1 mrg
618 1.1 mrg /* Search for any `extern(C)' functions that match any known GCC library builtin
619 1.1 mrg function in D and override its internal back-end symbol. */
620 1.1 mrg
621 1.1 mrg static void
622 1.1 mrg maybe_set_builtin_1 (Dsymbol *d)
623 1.1 mrg {
624 1.1 mrg AttribDeclaration *ad = d->isAttribDeclaration ();
625 1.1 mrg FuncDeclaration *fd = d->isFuncDeclaration ();
626 1.1 mrg
627 1.1 mrg if (ad != NULL)
628 1.1 mrg {
629 1.1 mrg /* Recursively search through attribute decls. */
630 1.1 mrg Dsymbols *decls = ad->include (NULL, NULL);
631 1.1 mrg if (decls && decls->dim)
632 1.1 mrg {
633 1.1 mrg for (size_t i = 0; i < decls->dim; i++)
634 1.1 mrg {
635 1.1 mrg Dsymbol *sym = (*decls)[i];
636 1.1 mrg maybe_set_builtin_1 (sym);
637 1.1 mrg }
638 1.1 mrg }
639 1.1 mrg }
640 1.1 mrg else if (fd && !fd->fbody)
641 1.1 mrg {
642 1.1 mrg tree t;
643 1.1 mrg
644 1.1 mrg for (size_t i = 0; vec_safe_iterate (gcc_builtins_libfuncs, i, &t); ++i)
645 1.1 mrg {
646 1.1 mrg gcc_assert (DECL_ASSEMBLER_NAME_SET_P (t));
647 1.1 mrg
648 1.1 mrg const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
649 1.1 mrg if (fd->ident != Identifier::idPool (name))
650 1.1 mrg continue;
651 1.1 mrg
652 1.1 mrg /* Found a match, tell the frontend this is a builtin. */
653 1.1 mrg DECL_LANG_SPECIFIC (t) = build_lang_decl (fd);
654 1.1 mrg fd->csym = t;
655 1.1 mrg fd->builtin = BUILTINyes;
656 1.1 mrg return;
657 1.1 mrg }
658 1.1 mrg }
659 1.1 mrg }
660 1.1 mrg
661 1.1 mrg /* A helper function for Target::loadModule. Traverse all members in module M
662 1.1 mrg to search for any functions that can be mapped to any GCC builtin. */
663 1.1 mrg
664 1.1 mrg void
665 1.1 mrg d_maybe_set_builtin (Module *m)
666 1.1 mrg {
667 1.1 mrg if (!m || !m->members)
668 1.1 mrg return;
669 1.1 mrg
670 1.1 mrg for (size_t i = 0; i < m->members->dim; i++)
671 1.1 mrg {
672 1.1 mrg Dsymbol *sym = (*m->members)[i];
673 1.1 mrg maybe_set_builtin_1 (sym);
674 1.1 mrg }
675 1.1 mrg }
676 1.1 mrg
677 1.1 mrg /* Used to help initialize the builtin-types.def table. When a type of
678 1.1 mrg the correct size doesn't exist, use error_mark_node instead of NULL.
679 1.1 mrg The latter results in segfaults even when a decl using the type doesn't
680 1.1 mrg get invoked. */
681 1.1 mrg
682 1.1 mrg static tree
683 1.1 mrg builtin_type_for_size (int size, bool unsignedp)
684 1.1 mrg {
685 1.1 mrg tree type = lang_hooks.types.type_for_size (size, unsignedp);
686 1.1 mrg return type ? type : error_mark_node;
687 1.1 mrg }
688 1.1 mrg
689 1.1 mrg /* Support for DEF_BUILTIN. */
690 1.1 mrg
691 1.1 mrg static void
692 1.1 mrg do_build_builtin_fn (built_in_function fncode,
693 1.1 mrg const char *name,
694 1.1 mrg built_in_class fnclass,
695 1.1 mrg tree fntype, bool both_p, bool fallback_p,
696 1.1 mrg tree fnattrs, bool implicit_p)
697 1.1 mrg {
698 1.1 mrg tree decl;
699 1.1 mrg const char *libname;
700 1.1 mrg
701 1.1 mrg if (fntype == error_mark_node)
702 1.1 mrg return;
703 1.1 mrg
704 1.1 mrg gcc_assert ((!both_p && !fallback_p)
705 1.1 mrg || !strncmp (name, "__builtin_",
706 1.1 mrg strlen ("__builtin_")));
707 1.1 mrg
708 1.1 mrg libname = name + strlen ("__builtin_");
709 1.1 mrg
710 1.1 mrg decl = add_builtin_function (name, fntype, fncode, fnclass,
711 1.1 mrg fallback_p ? libname : NULL, fnattrs);
712 1.1 mrg
713 1.1 mrg set_builtin_decl (fncode, decl, implicit_p);
714 1.1 mrg }
715 1.1 mrg
716 1.1 mrg /* Standard data types to be used in builtin argument declarations. */
717 1.1 mrg
718 1.1 mrg static GTY(()) tree string_type_node;
719 1.1 mrg static GTY(()) tree const_string_type_node;
720 1.1 mrg static GTY(()) tree wint_type_node;
721 1.1 mrg static GTY(()) tree intmax_type_node;
722 1.1 mrg static GTY(()) tree uintmax_type_node;
723 1.1 mrg static GTY(()) tree signed_size_type_node;
724 1.1 mrg
725 1.1 mrg
726 1.1 mrg /* Build nodes that would have been created by the C front-end; necessary
727 1.1 mrg for including builtin-types.def and ultimately builtins.def. */
728 1.1 mrg
729 1.1 mrg static void
730 1.1 mrg d_build_c_type_nodes (void)
731 1.1 mrg {
732 1.1 mrg void_list_node = build_tree_list (NULL_TREE, void_type_node);
733 1.1 mrg string_type_node = build_pointer_type (char_type_node);
734 1.1 mrg const_string_type_node
735 1.1 mrg = build_pointer_type (build_qualified_type (char_type_node,
736 1.1 mrg TYPE_QUAL_CONST));
737 1.1 mrg
738 1.1 mrg if (strcmp (SIZE_TYPE, "unsigned int") == 0)
739 1.1 mrg {
740 1.1 mrg intmax_type_node = integer_type_node;
741 1.1 mrg uintmax_type_node = unsigned_type_node;
742 1.1 mrg signed_size_type_node = integer_type_node;
743 1.1 mrg }
744 1.1 mrg else if (strcmp (SIZE_TYPE, "long unsigned int") == 0)
745 1.1 mrg {
746 1.1 mrg intmax_type_node = long_integer_type_node;
747 1.1 mrg uintmax_type_node = long_unsigned_type_node;
748 1.1 mrg signed_size_type_node = long_integer_type_node;
749 1.1 mrg }
750 1.1 mrg else if (strcmp (SIZE_TYPE, "long long unsigned int") == 0)
751 1.1 mrg {
752 1.1 mrg intmax_type_node = long_long_integer_type_node;
753 1.1 mrg uintmax_type_node = long_long_unsigned_type_node;
754 1.1 mrg signed_size_type_node = long_long_integer_type_node;
755 1.1 mrg }
756 1.1 mrg else
757 1.1 mrg gcc_unreachable ();
758 1.1 mrg
759 1.1 mrg wint_type_node = unsigned_type_node;
760 1.1 mrg pid_type_node = integer_type_node;
761 1.1 mrg }
762 1.1 mrg
763 1.1 mrg /* Build nodes that are used by the D front-end.
764 1.1 mrg These are distinct from C types. */
765 1.1 mrg
766 1.1 mrg static void
767 1.1 mrg d_build_d_type_nodes (void)
768 1.1 mrg {
769 1.1 mrg /* Integral types. */
770 1.1 mrg d_byte_type = make_signed_type (8);
771 1.1 mrg d_ubyte_type = make_unsigned_type (8);
772 1.1 mrg
773 1.1 mrg d_short_type = make_signed_type (16);
774 1.1 mrg d_ushort_type = make_unsigned_type (16);
775 1.1 mrg
776 1.1 mrg d_int_type = make_signed_type (32);
777 1.1 mrg d_uint_type = make_unsigned_type (32);
778 1.1 mrg
779 1.1 mrg d_long_type = make_signed_type (64);
780 1.1 mrg d_ulong_type = make_unsigned_type (64);
781 1.1 mrg
782 1.1 mrg d_cent_type = make_signed_type (128);
783 1.1 mrg d_ucent_type = make_unsigned_type (128);
784 1.1 mrg
785 1.1 mrg {
786 1.1 mrg /* Re-define size_t as a D type. */
787 1.1 mrg machine_mode type_mode = TYPE_MODE (size_type_node);
788 1.1 mrg size_type_node = lang_hooks.types.type_for_mode (type_mode, 1);
789 1.1 mrg }
790 1.1 mrg
791 1.1 mrg /* Bool and Character types. */
792 1.1 mrg d_bool_type = make_unsigned_type (1);
793 1.1 mrg TREE_SET_CODE (d_bool_type, BOOLEAN_TYPE);
794 1.1 mrg
795 1.1 mrg char8_type_node = make_unsigned_type (8);
796 1.1 mrg TYPE_STRING_FLAG (char8_type_node) = 1;
797 1.1 mrg
798 1.1 mrg char16_type_node = make_unsigned_type (16);
799 1.1 mrg TYPE_STRING_FLAG (char16_type_node) = 1;
800 1.1 mrg
801 1.1 mrg char32_type_node = make_unsigned_type (32);
802 1.1 mrg TYPE_STRING_FLAG (char32_type_node) = 1;
803 1.1 mrg
804 1.1 mrg /* Imaginary types. */
805 1.1 mrg ifloat_type_node = build_distinct_type_copy (float_type_node);
806 1.1 mrg TYPE_IMAGINARY_FLOAT (ifloat_type_node) = 1;
807 1.1 mrg
808 1.1 mrg idouble_type_node = build_distinct_type_copy (double_type_node);
809 1.1 mrg TYPE_IMAGINARY_FLOAT (idouble_type_node) = 1;
810 1.1 mrg
811 1.1 mrg ireal_type_node = build_distinct_type_copy (long_double_type_node);
812 1.1 mrg TYPE_IMAGINARY_FLOAT (ireal_type_node) = 1;
813 1.1 mrg
814 1.1 mrg /* Used for ModuleInfo, ClassInfo, and Interface decls. */
815 1.1 mrg unknown_type_node = make_node (RECORD_TYPE);
816 1.1 mrg
817 1.1 mrg /* Make sure we get a unique function type, so we can give
818 1.1 mrg its pointer type a name. (This wins for gdb). */
819 1.1 mrg {
820 1.1 mrg tree vfunc_type = make_node (FUNCTION_TYPE);
821 1.1 mrg TREE_TYPE (vfunc_type) = d_int_type;
822 1.1 mrg TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
823 1.1 mrg layout_type (vfunc_type);
824 1.1 mrg
825 1.1 mrg vtable_entry_type = build_pointer_type (vfunc_type);
826 1.1 mrg }
827 1.1 mrg
828 1.1 mrg vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
829 1.1 mrg layout_type (vtbl_ptr_type_node);
830 1.1 mrg
831 1.1 mrg /* When an object is accessed via an interface, this type appears
832 1.1 mrg as the first entry in its vtable. */
833 1.1 mrg {
834 1.1 mrg tree domain = build_index_type (size_int (3));
835 1.1 mrg vtbl_interface_type_node = build_array_type (ptr_type_node, domain);
836 1.1 mrg }
837 1.1 mrg
838 1.1 mrg /* Use `void[]' as a generic dynamic array type. */
839 1.1 mrg array_type_node = make_struct_type ("__builtin_void[]", 2,
840 1.1 mrg get_identifier ("length"), size_type_node,
841 1.1 mrg get_identifier ("ptr"), ptr_type_node);
842 1.1 mrg TYPE_DYNAMIC_ARRAY (array_type_node) = 1;
843 1.1 mrg
844 1.1 mrg null_array_node = d_array_value (array_type_node, size_zero_node,
845 1.1 mrg null_pointer_node);
846 1.1 mrg }
847 1.1 mrg
848 1.1 mrg /* Handle default attributes. */
849 1.1 mrg
850 1.1 mrg enum built_in_attribute
851 1.1 mrg {
852 1.1 mrg #define DEF_ATTR_NULL_TREE(ENUM) ENUM,
853 1.1 mrg #define DEF_ATTR_INT(ENUM, VALUE) ENUM,
854 1.1 mrg #define DEF_ATTR_STRING(ENUM, VALUE) ENUM,
855 1.1 mrg #define DEF_ATTR_IDENT(ENUM, STRING) ENUM,
856 1.1 mrg #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) ENUM,
857 1.1 mrg #include "builtin-attrs.def"
858 1.1 mrg #undef DEF_ATTR_NULL_TREE
859 1.1 mrg #undef DEF_ATTR_INT
860 1.1 mrg #undef DEF_ATTR_STRING
861 1.1 mrg #undef DEF_ATTR_IDENT
862 1.1 mrg #undef DEF_ATTR_TREE_LIST
863 1.1 mrg ATTR_LAST
864 1.1 mrg };
865 1.1 mrg
866 1.1 mrg static GTY(()) tree built_in_attributes[(int) ATTR_LAST];
867 1.1 mrg
868 1.1 mrg /* Initialize the attribute table for all the supported builtins. */
869 1.1 mrg
870 1.1 mrg static void
871 1.1 mrg d_init_attributes (void)
872 1.1 mrg {
873 1.1 mrg /* Fill in the built_in_attributes array. */
874 1.1 mrg #define DEF_ATTR_NULL_TREE(ENUM) \
875 1.1 mrg built_in_attributes[(int) ENUM] = NULL_TREE;
876 1.1 mrg # define DEF_ATTR_INT(ENUM, VALUE) \
877 1.1 mrg built_in_attributes[(int) ENUM] = build_int_cst (NULL_TREE, VALUE);
878 1.1 mrg #define DEF_ATTR_STRING(ENUM, VALUE) \
879 1.1 mrg built_in_attributes[(int) ENUM] = build_string (strlen (VALUE), VALUE);
880 1.1 mrg #define DEF_ATTR_IDENT(ENUM, STRING) \
881 1.1 mrg built_in_attributes[(int) ENUM] = get_identifier (STRING);
882 1.1 mrg #define DEF_ATTR_TREE_LIST(ENUM, PURPOSE, VALUE, CHAIN) \
883 1.1 mrg built_in_attributes[(int) ENUM] \
884 1.1 mrg = tree_cons (built_in_attributes[(int) PURPOSE], \
885 1.1 mrg built_in_attributes[(int) VALUE], \
886 1.1 mrg built_in_attributes[(int) CHAIN]);
887 1.1 mrg #include "builtin-attrs.def"
888 1.1 mrg #undef DEF_ATTR_NULL_TREE
889 1.1 mrg #undef DEF_ATTR_INT
890 1.1 mrg #undef DEF_ATTR_STRING
891 1.1 mrg #undef DEF_ATTR_IDENT
892 1.1 mrg #undef DEF_ATTR_TREE_LIST
893 1.1 mrg }
894 1.1 mrg
895 1.1 mrg /* Builtin types. */
896 1.1 mrg
897 1.1 mrg enum d_builtin_type
898 1.1 mrg {
899 1.1 mrg #define DEF_PRIMITIVE_TYPE(NAME, VALUE) NAME,
900 1.1 mrg #define DEF_FUNCTION_TYPE_0(NAME, RETURN) NAME,
901 1.1 mrg #define DEF_FUNCTION_TYPE_1(NAME, RETURN, ARG1) NAME,
902 1.1 mrg #define DEF_FUNCTION_TYPE_2(NAME, RETURN, ARG1, ARG2) NAME,
903 1.1 mrg #define DEF_FUNCTION_TYPE_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
904 1.1 mrg #define DEF_FUNCTION_TYPE_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
905 1.1 mrg #define DEF_FUNCTION_TYPE_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) NAME,
906 1.1 mrg #define DEF_FUNCTION_TYPE_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
907 1.1 mrg ARG6) NAME,
908 1.1 mrg #define DEF_FUNCTION_TYPE_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
909 1.1 mrg ARG6, ARG7) NAME,
910 1.1 mrg #define DEF_FUNCTION_TYPE_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
911 1.1 mrg ARG6, ARG7, ARG8) NAME,
912 1.1 mrg #define DEF_FUNCTION_TYPE_9(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
913 1.1 mrg ARG6, ARG7, ARG8, ARG9) NAME,
914 1.1 mrg #define DEF_FUNCTION_TYPE_10(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
915 1.1 mrg ARG6, ARG7, ARG8, ARG9, ARG10) NAME,
916 1.1 mrg #define DEF_FUNCTION_TYPE_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
917 1.1 mrg ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
918 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_0(NAME, RETURN) NAME,
919 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_1(NAME, RETURN, ARG1) NAME,
920 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_2(NAME, RETURN, ARG1, ARG2) NAME,
921 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME,
922 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME,
923 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
924 1.1 mrg NAME,
925 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_6(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
926 1.1 mrg ARG6) NAME,
927 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
928 1.1 mrg ARG6, ARG7) NAME,
929 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
930 1.1 mrg ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME,
931 1.1 mrg #define DEF_POINTER_TYPE(NAME, TYPE) NAME,
932 1.1 mrg #include "builtin-types.def"
933 1.1 mrg #undef DEF_PRIMITIVE_TYPE
934 1.1 mrg #undef DEF_FUNCTION_TYPE_0
935 1.1 mrg #undef DEF_FUNCTION_TYPE_1
936 1.1 mrg #undef DEF_FUNCTION_TYPE_2
937 1.1 mrg #undef DEF_FUNCTION_TYPE_3
938 1.1 mrg #undef DEF_FUNCTION_TYPE_4
939 1.1 mrg #undef DEF_FUNCTION_TYPE_5
940 1.1 mrg #undef DEF_FUNCTION_TYPE_6
941 1.1 mrg #undef DEF_FUNCTION_TYPE_7
942 1.1 mrg #undef DEF_FUNCTION_TYPE_8
943 1.1 mrg #undef DEF_FUNCTION_TYPE_9
944 1.1 mrg #undef DEF_FUNCTION_TYPE_10
945 1.1 mrg #undef DEF_FUNCTION_TYPE_11
946 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_0
947 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_1
948 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_2
949 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_3
950 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_4
951 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_5
952 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_6
953 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_7
954 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_11
955 1.1 mrg #undef DEF_POINTER_TYPE
956 1.1 mrg BT_LAST
957 1.1 mrg };
958 1.1 mrg
959 1.1 mrg typedef enum d_builtin_type builtin_type;
960 1.1 mrg
961 1.1 mrg /* A temporary array used in communication with def_fn_type. */
962 1.1 mrg static GTY(()) tree builtin_types[(int) BT_LAST + 1];
963 1.1 mrg
964 1.1 mrg /* A helper function for d_init_builtins. Build function type for DEF with
965 1.1 mrg return type RET and N arguments. If VAR is true, then the function should
966 1.1 mrg be variadic after those N arguments.
967 1.1 mrg
968 1.1 mrg Takes special care not to ICE if any of the types involved are
969 1.1 mrg error_mark_node, which indicates that said type is not in fact available
970 1.1 mrg (see builtin_type_for_size). In which case the function type as a whole
971 1.1 mrg should be error_mark_node. */
972 1.1 mrg
973 1.1 mrg static void
974 1.1 mrg def_fn_type (builtin_type def, builtin_type ret, bool var, int n, ...)
975 1.1 mrg {
976 1.1 mrg tree t;
977 1.1 mrg tree *args = XALLOCAVEC (tree, n);
978 1.1 mrg va_list list;
979 1.1 mrg int i;
980 1.1 mrg
981 1.1 mrg va_start (list, n);
982 1.1 mrg for (i = 0; i < n; ++i)
983 1.1 mrg {
984 1.1 mrg builtin_type a = (builtin_type) va_arg (list, int);
985 1.1 mrg t = builtin_types[a];
986 1.1 mrg if (t == error_mark_node)
987 1.1 mrg goto egress;
988 1.1 mrg args[i] = t;
989 1.1 mrg }
990 1.1 mrg
991 1.1 mrg t = builtin_types[ret];
992 1.1 mrg if (t == error_mark_node)
993 1.1 mrg goto egress;
994 1.1 mrg if (var)
995 1.1 mrg t = build_varargs_function_type_array (t, n, args);
996 1.1 mrg else
997 1.1 mrg t = build_function_type_array (t, n, args);
998 1.1 mrg
999 1.1 mrg egress:
1000 1.1 mrg builtin_types[def] = t;
1001 1.1 mrg va_end (list);
1002 1.1 mrg }
1003 1.1 mrg
1004 1.1 mrg /* Create builtin types and functions. VA_LIST_REF_TYPE_NODE and
1005 1.1 mrg VA_LIST_ARG_TYPE_NODE are used in builtin-types.def. */
1006 1.1 mrg
1007 1.1 mrg static void
1008 1.1 mrg d_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED,
1009 1.1 mrg tree va_list_arg_type_node ATTRIBUTE_UNUSED)
1010 1.1 mrg {
1011 1.1 mrg #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
1012 1.1 mrg builtin_types[(int) ENUM] = VALUE;
1013 1.1 mrg #define DEF_FUNCTION_TYPE_0(ENUM, RETURN) \
1014 1.1 mrg def_fn_type (ENUM, RETURN, 0, 0);
1015 1.1 mrg #define DEF_FUNCTION_TYPE_1(ENUM, RETURN, ARG1) \
1016 1.1 mrg def_fn_type (ENUM, RETURN, 0, 1, ARG1);
1017 1.1 mrg #define DEF_FUNCTION_TYPE_2(ENUM, RETURN, ARG1, ARG2) \
1018 1.1 mrg def_fn_type (ENUM, RETURN, 0, 2, ARG1, ARG2);
1019 1.1 mrg #define DEF_FUNCTION_TYPE_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1020 1.1 mrg def_fn_type (ENUM, RETURN, 0, 3, ARG1, ARG2, ARG3);
1021 1.1 mrg #define DEF_FUNCTION_TYPE_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1022 1.1 mrg def_fn_type (ENUM, RETURN, 0, 4, ARG1, ARG2, ARG3, ARG4);
1023 1.1 mrg #define DEF_FUNCTION_TYPE_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1024 1.1 mrg def_fn_type (ENUM, RETURN, 0, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1025 1.1 mrg #define DEF_FUNCTION_TYPE_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1026 1.1 mrg ARG6) \
1027 1.1 mrg def_fn_type (ENUM, RETURN, 0, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1028 1.1 mrg #define DEF_FUNCTION_TYPE_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1029 1.1 mrg ARG6, ARG7) \
1030 1.1 mrg def_fn_type (ENUM, RETURN, 0, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1031 1.1 mrg #define DEF_FUNCTION_TYPE_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1032 1.1 mrg ARG6, ARG7, ARG8) \
1033 1.1 mrg def_fn_type (ENUM, RETURN, 0, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1034 1.1 mrg ARG7, ARG8);
1035 1.1 mrg #define DEF_FUNCTION_TYPE_9(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1036 1.1 mrg ARG6, ARG7, ARG8, ARG9) \
1037 1.1 mrg def_fn_type (ENUM, RETURN, 0, 9, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1038 1.1 mrg ARG7, ARG8, ARG9);
1039 1.1 mrg #define DEF_FUNCTION_TYPE_10(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1040 1.1 mrg ARG6, ARG7, ARG8, ARG9, ARG10) \
1041 1.1 mrg def_fn_type (ENUM, RETURN, 0, 10, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1042 1.1 mrg ARG7, ARG8, ARG9, ARG10);
1043 1.1 mrg #define DEF_FUNCTION_TYPE_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1044 1.1 mrg ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1045 1.1 mrg def_fn_type (ENUM, RETURN, 0, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1046 1.1 mrg ARG7, ARG8, ARG9, ARG10, ARG11);
1047 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_0(ENUM, RETURN) \
1048 1.1 mrg def_fn_type (ENUM, RETURN, 1, 0);
1049 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_1(ENUM, RETURN, ARG1) \
1050 1.1 mrg def_fn_type (ENUM, RETURN, 1, 1, ARG1);
1051 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_2(ENUM, RETURN, ARG1, ARG2) \
1052 1.1 mrg def_fn_type (ENUM, RETURN, 1, 2, ARG1, ARG2);
1053 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_3(ENUM, RETURN, ARG1, ARG2, ARG3) \
1054 1.1 mrg def_fn_type (ENUM, RETURN, 1, 3, ARG1, ARG2, ARG3);
1055 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_4(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4) \
1056 1.1 mrg def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4);
1057 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \
1058 1.1 mrg def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5);
1059 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_6(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1060 1.1 mrg ARG6) \
1061 1.1 mrg def_fn_type (ENUM, RETURN, 1, 6, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6);
1062 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1063 1.1 mrg ARG6, ARG7) \
1064 1.1 mrg def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7);
1065 1.1 mrg #define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \
1066 1.1 mrg ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \
1067 1.1 mrg def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \
1068 1.1 mrg ARG7, ARG8, ARG9, ARG10, ARG11);
1069 1.1 mrg #define DEF_POINTER_TYPE(ENUM, TYPE) \
1070 1.1 mrg builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]);
1071 1.1 mrg
1072 1.1 mrg #include "builtin-types.def"
1073 1.1 mrg
1074 1.1 mrg #undef DEF_PRIMITIVE_TYPE
1075 1.1 mrg #undef DEF_FUNCTION_TYPE_1
1076 1.1 mrg #undef DEF_FUNCTION_TYPE_2
1077 1.1 mrg #undef DEF_FUNCTION_TYPE_3
1078 1.1 mrg #undef DEF_FUNCTION_TYPE_4
1079 1.1 mrg #undef DEF_FUNCTION_TYPE_5
1080 1.1 mrg #undef DEF_FUNCTION_TYPE_6
1081 1.1 mrg #undef DEF_FUNCTION_TYPE_7
1082 1.1 mrg #undef DEF_FUNCTION_TYPE_8
1083 1.1 mrg #undef DEF_FUNCTION_TYPE_9
1084 1.1 mrg #undef DEF_FUNCTION_TYPE_10
1085 1.1 mrg #undef DEF_FUNCTION_TYPE_11
1086 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_0
1087 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_1
1088 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_2
1089 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_3
1090 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_4
1091 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_5
1092 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_6
1093 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_7
1094 1.1 mrg #undef DEF_FUNCTION_TYPE_VAR_11
1095 1.1 mrg #undef DEF_POINTER_TYPE
1096 1.1 mrg builtin_types[(int) BT_LAST] = NULL_TREE;
1097 1.1 mrg
1098 1.1 mrg d_init_attributes ();
1099 1.1 mrg
1100 1.1 mrg #define DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \
1101 1.1 mrg NONANSI_P, ATTRS, IMPLICIT, COND) \
1102 1.1 mrg if (NAME && COND) \
1103 1.1 mrg do_build_builtin_fn (ENUM, NAME, CLASS, \
1104 1.1 mrg builtin_types[(int) TYPE], \
1105 1.1 mrg BOTH_P, FALLBACK_P, \
1106 1.1 mrg built_in_attributes[(int) ATTRS], IMPLICIT);
1107 1.1 mrg #include "builtins.def"
1108 1.1 mrg #undef DEF_BUILTIN
1109 1.1 mrg }
1110 1.1 mrg
1111 1.1 mrg /* Build builtin functions and types for the D language frontend. */
1112 1.1 mrg
1113 1.1 mrg void
1114 1.1 mrg d_init_builtins (void)
1115 1.1 mrg {
1116 1.1 mrg /* Build the "standard" abi va_list. */
1117 1.1 mrg Type::tvalist = build_frontend_type (va_list_type_node);
1118 1.1 mrg if (!Type::tvalist)
1119 1.1 mrg {
1120 1.1 mrg error ("cannot represent built-in va_list type in D");
1121 1.1 mrg gcc_unreachable ();
1122 1.1 mrg }
1123 1.1 mrg
1124 1.1 mrg /* Map the va_list type to the D frontend Type. This is to prevent both
1125 1.1 mrg errors in gimplification or an ICE in targetm.canonical_va_list_type. */
1126 1.1 mrg Type::tvalist->ctype = va_list_type_node;
1127 1.1 mrg TYPE_LANG_SPECIFIC (va_list_type_node) = build_lang_type (Type::tvalist);
1128 1.1 mrg
1129 1.1 mrg d_build_c_type_nodes ();
1130 1.1 mrg d_build_d_type_nodes ();
1131 1.1 mrg
1132 1.1 mrg if (TREE_CODE (va_list_type_node) == ARRAY_TYPE)
1133 1.1 mrg {
1134 1.1 mrg /* It might seem natural to make the argument type a pointer, but there
1135 1.1 mrg is no implicit casting from arrays to pointers in D. */
1136 1.1 mrg d_define_builtins (va_list_type_node, va_list_type_node);
1137 1.1 mrg }
1138 1.1 mrg else
1139 1.1 mrg {
1140 1.1 mrg d_define_builtins (build_reference_type (va_list_type_node),
1141 1.1 mrg va_list_type_node);
1142 1.1 mrg }
1143 1.1 mrg
1144 1.1 mrg targetm.init_builtins ();
1145 1.1 mrg build_common_builtin_nodes ();
1146 1.1 mrg }
1147 1.1 mrg
1148 1.1 mrg /* Registration of machine- or os-specific builtin types.
1149 1.1 mrg Add to builtin types list for maybe processing later
1150 1.1 mrg if `gcc.builtins' was imported into the current module. */
1151 1.1 mrg
1152 1.1 mrg void
1153 1.1 mrg d_register_builtin_type (tree type, const char *name)
1154 1.1 mrg {
1155 1.1 mrg tree decl = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
1156 1.1 mrg get_identifier (name), type);
1157 1.1 mrg DECL_ARTIFICIAL (decl) = 1;
1158 1.1 mrg
1159 1.1 mrg if (!TYPE_NAME (type))
1160 1.1 mrg TYPE_NAME (type) = decl;
1161 1.1 mrg
1162 1.1 mrg vec_safe_push (gcc_builtins_types, decl);
1163 1.1 mrg }
1164 1.1 mrg
1165 1.1 mrg /* Add DECL to builtin functions list for maybe processing later
1166 1.1 mrg if `gcc.builtins' was imported into the current module. */
1167 1.1 mrg
1168 1.1 mrg tree
1169 1.1 mrg d_builtin_function (tree decl)
1170 1.1 mrg {
1171 1.1 mrg if (!flag_no_builtin && DECL_ASSEMBLER_NAME_SET_P (decl))
1172 1.1 mrg vec_safe_push (gcc_builtins_libfuncs, decl);
1173 1.1 mrg
1174 1.1 mrg vec_safe_push (gcc_builtins_functions, decl);
1175 1.1 mrg return decl;
1176 1.1 mrg }
1177 1.1 mrg
1178 1.1 mrg
1179 1.1 mrg #include "gt-d-d-builtins.h"
1180