annotate gcc/d/runtime.cc @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
145
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
1 /* runtime.cc -- D runtime functions called by generated code.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
2 Copyright (C) 2006-2020 Free Software Foundation, Inc.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
3
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
4 GCC is free software; you can redistribute it and/or modify
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
5 it under the terms of the GNU General Public License as published by
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
6 the Free Software Foundation; either version 3, or (at your option)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
7 any later version.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
8
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
9 GCC is distributed in the hope that it will be useful,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
12 GNU General Public License for more details.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
13
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
14 You should have received a copy of the GNU General Public License
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
15 along with GCC; see the file COPYING3. If not see
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
16 <http://www.gnu.org/licenses/>. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
17
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
18 #include "config.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
19 #include "system.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
20 #include "coretypes.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
21
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
22 #include "dmd/aggregate.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
23 #include "dmd/mtype.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
24
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
25 #include "tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
26 #include "fold-const.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
27 #include "stringpool.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
28
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
29 #include "d-tree.h"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
30
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
31
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
32 /* During the codegen pass, the compiler may do lowering of expressions to call
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
33 various runtime library functions. Most are implemented in the `rt' package.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
34 We represent them in the frontend here, however there's no guarantee that
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
35 the compiler implementation actually matches the actual implementation. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
36
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
37 enum d_libcall_type
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
38 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
39 LCT_VOID, /* void */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
40 LCT_BYTE, /* byte */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
41 LCT_INT, /* int */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
42 LCT_UINT, /* uint */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
43 LCT_BOOL, /* bool */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
44 LCT_DCHAR, /* dchar */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
45 LCT_VOIDPTR, /* void* */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
46 LCT_STRING, /* string */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
47 LCT_WSTRING, /* wstring */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
48 LCT_DSTRING, /* dstring */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
49 LCT_SIZE_T, /* size_t */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
50 LCT_ASSOCARRAY, /* void[void] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
51 LCT_ARRAY_VOID, /* void[] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
52 LCT_ARRAY_SIZE_T, /* size_t[] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
53 LCT_ARRAY_BYTE, /* byte[] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
54 LCT_ARRAY_STRING, /* string[] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
55 LCT_ARRAY_WSTRING, /* wstring[] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
56 LCT_ARRAY_DSTRING, /* dstring[] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
57 LCT_ARRAYARRAY_BYTE, /* byte[][] */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
58 LCT_POINTER_ASSOCARRAY, /* void[void]* */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
59 LCT_POINTER_VOIDPTR, /* void** */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
60 LCT_ARRAYPTR_VOID, /* void[]* */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
61 LCT_ARRAYPTR_BYTE, /* byte[]* */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
62 LCT_TYPEINFO, /* TypeInfo */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
63 LCT_CLASSINFO, /* TypeInfo_Class */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
64 LCT_OBJECT, /* Object */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
65 LCT_CONST_TYPEINFO, /* const(TypeInfo) */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
66 LCT_CONST_CLASSINFO, /* const(ClassInfo) */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
67 LCT_END
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
68 };
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
69
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
70 /* An array of all types that are used by the runtime functions we need. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
71
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
72 static Type *libcall_types[LCT_END];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
73
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
74 /* Our internal list of library functions. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
75
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
76 static tree libcall_decls[LIBCALL_LAST];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
77
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
78
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
79 /* Return the frontend Type that is described by TYPE. Most are readily cached
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
80 by the frontend proper, and likewise the use of pointerTo(), constOf(), and
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
81 arrayOf() will return cached types if they have been requested before. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
82
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
83 static Type *
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
84 get_libcall_type (d_libcall_type type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
85 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
86 if (libcall_types[type])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
87 return libcall_types[type];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
88
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
89 switch (type)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
90 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
91 case LCT_VOID:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
92 libcall_types[type] = Type::tvoid;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
93 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
94
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
95 case LCT_BYTE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
96 libcall_types[type] = Type::tint8;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
97 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
98
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
99 case LCT_INT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
100 libcall_types[type] = Type::tint32;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
101 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
102
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
103 case LCT_UINT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
104 libcall_types[type] = Type::tuns32;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
105 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
106
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
107 case LCT_BOOL:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
108 libcall_types[type] = Type::tbool;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
109 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
110
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
111 case LCT_DCHAR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
112 libcall_types[type] = Type::tdchar;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
113 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
114
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
115 case LCT_VOIDPTR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
116 libcall_types[type] = Type::tvoidptr;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
117 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
118
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
119 case LCT_STRING:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
120 libcall_types[type] = Type::tstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
121 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
122
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
123 case LCT_WSTRING:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
124 libcall_types[type] = Type::twstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
125 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
126
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
127 case LCT_DSTRING:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
128 libcall_types[type] = Type::tdstring;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
129 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
130
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
131 case LCT_SIZE_T:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
132 libcall_types[type] = Type::tsize_t;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
133 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
134
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
135 case LCT_ASSOCARRAY:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
136 libcall_types[type] = TypeAArray::create (Type::tvoid, Type::tvoid);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
137 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
138
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
139 case LCT_TYPEINFO:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
140 libcall_types[type] = Type::dtypeinfo->type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
141 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
142
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
143 case LCT_CLASSINFO:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
144 libcall_types[type] = Type::typeinfoclass->type;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
145 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
146
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
147 case LCT_OBJECT:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
148 libcall_types[type] = get_object_type ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
149 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
150
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
151 case LCT_CONST_TYPEINFO:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
152 libcall_types[type] = Type::dtypeinfo->type->constOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
153 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
154
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
155 case LCT_CONST_CLASSINFO:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
156 libcall_types[type] = Type::typeinfoclass->type->constOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
157 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
158
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
159 case LCT_ARRAY_VOID:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
160 libcall_types[type] = Type::tvoid->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
161 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
162
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
163 case LCT_ARRAY_SIZE_T:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
164 libcall_types[type] = Type::tsize_t->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
165 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
166
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
167 case LCT_ARRAY_BYTE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
168 libcall_types[type] = Type::tint8->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
169 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
170
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
171 case LCT_ARRAY_STRING:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
172 libcall_types[type] = Type::tstring->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
173 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
174
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
175 case LCT_ARRAY_WSTRING:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
176 libcall_types[type] = Type::twstring->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
177 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
178
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
179 case LCT_ARRAY_DSTRING:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
180 libcall_types[type] = Type::tdstring->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
181 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
182
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
183 case LCT_ARRAYARRAY_BYTE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
184 libcall_types[type] = Type::tint8->arrayOf ()->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
185 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
186
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
187 case LCT_POINTER_ASSOCARRAY:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
188 libcall_types[type] = get_libcall_type (LCT_ASSOCARRAY)->pointerTo ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
189 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
190
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
191 case LCT_POINTER_VOIDPTR:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
192 libcall_types[type] = Type::tvoidptr->arrayOf ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
193 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
194
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
195 case LCT_ARRAYPTR_VOID:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
196 libcall_types[type] = Type::tvoid->arrayOf ()->pointerTo ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
197 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
198
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
199 case LCT_ARRAYPTR_BYTE:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
200 libcall_types[type] = Type::tint8->arrayOf ()->pointerTo ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
201 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
202
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
203 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
204 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
205 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
206
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
207 return libcall_types[type];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
208 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
209
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
210 /* Builds and returns function declaration named NAME. The RETURN_TYPE is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
211 the type returned, FLAGS are the expression call flags, and NPARAMS is
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
212 the number of arguments, the types of which are provided in `...'. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
213
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
214 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
215 build_libcall_decl (const char *name, d_libcall_type return_type,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
216 int flags, int nparams, ...)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
217 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
218 tree *args = XALLOCAVEC (tree, nparams);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
219 bool varargs = false;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
220 tree fntype;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
221
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
222 /* Add parameter types, using 'void' as the last parameter type
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
223 to mean this function accepts a variable list of arguments. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
224 va_list ap;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
225 va_start (ap, nparams);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
226
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
227 for (int i = 0; i < nparams; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
228 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
229 d_libcall_type ptype = (d_libcall_type) va_arg (ap, int);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
230 Type *type = get_libcall_type (ptype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
231
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
232 if (type == Type::tvoid)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
233 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
234 varargs = true;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
235 nparams = i;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
236 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
237 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
238 args[i] = build_ctype (type);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
239 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
240
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
241 va_end (ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
242
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
243 /* Build the function. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
244 tree tret = build_ctype (get_libcall_type (return_type));
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
245 if (varargs)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
246 fntype = build_varargs_function_type_array (tret, nparams, args);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
247 else
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
248 fntype = build_function_type_array (tret, nparams, args);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
249
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
250 tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
251 get_identifier (name), fntype);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
252 DECL_EXTERNAL (decl) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
253 TREE_PUBLIC (decl) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
254 DECL_ARTIFICIAL (decl) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
255 DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
256 DECL_VISIBILITY_SPECIFIED (decl) = 1;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
257
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
258 /* Set any attributes on the function, such as malloc or noreturn. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
259 set_call_expr_flags (decl, flags);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
260
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
261 return decl;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
262 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
263
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
264 /* Return or create the runtime library function declaration for LIBCALL.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
265 Library functions are generated as needed. This could probably be changed in
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
266 the future to be done in the compiler init stage, like GCC builtin trees are,
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
267 however we depend on run-time initialization of types whose definitions are
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
268 in the library such as `Object' or `TypeInfo'. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
269
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
270 static tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
271 get_libcall (libcall_fn libcall)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
272 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
273 if (libcall_decls[libcall])
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
274 return libcall_decls[libcall];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
275
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
276 switch (libcall)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
277 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
278 #define DEF_D_RUNTIME(CODE, NAME, TYPE, PARAMS, FLAGS) \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
279 case LIBCALL_ ## CODE: \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
280 libcall_decls[libcall] = build_libcall_decl (NAME, TYPE, FLAGS, PARAMS); \
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
281 break;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
282
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
283 #include "runtime.def"
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
284
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
285 #undef DEF_D_RUNTIME
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
286
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
287 default:
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
288 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
289 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
290
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
291 return libcall_decls[libcall];
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
292 }
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
293
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
294 /* Generate a call to LIBCALL, returning the result as TYPE. NARGS is the
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
295 number of call arguments, the expressions of which are provided in `...'.
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
296 This does not perform conversions or promotions on the arguments. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
297
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
298 tree
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
299 build_libcall (libcall_fn libcall, Type *type, int nargs, ...)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
300 {
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
301 /* Build the call expression to the runtime function. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
302 tree decl = get_libcall (libcall);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
303 tree *args = XALLOCAVEC (tree, nargs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
304 va_list ap;
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
305
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
306 va_start (ap, nargs);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
307 for (int i = 0; i < nargs; i++)
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
308 args[i] = va_arg (ap, tree);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
309 va_end (ap);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
310
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
311 tree result = build_call_expr_loc_array (input_location, decl, nargs, args);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
312
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
313 /* Assumes caller knows what it is doing. */
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
314 return convert (build_ctype (type), result);
1830386684a0 gcc-9.2.0
anatofuz
parents:
diff changeset
315 }