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