1 /* runtime.cc -- D runtime functions called by generated code.
2 Copyright (C) 2006-2019 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
20 #include "coretypes.h"
22 #include "dmd/aggregate.h"
23 #include "dmd/mtype.h"
26 #include "fold-const.h"
27 #include "stringpool.h"
32 /* During the codegen pass, the compiler may do lowering of expressions to call
33 various runtime library functions. Most are implemented in the `rt' package.
34 We represent them in the frontend here, however there's no guarantee that
35 the compiler implementation actually matches the actual implementation. */
44 LCT_DCHAR
, /* dchar */
45 LCT_VOIDPTR
, /* void* */
46 LCT_STRING
, /* string */
47 LCT_WSTRING
, /* wstring */
48 LCT_DSTRING
, /* dstring */
49 LCT_SIZE_T
, /* size_t */
50 LCT_ASSOCARRAY
, /* void[void] */
51 LCT_ARRAY_VOID
, /* void[] */
52 LCT_ARRAY_SIZE_T
, /* size_t[] */
53 LCT_ARRAY_BYTE
, /* byte[] */
54 LCT_ARRAY_STRING
, /* string[] */
55 LCT_ARRAY_WSTRING
, /* wstring[] */
56 LCT_ARRAY_DSTRING
, /* dstring[] */
57 LCT_ARRAYARRAY_BYTE
, /* byte[][] */
58 LCT_POINTER_ASSOCARRAY
, /* void[void]* */
59 LCT_POINTER_VOIDPTR
, /* void** */
60 LCT_ARRAYPTR_VOID
, /* void[]* */
61 LCT_ARRAYPTR_BYTE
, /* byte[]* */
62 LCT_TYPEINFO
, /* TypeInfo */
63 LCT_CLASSINFO
, /* TypeInfo_Class */
64 LCT_OBJECT
, /* Object */
65 LCT_CONST_TYPEINFO
, /* const(TypeInfo) */
66 LCT_CONST_CLASSINFO
, /* const(ClassInfo) */
70 /* An array of all types that are used by the runtime functions we need. */
72 static Type
*libcall_types
[LCT_END
];
74 /* Our internal list of library functions. */
76 static tree libcall_decls
[LIBCALL_LAST
];
79 /* Return the frontend Type that is described by TYPE. Most are readily cached
80 by the frontend proper, and likewise the use of pointerTo(), constOf(), and
81 arrayOf() will return cached types if they have been requested before. */
84 get_libcall_type (d_libcall_type type
)
86 if (libcall_types
[type
])
87 return libcall_types
[type
];
92 libcall_types
[type
] = Type::tvoid
;
96 libcall_types
[type
] = Type::tint8
;
100 libcall_types
[type
] = Type::tint32
;
104 libcall_types
[type
] = Type::tuns32
;
108 libcall_types
[type
] = Type::tbool
;
112 libcall_types
[type
] = Type::tdchar
;
116 libcall_types
[type
] = Type::tvoidptr
;
120 libcall_types
[type
] = Type::tstring
;
124 libcall_types
[type
] = Type::twstring
;
128 libcall_types
[type
] = Type::tdstring
;
132 libcall_types
[type
] = Type::tsize_t
;
136 libcall_types
[type
] = TypeAArray::create (Type::tvoid
, Type::tvoid
);
140 libcall_types
[type
] = Type::dtypeinfo
->type
;
144 libcall_types
[type
] = Type::typeinfoclass
->type
;
148 libcall_types
[type
] = get_object_type ();
151 case LCT_CONST_TYPEINFO
:
152 libcall_types
[type
] = Type::dtypeinfo
->type
->constOf ();
155 case LCT_CONST_CLASSINFO
:
156 libcall_types
[type
] = Type::typeinfoclass
->type
->constOf ();
160 libcall_types
[type
] = Type::tvoid
->arrayOf ();
163 case LCT_ARRAY_SIZE_T
:
164 libcall_types
[type
] = Type::tsize_t
->arrayOf ();
168 libcall_types
[type
] = Type::tint8
->arrayOf ();
171 case LCT_ARRAY_STRING
:
172 libcall_types
[type
] = Type::tstring
->arrayOf ();
175 case LCT_ARRAY_WSTRING
:
176 libcall_types
[type
] = Type::twstring
->arrayOf ();
179 case LCT_ARRAY_DSTRING
:
180 libcall_types
[type
] = Type::tdstring
->arrayOf ();
183 case LCT_ARRAYARRAY_BYTE
:
184 libcall_types
[type
] = Type::tint8
->arrayOf ()->arrayOf ();
187 case LCT_POINTER_ASSOCARRAY
:
188 libcall_types
[type
] = get_libcall_type (LCT_ASSOCARRAY
)->pointerTo ();
191 case LCT_POINTER_VOIDPTR
:
192 libcall_types
[type
] = Type::tvoidptr
->arrayOf ();
195 case LCT_ARRAYPTR_VOID
:
196 libcall_types
[type
] = Type::tvoid
->arrayOf ()->pointerTo ();
199 case LCT_ARRAYPTR_BYTE
:
200 libcall_types
[type
] = Type::tint8
->arrayOf ()->pointerTo ();
207 return libcall_types
[type
];
210 /* Builds and returns function declaration named NAME. The RETURN_TYPE is
211 the type returned, FLAGS are the expression call flags, and NPARAMS is
212 the number of arguments, the types of which are provided in `...'. */
215 build_libcall_decl (const char *name
, d_libcall_type return_type
,
216 int flags
, int nparams
, ...)
218 tree
*args
= XALLOCAVEC (tree
, nparams
);
219 bool varargs
= false;
222 /* Add parameter types, using 'void' as the last parameter type
223 to mean this function accepts a variable list of arguments. */
225 va_start (ap
, nparams
);
227 for (int i
= 0; i
< nparams
; i
++)
229 d_libcall_type ptype
= (d_libcall_type
) va_arg (ap
, int);
230 Type
*type
= get_libcall_type (ptype
);
232 if (type
== Type::tvoid
)
238 args
[i
] = build_ctype (type
);
243 /* Build the function. */
244 tree tret
= build_ctype (get_libcall_type (return_type
));
246 fntype
= build_varargs_function_type_array (tret
, nparams
, args
);
248 fntype
= build_function_type_array (tret
, nparams
, args
);
250 tree decl
= build_decl (UNKNOWN_LOCATION
, FUNCTION_DECL
,
251 get_identifier (name
), fntype
);
252 DECL_EXTERNAL (decl
) = 1;
253 TREE_PUBLIC (decl
) = 1;
254 DECL_ARTIFICIAL (decl
) = 1;
255 DECL_VISIBILITY (decl
) = VISIBILITY_DEFAULT
;
256 DECL_VISIBILITY_SPECIFIED (decl
) = 1;
258 /* Set any attributes on the function, such as malloc or noreturn. */
259 set_call_expr_flags (decl
, flags
);
264 /* Return or create the runtime library function declaration for LIBCALL.
265 Library functions are generated as needed. This could probably be changed in
266 the future to be done in the compiler init stage, like GCC builtin trees are,
267 however we depend on run-time initialization of types whose definitions are
268 in the library such as `Object' or `TypeInfo'. */
271 get_libcall (libcall_fn libcall
)
273 if (libcall_decls
[libcall
])
274 return libcall_decls
[libcall
];
278 #define DEF_D_RUNTIME(CODE, NAME, TYPE, PARAMS, FLAGS) \
279 case LIBCALL_ ## CODE: \
280 libcall_decls[libcall] = build_libcall_decl (NAME, TYPE, FLAGS, PARAMS); \
283 #include "runtime.def"
291 return libcall_decls
[libcall
];
294 /* Generate a call to LIBCALL, returning the result as TYPE. NARGS is the
295 number of call arguments, the expressions of which are provided in `...'.
296 This does not perform conversions or promotions on the arguments. */
299 build_libcall (libcall_fn libcall
, Type
*type
, int nargs
, ...)
301 /* Build the call expression to the runtime function. */
302 tree decl
= get_libcall (libcall
);
303 tree
*args
= XALLOCAVEC (tree
, nargs
);
306 va_start (ap
, nargs
);
307 for (int i
= 0; i
< nargs
; i
++)
308 args
[i
] = va_arg (ap
, tree
);
311 tree result
= build_call_expr_loc_array (input_location
, decl
, nargs
, args
);
313 /* Assumes caller knows what it is doing. */
314 return convert (build_ctype (type
), result
);