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