annotate libcc1/libcp1plugin.cc @ 143:76e1cf5455ef

add cbc_gc test
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 19:24:05 +0900
parents 84e7813d76e9
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* Library interface to C++ front end.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2014-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of GCC. As it interacts with GDB through libcc1,
kono
parents:
diff changeset
5 they all become a single program as regards the GNU GPL's requirements.
kono
parents:
diff changeset
6
kono
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
10 version.
kono
parents:
diff changeset
11
kono
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
15 for more details.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
kono
parents:
diff changeset
20
kono
parents:
diff changeset
21 #include <cc1plugin-config.h>
kono
parents:
diff changeset
22
kono
parents:
diff changeset
23 #undef PACKAGE_NAME
kono
parents:
diff changeset
24 #undef PACKAGE_STRING
kono
parents:
diff changeset
25 #undef PACKAGE_TARNAME
kono
parents:
diff changeset
26 #undef PACKAGE_VERSION
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #include "../gcc/config.h"
kono
parents:
diff changeset
29
kono
parents:
diff changeset
30 #undef PACKAGE_NAME
kono
parents:
diff changeset
31 #undef PACKAGE_STRING
kono
parents:
diff changeset
32 #undef PACKAGE_TARNAME
kono
parents:
diff changeset
33 #undef PACKAGE_VERSION
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 #include "gcc-plugin.h"
kono
parents:
diff changeset
36 #include "system.h"
kono
parents:
diff changeset
37 #include "coretypes.h"
kono
parents:
diff changeset
38 #include "stringpool.h"
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 #include "gcc-interface.h"
kono
parents:
diff changeset
41 #include "hash-set.h"
kono
parents:
diff changeset
42 #include "machmode.h"
kono
parents:
diff changeset
43 #include "vec.h"
kono
parents:
diff changeset
44 #include "double-int.h"
kono
parents:
diff changeset
45 #include "input.h"
kono
parents:
diff changeset
46 #include "alias.h"
kono
parents:
diff changeset
47 #include "symtab.h"
kono
parents:
diff changeset
48 #include "options.h"
kono
parents:
diff changeset
49 #include "wide-int.h"
kono
parents:
diff changeset
50 #include "inchash.h"
kono
parents:
diff changeset
51 #include "tree.h"
kono
parents:
diff changeset
52 #include "fold-const.h"
kono
parents:
diff changeset
53 #include "stor-layout.h"
kono
parents:
diff changeset
54 #include "cp-tree.h"
kono
parents:
diff changeset
55 #include "toplev.h"
kono
parents:
diff changeset
56 #include "timevar.h"
kono
parents:
diff changeset
57 #include "hash-table.h"
kono
parents:
diff changeset
58 #include "tm.h"
kono
parents:
diff changeset
59 #include "c-family/c-pragma.h"
kono
parents:
diff changeset
60 // #include "c-lang.h"
kono
parents:
diff changeset
61 #include "diagnostic.h"
kono
parents:
diff changeset
62 #include "langhooks.h"
kono
parents:
diff changeset
63 #include "langhooks-def.h"
kono
parents:
diff changeset
64 #include "decl.h"
kono
parents:
diff changeset
65 #include "function.h"
kono
parents:
diff changeset
66 #undef cfun // we want to assign to it, and function.h won't let us
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 #include "callbacks.hh"
kono
parents:
diff changeset
69 #include "connection.hh"
kono
parents:
diff changeset
70 #include "marshall-cp.hh"
kono
parents:
diff changeset
71 #include "rpc.hh"
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 #ifdef __GNUC__
kono
parents:
diff changeset
74 #pragma GCC visibility push(default)
kono
parents:
diff changeset
75 #endif
kono
parents:
diff changeset
76 int plugin_is_GPL_compatible;
kono
parents:
diff changeset
77 #ifdef __GNUC__
kono
parents:
diff changeset
78 #pragma GCC visibility pop
kono
parents:
diff changeset
79 #endif
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 static int ATTRIBUTE_UNUSED
kono
parents:
diff changeset
84 check_symbol_mask[GCC_CP_SYMBOL_MASK >= GCC_CP_SYMBOL_END ? 1 : -1];
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 // This is put into the lang hooks when the plugin starts.
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 static void
kono
parents:
diff changeset
89 plugin_print_error_function (diagnostic_context *context, const char *file,
kono
parents:
diff changeset
90 diagnostic_info *diagnostic)
kono
parents:
diff changeset
91 {
kono
parents:
diff changeset
92 if (current_function_decl != NULL_TREE
kono
parents:
diff changeset
93 && DECL_NAME (current_function_decl) != NULL_TREE
kono
parents:
diff changeset
94 && strcmp (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)),
kono
parents:
diff changeset
95 GCC_FE_WRAPPER_FUNCTION) == 0)
kono
parents:
diff changeset
96 return;
kono
parents:
diff changeset
97 lhd_print_error_function (context, file, diagnostic);
kono
parents:
diff changeset
98 }
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 static unsigned long long
kono
parents:
diff changeset
103 convert_out (tree t)
kono
parents:
diff changeset
104 {
kono
parents:
diff changeset
105 return (unsigned long long) (uintptr_t) t;
kono
parents:
diff changeset
106 }
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 static tree
kono
parents:
diff changeset
109 convert_in (unsigned long long v)
kono
parents:
diff changeset
110 {
kono
parents:
diff changeset
111 return (tree) (uintptr_t) v;
kono
parents:
diff changeset
112 }
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116 struct decl_addr_value
kono
parents:
diff changeset
117 {
kono
parents:
diff changeset
118 tree decl;
kono
parents:
diff changeset
119 tree address;
kono
parents:
diff changeset
120 };
kono
parents:
diff changeset
121
kono
parents:
diff changeset
122 struct decl_addr_hasher : free_ptr_hash<decl_addr_value>
kono
parents:
diff changeset
123 {
kono
parents:
diff changeset
124 static inline hashval_t hash (const decl_addr_value *);
kono
parents:
diff changeset
125 static inline bool equal (const decl_addr_value *, const decl_addr_value *);
kono
parents:
diff changeset
126 };
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 inline hashval_t
kono
parents:
diff changeset
129 decl_addr_hasher::hash (const decl_addr_value *e)
kono
parents:
diff changeset
130 {
kono
parents:
diff changeset
131 return DECL_UID (e->decl);
kono
parents:
diff changeset
132 }
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 inline bool
kono
parents:
diff changeset
135 decl_addr_hasher::equal (const decl_addr_value *p1, const decl_addr_value *p2)
kono
parents:
diff changeset
136 {
kono
parents:
diff changeset
137 return p1->decl == p2->decl;
kono
parents:
diff changeset
138 }
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 struct string_hasher : nofree_ptr_hash<const char>
kono
parents:
diff changeset
143 {
kono
parents:
diff changeset
144 static inline hashval_t hash (const char *s)
kono
parents:
diff changeset
145 {
kono
parents:
diff changeset
146 return htab_hash_string (s);
kono
parents:
diff changeset
147 }
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 static inline bool equal (const char *p1, const char *p2)
kono
parents:
diff changeset
150 {
kono
parents:
diff changeset
151 return strcmp (p1, p2) == 0;
kono
parents:
diff changeset
152 }
kono
parents:
diff changeset
153 };
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156
kono
parents:
diff changeset
157 struct plugin_context : public cc1_plugin::connection
kono
parents:
diff changeset
158 {
kono
parents:
diff changeset
159 plugin_context (int fd);
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 // Map decls to addresses.
kono
parents:
diff changeset
162 hash_table<decl_addr_hasher> address_map;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 // A collection of trees that are preserved for the GC.
kono
parents:
diff changeset
165 hash_table< nofree_ptr_hash<tree_node> > preserved;
kono
parents:
diff changeset
166
kono
parents:
diff changeset
167 // File name cache.
kono
parents:
diff changeset
168 hash_table<string_hasher> file_names;
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 // Perform GC marking.
kono
parents:
diff changeset
171 void mark ();
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 // Preserve a tree during the plugin's operation.
kono
parents:
diff changeset
174 tree preserve (tree t)
kono
parents:
diff changeset
175 {
kono
parents:
diff changeset
176 tree_node **slot = preserved.find_slot (t, INSERT);
kono
parents:
diff changeset
177 *slot = t;
kono
parents:
diff changeset
178 return t;
kono
parents:
diff changeset
179 }
kono
parents:
diff changeset
180
kono
parents:
diff changeset
181 source_location get_source_location (const char *filename,
kono
parents:
diff changeset
182 unsigned int line_number)
kono
parents:
diff changeset
183 {
kono
parents:
diff changeset
184 if (filename == NULL)
kono
parents:
diff changeset
185 return UNKNOWN_LOCATION;
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 filename = intern_filename (filename);
kono
parents:
diff changeset
188 linemap_add (line_table, LC_ENTER, false, filename, line_number);
kono
parents:
diff changeset
189 source_location loc = linemap_line_start (line_table, line_number, 0);
kono
parents:
diff changeset
190 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
kono
parents:
diff changeset
191 return loc;
kono
parents:
diff changeset
192 }
kono
parents:
diff changeset
193
kono
parents:
diff changeset
194 private:
kono
parents:
diff changeset
195
kono
parents:
diff changeset
196 // Add a file name to FILE_NAMES and return the canonical copy.
kono
parents:
diff changeset
197 const char *intern_filename (const char *filename)
kono
parents:
diff changeset
198 {
kono
parents:
diff changeset
199 const char **slot = file_names.find_slot (filename, INSERT);
kono
parents:
diff changeset
200 if (*slot == NULL)
kono
parents:
diff changeset
201 {
kono
parents:
diff changeset
202 /* The file name must live as long as the line map, which
kono
parents:
diff changeset
203 effectively means as long as this compilation. So, we copy
kono
parents:
diff changeset
204 the string here but never free it. */
kono
parents:
diff changeset
205 *slot = xstrdup (filename);
kono
parents:
diff changeset
206 }
kono
parents:
diff changeset
207 return *slot;
kono
parents:
diff changeset
208 }
kono
parents:
diff changeset
209 };
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 static plugin_context *current_context;
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 plugin_context::plugin_context (int fd)
kono
parents:
diff changeset
216 : cc1_plugin::connection (fd),
kono
parents:
diff changeset
217 address_map (30),
kono
parents:
diff changeset
218 preserved (30),
kono
parents:
diff changeset
219 file_names (30)
kono
parents:
diff changeset
220 {
kono
parents:
diff changeset
221 }
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 void
kono
parents:
diff changeset
224 plugin_context::mark ()
kono
parents:
diff changeset
225 {
kono
parents:
diff changeset
226 for (hash_table<decl_addr_hasher>::iterator it = address_map.begin ();
kono
parents:
diff changeset
227 it != address_map.end ();
kono
parents:
diff changeset
228 ++it)
kono
parents:
diff changeset
229 {
kono
parents:
diff changeset
230 ggc_mark ((*it)->decl);
kono
parents:
diff changeset
231 ggc_mark ((*it)->address);
kono
parents:
diff changeset
232 }
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 for (hash_table< nofree_ptr_hash<tree_node> >::iterator
kono
parents:
diff changeset
235 it = preserved.begin (); it != preserved.end (); ++it)
kono
parents:
diff changeset
236 ggc_mark (&*it);
kono
parents:
diff changeset
237 }
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 static void
kono
parents:
diff changeset
240 plugin_binding_oracle (enum cp_oracle_request kind, tree identifier)
kono
parents:
diff changeset
241 {
kono
parents:
diff changeset
242 enum gcc_cp_oracle_request request;
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244 gcc_assert (current_context != NULL);
kono
parents:
diff changeset
245
kono
parents:
diff changeset
246 switch (kind)
kono
parents:
diff changeset
247 {
kono
parents:
diff changeset
248 case CP_ORACLE_IDENTIFIER:
kono
parents:
diff changeset
249 request = GCC_CP_ORACLE_IDENTIFIER;
kono
parents:
diff changeset
250 break;
kono
parents:
diff changeset
251 default:
kono
parents:
diff changeset
252 abort ();
kono
parents:
diff changeset
253 }
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 int ignore;
kono
parents:
diff changeset
256 cc1_plugin::call (current_context, "binding_oracle", &ignore,
kono
parents:
diff changeset
257 request, IDENTIFIER_POINTER (identifier));
kono
parents:
diff changeset
258 }
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 static int push_count;
kono
parents:
diff changeset
261
kono
parents:
diff changeset
262 /* at_function_scope_p () tests cfun, indicating we're actually
kono
parents:
diff changeset
263 compiling the function, but we don't even set it when pretending to
kono
parents:
diff changeset
264 enter a function scope. We use this distinction to tell these two
kono
parents:
diff changeset
265 cases apart: we don't want to define e.g. class names in the user
kono
parents:
diff changeset
266 expression function's scope, when they're local to the original
kono
parents:
diff changeset
267 function, because they'd get the wrong linkage name. */
kono
parents:
diff changeset
268
kono
parents:
diff changeset
269 static bool
kono
parents:
diff changeset
270 at_fake_function_scope_p ()
kono
parents:
diff changeset
271 {
kono
parents:
diff changeset
272 return (!cfun || cfun->decl != current_function_decl)
kono
parents:
diff changeset
273 && current_scope () == current_function_decl;
kono
parents:
diff changeset
274 }
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 static void
kono
parents:
diff changeset
277 push_fake_function (tree fndecl, scope_kind kind = sk_function_parms)
kono
parents:
diff changeset
278 {
kono
parents:
diff changeset
279 current_function_decl = fndecl;
kono
parents:
diff changeset
280 begin_scope (kind, fndecl);
kono
parents:
diff changeset
281 ++function_depth;
kono
parents:
diff changeset
282 begin_scope (sk_block, NULL);
kono
parents:
diff changeset
283 }
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 static void
kono
parents:
diff changeset
286 pop_scope ()
kono
parents:
diff changeset
287 {
kono
parents:
diff changeset
288 if (toplevel_bindings_p () && current_namespace == global_namespace)
kono
parents:
diff changeset
289 pop_from_top_level ();
kono
parents:
diff changeset
290 else if (at_namespace_scope_p ())
kono
parents:
diff changeset
291 pop_namespace ();
kono
parents:
diff changeset
292 else if (at_class_scope_p ())
kono
parents:
diff changeset
293 popclass ();
kono
parents:
diff changeset
294 else
kono
parents:
diff changeset
295 {
kono
parents:
diff changeset
296 gcc_assert (at_fake_function_scope_p ());
kono
parents:
diff changeset
297 gcc_assert (!at_function_scope_p ());
kono
parents:
diff changeset
298 gcc_assert (current_binding_level->kind == sk_block
kono
parents:
diff changeset
299 && current_binding_level->this_entity == NULL);
kono
parents:
diff changeset
300 leave_scope ();
kono
parents:
diff changeset
301 --function_depth;
kono
parents:
diff changeset
302 gcc_assert (current_binding_level->this_entity
kono
parents:
diff changeset
303 == current_function_decl);
kono
parents:
diff changeset
304 leave_scope ();
kono
parents:
diff changeset
305 current_function_decl = NULL;
kono
parents:
diff changeset
306 for (cp_binding_level *scope = current_binding_level;
kono
parents:
diff changeset
307 scope; scope = scope->level_chain)
kono
parents:
diff changeset
308 if (scope->kind == sk_function_parms)
kono
parents:
diff changeset
309 {
kono
parents:
diff changeset
310 current_function_decl = scope->this_entity;
kono
parents:
diff changeset
311 break;
kono
parents:
diff changeset
312 }
kono
parents:
diff changeset
313 }
kono
parents:
diff changeset
314 }
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 static void
kono
parents:
diff changeset
317 supplement_binding (cxx_binding *binding, tree decl)
kono
parents:
diff changeset
318 {
kono
parents:
diff changeset
319 /* FIXME: this is pretty much a copy of supplement_binding_1 in
kono
parents:
diff changeset
320 ../gcc/cp/name-lookup.c; the few replaced/removed bits are marked
kono
parents:
diff changeset
321 with "// _1:". */
kono
parents:
diff changeset
322 tree bval = binding->value;
kono
parents:
diff changeset
323 bool ok = true;
kono
parents:
diff changeset
324 tree target_bval = strip_using_decl (bval);
kono
parents:
diff changeset
325 tree target_decl = strip_using_decl (decl);
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 if (TREE_CODE (target_decl) == TYPE_DECL && DECL_ARTIFICIAL (target_decl)
kono
parents:
diff changeset
328 && target_decl != target_bval
kono
parents:
diff changeset
329 && (TREE_CODE (target_bval) != TYPE_DECL
kono
parents:
diff changeset
330 /* We allow pushing an enum multiple times in a class
kono
parents:
diff changeset
331 template in order to handle late matching of underlying
kono
parents:
diff changeset
332 type on an opaque-enum-declaration followed by an
kono
parents:
diff changeset
333 enum-specifier. */
kono
parents:
diff changeset
334 || (processing_template_decl
kono
parents:
diff changeset
335 && TREE_CODE (TREE_TYPE (target_decl)) == ENUMERAL_TYPE
kono
parents:
diff changeset
336 && TREE_CODE (TREE_TYPE (target_bval)) == ENUMERAL_TYPE
kono
parents:
diff changeset
337 && (dependent_type_p (ENUM_UNDERLYING_TYPE
kono
parents:
diff changeset
338 (TREE_TYPE (target_decl)))
kono
parents:
diff changeset
339 || dependent_type_p (ENUM_UNDERLYING_TYPE
kono
parents:
diff changeset
340 (TREE_TYPE (target_bval)))))))
kono
parents:
diff changeset
341 /* The new name is the type name. */
kono
parents:
diff changeset
342 binding->type = decl;
kono
parents:
diff changeset
343 else if (/* TARGET_BVAL is null when push_class_level_binding moves
kono
parents:
diff changeset
344 an inherited type-binding out of the way to make room
kono
parents:
diff changeset
345 for a new value binding. */
kono
parents:
diff changeset
346 !target_bval
kono
parents:
diff changeset
347 /* TARGET_BVAL is error_mark_node when TARGET_DECL's name
kono
parents:
diff changeset
348 has been used in a non-class scope prior declaration.
kono
parents:
diff changeset
349 In that case, we should have already issued a
kono
parents:
diff changeset
350 diagnostic; for graceful error recovery purpose, pretend
kono
parents:
diff changeset
351 this was the intended declaration for that name. */
kono
parents:
diff changeset
352 || target_bval == error_mark_node
kono
parents:
diff changeset
353 /* If TARGET_BVAL is anticipated but has not yet been
kono
parents:
diff changeset
354 declared, pretend it is not there at all. */
kono
parents:
diff changeset
355 || (TREE_CODE (target_bval) == FUNCTION_DECL
kono
parents:
diff changeset
356 && DECL_ANTICIPATED (target_bval)
kono
parents:
diff changeset
357 && !DECL_HIDDEN_FRIEND_P (target_bval)))
kono
parents:
diff changeset
358 binding->value = decl;
kono
parents:
diff changeset
359 else if (TREE_CODE (target_bval) == TYPE_DECL
kono
parents:
diff changeset
360 && DECL_ARTIFICIAL (target_bval)
kono
parents:
diff changeset
361 && target_decl != target_bval
kono
parents:
diff changeset
362 && (TREE_CODE (target_decl) != TYPE_DECL
kono
parents:
diff changeset
363 || same_type_p (TREE_TYPE (target_decl),
kono
parents:
diff changeset
364 TREE_TYPE (target_bval))))
kono
parents:
diff changeset
365 {
kono
parents:
diff changeset
366 /* The old binding was a type name. It was placed in
kono
parents:
diff changeset
367 VALUE field because it was thought, at the point it was
kono
parents:
diff changeset
368 declared, to be the only entity with such a name. Move the
kono
parents:
diff changeset
369 type name into the type slot; it is now hidden by the new
kono
parents:
diff changeset
370 binding. */
kono
parents:
diff changeset
371 binding->type = bval;
kono
parents:
diff changeset
372 binding->value = decl;
kono
parents:
diff changeset
373 binding->value_is_inherited = false;
kono
parents:
diff changeset
374 }
kono
parents:
diff changeset
375 else if (TREE_CODE (target_bval) == TYPE_DECL
kono
parents:
diff changeset
376 && TREE_CODE (target_decl) == TYPE_DECL
kono
parents:
diff changeset
377 && DECL_NAME (target_decl) == DECL_NAME (target_bval)
kono
parents:
diff changeset
378 && binding->scope->kind != sk_class
kono
parents:
diff changeset
379 && (same_type_p (TREE_TYPE (target_decl), TREE_TYPE (target_bval))
kono
parents:
diff changeset
380 /* If either type involves template parameters, we must
kono
parents:
diff changeset
381 wait until instantiation. */
kono
parents:
diff changeset
382 || uses_template_parms (TREE_TYPE (target_decl))
kono
parents:
diff changeset
383 || uses_template_parms (TREE_TYPE (target_bval))))
kono
parents:
diff changeset
384 /* We have two typedef-names, both naming the same type to have
kono
parents:
diff changeset
385 the same name. In general, this is OK because of:
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 [dcl.typedef]
kono
parents:
diff changeset
388
kono
parents:
diff changeset
389 In a given scope, a typedef specifier can be used to redefine
kono
parents:
diff changeset
390 the name of any type declared in that scope to refer to the
kono
parents:
diff changeset
391 type to which it already refers.
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 However, in class scopes, this rule does not apply due to the
kono
parents:
diff changeset
394 stricter language in [class.mem] prohibiting redeclarations of
kono
parents:
diff changeset
395 members. */
kono
parents:
diff changeset
396 ok = false;
kono
parents:
diff changeset
397 /* There can be two block-scope declarations of the same variable,
kono
parents:
diff changeset
398 so long as they are `extern' declarations. However, there cannot
kono
parents:
diff changeset
399 be two declarations of the same static data member:
kono
parents:
diff changeset
400
kono
parents:
diff changeset
401 [class.mem]
kono
parents:
diff changeset
402
kono
parents:
diff changeset
403 A member shall not be declared twice in the
kono
parents:
diff changeset
404 member-specification. */
kono
parents:
diff changeset
405 else if (VAR_P (target_decl)
kono
parents:
diff changeset
406 && VAR_P (target_bval)
kono
parents:
diff changeset
407 && DECL_EXTERNAL (target_decl) && DECL_EXTERNAL (target_bval)
kono
parents:
diff changeset
408 && !DECL_CLASS_SCOPE_P (target_decl))
kono
parents:
diff changeset
409 {
kono
parents:
diff changeset
410 duplicate_decls (decl, binding->value, /*newdecl_is_friend=*/false);
kono
parents:
diff changeset
411 ok = false;
kono
parents:
diff changeset
412 }
kono
parents:
diff changeset
413 else if (TREE_CODE (decl) == NAMESPACE_DECL
kono
parents:
diff changeset
414 && TREE_CODE (bval) == NAMESPACE_DECL
kono
parents:
diff changeset
415 && DECL_NAMESPACE_ALIAS (decl)
kono
parents:
diff changeset
416 && DECL_NAMESPACE_ALIAS (bval)
kono
parents:
diff changeset
417 && ORIGINAL_NAMESPACE (bval) == ORIGINAL_NAMESPACE (decl))
kono
parents:
diff changeset
418 /* [namespace.alias]
kono
parents:
diff changeset
419
kono
parents:
diff changeset
420 In a declarative region, a namespace-alias-definition can be
kono
parents:
diff changeset
421 used to redefine a namespace-alias declared in that declarative
kono
parents:
diff changeset
422 region to refer only to the namespace to which it already
kono
parents:
diff changeset
423 refers. */
kono
parents:
diff changeset
424 ok = false;
kono
parents:
diff changeset
425 else
kono
parents:
diff changeset
426 {
kono
parents:
diff changeset
427 // _1: diagnose_name_conflict (decl, bval);
kono
parents:
diff changeset
428 ok = false;
kono
parents:
diff changeset
429 }
kono
parents:
diff changeset
430
kono
parents:
diff changeset
431 gcc_assert (ok); // _1: return ok;
kono
parents:
diff changeset
432 }
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 static void
kono
parents:
diff changeset
435 reactivate_decl (tree decl, cp_binding_level *b)
kono
parents:
diff changeset
436 {
kono
parents:
diff changeset
437 bool in_function_p = TREE_CODE (b->this_entity) == FUNCTION_DECL;
kono
parents:
diff changeset
438 gcc_assert (in_function_p
kono
parents:
diff changeset
439 || (b == current_binding_level
kono
parents:
diff changeset
440 && !at_class_scope_p ()));
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 tree id = DECL_NAME (decl);
kono
parents:
diff changeset
443 tree type = NULL_TREE;
kono
parents:
diff changeset
444 if (TREE_CODE (decl) == TYPE_DECL)
kono
parents:
diff changeset
445 type = TREE_TYPE (decl);
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 if (type && TYPE_NAME (type) == decl
kono
parents:
diff changeset
448 && (RECORD_OR_UNION_CODE_P (TREE_CODE (type))
kono
parents:
diff changeset
449 || TREE_CODE (type) == ENUMERAL_TYPE))
kono
parents:
diff changeset
450 {
kono
parents:
diff changeset
451 gcc_assert (in_function_p && DECL_CONTEXT (decl) == b->this_entity);
kono
parents:
diff changeset
452 type = TREE_TYPE (decl);
kono
parents:
diff changeset
453 }
kono
parents:
diff changeset
454 else
kono
parents:
diff changeset
455 {
kono
parents:
diff changeset
456 gcc_assert (DECL_CONTEXT (decl) == b->this_entity
kono
parents:
diff changeset
457 || DECL_CONTEXT (decl) == global_namespace
kono
parents:
diff changeset
458 || TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL);
kono
parents:
diff changeset
459 type = NULL_TREE;
kono
parents:
diff changeset
460 }
kono
parents:
diff changeset
461
kono
parents:
diff changeset
462 /* Adjust IDENTIFIER_BINDING to what it would have been if we were
kono
parents:
diff changeset
463 at binding level B. Save the binding chain up to that point in
kono
parents:
diff changeset
464 [binding, *chainp), and take note of the outermost bindings found
kono
parents:
diff changeset
465 before B. */
kono
parents:
diff changeset
466 cxx_binding *binding = IDENTIFIER_BINDING (id), **chainp = NULL;
kono
parents:
diff changeset
467 tree *shadowing_type_p = NULL;
kono
parents:
diff changeset
468 if (binding)
kono
parents:
diff changeset
469 {
kono
parents:
diff changeset
470 cp_binding_level *bc = current_binding_level;
kono
parents:
diff changeset
471 for (cxx_binding *prev_binding = binding;
kono
parents:
diff changeset
472 prev_binding; prev_binding = prev_binding->previous)
kono
parents:
diff changeset
473 {
kono
parents:
diff changeset
474 while (bc != b && bc != prev_binding->scope)
kono
parents:
diff changeset
475 bc = bc->level_chain;
kono
parents:
diff changeset
476 if (bc == b)
kono
parents:
diff changeset
477 {
kono
parents:
diff changeset
478 if (!chainp)
kono
parents:
diff changeset
479 binding = NULL;
kono
parents:
diff changeset
480 break;
kono
parents:
diff changeset
481 }
kono
parents:
diff changeset
482 chainp = &prev_binding->previous;
kono
parents:
diff changeset
483 if (type)
kono
parents:
diff changeset
484 for (tree tshadow = prev_binding->scope->type_shadowed;
kono
parents:
diff changeset
485 tshadow; tshadow = TREE_CHAIN (tshadow))
kono
parents:
diff changeset
486 if (TREE_PURPOSE (tshadow) == id)
kono
parents:
diff changeset
487 {
kono
parents:
diff changeset
488 shadowing_type_p = &TREE_VALUE (tshadow);
kono
parents:
diff changeset
489 break;
kono
parents:
diff changeset
490 }
kono
parents:
diff changeset
491 }
kono
parents:
diff changeset
492 }
kono
parents:
diff changeset
493 if (chainp)
kono
parents:
diff changeset
494 {
kono
parents:
diff changeset
495 IDENTIFIER_BINDING (id) = *chainp;
kono
parents:
diff changeset
496 *chainp = NULL;
kono
parents:
diff changeset
497 }
kono
parents:
diff changeset
498
kono
parents:
diff changeset
499 /* Like push_local_binding, supplement or add a binding to the
kono
parents:
diff changeset
500 desired level. */
kono
parents:
diff changeset
501 if (IDENTIFIER_BINDING (id) && IDENTIFIER_BINDING (id)->scope == b)
kono
parents:
diff changeset
502 supplement_binding (IDENTIFIER_BINDING (id), decl);
kono
parents:
diff changeset
503 else
kono
parents:
diff changeset
504 push_binding (id, decl, b);
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 /* Now restore the binding chain we'd temporarily removed. */
kono
parents:
diff changeset
507 if (chainp)
kono
parents:
diff changeset
508 {
kono
parents:
diff changeset
509 *chainp = IDENTIFIER_BINDING (id);
kono
parents:
diff changeset
510 IDENTIFIER_BINDING (id) = binding;
kono
parents:
diff changeset
511
kono
parents:
diff changeset
512 if (type)
kono
parents:
diff changeset
513 {
kono
parents:
diff changeset
514 /* Insert the new type binding in the shadowing_type_p
kono
parents:
diff changeset
515 TREE_VALUE chain. */
kono
parents:
diff changeset
516 tree shadowed_type = NULL_TREE;
kono
parents:
diff changeset
517 if (shadowing_type_p)
kono
parents:
diff changeset
518 {
kono
parents:
diff changeset
519 shadowed_type = *shadowing_type_p;
kono
parents:
diff changeset
520 *shadowing_type_p = type;
kono
parents:
diff changeset
521 }
kono
parents:
diff changeset
522
kono
parents:
diff changeset
523 b->type_shadowed = tree_cons (id, shadowed_type, b->type_shadowed);
kono
parents:
diff changeset
524 TREE_TYPE (b->type_shadowed) = type;
kono
parents:
diff changeset
525 }
kono
parents:
diff changeset
526 }
kono
parents:
diff changeset
527 else if (type)
kono
parents:
diff changeset
528 {
kono
parents:
diff changeset
529 /* Our new binding is the active one, so shadow the earlier
kono
parents:
diff changeset
530 binding. */
kono
parents:
diff changeset
531 b->type_shadowed = tree_cons (id, REAL_IDENTIFIER_TYPE_VALUE (id),
kono
parents:
diff changeset
532 b->type_shadowed);
kono
parents:
diff changeset
533 TREE_TYPE (b->type_shadowed) = type;
kono
parents:
diff changeset
534 SET_IDENTIFIER_TYPE_VALUE (id, type);
kono
parents:
diff changeset
535 }
kono
parents:
diff changeset
536
kono
parents:
diff changeset
537 /* Record that we have a binding for ID, like add_decl_to_level. */
kono
parents:
diff changeset
538 tree node = build_tree_list (NULL_TREE, decl);
kono
parents:
diff changeset
539 TREE_CHAIN (node) = b->names;
kono
parents:
diff changeset
540 b->names = node;
kono
parents:
diff changeset
541 }
kono
parents:
diff changeset
542
kono
parents:
diff changeset
543 static void
kono
parents:
diff changeset
544 plugin_pragma_push_user_expression (cpp_reader *)
kono
parents:
diff changeset
545 {
kono
parents:
diff changeset
546 if (push_count++)
kono
parents:
diff changeset
547 return;
kono
parents:
diff changeset
548
kono
parents:
diff changeset
549 gcc_assert (!current_class_ptr);
kono
parents:
diff changeset
550 gcc_assert (!current_class_ref);
kono
parents:
diff changeset
551
kono
parents:
diff changeset
552 gcc_assert (!cp_binding_oracle);
kono
parents:
diff changeset
553 cp_binding_oracle = plugin_binding_oracle;
kono
parents:
diff changeset
554
kono
parents:
diff changeset
555 /* Make the function containing the user expression a global
kono
parents:
diff changeset
556 friend, so as to bypass access controls in it. */
kono
parents:
diff changeset
557 if (at_function_scope_p ())
kono
parents:
diff changeset
558 set_global_friend (current_function_decl);
kono
parents:
diff changeset
559
kono
parents:
diff changeset
560 gcc_assert (at_function_scope_p ());
kono
parents:
diff changeset
561 function *save_cfun = cfun;
kono
parents:
diff changeset
562 cp_binding_level *orig_binding_level = current_binding_level;
kono
parents:
diff changeset
563 {
kono
parents:
diff changeset
564 int success;
kono
parents:
diff changeset
565 cc1_plugin::call (current_context, "enter_scope", &success);
kono
parents:
diff changeset
566 }
kono
parents:
diff changeset
567 gcc_assert (at_fake_function_scope_p () || at_function_scope_p ());
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 function *unchanged_cfun = cfun;
kono
parents:
diff changeset
570 tree changed_func_decl = current_function_decl;
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 gcc_assert (current_class_type == DECL_CONTEXT (current_function_decl)
kono
parents:
diff changeset
573 || !(RECORD_OR_UNION_CODE_P
kono
parents:
diff changeset
574 (TREE_CODE (DECL_CONTEXT (current_function_decl)))));
kono
parents:
diff changeset
575 push_fake_function (save_cfun->decl, sk_block);
kono
parents:
diff changeset
576 current_class_type = NULL_TREE;
kono
parents:
diff changeset
577 if (unchanged_cfun)
kono
parents:
diff changeset
578 {
kono
parents:
diff changeset
579 /* If we get here, GDB did NOT change the context. */
kono
parents:
diff changeset
580 gcc_assert (cfun == save_cfun);
kono
parents:
diff changeset
581 gcc_assert (at_function_scope_p ());
kono
parents:
diff changeset
582 gcc_assert (orig_binding_level
kono
parents:
diff changeset
583 == current_binding_level->level_chain->level_chain);
kono
parents:
diff changeset
584 }
kono
parents:
diff changeset
585 else
kono
parents:
diff changeset
586 {
kono
parents:
diff changeset
587 cfun = save_cfun;
kono
parents:
diff changeset
588 gcc_assert (at_function_scope_p ());
kono
parents:
diff changeset
589
kono
parents:
diff changeset
590 cp_binding_level *b = current_binding_level->level_chain;
kono
parents:
diff changeset
591 gcc_assert (b->this_entity == cfun->decl);
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593 /* Reactivate local names from the previous context. Use
kono
parents:
diff changeset
594 IDENTIFIER_MARKED to avoid reactivating shadowed names. */
kono
parents:
diff changeset
595 for (cp_binding_level *level = orig_binding_level;;)
kono
parents:
diff changeset
596 {
kono
parents:
diff changeset
597 for (tree name = level->names;
kono
parents:
diff changeset
598 name; name = TREE_CHAIN (name))
kono
parents:
diff changeset
599 {
kono
parents:
diff changeset
600 tree decl = name;
kono
parents:
diff changeset
601 if (TREE_CODE (decl) == TREE_LIST)
kono
parents:
diff changeset
602 decl = TREE_VALUE (decl);
kono
parents:
diff changeset
603 if (IDENTIFIER_MARKED (DECL_NAME (decl)))
kono
parents:
diff changeset
604 continue;
kono
parents:
diff changeset
605 IDENTIFIER_MARKED (DECL_NAME (decl)) = 1;
kono
parents:
diff changeset
606 reactivate_decl (decl, b);
kono
parents:
diff changeset
607 }
kono
parents:
diff changeset
608 if (level->kind == sk_function_parms
kono
parents:
diff changeset
609 && level->this_entity == cfun->decl)
kono
parents:
diff changeset
610 break;
kono
parents:
diff changeset
611 gcc_assert (!level->this_entity);
kono
parents:
diff changeset
612 level = level->level_chain;
kono
parents:
diff changeset
613 }
kono
parents:
diff changeset
614
kono
parents:
diff changeset
615 /* Now, clear the markers. */
kono
parents:
diff changeset
616 for (tree name = b->names; name; name = TREE_CHAIN (name))
kono
parents:
diff changeset
617 {
kono
parents:
diff changeset
618 tree decl = name;
kono
parents:
diff changeset
619 if (TREE_CODE (decl) == TREE_LIST)
kono
parents:
diff changeset
620 decl = TREE_VALUE (decl);
kono
parents:
diff changeset
621 gcc_assert (IDENTIFIER_MARKED (DECL_NAME (decl)));
kono
parents:
diff changeset
622 IDENTIFIER_MARKED (DECL_NAME (decl)) = 0;
kono
parents:
diff changeset
623 }
kono
parents:
diff changeset
624 }
kono
parents:
diff changeset
625
kono
parents:
diff changeset
626 if (unchanged_cfun || DECL_NONSTATIC_MEMBER_FUNCTION_P (changed_func_decl))
kono
parents:
diff changeset
627 {
kono
parents:
diff changeset
628 /* Check whether the oracle supplies us with a "this", and if
kono
parents:
diff changeset
629 so, arrange for data members and this itself to be
kono
parents:
diff changeset
630 usable. */
kono
parents:
diff changeset
631 tree this_val = lookup_name (get_identifier ("this"));
kono
parents:
diff changeset
632 current_class_ref = !this_val ? NULL_TREE
kono
parents:
diff changeset
633 : cp_build_indirect_ref (this_val, RO_NULL, tf_warning_or_error);
kono
parents:
diff changeset
634 current_class_ptr = this_val;
kono
parents:
diff changeset
635 }
kono
parents:
diff changeset
636 }
kono
parents:
diff changeset
637
kono
parents:
diff changeset
638 static void
kono
parents:
diff changeset
639 plugin_pragma_pop_user_expression (cpp_reader *)
kono
parents:
diff changeset
640 {
kono
parents:
diff changeset
641 if (--push_count)
kono
parents:
diff changeset
642 return;
kono
parents:
diff changeset
643
kono
parents:
diff changeset
644 gcc_assert (cp_binding_oracle);
kono
parents:
diff changeset
645
kono
parents:
diff changeset
646 gcc_assert (at_function_scope_p ());
kono
parents:
diff changeset
647 function *save_cfun = cfun;
kono
parents:
diff changeset
648 current_class_ptr = NULL_TREE;
kono
parents:
diff changeset
649 current_class_ref = NULL_TREE;
kono
parents:
diff changeset
650
kono
parents:
diff changeset
651 cfun = NULL;
kono
parents:
diff changeset
652 pop_scope ();
kono
parents:
diff changeset
653 if (RECORD_OR_UNION_CODE_P (TREE_CODE (DECL_CONTEXT (current_function_decl))))
kono
parents:
diff changeset
654 current_class_type = DECL_CONTEXT (current_function_decl);
kono
parents:
diff changeset
655 {
kono
parents:
diff changeset
656 int success;
kono
parents:
diff changeset
657 cc1_plugin::call (current_context, "leave_scope", &success);
kono
parents:
diff changeset
658 }
kono
parents:
diff changeset
659 if (!cfun)
kono
parents:
diff changeset
660 cfun = save_cfun;
kono
parents:
diff changeset
661 else
kono
parents:
diff changeset
662 gcc_assert (cfun == save_cfun);
kono
parents:
diff changeset
663
kono
parents:
diff changeset
664 cp_binding_oracle = NULL;
kono
parents:
diff changeset
665 gcc_assert (at_function_scope_p ());
kono
parents:
diff changeset
666 }
kono
parents:
diff changeset
667
kono
parents:
diff changeset
668 static void
kono
parents:
diff changeset
669 plugin_init_extra_pragmas (void *, void *)
kono
parents:
diff changeset
670 {
kono
parents:
diff changeset
671 c_register_pragma ("GCC", "push_user_expression", plugin_pragma_push_user_expression);
kono
parents:
diff changeset
672 c_register_pragma ("GCC", "pop_user_expression", plugin_pragma_pop_user_expression);
kono
parents:
diff changeset
673 /* FIXME: this one should go once we get GDB to use push and pop. */
kono
parents:
diff changeset
674 c_register_pragma ("GCC", "user_expression", plugin_pragma_push_user_expression);
kono
parents:
diff changeset
675 }
kono
parents:
diff changeset
676
kono
parents:
diff changeset
677
kono
parents:
diff changeset
678
kono
parents:
diff changeset
679 static decl_addr_value
kono
parents:
diff changeset
680 build_decl_addr_value (tree decl, gcc_address address)
kono
parents:
diff changeset
681 {
kono
parents:
diff changeset
682 decl_addr_value value = {
kono
parents:
diff changeset
683 decl,
kono
parents:
diff changeset
684 build_int_cst_type (ptr_type_node, address)
kono
parents:
diff changeset
685 };
kono
parents:
diff changeset
686 return value;
kono
parents:
diff changeset
687 }
kono
parents:
diff changeset
688
kono
parents:
diff changeset
689 static decl_addr_value *
kono
parents:
diff changeset
690 record_decl_address (plugin_context *ctx, decl_addr_value value)
kono
parents:
diff changeset
691 {
kono
parents:
diff changeset
692 decl_addr_value **slot = ctx->address_map.find_slot (&value, INSERT);
kono
parents:
diff changeset
693 gcc_assert (*slot == NULL);
kono
parents:
diff changeset
694 *slot
kono
parents:
diff changeset
695 = static_cast<decl_addr_value *> (xmalloc (sizeof (decl_addr_value)));
kono
parents:
diff changeset
696 **slot = value;
kono
parents:
diff changeset
697 /* We don't want GCC to warn about e.g. static functions
kono
parents:
diff changeset
698 without a code definition. */
kono
parents:
diff changeset
699 TREE_NO_WARNING (value.decl) = 1;
kono
parents:
diff changeset
700 return *slot;
kono
parents:
diff changeset
701 }
kono
parents:
diff changeset
702
kono
parents:
diff changeset
703 // Maybe rewrite a decl to its address.
kono
parents:
diff changeset
704 static tree
kono
parents:
diff changeset
705 address_rewriter (tree *in, int *walk_subtrees, void *arg)
kono
parents:
diff changeset
706 {
kono
parents:
diff changeset
707 plugin_context *ctx = (plugin_context *) arg;
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 if (!DECL_P (*in)
kono
parents:
diff changeset
710 || TREE_CODE (*in) == NAMESPACE_DECL
kono
parents:
diff changeset
711 || DECL_NAME (*in) == NULL_TREE)
kono
parents:
diff changeset
712 return NULL_TREE;
kono
parents:
diff changeset
713
kono
parents:
diff changeset
714 decl_addr_value value;
kono
parents:
diff changeset
715 value.decl = *in;
kono
parents:
diff changeset
716 decl_addr_value *found_value = ctx->address_map.find (&value);
kono
parents:
diff changeset
717 if (found_value != NULL)
kono
parents:
diff changeset
718 ;
kono
parents:
diff changeset
719 else if (HAS_DECL_ASSEMBLER_NAME_P (*in))
kono
parents:
diff changeset
720 {
kono
parents:
diff changeset
721 gcc_address address;
kono
parents:
diff changeset
722
kono
parents:
diff changeset
723 if (!cc1_plugin::call (ctx, "address_oracle", &address,
kono
parents:
diff changeset
724 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (*in))))
kono
parents:
diff changeset
725 return NULL_TREE;
kono
parents:
diff changeset
726 if (address == 0)
kono
parents:
diff changeset
727 return NULL_TREE;
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 // Insert the decl into the address map in case it is referenced
kono
parents:
diff changeset
730 // again.
kono
parents:
diff changeset
731 value = build_decl_addr_value (value.decl, address);
kono
parents:
diff changeset
732 found_value = record_decl_address (ctx, value);
kono
parents:
diff changeset
733 }
kono
parents:
diff changeset
734 else
kono
parents:
diff changeset
735 return NULL_TREE;
kono
parents:
diff changeset
736
kono
parents:
diff changeset
737 if (found_value->address != error_mark_node)
kono
parents:
diff changeset
738 {
kono
parents:
diff changeset
739 // We have an address for the decl, so rewrite the tree.
kono
parents:
diff changeset
740 tree ptr_type = build_pointer_type (TREE_TYPE (*in));
kono
parents:
diff changeset
741 *in = fold_build1 (INDIRECT_REF, TREE_TYPE (*in),
kono
parents:
diff changeset
742 fold_build1 (CONVERT_EXPR, ptr_type,
kono
parents:
diff changeset
743 found_value->address));
kono
parents:
diff changeset
744 }
kono
parents:
diff changeset
745
kono
parents:
diff changeset
746 *walk_subtrees = 0;
kono
parents:
diff changeset
747
kono
parents:
diff changeset
748 return NULL_TREE;
kono
parents:
diff changeset
749 }
kono
parents:
diff changeset
750
kono
parents:
diff changeset
751 // When generating code for gdb, we want to be able to use absolute
kono
parents:
diff changeset
752 // addresses to refer to otherwise external objects that gdb knows
kono
parents:
diff changeset
753 // about. gdb passes in these addresses when building decls, and then
kono
parents:
diff changeset
754 // before gimplification we go through the trees, rewriting uses to
kono
parents:
diff changeset
755 // the equivalent of "*(TYPE *) ADDR".
kono
parents:
diff changeset
756 static void
kono
parents:
diff changeset
757 rewrite_decls_to_addresses (void *function_in, void *)
kono
parents:
diff changeset
758 {
kono
parents:
diff changeset
759 tree function = (tree) function_in;
kono
parents:
diff changeset
760
kono
parents:
diff changeset
761 // Do nothing if we're not in gdb.
kono
parents:
diff changeset
762 if (current_context == NULL)
kono
parents:
diff changeset
763 return;
kono
parents:
diff changeset
764
kono
parents:
diff changeset
765 walk_tree (&DECL_SAVED_TREE (function), address_rewriter, current_context,
kono
parents:
diff changeset
766 NULL);
kono
parents:
diff changeset
767 }
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769
kono
parents:
diff changeset
770
kono
parents:
diff changeset
771 static inline tree
kono
parents:
diff changeset
772 safe_push_template_decl (tree decl)
kono
parents:
diff changeset
773 {
kono
parents:
diff changeset
774 void (*save_oracle) (enum cp_oracle_request, tree identifier);
kono
parents:
diff changeset
775
kono
parents:
diff changeset
776 save_oracle = cp_binding_oracle;
kono
parents:
diff changeset
777 cp_binding_oracle = NULL;
kono
parents:
diff changeset
778
kono
parents:
diff changeset
779 tree ret = push_template_decl (decl);
kono
parents:
diff changeset
780
kono
parents:
diff changeset
781 cp_binding_oracle = save_oracle;
kono
parents:
diff changeset
782
kono
parents:
diff changeset
783 return ret;
kono
parents:
diff changeset
784 }
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 static inline tree
kono
parents:
diff changeset
787 safe_pushtag (tree name, tree type, tag_scope scope)
kono
parents:
diff changeset
788 {
kono
parents:
diff changeset
789 void (*save_oracle) (enum cp_oracle_request, tree identifier);
kono
parents:
diff changeset
790
kono
parents:
diff changeset
791 save_oracle = cp_binding_oracle;
kono
parents:
diff changeset
792 cp_binding_oracle = NULL;
kono
parents:
diff changeset
793
kono
parents:
diff changeset
794 tree ret = pushtag (name, type, scope);
kono
parents:
diff changeset
795
kono
parents:
diff changeset
796 cp_binding_oracle = save_oracle;
kono
parents:
diff changeset
797
kono
parents:
diff changeset
798 return ret;
kono
parents:
diff changeset
799 }
kono
parents:
diff changeset
800
kono
parents:
diff changeset
801 static inline tree
kono
parents:
diff changeset
802 safe_pushdecl_maybe_friend (tree decl, bool is_friend)
kono
parents:
diff changeset
803 {
kono
parents:
diff changeset
804 void (*save_oracle) (enum cp_oracle_request, tree identifier);
kono
parents:
diff changeset
805
kono
parents:
diff changeset
806 save_oracle = cp_binding_oracle;
kono
parents:
diff changeset
807 cp_binding_oracle = NULL;
kono
parents:
diff changeset
808
kono
parents:
diff changeset
809 tree ret = pushdecl (decl, is_friend);
kono
parents:
diff changeset
810
kono
parents:
diff changeset
811 cp_binding_oracle = save_oracle;
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 return ret;
kono
parents:
diff changeset
814 }
kono
parents:
diff changeset
815
kono
parents:
diff changeset
816
kono
parents:
diff changeset
817
kono
parents:
diff changeset
818 int
kono
parents:
diff changeset
819 plugin_push_namespace (cc1_plugin::connection *,
kono
parents:
diff changeset
820 const char *name)
kono
parents:
diff changeset
821 {
kono
parents:
diff changeset
822 if (name && !*name)
kono
parents:
diff changeset
823 push_to_top_level ();
kono
parents:
diff changeset
824 else
kono
parents:
diff changeset
825 push_namespace (name ? get_identifier (name) : NULL);
kono
parents:
diff changeset
826
kono
parents:
diff changeset
827 return 1;
kono
parents:
diff changeset
828 }
kono
parents:
diff changeset
829
kono
parents:
diff changeset
830 int
kono
parents:
diff changeset
831 plugin_push_class (cc1_plugin::connection *,
kono
parents:
diff changeset
832 gcc_type type_in)
kono
parents:
diff changeset
833 {
kono
parents:
diff changeset
834 tree type = convert_in (type_in);
kono
parents:
diff changeset
835 gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (type)));
kono
parents:
diff changeset
836 gcc_assert (TYPE_CONTEXT (type) == FROB_CONTEXT (current_scope ()));
kono
parents:
diff changeset
837
kono
parents:
diff changeset
838 pushclass (type);
kono
parents:
diff changeset
839
kono
parents:
diff changeset
840 return 1;
kono
parents:
diff changeset
841 }
kono
parents:
diff changeset
842
kono
parents:
diff changeset
843 int
kono
parents:
diff changeset
844 plugin_push_function (cc1_plugin::connection *,
kono
parents:
diff changeset
845 gcc_decl function_decl_in)
kono
parents:
diff changeset
846 {
kono
parents:
diff changeset
847 tree fndecl = convert_in (function_decl_in);
kono
parents:
diff changeset
848 gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
kono
parents:
diff changeset
849 gcc_assert (DECL_CONTEXT (fndecl) == FROB_CONTEXT (current_scope ()));
kono
parents:
diff changeset
850
kono
parents:
diff changeset
851 push_fake_function (fndecl);
kono
parents:
diff changeset
852
kono
parents:
diff changeset
853 return 1;
kono
parents:
diff changeset
854 }
kono
parents:
diff changeset
855
kono
parents:
diff changeset
856 int
kono
parents:
diff changeset
857 plugin_pop_binding_level (cc1_plugin::connection *)
kono
parents:
diff changeset
858 {
kono
parents:
diff changeset
859 pop_scope ();
kono
parents:
diff changeset
860 return 1;
kono
parents:
diff changeset
861 }
kono
parents:
diff changeset
862
kono
parents:
diff changeset
863 int
kono
parents:
diff changeset
864 plugin_reactivate_decl (cc1_plugin::connection *,
kono
parents:
diff changeset
865 gcc_decl decl_in,
kono
parents:
diff changeset
866 gcc_decl scope_in)
kono
parents:
diff changeset
867 {
kono
parents:
diff changeset
868 tree decl = convert_in (decl_in);
kono
parents:
diff changeset
869 tree scope = convert_in (scope_in);
kono
parents:
diff changeset
870 gcc_assert (TREE_CODE (decl) == VAR_DECL
kono
parents:
diff changeset
871 || TREE_CODE (decl) == FUNCTION_DECL
kono
parents:
diff changeset
872 || TREE_CODE (decl) == TYPE_DECL);
kono
parents:
diff changeset
873 cp_binding_level *b;
kono
parents:
diff changeset
874 if (scope)
kono
parents:
diff changeset
875 {
kono
parents:
diff changeset
876 gcc_assert (TREE_CODE (scope) == FUNCTION_DECL);
kono
parents:
diff changeset
877 for (b = current_binding_level;
kono
parents:
diff changeset
878 b->this_entity != scope;
kono
parents:
diff changeset
879 b = b->level_chain)
kono
parents:
diff changeset
880 gcc_assert (b->this_entity != global_namespace);
kono
parents:
diff changeset
881 }
kono
parents:
diff changeset
882 else
kono
parents:
diff changeset
883 {
kono
parents:
diff changeset
884 gcc_assert (!at_class_scope_p ());
kono
parents:
diff changeset
885 b = current_binding_level;
kono
parents:
diff changeset
886 }
kono
parents:
diff changeset
887
kono
parents:
diff changeset
888 reactivate_decl (decl, b);
kono
parents:
diff changeset
889 return 1;
kono
parents:
diff changeset
890 }
kono
parents:
diff changeset
891
kono
parents:
diff changeset
892 static tree
kono
parents:
diff changeset
893 get_current_scope ()
kono
parents:
diff changeset
894 {
kono
parents:
diff changeset
895 tree decl;
kono
parents:
diff changeset
896
kono
parents:
diff changeset
897 if (at_namespace_scope_p ())
kono
parents:
diff changeset
898 decl = current_namespace;
kono
parents:
diff changeset
899 else if (at_class_scope_p ())
kono
parents:
diff changeset
900 decl = TYPE_NAME (current_class_type);
kono
parents:
diff changeset
901 else if (at_fake_function_scope_p () || at_function_scope_p ())
kono
parents:
diff changeset
902 decl = current_function_decl;
kono
parents:
diff changeset
903 else
kono
parents:
diff changeset
904 gcc_unreachable ();
kono
parents:
diff changeset
905
kono
parents:
diff changeset
906 return decl;
kono
parents:
diff changeset
907 }
kono
parents:
diff changeset
908
kono
parents:
diff changeset
909 gcc_decl
kono
parents:
diff changeset
910 plugin_get_current_binding_level_decl (cc1_plugin::connection *)
kono
parents:
diff changeset
911 {
kono
parents:
diff changeset
912 tree decl = get_current_scope ();
kono
parents:
diff changeset
913
kono
parents:
diff changeset
914 return convert_out (decl);
kono
parents:
diff changeset
915 }
kono
parents:
diff changeset
916
kono
parents:
diff changeset
917 int
kono
parents:
diff changeset
918 plugin_make_namespace_inline (cc1_plugin::connection *)
kono
parents:
diff changeset
919 {
kono
parents:
diff changeset
920 tree inline_ns = current_namespace;
kono
parents:
diff changeset
921
kono
parents:
diff changeset
922 gcc_assert (toplevel_bindings_p ());
kono
parents:
diff changeset
923 gcc_assert (inline_ns != global_namespace);
kono
parents:
diff changeset
924
kono
parents:
diff changeset
925 tree parent_ns = CP_DECL_CONTEXT (inline_ns);
kono
parents:
diff changeset
926
kono
parents:
diff changeset
927 if (DECL_NAMESPACE_INLINE_P (inline_ns))
kono
parents:
diff changeset
928 return 0;
kono
parents:
diff changeset
929
kono
parents:
diff changeset
930 DECL_NAMESPACE_INLINE_P (inline_ns) = true;
kono
parents:
diff changeset
931 vec_safe_push (DECL_NAMESPACE_INLINEES (parent_ns), inline_ns);
kono
parents:
diff changeset
932
kono
parents:
diff changeset
933 return 1;
kono
parents:
diff changeset
934 }
kono
parents:
diff changeset
935
kono
parents:
diff changeset
936 int
kono
parents:
diff changeset
937 plugin_add_using_namespace (cc1_plugin::connection *,
kono
parents:
diff changeset
938 gcc_decl used_ns_in)
kono
parents:
diff changeset
939 {
kono
parents:
diff changeset
940 tree used_ns = convert_in (used_ns_in);
kono
parents:
diff changeset
941
kono
parents:
diff changeset
942 gcc_assert (TREE_CODE (used_ns) == NAMESPACE_DECL);
kono
parents:
diff changeset
943
kono
parents:
diff changeset
944 finish_namespace_using_directive (used_ns, NULL_TREE);
kono
parents:
diff changeset
945
kono
parents:
diff changeset
946 return 1;
kono
parents:
diff changeset
947 }
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 int
kono
parents:
diff changeset
950 plugin_add_namespace_alias (cc1_plugin::connection *,
kono
parents:
diff changeset
951 const char *id,
kono
parents:
diff changeset
952 gcc_decl target_in)
kono
parents:
diff changeset
953 {
kono
parents:
diff changeset
954 tree name = get_identifier (id);
kono
parents:
diff changeset
955 tree target = convert_in (target_in);
kono
parents:
diff changeset
956
kono
parents:
diff changeset
957 do_namespace_alias (name, target);
kono
parents:
diff changeset
958
kono
parents:
diff changeset
959 return 1;
kono
parents:
diff changeset
960 }
kono
parents:
diff changeset
961
kono
parents:
diff changeset
962 static inline void
kono
parents:
diff changeset
963 set_access_flags (tree decl, enum gcc_cp_symbol_kind flags)
kono
parents:
diff changeset
964 {
kono
parents:
diff changeset
965 gcc_assert (!(flags & GCC_CP_ACCESS_MASK) == !DECL_CLASS_SCOPE_P (decl));
kono
parents:
diff changeset
966
kono
parents:
diff changeset
967 switch (flags & GCC_CP_ACCESS_MASK)
kono
parents:
diff changeset
968 {
kono
parents:
diff changeset
969 case GCC_CP_ACCESS_PRIVATE:
kono
parents:
diff changeset
970 TREE_PRIVATE (decl) = true;
kono
parents:
diff changeset
971 current_access_specifier = access_private_node;
kono
parents:
diff changeset
972 break;
kono
parents:
diff changeset
973
kono
parents:
diff changeset
974 case GCC_CP_ACCESS_PROTECTED:
kono
parents:
diff changeset
975 TREE_PROTECTED (decl) = true;
kono
parents:
diff changeset
976 current_access_specifier = access_protected_node;
kono
parents:
diff changeset
977 break;
kono
parents:
diff changeset
978
kono
parents:
diff changeset
979 case GCC_CP_ACCESS_PUBLIC:
kono
parents:
diff changeset
980 current_access_specifier = access_public_node;
kono
parents:
diff changeset
981 break;
kono
parents:
diff changeset
982
kono
parents:
diff changeset
983 default:
kono
parents:
diff changeset
984 break;
kono
parents:
diff changeset
985 }
kono
parents:
diff changeset
986 }
kono
parents:
diff changeset
987
kono
parents:
diff changeset
988 int
kono
parents:
diff changeset
989 plugin_add_using_decl (cc1_plugin::connection *,
kono
parents:
diff changeset
990 enum gcc_cp_symbol_kind flags,
kono
parents:
diff changeset
991 gcc_decl target_in)
kono
parents:
diff changeset
992 {
kono
parents:
diff changeset
993 tree target = convert_in (target_in);
kono
parents:
diff changeset
994 gcc_assert ((flags & GCC_CP_SYMBOL_MASK) == GCC_CP_SYMBOL_USING);
kono
parents:
diff changeset
995 gcc_assert (!(flags & GCC_CP_FLAG_MASK));
kono
parents:
diff changeset
996 enum gcc_cp_symbol_kind acc_flags;
kono
parents:
diff changeset
997 acc_flags = (enum gcc_cp_symbol_kind) (flags & GCC_CP_ACCESS_MASK);
kono
parents:
diff changeset
998
kono
parents:
diff changeset
999 gcc_assert (!template_parm_scope_p ());
kono
parents:
diff changeset
1000
kono
parents:
diff changeset
1001 bool class_member_p = at_class_scope_p ();
kono
parents:
diff changeset
1002 gcc_assert (!(acc_flags & GCC_CP_ACCESS_MASK) == !class_member_p);
kono
parents:
diff changeset
1003
kono
parents:
diff changeset
1004 tree identifier = DECL_NAME (target);
kono
parents:
diff changeset
1005 tree tcontext = DECL_CONTEXT (target);
kono
parents:
diff changeset
1006
kono
parents:
diff changeset
1007 if (UNSCOPED_ENUM_P (tcontext))
kono
parents:
diff changeset
1008 tcontext = CP_TYPE_CONTEXT (tcontext);
kono
parents:
diff changeset
1009
kono
parents:
diff changeset
1010 if (class_member_p)
kono
parents:
diff changeset
1011 {
kono
parents:
diff changeset
1012 tree decl = do_class_using_decl (tcontext, identifier);
kono
parents:
diff changeset
1013
kono
parents:
diff changeset
1014 set_access_flags (decl, flags);
kono
parents:
diff changeset
1015
kono
parents:
diff changeset
1016 finish_member_declaration (decl);
kono
parents:
diff changeset
1017 }
kono
parents:
diff changeset
1018 else
kono
parents:
diff changeset
1019 {
kono
parents:
diff changeset
1020 /* We can't be at local scope. */
kono
parents:
diff changeset
1021 gcc_assert (at_namespace_scope_p ());
kono
parents:
diff changeset
1022 finish_namespace_using_decl (target, tcontext, identifier);
kono
parents:
diff changeset
1023 }
kono
parents:
diff changeset
1024
kono
parents:
diff changeset
1025 return 1;
kono
parents:
diff changeset
1026 }
kono
parents:
diff changeset
1027
kono
parents:
diff changeset
1028 static tree
kono
parents:
diff changeset
1029 build_named_class_type (enum tree_code code,
kono
parents:
diff changeset
1030 tree id,
kono
parents:
diff changeset
1031 source_location loc)
kono
parents:
diff changeset
1032 {
kono
parents:
diff changeset
1033 /* See at_fake_function_scope_p. */
kono
parents:
diff changeset
1034 gcc_assert (!at_function_scope_p ());
kono
parents:
diff changeset
1035 tree type = make_class_type (code);
kono
parents:
diff changeset
1036 tree type_decl = build_decl (loc, TYPE_DECL, id, type);
kono
parents:
diff changeset
1037 TYPE_NAME (type) = type_decl;
kono
parents:
diff changeset
1038 TYPE_STUB_DECL (type) = type_decl;
kono
parents:
diff changeset
1039 DECL_CONTEXT (type_decl) = TYPE_CONTEXT (type);
kono
parents:
diff changeset
1040
kono
parents:
diff changeset
1041 return type_decl;
kono
parents:
diff changeset
1042 }
kono
parents:
diff changeset
1043
kono
parents:
diff changeset
1044 /* Abuse an unused field of the dummy template parms entry to hold the
kono
parents:
diff changeset
1045 parm list. */
kono
parents:
diff changeset
1046 #define TP_PARM_LIST TREE_TYPE (current_template_parms)
kono
parents:
diff changeset
1047
kono
parents:
diff changeset
1048 gcc_decl
kono
parents:
diff changeset
1049 plugin_build_decl (cc1_plugin::connection *self,
kono
parents:
diff changeset
1050 const char *name,
kono
parents:
diff changeset
1051 enum gcc_cp_symbol_kind sym_kind,
kono
parents:
diff changeset
1052 gcc_type sym_type_in,
kono
parents:
diff changeset
1053 const char *substitution_name,
kono
parents:
diff changeset
1054 gcc_address address,
kono
parents:
diff changeset
1055 const char *filename,
kono
parents:
diff changeset
1056 unsigned int line_number)
kono
parents:
diff changeset
1057 {
kono
parents:
diff changeset
1058 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
1059 gcc_assert (!name || !strchr (name, ':')); // FIXME: this can go eventually.
kono
parents:
diff changeset
1060
kono
parents:
diff changeset
1061 enum tree_code code;
kono
parents:
diff changeset
1062 tree decl;
kono
parents:
diff changeset
1063 tree sym_type = convert_in (sym_type_in);
kono
parents:
diff changeset
1064 enum gcc_cp_symbol_kind sym_flags;
kono
parents:
diff changeset
1065 sym_flags = (enum gcc_cp_symbol_kind) (sym_kind & GCC_CP_FLAG_MASK);
kono
parents:
diff changeset
1066 enum gcc_cp_symbol_kind acc_flags;
kono
parents:
diff changeset
1067 acc_flags = (enum gcc_cp_symbol_kind) (sym_kind & GCC_CP_ACCESS_MASK);
kono
parents:
diff changeset
1068 sym_kind = (enum gcc_cp_symbol_kind) (sym_kind & GCC_CP_SYMBOL_MASK);
kono
parents:
diff changeset
1069
kono
parents:
diff changeset
1070 switch (sym_kind)
kono
parents:
diff changeset
1071 {
kono
parents:
diff changeset
1072 case GCC_CP_SYMBOL_FUNCTION:
kono
parents:
diff changeset
1073 code = FUNCTION_DECL;
kono
parents:
diff changeset
1074 gcc_assert (!(sym_flags & ~GCC_CP_FLAG_MASK_FUNCTION));
kono
parents:
diff changeset
1075 break;
kono
parents:
diff changeset
1076
kono
parents:
diff changeset
1077 case GCC_CP_SYMBOL_VARIABLE:
kono
parents:
diff changeset
1078 code = VAR_DECL;
kono
parents:
diff changeset
1079 gcc_assert (!(sym_flags & ~GCC_CP_FLAG_MASK_VARIABLE));
kono
parents:
diff changeset
1080 break;
kono
parents:
diff changeset
1081
kono
parents:
diff changeset
1082 case GCC_CP_SYMBOL_TYPEDEF:
kono
parents:
diff changeset
1083 code = TYPE_DECL;
kono
parents:
diff changeset
1084 gcc_assert (!sym_flags);
kono
parents:
diff changeset
1085 break;
kono
parents:
diff changeset
1086
kono
parents:
diff changeset
1087 case GCC_CP_SYMBOL_CLASS:
kono
parents:
diff changeset
1088 code = RECORD_TYPE;
kono
parents:
diff changeset
1089 gcc_assert (!(sym_flags & ~GCC_CP_FLAG_MASK_CLASS));
kono
parents:
diff changeset
1090 gcc_assert (!sym_type);
kono
parents:
diff changeset
1091 break;
kono
parents:
diff changeset
1092
kono
parents:
diff changeset
1093 case GCC_CP_SYMBOL_UNION:
kono
parents:
diff changeset
1094 code = UNION_TYPE;
kono
parents:
diff changeset
1095 gcc_assert (!sym_flags);
kono
parents:
diff changeset
1096 gcc_assert (!sym_type);
kono
parents:
diff changeset
1097 break;
kono
parents:
diff changeset
1098
kono
parents:
diff changeset
1099 default:
kono
parents:
diff changeset
1100 gcc_unreachable ();
kono
parents:
diff changeset
1101 }
kono
parents:
diff changeset
1102
kono
parents:
diff changeset
1103 bool template_decl_p = template_parm_scope_p ();
kono
parents:
diff changeset
1104
kono
parents:
diff changeset
1105 if (template_decl_p)
kono
parents:
diff changeset
1106 {
kono
parents:
diff changeset
1107 gcc_assert (code == FUNCTION_DECL || code == RECORD_TYPE
kono
parents:
diff changeset
1108 || code == TYPE_DECL);
kono
parents:
diff changeset
1109
kono
parents:
diff changeset
1110 /* Finish the template parm list that started this template parm. */
kono
parents:
diff changeset
1111 end_template_parm_list (TP_PARM_LIST);
kono
parents:
diff changeset
1112
kono
parents:
diff changeset
1113 gcc_assert (!address);
kono
parents:
diff changeset
1114 gcc_assert (!substitution_name);
kono
parents:
diff changeset
1115 }
kono
parents:
diff changeset
1116
kono
parents:
diff changeset
1117 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
1118 bool class_member_p = at_class_scope_p ();
kono
parents:
diff changeset
1119 bool ctor = false, dtor = false, assop = false;
kono
parents:
diff changeset
1120 tree_code opcode = ERROR_MARK;
kono
parents:
diff changeset
1121
kono
parents:
diff changeset
1122 gcc_assert (!(acc_flags & GCC_CP_ACCESS_MASK) == !class_member_p);
kono
parents:
diff changeset
1123
kono
parents:
diff changeset
1124 tree identifier;
kono
parents:
diff changeset
1125 if (code != FUNCTION_DECL
kono
parents:
diff changeset
1126 || !(sym_flags & GCC_CP_FLAG_SPECIAL_FUNCTION))
kono
parents:
diff changeset
1127 {
kono
parents:
diff changeset
1128 if (name)
kono
parents:
diff changeset
1129 identifier = get_identifier (name);
kono
parents:
diff changeset
1130 else
kono
parents:
diff changeset
1131 {
kono
parents:
diff changeset
1132 gcc_assert (RECORD_OR_UNION_CODE_P (code));
kono
parents:
diff changeset
1133 identifier = make_anon_name ();
kono
parents:
diff changeset
1134 }
kono
parents:
diff changeset
1135 }
kono
parents:
diff changeset
1136
kono
parents:
diff changeset
1137 if (code == FUNCTION_DECL)
kono
parents:
diff changeset
1138 {
kono
parents:
diff changeset
1139 if (sym_flags & GCC_CP_FLAG_SPECIAL_FUNCTION)
kono
parents:
diff changeset
1140 {
kono
parents:
diff changeset
1141 #define CHARS2(f,s) (((unsigned char)f << CHAR_BIT) | (unsigned char)s)
kono
parents:
diff changeset
1142 switch (CHARS2 (name[0], name[1]))
kono
parents:
diff changeset
1143 {
kono
parents:
diff changeset
1144 case CHARS2 ('C', 0x0): // ctor base declaration
kono
parents:
diff changeset
1145 case CHARS2 ('C', ' '):
kono
parents:
diff changeset
1146 case CHARS2 ('C', '1'):
kono
parents:
diff changeset
1147 case CHARS2 ('C', '2'):
kono
parents:
diff changeset
1148 case CHARS2 ('C', '4'):
kono
parents:
diff changeset
1149 ctor = true;
kono
parents:
diff changeset
1150 cdtor:
kono
parents:
diff changeset
1151 gcc_assert (!address);
kono
parents:
diff changeset
1152 gcc_assert (!substitution_name);
kono
parents:
diff changeset
1153 identifier = DECL_NAME (TYPE_NAME (current_class_type));
kono
parents:
diff changeset
1154 break;
kono
parents:
diff changeset
1155 case CHARS2 ('D', 0x0): // dtor base declaration
kono
parents:
diff changeset
1156 case CHARS2 ('D', ' '):
kono
parents:
diff changeset
1157 case CHARS2 ('D', '0'):
kono
parents:
diff changeset
1158 case CHARS2 ('D', '1'):
kono
parents:
diff changeset
1159 case CHARS2 ('D', '2'):
kono
parents:
diff changeset
1160 case CHARS2 ('D', '4'):
kono
parents:
diff changeset
1161 gcc_assert (!template_decl_p);
kono
parents:
diff changeset
1162 dtor = true;
kono
parents:
diff changeset
1163 goto cdtor;
kono
parents:
diff changeset
1164 case CHARS2 ('n', 'w'): // operator new
kono
parents:
diff changeset
1165 opcode = NEW_EXPR;
kono
parents:
diff changeset
1166 break;
kono
parents:
diff changeset
1167 case CHARS2 ('n', 'a'): // operator new[]
kono
parents:
diff changeset
1168 opcode = VEC_NEW_EXPR;
kono
parents:
diff changeset
1169 break;
kono
parents:
diff changeset
1170 case CHARS2 ('d', 'l'): // operator delete
kono
parents:
diff changeset
1171 opcode = DELETE_EXPR;
kono
parents:
diff changeset
1172 break;
kono
parents:
diff changeset
1173 case CHARS2 ('d', 'a'): // operator delete[]
kono
parents:
diff changeset
1174 opcode = VEC_DELETE_EXPR;
kono
parents:
diff changeset
1175 break;
kono
parents:
diff changeset
1176 case CHARS2 ('p', 's'): // operator + (unary)
kono
parents:
diff changeset
1177 opcode = PLUS_EXPR;
kono
parents:
diff changeset
1178 break;
kono
parents:
diff changeset
1179 case CHARS2 ('n', 'g'): // operator - (unary)
kono
parents:
diff changeset
1180 opcode = MINUS_EXPR;
kono
parents:
diff changeset
1181 break;
kono
parents:
diff changeset
1182 case CHARS2 ('a', 'd'): // operator & (unary)
kono
parents:
diff changeset
1183 opcode = BIT_AND_EXPR;
kono
parents:
diff changeset
1184 break;
kono
parents:
diff changeset
1185 case CHARS2 ('d', 'e'): // operator * (unary)
kono
parents:
diff changeset
1186 opcode = MULT_EXPR;
kono
parents:
diff changeset
1187 break;
kono
parents:
diff changeset
1188 case CHARS2 ('c', 'o'): // operator ~
kono
parents:
diff changeset
1189 opcode = BIT_NOT_EXPR;
kono
parents:
diff changeset
1190 break;
kono
parents:
diff changeset
1191 case CHARS2 ('p', 'l'): // operator +
kono
parents:
diff changeset
1192 opcode = PLUS_EXPR;
kono
parents:
diff changeset
1193 break;
kono
parents:
diff changeset
1194 case CHARS2 ('m', 'i'): // operator -
kono
parents:
diff changeset
1195 opcode = MINUS_EXPR;
kono
parents:
diff changeset
1196 break;
kono
parents:
diff changeset
1197 case CHARS2 ('m', 'l'): // operator *
kono
parents:
diff changeset
1198 opcode = MULT_EXPR;
kono
parents:
diff changeset
1199 break;
kono
parents:
diff changeset
1200 case CHARS2 ('d', 'v'): // operator /
kono
parents:
diff changeset
1201 opcode = TRUNC_DIV_EXPR;
kono
parents:
diff changeset
1202 break;
kono
parents:
diff changeset
1203 case CHARS2 ('r', 'm'): // operator %
kono
parents:
diff changeset
1204 opcode = TRUNC_MOD_EXPR;
kono
parents:
diff changeset
1205 break;
kono
parents:
diff changeset
1206 case CHARS2 ('a', 'n'): // operator &
kono
parents:
diff changeset
1207 opcode = BIT_AND_EXPR;
kono
parents:
diff changeset
1208 break;
kono
parents:
diff changeset
1209 case CHARS2 ('o', 'r'): // operator |
kono
parents:
diff changeset
1210 opcode = BIT_IOR_EXPR;
kono
parents:
diff changeset
1211 break;
kono
parents:
diff changeset
1212 case CHARS2 ('e', 'o'): // operator ^
kono
parents:
diff changeset
1213 opcode = BIT_XOR_EXPR;
kono
parents:
diff changeset
1214 break;
kono
parents:
diff changeset
1215 case CHARS2 ('a', 'S'): // operator =
kono
parents:
diff changeset
1216 opcode = NOP_EXPR;
kono
parents:
diff changeset
1217 assop = true;
kono
parents:
diff changeset
1218 break;
kono
parents:
diff changeset
1219 case CHARS2 ('p', 'L'): // operator +=
kono
parents:
diff changeset
1220 opcode = PLUS_EXPR;
kono
parents:
diff changeset
1221 assop = true;
kono
parents:
diff changeset
1222 break;
kono
parents:
diff changeset
1223 case CHARS2 ('m', 'I'): // operator -=
kono
parents:
diff changeset
1224 opcode = MINUS_EXPR;
kono
parents:
diff changeset
1225 assop = true;
kono
parents:
diff changeset
1226 break;
kono
parents:
diff changeset
1227 case CHARS2 ('m', 'L'): // operator *=
kono
parents:
diff changeset
1228 opcode = MULT_EXPR;
kono
parents:
diff changeset
1229 assop = true;
kono
parents:
diff changeset
1230 break;
kono
parents:
diff changeset
1231 case CHARS2 ('d', 'V'): // operator /=
kono
parents:
diff changeset
1232 opcode = TRUNC_DIV_EXPR;
kono
parents:
diff changeset
1233 assop = true;
kono
parents:
diff changeset
1234 break;
kono
parents:
diff changeset
1235 case CHARS2 ('r', 'M'): // operator %=
kono
parents:
diff changeset
1236 opcode = TRUNC_MOD_EXPR;
kono
parents:
diff changeset
1237 assop = true;
kono
parents:
diff changeset
1238 break;
kono
parents:
diff changeset
1239 case CHARS2 ('a', 'N'): // operator &=
kono
parents:
diff changeset
1240 opcode = BIT_AND_EXPR;
kono
parents:
diff changeset
1241 assop = true;
kono
parents:
diff changeset
1242 break;
kono
parents:
diff changeset
1243 case CHARS2 ('o', 'R'): // operator |=
kono
parents:
diff changeset
1244 opcode = BIT_IOR_EXPR;
kono
parents:
diff changeset
1245 assop = true;
kono
parents:
diff changeset
1246 break;
kono
parents:
diff changeset
1247 case CHARS2 ('e', 'O'): // operator ^=
kono
parents:
diff changeset
1248 opcode = BIT_XOR_EXPR;
kono
parents:
diff changeset
1249 assop = true;
kono
parents:
diff changeset
1250 break;
kono
parents:
diff changeset
1251 case CHARS2 ('l', 's'): // operator <<
kono
parents:
diff changeset
1252 opcode = LSHIFT_EXPR;
kono
parents:
diff changeset
1253 break;
kono
parents:
diff changeset
1254 case CHARS2 ('r', 's'): // operator >>
kono
parents:
diff changeset
1255 opcode = RSHIFT_EXPR;
kono
parents:
diff changeset
1256 break;
kono
parents:
diff changeset
1257 case CHARS2 ('l', 'S'): // operator <<=
kono
parents:
diff changeset
1258 opcode = LSHIFT_EXPR;
kono
parents:
diff changeset
1259 assop = true;
kono
parents:
diff changeset
1260 break;
kono
parents:
diff changeset
1261 case CHARS2 ('r', 'S'): // operator >>=
kono
parents:
diff changeset
1262 opcode = RSHIFT_EXPR;
kono
parents:
diff changeset
1263 assop = true;
kono
parents:
diff changeset
1264 break;
kono
parents:
diff changeset
1265 case CHARS2 ('e', 'q'): // operator ==
kono
parents:
diff changeset
1266 opcode = EQ_EXPR;
kono
parents:
diff changeset
1267 break;
kono
parents:
diff changeset
1268 case CHARS2 ('n', 'e'): // operator !=
kono
parents:
diff changeset
1269 opcode = NE_EXPR;
kono
parents:
diff changeset
1270 break;
kono
parents:
diff changeset
1271 case CHARS2 ('l', 't'): // operator <
kono
parents:
diff changeset
1272 opcode = LT_EXPR;
kono
parents:
diff changeset
1273 break;
kono
parents:
diff changeset
1274 case CHARS2 ('g', 't'): // operator >
kono
parents:
diff changeset
1275 opcode = GT_EXPR;
kono
parents:
diff changeset
1276 break;
kono
parents:
diff changeset
1277 case CHARS2 ('l', 'e'): // operator <=
kono
parents:
diff changeset
1278 opcode = LE_EXPR;
kono
parents:
diff changeset
1279 break;
kono
parents:
diff changeset
1280 case CHARS2 ('g', 'e'): // operator >=
kono
parents:
diff changeset
1281 opcode = GE_EXPR;
kono
parents:
diff changeset
1282 break;
kono
parents:
diff changeset
1283 case CHARS2 ('n', 't'): // operator !
kono
parents:
diff changeset
1284 opcode = TRUTH_NOT_EXPR;
kono
parents:
diff changeset
1285 break;
kono
parents:
diff changeset
1286 case CHARS2 ('a', 'a'): // operator &&
kono
parents:
diff changeset
1287 opcode = TRUTH_ANDIF_EXPR;
kono
parents:
diff changeset
1288 break;
kono
parents:
diff changeset
1289 case CHARS2 ('o', 'o'): // operator ||
kono
parents:
diff changeset
1290 opcode = TRUTH_ORIF_EXPR;
kono
parents:
diff changeset
1291 break;
kono
parents:
diff changeset
1292 case CHARS2 ('p', 'p'): // operator ++
kono
parents:
diff changeset
1293 opcode = POSTINCREMENT_EXPR;
kono
parents:
diff changeset
1294 break;
kono
parents:
diff changeset
1295 case CHARS2 ('m', 'm'): // operator --
kono
parents:
diff changeset
1296 /* This stands for either one as an operator name, and
kono
parents:
diff changeset
1297 "pp" and "mm" stand for POST??CREMENT, but for some
kono
parents:
diff changeset
1298 reason the parser uses this opcode name for
kono
parents:
diff changeset
1299 operator--; let's follow their practice. */
kono
parents:
diff changeset
1300 opcode = PREDECREMENT_EXPR;
kono
parents:
diff changeset
1301 break;
kono
parents:
diff changeset
1302 case CHARS2 ('c', 'm'): // operator ,
kono
parents:
diff changeset
1303 opcode = COMPOUND_EXPR;
kono
parents:
diff changeset
1304 break;
kono
parents:
diff changeset
1305 case CHARS2 ('p', 'm'): // operator ->*
kono
parents:
diff changeset
1306 opcode = MEMBER_REF;
kono
parents:
diff changeset
1307 break;
kono
parents:
diff changeset
1308 case CHARS2 ('p', 't'): // operator ->
kono
parents:
diff changeset
1309 opcode = COMPONENT_REF;
kono
parents:
diff changeset
1310 break;
kono
parents:
diff changeset
1311 case CHARS2 ('c', 'l'): // operator ()
kono
parents:
diff changeset
1312 opcode = CALL_EXPR;
kono
parents:
diff changeset
1313 break;
kono
parents:
diff changeset
1314 case CHARS2 ('i', 'x'): // operator []
kono
parents:
diff changeset
1315 opcode = ARRAY_REF;
kono
parents:
diff changeset
1316 break;
kono
parents:
diff changeset
1317 case CHARS2 ('c', 'v'): // operator <T> (conversion operator)
kono
parents:
diff changeset
1318 identifier = make_conv_op_name (TREE_TYPE (sym_type));
kono
parents:
diff changeset
1319 break;
kono
parents:
diff changeset
1320 // C++11-only:
kono
parents:
diff changeset
1321 case CHARS2 ('l', 'i'): // operator "" <id>
kono
parents:
diff changeset
1322 {
kono
parents:
diff changeset
1323 char *id = (char *)name + 2;
kono
parents:
diff changeset
1324 bool freeid = false;
kono
parents:
diff changeset
1325 if (*id >= '0' && *id <= '9')
kono
parents:
diff changeset
1326 {
kono
parents:
diff changeset
1327 unsigned len = 0;
kono
parents:
diff changeset
1328 do
kono
parents:
diff changeset
1329 {
kono
parents:
diff changeset
1330 len *= 10;
kono
parents:
diff changeset
1331 len += id[0] - '0';
kono
parents:
diff changeset
1332 id++;
kono
parents:
diff changeset
1333 }
kono
parents:
diff changeset
1334 while (*id && *id >= '0' && *id <= '9');
kono
parents:
diff changeset
1335 id = xstrndup (id, len);
kono
parents:
diff changeset
1336 freeid = true;
kono
parents:
diff changeset
1337 }
kono
parents:
diff changeset
1338 identifier = cp_literal_operator_id (id);
kono
parents:
diff changeset
1339 if (freeid)
kono
parents:
diff changeset
1340 free (id);
kono
parents:
diff changeset
1341 }
kono
parents:
diff changeset
1342 break;
kono
parents:
diff changeset
1343 case CHARS2 ('q', 'u'): // ternary operator, not overloadable.
kono
parents:
diff changeset
1344 default:
kono
parents:
diff changeset
1345 gcc_unreachable ();
kono
parents:
diff changeset
1346 }
kono
parents:
diff changeset
1347
kono
parents:
diff changeset
1348 if (opcode != ERROR_MARK)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1349 identifier = ovl_op_identifier (assop, opcode);
111
kono
parents:
diff changeset
1350 }
kono
parents:
diff changeset
1351 decl = build_lang_decl_loc (loc, code, identifier, sym_type);
kono
parents:
diff changeset
1352 /* FIXME: current_lang_name is lang_name_c while compiling an
kono
parents:
diff changeset
1353 extern "C" function, and we haven't switched to a global
kono
parents:
diff changeset
1354 context at this point, and this breaks function
kono
parents:
diff changeset
1355 overloading. */
kono
parents:
diff changeset
1356 SET_DECL_LANGUAGE (decl, lang_cplusplus);
kono
parents:
diff changeset
1357 if (TREE_CODE (sym_type) == METHOD_TYPE)
kono
parents:
diff changeset
1358 DECL_ARGUMENTS (decl) = build_this_parm (decl, current_class_type,
kono
parents:
diff changeset
1359 cp_type_quals (sym_type));
kono
parents:
diff changeset
1360 for (tree arg = TREE_CODE (sym_type) == METHOD_TYPE
kono
parents:
diff changeset
1361 ? TREE_CHAIN (TYPE_ARG_TYPES (sym_type))
kono
parents:
diff changeset
1362 : TYPE_ARG_TYPES (sym_type);
kono
parents:
diff changeset
1363 arg && arg != void_list_node;
kono
parents:
diff changeset
1364 arg = TREE_CHAIN (arg))
kono
parents:
diff changeset
1365 {
kono
parents:
diff changeset
1366 tree parm = cp_build_parm_decl (decl, NULL_TREE, TREE_VALUE (arg));
kono
parents:
diff changeset
1367 DECL_CHAIN (parm) = DECL_ARGUMENTS (decl);
kono
parents:
diff changeset
1368 DECL_ARGUMENTS (decl) = parm;
kono
parents:
diff changeset
1369 }
kono
parents:
diff changeset
1370 DECL_ARGUMENTS (decl) = nreverse (DECL_ARGUMENTS (decl));
kono
parents:
diff changeset
1371 if (class_member_p)
kono
parents:
diff changeset
1372 {
kono
parents:
diff changeset
1373 if (TREE_CODE (sym_type) == FUNCTION_TYPE)
kono
parents:
diff changeset
1374 DECL_STATIC_FUNCTION_P (decl) = 1;
kono
parents:
diff changeset
1375 if (sym_flags & GCC_CP_FLAG_VIRTUAL_FUNCTION)
kono
parents:
diff changeset
1376 {
kono
parents:
diff changeset
1377 DECL_VIRTUAL_P (decl) = 1;
kono
parents:
diff changeset
1378 if (sym_flags & GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION)
kono
parents:
diff changeset
1379 DECL_PURE_VIRTUAL_P (decl) = 1;
kono
parents:
diff changeset
1380 if (sym_flags & GCC_CP_FLAG_FINAL_VIRTUAL_FUNCTION)
kono
parents:
diff changeset
1381 DECL_FINAL_P (decl) = 1;
kono
parents:
diff changeset
1382 }
kono
parents:
diff changeset
1383 else
kono
parents:
diff changeset
1384 gcc_assert (!(sym_flags & (GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION
kono
parents:
diff changeset
1385 | GCC_CP_FLAG_FINAL_VIRTUAL_FUNCTION)));
kono
parents:
diff changeset
1386 }
kono
parents:
diff changeset
1387 else
kono
parents:
diff changeset
1388 {
kono
parents:
diff changeset
1389 gcc_assert (!(sym_flags & (GCC_CP_FLAG_VIRTUAL_FUNCTION
kono
parents:
diff changeset
1390 | GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION
kono
parents:
diff changeset
1391 | GCC_CP_FLAG_FINAL_VIRTUAL_FUNCTION)));
kono
parents:
diff changeset
1392 gcc_assert (!ctor && !dtor && !assop);
kono
parents:
diff changeset
1393 }
kono
parents:
diff changeset
1394 if (sym_flags & GCC_CP_FLAG_EXPLICIT_FUNCTION)
kono
parents:
diff changeset
1395 DECL_NONCONVERTING_P (decl) = 1;
kono
parents:
diff changeset
1396 if (sym_flags & GCC_CP_FLAG_DEFAULTED_FUNCTION)
kono
parents:
diff changeset
1397 {
kono
parents:
diff changeset
1398 DECL_INITIAL (decl) = ridpointers[(int)RID_DEFAULT];
kono
parents:
diff changeset
1399 DECL_DEFAULTED_FN (decl) = 1;
kono
parents:
diff changeset
1400 }
kono
parents:
diff changeset
1401 if (sym_flags & GCC_CP_FLAG_DELETED_FUNCTION)
kono
parents:
diff changeset
1402 {
kono
parents:
diff changeset
1403 // DECL_INITIAL (decl) = ridpointers[(int)RID_DELETE];
kono
parents:
diff changeset
1404 DECL_DELETED_FN (decl) = 1;
kono
parents:
diff changeset
1405 DECL_DECLARED_INLINE_P (decl) = 1;
kono
parents:
diff changeset
1406 DECL_INITIAL (decl) = error_mark_node;
kono
parents:
diff changeset
1407 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1408
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1409 if (ctor)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1410 DECL_CXX_CONSTRUCTOR_P (decl) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1411 else if (dtor)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1412 DECL_CXX_DESTRUCTOR_P (decl) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1413 else if ((sym_flags & GCC_CP_FLAG_SPECIAL_FUNCTION)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1414 && opcode != ERROR_MARK)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1415 DECL_OVERLOADED_OPERATOR_CODE_RAW (decl) = ovl_op_mapping[opcode];
111
kono
parents:
diff changeset
1416 }
kono
parents:
diff changeset
1417 else if (RECORD_OR_UNION_CODE_P (code))
kono
parents:
diff changeset
1418 {
kono
parents:
diff changeset
1419 decl = build_named_class_type (code, identifier, loc);
kono
parents:
diff changeset
1420 tree type = TREE_TYPE (decl);
kono
parents:
diff changeset
1421
kono
parents:
diff changeset
1422 if (code == RECORD_TYPE
kono
parents:
diff changeset
1423 && !(sym_flags & GCC_CP_FLAG_CLASS_IS_STRUCT))
kono
parents:
diff changeset
1424 CLASSTYPE_DECLARED_CLASS (type) = true;
kono
parents:
diff changeset
1425 }
kono
parents:
diff changeset
1426 else if (class_member_p)
kono
parents:
diff changeset
1427 {
kono
parents:
diff changeset
1428 decl = build_lang_decl_loc (loc, code, identifier, sym_type);
kono
parents:
diff changeset
1429
kono
parents:
diff changeset
1430 if (TREE_CODE (decl) == VAR_DECL)
kono
parents:
diff changeset
1431 {
kono
parents:
diff changeset
1432 DECL_THIS_STATIC (decl) = 1;
kono
parents:
diff changeset
1433 // The remainder of this block does the same as:
kono
parents:
diff changeset
1434 // set_linkage_for_static_data_member (decl);
kono
parents:
diff changeset
1435 TREE_PUBLIC (decl) = 1;
kono
parents:
diff changeset
1436 TREE_STATIC (decl) = 1;
kono
parents:
diff changeset
1437 DECL_INTERFACE_KNOWN (decl) = 1;
kono
parents:
diff changeset
1438
kono
parents:
diff changeset
1439 // FIXME: sym_flags & GCC_CP_FLAG_THREAD_LOCAL_VARIABLE
kono
parents:
diff changeset
1440 gcc_assert (!(sym_flags & GCC_CP_FLAG_THREAD_LOCAL_VARIABLE));
kono
parents:
diff changeset
1441
kono
parents:
diff changeset
1442 if (sym_flags & GCC_CP_FLAG_CONSTEXPR_VARIABLE)
kono
parents:
diff changeset
1443 DECL_DECLARED_CONSTEXPR_P (decl) = true;
kono
parents:
diff changeset
1444 }
kono
parents:
diff changeset
1445 }
kono
parents:
diff changeset
1446 else
kono
parents:
diff changeset
1447 {
kono
parents:
diff changeset
1448 decl = build_decl (loc, code, identifier, sym_type);
kono
parents:
diff changeset
1449
kono
parents:
diff changeset
1450 if (TREE_CODE (decl) == VAR_DECL)
kono
parents:
diff changeset
1451 {
kono
parents:
diff changeset
1452 // FIXME: sym_flags & GCC_CP_FLAG_THREAD_LOCAL_VARIABLE
kono
parents:
diff changeset
1453 gcc_assert (!(sym_flags & GCC_CP_FLAG_THREAD_LOCAL_VARIABLE));
kono
parents:
diff changeset
1454
kono
parents:
diff changeset
1455 if (sym_flags & GCC_CP_FLAG_CONSTEXPR_VARIABLE)
kono
parents:
diff changeset
1456 DECL_DECLARED_CONSTEXPR_P (decl) = true;
kono
parents:
diff changeset
1457 }
kono
parents:
diff changeset
1458 }
kono
parents:
diff changeset
1459 TREE_USED (decl) = 1;
kono
parents:
diff changeset
1460 TREE_ADDRESSABLE (decl) = 1;
kono
parents:
diff changeset
1461
kono
parents:
diff changeset
1462 if (class_member_p)
kono
parents:
diff changeset
1463 DECL_CONTEXT (decl) = FROB_CONTEXT (current_class_type);
kono
parents:
diff changeset
1464 else if (at_namespace_scope_p ())
kono
parents:
diff changeset
1465 DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ());
kono
parents:
diff changeset
1466
kono
parents:
diff changeset
1467 set_access_flags (decl, acc_flags);
kono
parents:
diff changeset
1468
kono
parents:
diff changeset
1469 /* If this is the typedef that names an otherwise anonymous type,
kono
parents:
diff changeset
1470 propagate the typedef name to the type. In normal compilation,
kono
parents:
diff changeset
1471 this is done in grokdeclarator. */
kono
parents:
diff changeset
1472 if (sym_kind == GCC_CP_SYMBOL_TYPEDEF
kono
parents:
diff changeset
1473 && !template_decl_p
kono
parents:
diff changeset
1474 && DECL_CONTEXT (decl) == TYPE_CONTEXT (sym_type)
kono
parents:
diff changeset
1475 && TYPE_UNNAMED_P (sym_type))
kono
parents:
diff changeset
1476 name_unnamed_type (sym_type, decl);
kono
parents:
diff changeset
1477
kono
parents:
diff changeset
1478 if (sym_kind != GCC_CP_SYMBOL_TYPEDEF
kono
parents:
diff changeset
1479 && sym_kind != GCC_CP_SYMBOL_CLASS
kono
parents:
diff changeset
1480 && sym_kind != GCC_CP_SYMBOL_UNION
kono
parents:
diff changeset
1481 && !template_decl_p && !ctor && !dtor)
kono
parents:
diff changeset
1482 {
kono
parents:
diff changeset
1483 decl_addr_value value;
kono
parents:
diff changeset
1484
kono
parents:
diff changeset
1485 DECL_EXTERNAL (decl) = 1;
kono
parents:
diff changeset
1486 value.decl = decl;
kono
parents:
diff changeset
1487 if (substitution_name != NULL)
kono
parents:
diff changeset
1488 {
kono
parents:
diff changeset
1489 // If the translator gave us a name without a binding,
kono
parents:
diff changeset
1490 // we can just substitute error_mark_node, since we know the
kono
parents:
diff changeset
1491 // translator will be reporting an error anyhow.
kono
parents:
diff changeset
1492 value.address
kono
parents:
diff changeset
1493 = lookup_name (get_identifier (substitution_name));
kono
parents:
diff changeset
1494 if (value.address == NULL_TREE)
kono
parents:
diff changeset
1495 value.address = error_mark_node;
kono
parents:
diff changeset
1496 }
kono
parents:
diff changeset
1497 else if (address)
kono
parents:
diff changeset
1498 value.address = build_int_cst_type (ptr_type_node, address);
kono
parents:
diff changeset
1499 else
kono
parents:
diff changeset
1500 value.address = NULL;
kono
parents:
diff changeset
1501 if (value.address)
kono
parents:
diff changeset
1502 record_decl_address (ctx, value);
kono
parents:
diff changeset
1503 }
kono
parents:
diff changeset
1504
kono
parents:
diff changeset
1505 if (class_member_p && code == FUNCTION_DECL)
kono
parents:
diff changeset
1506 {
kono
parents:
diff changeset
1507 if (ctor || dtor)
kono
parents:
diff changeset
1508 maybe_retrofit_in_chrg (decl);
kono
parents:
diff changeset
1509
kono
parents:
diff changeset
1510 grok_special_member_properties (decl);
kono
parents:
diff changeset
1511 }
kono
parents:
diff changeset
1512
kono
parents:
diff changeset
1513 if (template_decl_p)
kono
parents:
diff changeset
1514 {
kono
parents:
diff changeset
1515 if (RECORD_OR_UNION_CODE_P (code))
kono
parents:
diff changeset
1516 safe_pushtag (identifier, TREE_TYPE (decl), ts_current);
kono
parents:
diff changeset
1517 else
kono
parents:
diff changeset
1518 decl = safe_push_template_decl (decl);
kono
parents:
diff changeset
1519
kono
parents:
diff changeset
1520 tree tdecl = NULL_TREE;
kono
parents:
diff changeset
1521 if (class_member_p)
kono
parents:
diff changeset
1522 tdecl = finish_member_template_decl (decl);
kono
parents:
diff changeset
1523
kono
parents:
diff changeset
1524 end_template_decl ();
kono
parents:
diff changeset
1525
kono
parents:
diff changeset
1526 /* We only support one level of templates, because we only
kono
parents:
diff changeset
1527 support declaring generics; actual definitions are only of
kono
parents:
diff changeset
1528 specializations. */
kono
parents:
diff changeset
1529 gcc_assert (!template_parm_scope_p ());
kono
parents:
diff changeset
1530
kono
parents:
diff changeset
1531 if (class_member_p)
kono
parents:
diff changeset
1532 finish_member_declaration (tdecl);
kono
parents:
diff changeset
1533 }
kono
parents:
diff changeset
1534 else if (RECORD_OR_UNION_CODE_P (code))
kono
parents:
diff changeset
1535 safe_pushtag (identifier, TREE_TYPE (decl), ts_current);
kono
parents:
diff changeset
1536 else if (class_member_p)
kono
parents:
diff changeset
1537 finish_member_declaration (decl);
kono
parents:
diff changeset
1538 else
kono
parents:
diff changeset
1539 decl = safe_pushdecl_maybe_friend (decl, false);
kono
parents:
diff changeset
1540
kono
parents:
diff changeset
1541 if ((ctor || dtor)
kono
parents:
diff changeset
1542 /* Don't crash after a duplicate declaration of a cdtor. */
kono
parents:
diff changeset
1543 && TYPE_FIELDS (current_class_type) == decl)
kono
parents:
diff changeset
1544 {
kono
parents:
diff changeset
1545 /* ctors and dtors clones are chained after DECL.
kono
parents:
diff changeset
1546 However, we create the clones before TYPE_METHODS is
kono
parents:
diff changeset
1547 reversed. We test for cloned methods after reversal,
kono
parents:
diff changeset
1548 however, and the test requires the clones to follow
kono
parents:
diff changeset
1549 DECL. So, we reverse the chain of clones now, so
kono
parents:
diff changeset
1550 that it will come out in the right order after
kono
parents:
diff changeset
1551 reversal. */
kono
parents:
diff changeset
1552 tree save = DECL_CHAIN (decl);
kono
parents:
diff changeset
1553 DECL_CHAIN (decl) = NULL_TREE;
kono
parents:
diff changeset
1554 clone_function_decl (decl, /*update_methods=*/true);
kono
parents:
diff changeset
1555 gcc_assert (TYPE_FIELDS (current_class_type) == decl);
kono
parents:
diff changeset
1556 TYPE_FIELDS (current_class_type)
kono
parents:
diff changeset
1557 = nreverse (TYPE_FIELDS (current_class_type));
kono
parents:
diff changeset
1558 DECL_CHAIN (decl) = save;
kono
parents:
diff changeset
1559 }
kono
parents:
diff changeset
1560
kono
parents:
diff changeset
1561 rest_of_decl_compilation (decl, toplevel_bindings_p (), 0);
kono
parents:
diff changeset
1562
kono
parents:
diff changeset
1563 return convert_out (ctx->preserve (decl));
kono
parents:
diff changeset
1564 }
kono
parents:
diff changeset
1565
kono
parents:
diff changeset
1566 gcc_decl
kono
parents:
diff changeset
1567 plugin_define_cdtor_clone (cc1_plugin::connection *self,
kono
parents:
diff changeset
1568 const char *name,
kono
parents:
diff changeset
1569 gcc_decl cdtor_in,
kono
parents:
diff changeset
1570 gcc_address address)
kono
parents:
diff changeset
1571 {
kono
parents:
diff changeset
1572 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
1573 tree decl = convert_in (cdtor_in);
kono
parents:
diff changeset
1574 bool ctor = false;
kono
parents:
diff changeset
1575 bool dtor = false;
kono
parents:
diff changeset
1576 tree identifier;
kono
parents:
diff changeset
1577
kono
parents:
diff changeset
1578 switch (CHARS2 (name[0], name[1]))
kono
parents:
diff changeset
1579 {
kono
parents:
diff changeset
1580 case CHARS2 ('C', '1'): // in-charge constructor
kono
parents:
diff changeset
1581 identifier = complete_ctor_identifier;
kono
parents:
diff changeset
1582 ctor = true;
kono
parents:
diff changeset
1583 break;
kono
parents:
diff changeset
1584 case CHARS2 ('C', '2'): // not-in-charge constructor
kono
parents:
diff changeset
1585 identifier = base_ctor_identifier;
kono
parents:
diff changeset
1586 ctor = true;
kono
parents:
diff changeset
1587 break;
kono
parents:
diff changeset
1588 case CHARS2 ('C', '4'):
kono
parents:
diff changeset
1589 identifier = ctor_identifier; // unified constructor
kono
parents:
diff changeset
1590 ctor = true;
kono
parents:
diff changeset
1591 break;
kono
parents:
diff changeset
1592 case CHARS2 ('D', '0'): // deleting destructor
kono
parents:
diff changeset
1593 identifier = deleting_dtor_identifier;
kono
parents:
diff changeset
1594 dtor = true;
kono
parents:
diff changeset
1595 break;
kono
parents:
diff changeset
1596 case CHARS2 ('D', '1'): // in-charge destructor
kono
parents:
diff changeset
1597 identifier = complete_dtor_identifier;
kono
parents:
diff changeset
1598 dtor = true;
kono
parents:
diff changeset
1599 break;
kono
parents:
diff changeset
1600 case CHARS2 ('D', '2'): // not-in-charge destructor
kono
parents:
diff changeset
1601 identifier = base_dtor_identifier;
kono
parents:
diff changeset
1602 dtor = true;
kono
parents:
diff changeset
1603 break;
kono
parents:
diff changeset
1604 case CHARS2 ('D', '4'):
kono
parents:
diff changeset
1605 identifier = dtor_identifier; // unified destructor
kono
parents:
diff changeset
1606 dtor = true;
kono
parents:
diff changeset
1607 break;
kono
parents:
diff changeset
1608
kono
parents:
diff changeset
1609 default:
kono
parents:
diff changeset
1610 gcc_unreachable ();
kono
parents:
diff changeset
1611 }
kono
parents:
diff changeset
1612
kono
parents:
diff changeset
1613 gcc_assert (!ctor != !dtor);
kono
parents:
diff changeset
1614 gcc_assert (ctor
kono
parents:
diff changeset
1615 ? (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl)
kono
parents:
diff changeset
1616 && DECL_NAME (decl) == ctor_identifier)
kono
parents:
diff changeset
1617 : (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)
kono
parents:
diff changeset
1618 && DECL_NAME (decl) == dtor_identifier));
kono
parents:
diff changeset
1619
kono
parents:
diff changeset
1620 while (decl && DECL_NAME (decl) != identifier)
kono
parents:
diff changeset
1621 {
kono
parents:
diff changeset
1622 decl = DECL_CHAIN (decl);
kono
parents:
diff changeset
1623 if (decl && !DECL_CLONED_FUNCTION_P (decl))
kono
parents:
diff changeset
1624 decl = NULL_TREE;
kono
parents:
diff changeset
1625 }
kono
parents:
diff changeset
1626 gcc_assert (decl);
kono
parents:
diff changeset
1627
kono
parents:
diff changeset
1628 record_decl_address (ctx, build_decl_addr_value (decl, address));
kono
parents:
diff changeset
1629
kono
parents:
diff changeset
1630 return convert_out (decl);
kono
parents:
diff changeset
1631 }
kono
parents:
diff changeset
1632
kono
parents:
diff changeset
1633 int
kono
parents:
diff changeset
1634 plugin_add_friend (cc1_plugin::connection * /* self */,
kono
parents:
diff changeset
1635 gcc_decl decl_in,
kono
parents:
diff changeset
1636 gcc_type type_in)
kono
parents:
diff changeset
1637 {
kono
parents:
diff changeset
1638 tree decl = convert_in (decl_in);
kono
parents:
diff changeset
1639 tree type = convert_in (type_in);
kono
parents:
diff changeset
1640
kono
parents:
diff changeset
1641 gcc_assert (type || at_class_scope_p ());
kono
parents:
diff changeset
1642
kono
parents:
diff changeset
1643 if (!type)
kono
parents:
diff changeset
1644 type = current_class_type;
kono
parents:
diff changeset
1645 else
kono
parents:
diff changeset
1646 gcc_assert (TREE_CODE (type) == RECORD_TYPE);
kono
parents:
diff changeset
1647
kono
parents:
diff changeset
1648 if (TYPE_P (decl))
kono
parents:
diff changeset
1649 make_friend_class (type, TREE_TYPE (decl), true);
kono
parents:
diff changeset
1650 else
kono
parents:
diff changeset
1651 {
kono
parents:
diff changeset
1652 DECL_FRIEND_P (decl) = true;
kono
parents:
diff changeset
1653 add_friend (type, decl, true);
kono
parents:
diff changeset
1654 }
kono
parents:
diff changeset
1655
kono
parents:
diff changeset
1656 return 1;
kono
parents:
diff changeset
1657 }
kono
parents:
diff changeset
1658
kono
parents:
diff changeset
1659 gcc_type
kono
parents:
diff changeset
1660 plugin_build_pointer_type (cc1_plugin::connection *,
kono
parents:
diff changeset
1661 gcc_type base_type)
kono
parents:
diff changeset
1662 {
kono
parents:
diff changeset
1663 // No need to preserve a pointer type as the base type is preserved.
kono
parents:
diff changeset
1664 return convert_out (build_pointer_type (convert_in (base_type)));
kono
parents:
diff changeset
1665 }
kono
parents:
diff changeset
1666
kono
parents:
diff changeset
1667 gcc_type
kono
parents:
diff changeset
1668 plugin_build_reference_type (cc1_plugin::connection *,
kono
parents:
diff changeset
1669 gcc_type base_type_in,
kono
parents:
diff changeset
1670 enum gcc_cp_ref_qualifiers rquals)
kono
parents:
diff changeset
1671 {
kono
parents:
diff changeset
1672 bool rval;
kono
parents:
diff changeset
1673
kono
parents:
diff changeset
1674 switch (rquals)
kono
parents:
diff changeset
1675 {
kono
parents:
diff changeset
1676 case GCC_CP_REF_QUAL_LVALUE:
kono
parents:
diff changeset
1677 rval = false;
kono
parents:
diff changeset
1678 break;
kono
parents:
diff changeset
1679 case GCC_CP_REF_QUAL_RVALUE:
kono
parents:
diff changeset
1680 rval = true;
kono
parents:
diff changeset
1681 break;
kono
parents:
diff changeset
1682 case GCC_CP_REF_QUAL_NONE:
kono
parents:
diff changeset
1683 default:
kono
parents:
diff changeset
1684 gcc_unreachable ();
kono
parents:
diff changeset
1685 }
kono
parents:
diff changeset
1686
kono
parents:
diff changeset
1687 tree rtype = cp_build_reference_type (convert_in (base_type_in), rval);
kono
parents:
diff changeset
1688
kono
parents:
diff changeset
1689 return convert_out (rtype);
kono
parents:
diff changeset
1690 }
kono
parents:
diff changeset
1691
kono
parents:
diff changeset
1692 static tree
kono
parents:
diff changeset
1693 start_class_def (tree type,
kono
parents:
diff changeset
1694 const gcc_vbase_array *base_classes)
kono
parents:
diff changeset
1695 {
kono
parents:
diff changeset
1696 tree bases = NULL;
kono
parents:
diff changeset
1697 if (base_classes)
kono
parents:
diff changeset
1698 {
kono
parents:
diff changeset
1699 for (int i = 0; i < base_classes->n_elements; i++)
kono
parents:
diff changeset
1700 {
kono
parents:
diff changeset
1701 tree access;
kono
parents:
diff changeset
1702
kono
parents:
diff changeset
1703 gcc_assert ((base_classes->flags[i] & GCC_CP_SYMBOL_MASK)
kono
parents:
diff changeset
1704 == GCC_CP_SYMBOL_BASECLASS);
kono
parents:
diff changeset
1705
kono
parents:
diff changeset
1706 switch (base_classes->flags[i] & GCC_CP_ACCESS_MASK)
kono
parents:
diff changeset
1707 {
kono
parents:
diff changeset
1708 case GCC_CP_ACCESS_PRIVATE:
kono
parents:
diff changeset
1709 access = ridpointers[(int)RID_PRIVATE];
kono
parents:
diff changeset
1710 break;
kono
parents:
diff changeset
1711
kono
parents:
diff changeset
1712 case GCC_CP_ACCESS_PROTECTED:
kono
parents:
diff changeset
1713 access = ridpointers[(int)RID_PROTECTED];
kono
parents:
diff changeset
1714 break;
kono
parents:
diff changeset
1715
kono
parents:
diff changeset
1716 case GCC_CP_ACCESS_PUBLIC:
kono
parents:
diff changeset
1717 access = ridpointers[(int)RID_PUBLIC];
kono
parents:
diff changeset
1718 break;
kono
parents:
diff changeset
1719
kono
parents:
diff changeset
1720 default:
kono
parents:
diff changeset
1721 gcc_unreachable ();
kono
parents:
diff changeset
1722 }
kono
parents:
diff changeset
1723
kono
parents:
diff changeset
1724 tree base = finish_base_specifier
kono
parents:
diff changeset
1725 (convert_in (base_classes->elements[i]), access,
kono
parents:
diff changeset
1726 (base_classes->flags[i] & GCC_CP_FLAG_BASECLASS_VIRTUAL) != 0);
kono
parents:
diff changeset
1727 TREE_CHAIN (base) = bases;
kono
parents:
diff changeset
1728 bases = base;
kono
parents:
diff changeset
1729 }
kono
parents:
diff changeset
1730 bases = nreverse (bases);
kono
parents:
diff changeset
1731 }
kono
parents:
diff changeset
1732 xref_basetypes (type, bases);
kono
parents:
diff changeset
1733 begin_class_definition (type);
kono
parents:
diff changeset
1734 return type;
kono
parents:
diff changeset
1735 }
kono
parents:
diff changeset
1736
kono
parents:
diff changeset
1737 gcc_type
kono
parents:
diff changeset
1738 plugin_start_class_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
1739 gcc_decl typedecl_in,
kono
parents:
diff changeset
1740 const gcc_vbase_array *base_classes,
kono
parents:
diff changeset
1741 const char *filename,
kono
parents:
diff changeset
1742 unsigned int line_number)
kono
parents:
diff changeset
1743 {
kono
parents:
diff changeset
1744 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
1745 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
1746 tree typedecl = convert_in (typedecl_in);
kono
parents:
diff changeset
1747 tree type = TREE_TYPE (typedecl);
kono
parents:
diff changeset
1748
kono
parents:
diff changeset
1749 gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (type)));
kono
parents:
diff changeset
1750 gcc_assert (!COMPLETE_TYPE_P (type));
kono
parents:
diff changeset
1751
kono
parents:
diff changeset
1752 DECL_SOURCE_LOCATION (typedecl) = loc;
kono
parents:
diff changeset
1753
kono
parents:
diff changeset
1754 tree result = start_class_def (type, base_classes);
kono
parents:
diff changeset
1755
kono
parents:
diff changeset
1756 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
1757 }
kono
parents:
diff changeset
1758
kono
parents:
diff changeset
1759 gcc_type
kono
parents:
diff changeset
1760 plugin_start_closure_class_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
1761 int discriminator,
kono
parents:
diff changeset
1762 gcc_decl extra_scope_in,
kono
parents:
diff changeset
1763 enum gcc_cp_symbol_kind flags,
kono
parents:
diff changeset
1764 const char *filename,
kono
parents:
diff changeset
1765 unsigned int line_number)
kono
parents:
diff changeset
1766 {
kono
parents:
diff changeset
1767 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
1768 tree extra_scope = convert_in (extra_scope_in);
kono
parents:
diff changeset
1769
kono
parents:
diff changeset
1770 gcc_assert ((flags & GCC_CP_SYMBOL_MASK) == GCC_CP_SYMBOL_LAMBDA_CLOSURE);
kono
parents:
diff changeset
1771 gcc_assert ((flags & (~(GCC_CP_SYMBOL_MASK | GCC_CP_ACCESS_MASK))) == 0);
kono
parents:
diff changeset
1772
kono
parents:
diff changeset
1773 gcc_assert (!(flags & GCC_CP_ACCESS_MASK) == !at_class_scope_p ());
kono
parents:
diff changeset
1774
kono
parents:
diff changeset
1775 /* See at_fake_function_scope_p. */
kono
parents:
diff changeset
1776 gcc_assert (!at_function_scope_p ());
kono
parents:
diff changeset
1777
kono
parents:
diff changeset
1778 if (extra_scope)
kono
parents:
diff changeset
1779 {
kono
parents:
diff changeset
1780 if (TREE_CODE (extra_scope) == PARM_DECL)
kono
parents:
diff changeset
1781 {
kono
parents:
diff changeset
1782 gcc_assert (at_fake_function_scope_p ());
kono
parents:
diff changeset
1783 /* Check that the given extra_scope is one of the parameters of
kono
parents:
diff changeset
1784 the current function. */
kono
parents:
diff changeset
1785 for (tree parm = DECL_ARGUMENTS (current_function_decl);
kono
parents:
diff changeset
1786 ; parm = DECL_CHAIN (parm))
kono
parents:
diff changeset
1787 {
kono
parents:
diff changeset
1788 gcc_assert (parm);
kono
parents:
diff changeset
1789 if (parm == extra_scope)
kono
parents:
diff changeset
1790 break;
kono
parents:
diff changeset
1791 }
kono
parents:
diff changeset
1792 }
kono
parents:
diff changeset
1793 else if (TREE_CODE (extra_scope) == FIELD_DECL)
kono
parents:
diff changeset
1794 {
kono
parents:
diff changeset
1795 gcc_assert (at_class_scope_p ());
kono
parents:
diff changeset
1796 gcc_assert (DECL_CONTEXT (extra_scope) == current_class_type);
kono
parents:
diff changeset
1797 }
kono
parents:
diff changeset
1798 else
kono
parents:
diff changeset
1799 /* FIXME: does this ever really occur? */
kono
parents:
diff changeset
1800 gcc_assert (TREE_CODE (extra_scope) == VAR_DECL);
kono
parents:
diff changeset
1801 }
kono
parents:
diff changeset
1802
kono
parents:
diff changeset
1803 tree lambda_expr = build_lambda_expr ();
kono
parents:
diff changeset
1804
kono
parents:
diff changeset
1805 LAMBDA_EXPR_LOCATION (lambda_expr) = ctx->get_source_location (filename,
kono
parents:
diff changeset
1806 line_number);
kono
parents:
diff changeset
1807
kono
parents:
diff changeset
1808 tree type = begin_lambda_type (lambda_expr);
kono
parents:
diff changeset
1809
kono
parents:
diff changeset
1810 /* Instead of calling record_lambda_scope, do this: */
kono
parents:
diff changeset
1811 LAMBDA_EXPR_EXTRA_SCOPE (lambda_expr) = extra_scope;
kono
parents:
diff changeset
1812 LAMBDA_EXPR_DISCRIMINATOR (lambda_expr) = discriminator;
kono
parents:
diff changeset
1813
kono
parents:
diff changeset
1814 tree decl = TYPE_NAME (type);
kono
parents:
diff changeset
1815 determine_visibility (decl);
kono
parents:
diff changeset
1816 set_access_flags (decl, flags);
kono
parents:
diff changeset
1817
kono
parents:
diff changeset
1818 return convert_out (ctx->preserve (type));
kono
parents:
diff changeset
1819 }
kono
parents:
diff changeset
1820
kono
parents:
diff changeset
1821 gcc_expr
kono
parents:
diff changeset
1822 plugin_build_lambda_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
1823 gcc_type closure_type_in)
kono
parents:
diff changeset
1824 {
kono
parents:
diff changeset
1825 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
1826 tree closure_type = convert_in (closure_type_in);
kono
parents:
diff changeset
1827
kono
parents:
diff changeset
1828 gcc_assert (LAMBDA_TYPE_P (closure_type));
kono
parents:
diff changeset
1829
kono
parents:
diff changeset
1830 tree lambda_expr = CLASSTYPE_LAMBDA_EXPR (closure_type);
kono
parents:
diff changeset
1831
kono
parents:
diff changeset
1832 tree lambda_object = build_lambda_object (lambda_expr);
kono
parents:
diff changeset
1833
kono
parents:
diff changeset
1834 return convert_out (ctx->preserve (lambda_object));
kono
parents:
diff changeset
1835 }
kono
parents:
diff changeset
1836
kono
parents:
diff changeset
1837 gcc_decl
kono
parents:
diff changeset
1838 plugin_build_field (cc1_plugin::connection *,
kono
parents:
diff changeset
1839 const char *field_name,
kono
parents:
diff changeset
1840 gcc_type field_type_in,
kono
parents:
diff changeset
1841 enum gcc_cp_symbol_kind flags,
kono
parents:
diff changeset
1842 unsigned long bitsize,
kono
parents:
diff changeset
1843 unsigned long bitpos)
kono
parents:
diff changeset
1844 {
kono
parents:
diff changeset
1845 tree record_or_union_type = current_class_type;
kono
parents:
diff changeset
1846 tree field_type = convert_in (field_type_in);
kono
parents:
diff changeset
1847
kono
parents:
diff changeset
1848 gcc_assert (at_class_scope_p ());
kono
parents:
diff changeset
1849 gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (record_or_union_type)));
kono
parents:
diff changeset
1850 gcc_assert ((flags & GCC_CP_SYMBOL_MASK) == GCC_CP_SYMBOL_FIELD);
kono
parents:
diff changeset
1851 gcc_assert ((flags & (~(GCC_CP_SYMBOL_MASK | GCC_CP_ACCESS_MASK
kono
parents:
diff changeset
1852 | GCC_CP_FLAG_MASK_FIELD))) == 0);
kono
parents:
diff changeset
1853 gcc_assert ((flags & GCC_CP_ACCESS_MASK));
kono
parents:
diff changeset
1854
kono
parents:
diff changeset
1855 /* Note that gdb does not preserve the location of field decls, so
kono
parents:
diff changeset
1856 we can't provide a decent location here. */
kono
parents:
diff changeset
1857 tree decl = build_decl (BUILTINS_LOCATION, FIELD_DECL,
kono
parents:
diff changeset
1858 get_identifier (field_name), field_type);
kono
parents:
diff changeset
1859 DECL_FIELD_CONTEXT (decl) = record_or_union_type;
kono
parents:
diff changeset
1860
kono
parents:
diff changeset
1861 set_access_flags (decl, flags);
kono
parents:
diff changeset
1862
kono
parents:
diff changeset
1863 if ((flags & GCC_CP_FLAG_FIELD_MUTABLE) != 0)
kono
parents:
diff changeset
1864 DECL_MUTABLE_P (decl) = 1;
kono
parents:
diff changeset
1865
kono
parents:
diff changeset
1866 if (TREE_CODE (field_type) == INTEGER_TYPE
kono
parents:
diff changeset
1867 && TYPE_PRECISION (field_type) != bitsize)
kono
parents:
diff changeset
1868 {
kono
parents:
diff changeset
1869 DECL_BIT_FIELD_TYPE (decl) = field_type;
kono
parents:
diff changeset
1870 TREE_TYPE (decl)
kono
parents:
diff changeset
1871 = c_build_bitfield_integer_type (bitsize, TYPE_UNSIGNED (field_type));
kono
parents:
diff changeset
1872 }
kono
parents:
diff changeset
1873
kono
parents:
diff changeset
1874 SET_DECL_MODE (decl, TYPE_MODE (TREE_TYPE (decl)));
kono
parents:
diff changeset
1875
kono
parents:
diff changeset
1876 // There's no way to recover this from DWARF.
kono
parents:
diff changeset
1877 SET_DECL_OFFSET_ALIGN (decl, TYPE_PRECISION (pointer_sized_int_node));
kono
parents:
diff changeset
1878
kono
parents:
diff changeset
1879 tree pos = bitsize_int (bitpos);
kono
parents:
diff changeset
1880 pos_from_bit (&DECL_FIELD_OFFSET (decl), &DECL_FIELD_BIT_OFFSET (decl),
kono
parents:
diff changeset
1881 DECL_OFFSET_ALIGN (decl), pos);
kono
parents:
diff changeset
1882
kono
parents:
diff changeset
1883 DECL_SIZE (decl) = bitsize_int (bitsize);
kono
parents:
diff changeset
1884 DECL_SIZE_UNIT (decl) = size_int ((bitsize + BITS_PER_UNIT - 1)
kono
parents:
diff changeset
1885 / BITS_PER_UNIT);
kono
parents:
diff changeset
1886
kono
parents:
diff changeset
1887 DECL_CHAIN (decl) = TYPE_FIELDS (record_or_union_type);
kono
parents:
diff changeset
1888 TYPE_FIELDS (record_or_union_type) = decl;
kono
parents:
diff changeset
1889
kono
parents:
diff changeset
1890 return convert_out (decl);
kono
parents:
diff changeset
1891 }
kono
parents:
diff changeset
1892
kono
parents:
diff changeset
1893 int
kono
parents:
diff changeset
1894 plugin_finish_class_type (cc1_plugin::connection *,
kono
parents:
diff changeset
1895 unsigned long size_in_bytes)
kono
parents:
diff changeset
1896 {
kono
parents:
diff changeset
1897 tree record_or_union_type = current_class_type;
kono
parents:
diff changeset
1898
kono
parents:
diff changeset
1899 gcc_assert (RECORD_OR_UNION_CODE_P (TREE_CODE (record_or_union_type)));
kono
parents:
diff changeset
1900
kono
parents:
diff changeset
1901 finish_struct (record_or_union_type, NULL);
kono
parents:
diff changeset
1902
kono
parents:
diff changeset
1903 gcc_assert (compare_tree_int (TYPE_SIZE_UNIT (record_or_union_type),
kono
parents:
diff changeset
1904 size_in_bytes) == 0);
kono
parents:
diff changeset
1905
kono
parents:
diff changeset
1906 return 1;
kono
parents:
diff changeset
1907 }
kono
parents:
diff changeset
1908
kono
parents:
diff changeset
1909 gcc_type
kono
parents:
diff changeset
1910 plugin_start_enum_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
1911 const char *name,
kono
parents:
diff changeset
1912 gcc_type underlying_int_type_in,
kono
parents:
diff changeset
1913 enum gcc_cp_symbol_kind flags,
kono
parents:
diff changeset
1914 const char *filename,
kono
parents:
diff changeset
1915 unsigned int line_number)
kono
parents:
diff changeset
1916 {
kono
parents:
diff changeset
1917 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
1918 tree underlying_int_type = convert_in (underlying_int_type_in);
kono
parents:
diff changeset
1919
kono
parents:
diff changeset
1920 gcc_assert ((flags & GCC_CP_SYMBOL_MASK) == GCC_CP_SYMBOL_ENUM);
kono
parents:
diff changeset
1921 gcc_assert ((flags & (~(GCC_CP_SYMBOL_MASK | GCC_CP_ACCESS_MASK
kono
parents:
diff changeset
1922 | GCC_CP_FLAG_MASK_ENUM))) == 0);
kono
parents:
diff changeset
1923 gcc_assert (!(flags & GCC_CP_ACCESS_MASK) == !at_class_scope_p ());
kono
parents:
diff changeset
1924
kono
parents:
diff changeset
1925 if (underlying_int_type == error_mark_node)
kono
parents:
diff changeset
1926 return convert_out (error_mark_node);
kono
parents:
diff changeset
1927
kono
parents:
diff changeset
1928 bool is_new_type = false;
kono
parents:
diff changeset
1929
kono
parents:
diff changeset
1930 tree id = name ? get_identifier (name) : make_anon_name ();
kono
parents:
diff changeset
1931
kono
parents:
diff changeset
1932 tree type = start_enum (id, NULL_TREE,
kono
parents:
diff changeset
1933 underlying_int_type,
kono
parents:
diff changeset
1934 /* attributes = */ NULL_TREE,
kono
parents:
diff changeset
1935 !!(flags & GCC_CP_FLAG_ENUM_SCOPED), &is_new_type);
kono
parents:
diff changeset
1936
kono
parents:
diff changeset
1937 gcc_assert (is_new_type);
kono
parents:
diff changeset
1938
kono
parents:
diff changeset
1939 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
1940 tree type_decl = TYPE_NAME (type);
kono
parents:
diff changeset
1941 DECL_SOURCE_LOCATION (type_decl) = loc;
kono
parents:
diff changeset
1942 SET_OPAQUE_ENUM_P (type, false);
kono
parents:
diff changeset
1943
kono
parents:
diff changeset
1944 set_access_flags (type_decl, flags);
kono
parents:
diff changeset
1945
kono
parents:
diff changeset
1946 return convert_out (ctx->preserve (type));
kono
parents:
diff changeset
1947 }
kono
parents:
diff changeset
1948
kono
parents:
diff changeset
1949 gcc_decl
kono
parents:
diff changeset
1950 plugin_build_enum_constant (cc1_plugin::connection *,
kono
parents:
diff changeset
1951 gcc_type enum_type_in,
kono
parents:
diff changeset
1952 const char *name,
kono
parents:
diff changeset
1953 unsigned long value)
kono
parents:
diff changeset
1954 {
kono
parents:
diff changeset
1955 tree enum_type = convert_in (enum_type_in);
kono
parents:
diff changeset
1956
kono
parents:
diff changeset
1957 gcc_assert (TREE_CODE (enum_type) == ENUMERAL_TYPE);
kono
parents:
diff changeset
1958
kono
parents:
diff changeset
1959 build_enumerator (get_identifier (name), build_int_cst (enum_type, value),
kono
parents:
diff changeset
1960 enum_type, NULL_TREE, BUILTINS_LOCATION);
kono
parents:
diff changeset
1961
kono
parents:
diff changeset
1962 return convert_out (TREE_VALUE (TYPE_VALUES (enum_type)));
kono
parents:
diff changeset
1963 }
kono
parents:
diff changeset
1964
kono
parents:
diff changeset
1965 int
kono
parents:
diff changeset
1966 plugin_finish_enum_type (cc1_plugin::connection *,
kono
parents:
diff changeset
1967 gcc_type enum_type_in)
kono
parents:
diff changeset
1968 {
kono
parents:
diff changeset
1969 tree enum_type = convert_in (enum_type_in);
kono
parents:
diff changeset
1970
kono
parents:
diff changeset
1971 finish_enum_value_list (enum_type);
kono
parents:
diff changeset
1972 finish_enum (enum_type);
kono
parents:
diff changeset
1973
kono
parents:
diff changeset
1974 return 1;
kono
parents:
diff changeset
1975 }
kono
parents:
diff changeset
1976
kono
parents:
diff changeset
1977 gcc_type
kono
parents:
diff changeset
1978 plugin_build_function_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
1979 gcc_type return_type_in,
kono
parents:
diff changeset
1980 const struct gcc_type_array *argument_types_in,
kono
parents:
diff changeset
1981 int is_varargs)
kono
parents:
diff changeset
1982 {
kono
parents:
diff changeset
1983 tree *argument_types;
kono
parents:
diff changeset
1984 tree return_type = convert_in (return_type_in);
kono
parents:
diff changeset
1985 tree result;
kono
parents:
diff changeset
1986
kono
parents:
diff changeset
1987 argument_types = new tree[argument_types_in->n_elements];
kono
parents:
diff changeset
1988 for (int i = 0; i < argument_types_in->n_elements; ++i)
kono
parents:
diff changeset
1989 argument_types[i] = convert_in (argument_types_in->elements[i]);
kono
parents:
diff changeset
1990
kono
parents:
diff changeset
1991 if (is_varargs)
kono
parents:
diff changeset
1992 result = build_varargs_function_type_array (return_type,
kono
parents:
diff changeset
1993 argument_types_in->n_elements,
kono
parents:
diff changeset
1994 argument_types);
kono
parents:
diff changeset
1995 else
kono
parents:
diff changeset
1996 result = build_function_type_array (return_type,
kono
parents:
diff changeset
1997 argument_types_in->n_elements,
kono
parents:
diff changeset
1998 argument_types);
kono
parents:
diff changeset
1999
kono
parents:
diff changeset
2000 delete[] argument_types;
kono
parents:
diff changeset
2001
kono
parents:
diff changeset
2002 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2003 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
2004 }
kono
parents:
diff changeset
2005
kono
parents:
diff changeset
2006 #if 0
kono
parents:
diff changeset
2007
kono
parents:
diff changeset
2008 gcc_type
kono
parents:
diff changeset
2009 plugin_add_function_default_args (cc1_plugin::connection *self,
kono
parents:
diff changeset
2010 gcc_type function_type_in,
kono
parents:
diff changeset
2011 const struct gcc_cp_function_args *defaults)
kono
parents:
diff changeset
2012 {
kono
parents:
diff changeset
2013 tree function_type = convert_in (function_type_in);
kono
parents:
diff changeset
2014
kono
parents:
diff changeset
2015 gcc_assert (TREE_CODE (function_type) == FUNCTION_TYPE);
kono
parents:
diff changeset
2016
kono
parents:
diff changeset
2017 if (!defaults || !defaults->n_elements)
kono
parents:
diff changeset
2018 return function_type_in;
kono
parents:
diff changeset
2019
kono
parents:
diff changeset
2020 tree pargs = TYPE_ARG_TYPES (function_type);
kono
parents:
diff changeset
2021 tree nargs = NULL_TREE;
kono
parents:
diff changeset
2022
kono
parents:
diff changeset
2023 /* Build a reversed copy of the list of default-less arguments in
kono
parents:
diff changeset
2024 NARGS. At the end of the loop, PARGS will point to the end of
kono
parents:
diff changeset
2025 the argument list, or to the first argument that had a default
kono
parents:
diff changeset
2026 value. */
kono
parents:
diff changeset
2027 while (pargs && TREE_VALUE (pargs) != void_list_node
kono
parents:
diff changeset
2028 && !TREE_PURPOSE (pargs))
kono
parents:
diff changeset
2029 {
kono
parents:
diff changeset
2030 nargs = tree_cons (NULL_TREE, TREE_VALUE (pargs), nargs);
kono
parents:
diff changeset
2031 pargs = TREE_CHAIN (pargs);
kono
parents:
diff changeset
2032 }
kono
parents:
diff changeset
2033
kono
parents:
diff changeset
2034 /* Set the defaults in the now-leading NARGS, taking into account
kono
parents:
diff changeset
2035 that NARGS is reversed but DEFAULTS->elements isn't. */
kono
parents:
diff changeset
2036 tree ndargs = nargs;
kono
parents:
diff changeset
2037 int i = defaults->n_elements;
kono
parents:
diff changeset
2038 while (i--)
kono
parents:
diff changeset
2039 {
kono
parents:
diff changeset
2040 gcc_assert (ndargs);
kono
parents:
diff changeset
2041 tree deflt = convert_in (defaults->elements[i]);
kono
parents:
diff changeset
2042 if (!deflt)
kono
parents:
diff changeset
2043 deflt = error_mark_node;
kono
parents:
diff changeset
2044 TREE_PURPOSE (ndargs) = deflt;
kono
parents:
diff changeset
2045 ndargs = TREE_CHAIN (ndargs);
kono
parents:
diff changeset
2046 }
kono
parents:
diff changeset
2047
kono
parents:
diff changeset
2048 /* Finally, reverse NARGS, and append the remaining PARGS that
kono
parents:
diff changeset
2049 already had defaults. */
kono
parents:
diff changeset
2050 nargs = nreverse (nargs);
kono
parents:
diff changeset
2051 nargs = chainon (nargs, pargs);
kono
parents:
diff changeset
2052
kono
parents:
diff changeset
2053 tree result = build_function_type (TREE_TYPE (function_type), nargs);
kono
parents:
diff changeset
2054
kono
parents:
diff changeset
2055 /* Copy exceptions, attributes and whatnot. */
kono
parents:
diff changeset
2056 result = build_exception_variant (result,
kono
parents:
diff changeset
2057 TYPE_RAISES_EXCEPTIONS (function_type));
kono
parents:
diff changeset
2058 result = cp_build_type_attribute_variant (result,
kono
parents:
diff changeset
2059 TYPE_ATTRIBUTES (function_type));
kono
parents:
diff changeset
2060
kono
parents:
diff changeset
2061 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2062 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
2063 }
kono
parents:
diff changeset
2064
kono
parents:
diff changeset
2065 int
kono
parents:
diff changeset
2066 plugin_set_deferred_function_default_args (cc1_plugin::connection *,
kono
parents:
diff changeset
2067 gcc_decl function_in,
kono
parents:
diff changeset
2068 const struct gcc_cp_function_args
kono
parents:
diff changeset
2069 *defaults)
kono
parents:
diff changeset
2070 {
kono
parents:
diff changeset
2071 tree function = convert_in (function_in);
kono
parents:
diff changeset
2072
kono
parents:
diff changeset
2073 gcc_assert (TREE_CODE (function) == FUNCTION_DECL);
kono
parents:
diff changeset
2074
kono
parents:
diff changeset
2075 if (!defaults || !defaults->n_elements)
kono
parents:
diff changeset
2076 return 1;
kono
parents:
diff changeset
2077
kono
parents:
diff changeset
2078 tree arg = FUNCTION_FIRST_USER_PARMTYPE (function);
kono
parents:
diff changeset
2079
kono
parents:
diff changeset
2080 for (int i = 0; i < defaults->n_elements; i++)
kono
parents:
diff changeset
2081 {
kono
parents:
diff changeset
2082 while (arg && TREE_PURPOSE (arg) != error_mark_node)
kono
parents:
diff changeset
2083 arg = TREE_CHAIN (arg);
kono
parents:
diff changeset
2084
kono
parents:
diff changeset
2085 if (!arg)
kono
parents:
diff changeset
2086 return 0;
kono
parents:
diff changeset
2087
kono
parents:
diff changeset
2088 TREE_PURPOSE (arg) = convert_in (defaults->elements[i]);
kono
parents:
diff changeset
2089 arg = TREE_CHAIN (arg);
kono
parents:
diff changeset
2090 }
kono
parents:
diff changeset
2091
kono
parents:
diff changeset
2092 return 1;
kono
parents:
diff changeset
2093 }
kono
parents:
diff changeset
2094
kono
parents:
diff changeset
2095 #endif
kono
parents:
diff changeset
2096
kono
parents:
diff changeset
2097 gcc_decl
kono
parents:
diff changeset
2098 plugin_get_function_parameter_decl (cc1_plugin::connection *,
kono
parents:
diff changeset
2099 gcc_decl function_in,
kono
parents:
diff changeset
2100 int index)
kono
parents:
diff changeset
2101 {
kono
parents:
diff changeset
2102 tree function = convert_in (function_in);
kono
parents:
diff changeset
2103
kono
parents:
diff changeset
2104 gcc_assert (TREE_CODE (function) == FUNCTION_DECL);
kono
parents:
diff changeset
2105
kono
parents:
diff changeset
2106 if (index == -1)
kono
parents:
diff changeset
2107 {
kono
parents:
diff changeset
2108 gcc_assert (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE);
kono
parents:
diff changeset
2109
kono
parents:
diff changeset
2110 return convert_out (DECL_ARGUMENTS (function));
kono
parents:
diff changeset
2111 }
kono
parents:
diff changeset
2112
kono
parents:
diff changeset
2113 gcc_assert (index >= 0);
kono
parents:
diff changeset
2114
kono
parents:
diff changeset
2115 tree args = FUNCTION_FIRST_USER_PARM (function);
kono
parents:
diff changeset
2116
kono
parents:
diff changeset
2117 for (int i = 0; args && i < index; i++)
kono
parents:
diff changeset
2118 args = DECL_CHAIN (args);
kono
parents:
diff changeset
2119
kono
parents:
diff changeset
2120 return convert_out (args);
kono
parents:
diff changeset
2121 }
kono
parents:
diff changeset
2122
kono
parents:
diff changeset
2123 gcc_type
kono
parents:
diff changeset
2124 plugin_build_exception_spec_variant (cc1_plugin::connection *self,
kono
parents:
diff changeset
2125 gcc_type function_type_in,
kono
parents:
diff changeset
2126 const struct gcc_type_array *except_types_in)
kono
parents:
diff changeset
2127 {
kono
parents:
diff changeset
2128 tree function_type = convert_in (function_type_in);
kono
parents:
diff changeset
2129 tree except_types = NULL_TREE;
kono
parents:
diff changeset
2130
kono
parents:
diff changeset
2131 if (!except_types_in)
kono
parents:
diff changeset
2132 except_types = noexcept_false_spec;
kono
parents:
diff changeset
2133 else if (!except_types_in->n_elements)
kono
parents:
diff changeset
2134 except_types = empty_except_spec;
kono
parents:
diff changeset
2135 else
kono
parents:
diff changeset
2136 for (int i = 0; i < except_types_in->n_elements; i++)
kono
parents:
diff changeset
2137 except_types = add_exception_specifier (except_types,
kono
parents:
diff changeset
2138 convert_in
kono
parents:
diff changeset
2139 (except_types_in->elements[i]),
kono
parents:
diff changeset
2140 0);
kono
parents:
diff changeset
2141
kono
parents:
diff changeset
2142 function_type = build_exception_variant (function_type,
kono
parents:
diff changeset
2143 except_types);
kono
parents:
diff changeset
2144
kono
parents:
diff changeset
2145 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2146 return convert_out (ctx->preserve (function_type));
kono
parents:
diff changeset
2147 }
kono
parents:
diff changeset
2148
kono
parents:
diff changeset
2149 gcc_type
kono
parents:
diff changeset
2150 plugin_build_method_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
2151 gcc_type class_type_in,
kono
parents:
diff changeset
2152 gcc_type func_type_in,
kono
parents:
diff changeset
2153 enum gcc_cp_qualifiers quals_in,
kono
parents:
diff changeset
2154 enum gcc_cp_ref_qualifiers rquals_in)
kono
parents:
diff changeset
2155 {
kono
parents:
diff changeset
2156 tree class_type = convert_in (class_type_in);
kono
parents:
diff changeset
2157 tree func_type = convert_in (func_type_in);
kono
parents:
diff changeset
2158 cp_cv_quals quals = 0;
kono
parents:
diff changeset
2159 cp_ref_qualifier rquals;
kono
parents:
diff changeset
2160
kono
parents:
diff changeset
2161 if ((quals_in & GCC_CP_QUALIFIER_CONST) != 0)
kono
parents:
diff changeset
2162 quals |= TYPE_QUAL_CONST;
kono
parents:
diff changeset
2163 if ((quals_in & GCC_CP_QUALIFIER_VOLATILE) != 0)
kono
parents:
diff changeset
2164 quals |= TYPE_QUAL_VOLATILE;
kono
parents:
diff changeset
2165 gcc_assert ((quals_in & GCC_CP_QUALIFIER_RESTRICT) == 0);
kono
parents:
diff changeset
2166
kono
parents:
diff changeset
2167 switch (rquals_in)
kono
parents:
diff changeset
2168 {
kono
parents:
diff changeset
2169 case GCC_CP_REF_QUAL_NONE:
kono
parents:
diff changeset
2170 rquals = REF_QUAL_NONE;
kono
parents:
diff changeset
2171 break;
kono
parents:
diff changeset
2172 case GCC_CP_REF_QUAL_LVALUE:
kono
parents:
diff changeset
2173 rquals = REF_QUAL_LVALUE;
kono
parents:
diff changeset
2174 break;
kono
parents:
diff changeset
2175 case GCC_CP_REF_QUAL_RVALUE:
kono
parents:
diff changeset
2176 rquals = REF_QUAL_RVALUE;
kono
parents:
diff changeset
2177 break;
kono
parents:
diff changeset
2178 default:
kono
parents:
diff changeset
2179 gcc_unreachable ();
kono
parents:
diff changeset
2180 }
kono
parents:
diff changeset
2181
kono
parents:
diff changeset
2182 tree method_type = class_type
kono
parents:
diff changeset
2183 ? build_memfn_type (func_type, class_type, quals, rquals)
kono
parents:
diff changeset
2184 : apply_memfn_quals (func_type, quals, rquals);
kono
parents:
diff changeset
2185
kono
parents:
diff changeset
2186 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2187 return convert_out (ctx->preserve (method_type));
kono
parents:
diff changeset
2188 }
kono
parents:
diff changeset
2189
kono
parents:
diff changeset
2190 gcc_type
kono
parents:
diff changeset
2191 plugin_build_pointer_to_member_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
2192 gcc_type class_type_in,
kono
parents:
diff changeset
2193 gcc_type member_type_in)
kono
parents:
diff changeset
2194 {
kono
parents:
diff changeset
2195 tree class_type = convert_in (class_type_in);
kono
parents:
diff changeset
2196 tree member_type = convert_in (member_type_in);
kono
parents:
diff changeset
2197
kono
parents:
diff changeset
2198 tree memptr_type = build_ptrmem_type (class_type, member_type);
kono
parents:
diff changeset
2199
kono
parents:
diff changeset
2200 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2201 return convert_out (ctx->preserve (memptr_type));
kono
parents:
diff changeset
2202 }
kono
parents:
diff changeset
2203
kono
parents:
diff changeset
2204 int
kono
parents:
diff changeset
2205 plugin_start_template_decl (cc1_plugin::connection *)
kono
parents:
diff changeset
2206 {
kono
parents:
diff changeset
2207 begin_template_parm_list ();
kono
parents:
diff changeset
2208
kono
parents:
diff changeset
2209 TP_PARM_LIST = NULL_TREE;
kono
parents:
diff changeset
2210
kono
parents:
diff changeset
2211 return 1;
kono
parents:
diff changeset
2212 }
kono
parents:
diff changeset
2213
kono
parents:
diff changeset
2214 gcc_decl
kono
parents:
diff changeset
2215 plugin_get_type_decl (cc1_plugin::connection *,
kono
parents:
diff changeset
2216 gcc_type type_in)
kono
parents:
diff changeset
2217 {
kono
parents:
diff changeset
2218 tree type = convert_in (type_in);
kono
parents:
diff changeset
2219
kono
parents:
diff changeset
2220 tree name = TYPE_NAME (type);
kono
parents:
diff changeset
2221 gcc_assert (name);
kono
parents:
diff changeset
2222
kono
parents:
diff changeset
2223 return convert_out (name);
kono
parents:
diff changeset
2224 }
kono
parents:
diff changeset
2225
kono
parents:
diff changeset
2226 gcc_type
kono
parents:
diff changeset
2227 plugin_get_decl_type (cc1_plugin::connection *,
kono
parents:
diff changeset
2228 gcc_decl decl_in)
kono
parents:
diff changeset
2229 {
kono
parents:
diff changeset
2230 tree decl = convert_in (decl_in);
kono
parents:
diff changeset
2231
kono
parents:
diff changeset
2232 tree type = TREE_TYPE (decl);
kono
parents:
diff changeset
2233 gcc_assert (type);
kono
parents:
diff changeset
2234
kono
parents:
diff changeset
2235 return convert_out (type);
kono
parents:
diff changeset
2236 }
kono
parents:
diff changeset
2237
kono
parents:
diff changeset
2238 gcc_type
kono
parents:
diff changeset
2239 plugin_build_type_template_parameter (cc1_plugin::connection *self,
kono
parents:
diff changeset
2240 const char *id,
kono
parents:
diff changeset
2241 int /* bool */ pack_p,
kono
parents:
diff changeset
2242 gcc_type default_type,
kono
parents:
diff changeset
2243 const char *filename,
kono
parents:
diff changeset
2244 unsigned int line_number)
kono
parents:
diff changeset
2245 {
kono
parents:
diff changeset
2246 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2247 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
2248
kono
parents:
diff changeset
2249 gcc_assert (template_parm_scope_p ());
kono
parents:
diff changeset
2250
kono
parents:
diff changeset
2251 tree parm = finish_template_type_parm (class_type_node, get_identifier (id));
kono
parents:
diff changeset
2252 parm = build_tree_list (convert_in (default_type), parm);
kono
parents:
diff changeset
2253
kono
parents:
diff changeset
2254 gcc_assert (!(pack_p && default_type));
kono
parents:
diff changeset
2255
kono
parents:
diff changeset
2256 /* Create a type and a decl for the type parm, and add the decl to
kono
parents:
diff changeset
2257 TP_PARM_LIST. */
kono
parents:
diff changeset
2258 TP_PARM_LIST = process_template_parm (TP_PARM_LIST, loc, parm,
kono
parents:
diff changeset
2259 /* is_non_type = */ false, pack_p);
kono
parents:
diff changeset
2260
kono
parents:
diff changeset
2261 /* Locate the decl of the newly-added, processed template parm. */
kono
parents:
diff changeset
2262 parm = TREE_VALUE (tree_last (TP_PARM_LIST));
kono
parents:
diff changeset
2263
kono
parents:
diff changeset
2264 /* Return its type. */
kono
parents:
diff changeset
2265 return convert_out (ctx->preserve (TREE_TYPE (parm)));
kono
parents:
diff changeset
2266 }
kono
parents:
diff changeset
2267
kono
parents:
diff changeset
2268 gcc_utempl
kono
parents:
diff changeset
2269 plugin_build_template_template_parameter (cc1_plugin::connection *self,
kono
parents:
diff changeset
2270 const char *id,
kono
parents:
diff changeset
2271 int /* bool */ pack_p,
kono
parents:
diff changeset
2272 gcc_utempl default_templ,
kono
parents:
diff changeset
2273 const char *filename,
kono
parents:
diff changeset
2274 unsigned int line_number)
kono
parents:
diff changeset
2275 {
kono
parents:
diff changeset
2276 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2277 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
2278
kono
parents:
diff changeset
2279 gcc_assert (template_parm_scope_p ());
kono
parents:
diff changeset
2280
kono
parents:
diff changeset
2281 /* Finish the template parm list that started this template parm. */
kono
parents:
diff changeset
2282 end_template_parm_list (TP_PARM_LIST);
kono
parents:
diff changeset
2283
kono
parents:
diff changeset
2284 gcc_assert (template_parm_scope_p ());
kono
parents:
diff changeset
2285
kono
parents:
diff changeset
2286 tree parm = finish_template_template_parm (class_type_node,
kono
parents:
diff changeset
2287 get_identifier (id));
kono
parents:
diff changeset
2288 parm = build_tree_list (convert_in (default_templ), parm);
kono
parents:
diff changeset
2289
kono
parents:
diff changeset
2290 gcc_assert (!(pack_p && default_templ));
kono
parents:
diff changeset
2291
kono
parents:
diff changeset
2292 /* Create a type and a decl for the template parm, and add the decl
kono
parents:
diff changeset
2293 to TP_PARM_LIST. */
kono
parents:
diff changeset
2294 TP_PARM_LIST = process_template_parm (TP_PARM_LIST, loc, parm,
kono
parents:
diff changeset
2295 /* is_non_type = */ false, pack_p);
kono
parents:
diff changeset
2296
kono
parents:
diff changeset
2297 /* Locate the decl of the newly-added, processed template parm. */
kono
parents:
diff changeset
2298 parm = TREE_VALUE (tree_last (TP_PARM_LIST));
kono
parents:
diff changeset
2299
kono
parents:
diff changeset
2300 return convert_out (ctx->preserve (parm));
kono
parents:
diff changeset
2301 }
kono
parents:
diff changeset
2302
kono
parents:
diff changeset
2303 gcc_decl
kono
parents:
diff changeset
2304 plugin_build_value_template_parameter (cc1_plugin::connection *self,
kono
parents:
diff changeset
2305 gcc_type type,
kono
parents:
diff changeset
2306 const char *id,
kono
parents:
diff changeset
2307 gcc_expr default_value,
kono
parents:
diff changeset
2308 const char *filename,
kono
parents:
diff changeset
2309 unsigned int line_number)
kono
parents:
diff changeset
2310 {
kono
parents:
diff changeset
2311 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2312 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
2313
kono
parents:
diff changeset
2314 gcc_assert (template_parm_scope_p ());
kono
parents:
diff changeset
2315
kono
parents:
diff changeset
2316 cp_declarator declarator;
kono
parents:
diff changeset
2317 memset (&declarator, 0, sizeof (declarator));
kono
parents:
diff changeset
2318 // &declarator = make_id_declarator (NULL, get_identifier (id), sfk_none):
kono
parents:
diff changeset
2319 declarator.kind = cdk_id;
kono
parents:
diff changeset
2320 declarator.u.id.qualifying_scope = NULL;
kono
parents:
diff changeset
2321 declarator.u.id.unqualified_name = get_identifier (id);
kono
parents:
diff changeset
2322 declarator.u.id.sfk = sfk_none;
kono
parents:
diff changeset
2323
kono
parents:
diff changeset
2324 cp_decl_specifier_seq declspec;
kono
parents:
diff changeset
2325 memset (&declspec, 0, sizeof (declspec));
kono
parents:
diff changeset
2326 // cp_parser_set_decl_spec_type (&declspec, convert_in (type), -token-, false):
kono
parents:
diff changeset
2327 declspec.any_specifiers_p = declspec.any_type_specifiers_p = true;
kono
parents:
diff changeset
2328 declspec.type = convert_in (type);
kono
parents:
diff changeset
2329 declspec.locations[ds_type_spec] = loc;
kono
parents:
diff changeset
2330
kono
parents:
diff changeset
2331 tree parm = grokdeclarator (&declarator, &declspec, TPARM, 0, 0);
kono
parents:
diff changeset
2332 parm = build_tree_list (convert_in (default_value), parm);
kono
parents:
diff changeset
2333
kono
parents:
diff changeset
2334 /* Create a type and a decl for the template parm, and add the decl
kono
parents:
diff changeset
2335 to TP_PARM_LIST. */
kono
parents:
diff changeset
2336 TP_PARM_LIST = process_template_parm (TP_PARM_LIST, loc, parm,
kono
parents:
diff changeset
2337 /* is_non_type = */ true, false);
kono
parents:
diff changeset
2338
kono
parents:
diff changeset
2339 /* Locate the decl of the newly-added, processed template parm. */
kono
parents:
diff changeset
2340 parm = TREE_VALUE (tree_last (TP_PARM_LIST));
kono
parents:
diff changeset
2341
kono
parents:
diff changeset
2342 return convert_out (ctx->preserve (parm));
kono
parents:
diff changeset
2343 }
kono
parents:
diff changeset
2344
kono
parents:
diff changeset
2345 static tree
kono
parents:
diff changeset
2346 targlist (const gcc_cp_template_args *targs)
kono
parents:
diff changeset
2347 {
kono
parents:
diff changeset
2348 int n = targs->n_elements;
kono
parents:
diff changeset
2349 tree vec = make_tree_vec (n);
kono
parents:
diff changeset
2350 while (n--)
kono
parents:
diff changeset
2351 {
kono
parents:
diff changeset
2352 switch (targs->kinds[n])
kono
parents:
diff changeset
2353 {
kono
parents:
diff changeset
2354 case GCC_CP_TPARG_VALUE:
kono
parents:
diff changeset
2355 TREE_VEC_ELT (vec, n) = convert_in (targs->elements[n].value);
kono
parents:
diff changeset
2356 break;
kono
parents:
diff changeset
2357 case GCC_CP_TPARG_CLASS:
kono
parents:
diff changeset
2358 TREE_VEC_ELT (vec, n) = convert_in (targs->elements[n].type);
kono
parents:
diff changeset
2359 break;
kono
parents:
diff changeset
2360 case GCC_CP_TPARG_TEMPL:
kono
parents:
diff changeset
2361 TREE_VEC_ELT (vec, n) = convert_in (targs->elements[n].templ);
kono
parents:
diff changeset
2362 break;
kono
parents:
diff changeset
2363 case GCC_CP_TPARG_PACK:
kono
parents:
diff changeset
2364 TREE_VEC_ELT (vec, n) = convert_in (targs->elements[n].pack);
kono
parents:
diff changeset
2365 break;
kono
parents:
diff changeset
2366 default:
kono
parents:
diff changeset
2367 gcc_unreachable ();
kono
parents:
diff changeset
2368 }
kono
parents:
diff changeset
2369 }
kono
parents:
diff changeset
2370 return vec;
kono
parents:
diff changeset
2371 }
kono
parents:
diff changeset
2372
kono
parents:
diff changeset
2373 gcc_type
kono
parents:
diff changeset
2374 plugin_build_dependent_typename (cc1_plugin::connection *self,
kono
parents:
diff changeset
2375 gcc_type enclosing_type,
kono
parents:
diff changeset
2376 const char *id,
kono
parents:
diff changeset
2377 const gcc_cp_template_args *targs)
kono
parents:
diff changeset
2378 {
kono
parents:
diff changeset
2379 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2380 tree type = convert_in (enclosing_type);
kono
parents:
diff changeset
2381 tree name = get_identifier (id);
kono
parents:
diff changeset
2382 if (targs)
kono
parents:
diff changeset
2383 name = build_min_nt_loc (/*loc=*/0, TEMPLATE_ID_EXPR,
kono
parents:
diff changeset
2384 name, targlist (targs));
kono
parents:
diff changeset
2385 tree res = make_typename_type (type, name, typename_type,
kono
parents:
diff changeset
2386 /*complain=*/tf_error);
kono
parents:
diff changeset
2387 return convert_out (ctx->preserve (res));
kono
parents:
diff changeset
2388 }
kono
parents:
diff changeset
2389
kono
parents:
diff changeset
2390 gcc_utempl
kono
parents:
diff changeset
2391 plugin_build_dependent_class_template (cc1_plugin::connection *self,
kono
parents:
diff changeset
2392 gcc_type enclosing_type,
kono
parents:
diff changeset
2393 const char *id)
kono
parents:
diff changeset
2394 {
kono
parents:
diff changeset
2395 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2396 tree type = convert_in (enclosing_type);
kono
parents:
diff changeset
2397 tree name = get_identifier (id);
kono
parents:
diff changeset
2398 tree res = make_unbound_class_template (type, name, NULL_TREE,
kono
parents:
diff changeset
2399 /*complain=*/tf_error);
kono
parents:
diff changeset
2400 return convert_out (ctx->preserve (res));
kono
parents:
diff changeset
2401 }
kono
parents:
diff changeset
2402
kono
parents:
diff changeset
2403 gcc_type
kono
parents:
diff changeset
2404 plugin_build_dependent_type_template_id (cc1_plugin::connection *self,
kono
parents:
diff changeset
2405 gcc_utempl template_decl,
kono
parents:
diff changeset
2406 const gcc_cp_template_args *targs)
kono
parents:
diff changeset
2407 {
kono
parents:
diff changeset
2408 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2409 tree type = convert_in (template_decl);
kono
parents:
diff changeset
2410 tree decl = finish_template_type (type, targlist (targs),
kono
parents:
diff changeset
2411 /*entering_scope=*/false);
kono
parents:
diff changeset
2412 return convert_out (ctx->preserve (TREE_TYPE (decl)));
kono
parents:
diff changeset
2413 }
kono
parents:
diff changeset
2414
kono
parents:
diff changeset
2415 gcc_expr
kono
parents:
diff changeset
2416 plugin_build_dependent_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
2417 gcc_decl enclosing_scope,
kono
parents:
diff changeset
2418 enum gcc_cp_symbol_kind flags,
kono
parents:
diff changeset
2419 const char *name,
kono
parents:
diff changeset
2420 gcc_type conv_type_in,
kono
parents:
diff changeset
2421 const gcc_cp_template_args *targs)
kono
parents:
diff changeset
2422 {
kono
parents:
diff changeset
2423 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2424 tree scope = convert_in (enclosing_scope);
kono
parents:
diff changeset
2425 tree conv_type = convert_in (conv_type_in);
kono
parents:
diff changeset
2426 tree identifier;
kono
parents:
diff changeset
2427
kono
parents:
diff changeset
2428 if (TREE_CODE (scope) != NAMESPACE_DECL)
kono
parents:
diff changeset
2429 {
kono
parents:
diff changeset
2430 tree type = TREE_TYPE (scope);
kono
parents:
diff changeset
2431 gcc_assert (TYPE_NAME (type) == scope);
kono
parents:
diff changeset
2432 scope = type;
kono
parents:
diff changeset
2433 }
kono
parents:
diff changeset
2434
kono
parents:
diff changeset
2435 if (flags == (GCC_CP_SYMBOL_FUNCTION | GCC_CP_FLAG_SPECIAL_FUNCTION))
kono
parents:
diff changeset
2436 {
kono
parents:
diff changeset
2437 bool assop = false, convop = false;
kono
parents:
diff changeset
2438 tree_code opcode = ERROR_MARK;
kono
parents:
diff changeset
2439
kono
parents:
diff changeset
2440 switch (CHARS2 (name[0], name[1]))
kono
parents:
diff changeset
2441 {
kono
parents:
diff changeset
2442 case CHARS2 ('C', 0x0): // ctor base declaration
kono
parents:
diff changeset
2443 case CHARS2 ('C', ' '):
kono
parents:
diff changeset
2444 case CHARS2 ('C', '1'):
kono
parents:
diff changeset
2445 case CHARS2 ('C', '2'):
kono
parents:
diff changeset
2446 case CHARS2 ('C', '4'):
kono
parents:
diff changeset
2447 identifier = ctor_identifier;
kono
parents:
diff changeset
2448 break;
kono
parents:
diff changeset
2449 case CHARS2 ('D', 0x0): // dtor base declaration
kono
parents:
diff changeset
2450 case CHARS2 ('D', ' '):
kono
parents:
diff changeset
2451 case CHARS2 ('D', '0'):
kono
parents:
diff changeset
2452 case CHARS2 ('D', '1'):
kono
parents:
diff changeset
2453 case CHARS2 ('D', '2'):
kono
parents:
diff changeset
2454 case CHARS2 ('D', '4'):
kono
parents:
diff changeset
2455 gcc_assert (!targs);
kono
parents:
diff changeset
2456 identifier = dtor_identifier;
kono
parents:
diff changeset
2457 break;
kono
parents:
diff changeset
2458 case CHARS2 ('n', 'w'): // operator new
kono
parents:
diff changeset
2459 opcode = NEW_EXPR;
kono
parents:
diff changeset
2460 break;
kono
parents:
diff changeset
2461 case CHARS2 ('n', 'a'): // operator new[]
kono
parents:
diff changeset
2462 opcode = VEC_NEW_EXPR;
kono
parents:
diff changeset
2463 break;
kono
parents:
diff changeset
2464 case CHARS2 ('d', 'l'): // operator delete
kono
parents:
diff changeset
2465 opcode = DELETE_EXPR;
kono
parents:
diff changeset
2466 break;
kono
parents:
diff changeset
2467 case CHARS2 ('d', 'a'): // operator delete[]
kono
parents:
diff changeset
2468 opcode = VEC_DELETE_EXPR;
kono
parents:
diff changeset
2469 break;
kono
parents:
diff changeset
2470 case CHARS2 ('p', 's'): // operator + (unary)
kono
parents:
diff changeset
2471 opcode = PLUS_EXPR;
kono
parents:
diff changeset
2472 break;
kono
parents:
diff changeset
2473 case CHARS2 ('n', 'g'): // operator - (unary)
kono
parents:
diff changeset
2474 opcode = MINUS_EXPR;
kono
parents:
diff changeset
2475 break;
kono
parents:
diff changeset
2476 case CHARS2 ('a', 'd'): // operator & (unary)
kono
parents:
diff changeset
2477 opcode = BIT_AND_EXPR;
kono
parents:
diff changeset
2478 break;
kono
parents:
diff changeset
2479 case CHARS2 ('d', 'e'): // operator * (unary)
kono
parents:
diff changeset
2480 opcode = MULT_EXPR;
kono
parents:
diff changeset
2481 break;
kono
parents:
diff changeset
2482 case CHARS2 ('c', 'o'): // operator ~
kono
parents:
diff changeset
2483 opcode = BIT_NOT_EXPR;
kono
parents:
diff changeset
2484 break;
kono
parents:
diff changeset
2485 case CHARS2 ('p', 'l'): // operator +
kono
parents:
diff changeset
2486 opcode = PLUS_EXPR;
kono
parents:
diff changeset
2487 break;
kono
parents:
diff changeset
2488 case CHARS2 ('m', 'i'): // operator -
kono
parents:
diff changeset
2489 opcode = MINUS_EXPR;
kono
parents:
diff changeset
2490 break;
kono
parents:
diff changeset
2491 case CHARS2 ('m', 'l'): // operator *
kono
parents:
diff changeset
2492 opcode = MULT_EXPR;
kono
parents:
diff changeset
2493 break;
kono
parents:
diff changeset
2494 case CHARS2 ('d', 'v'): // operator /
kono
parents:
diff changeset
2495 opcode = TRUNC_DIV_EXPR;
kono
parents:
diff changeset
2496 break;
kono
parents:
diff changeset
2497 case CHARS2 ('r', 'm'): // operator %
kono
parents:
diff changeset
2498 opcode = TRUNC_MOD_EXPR;
kono
parents:
diff changeset
2499 break;
kono
parents:
diff changeset
2500 case CHARS2 ('a', 'n'): // operator &
kono
parents:
diff changeset
2501 opcode = BIT_AND_EXPR;
kono
parents:
diff changeset
2502 break;
kono
parents:
diff changeset
2503 case CHARS2 ('o', 'r'): // operator |
kono
parents:
diff changeset
2504 opcode = BIT_IOR_EXPR;
kono
parents:
diff changeset
2505 break;
kono
parents:
diff changeset
2506 case CHARS2 ('e', 'o'): // operator ^
kono
parents:
diff changeset
2507 opcode = BIT_XOR_EXPR;
kono
parents:
diff changeset
2508 break;
kono
parents:
diff changeset
2509 case CHARS2 ('a', 'S'): // operator =
kono
parents:
diff changeset
2510 opcode = NOP_EXPR;
kono
parents:
diff changeset
2511 assop = true;
kono
parents:
diff changeset
2512 break;
kono
parents:
diff changeset
2513 case CHARS2 ('p', 'L'): // operator +=
kono
parents:
diff changeset
2514 opcode = PLUS_EXPR;
kono
parents:
diff changeset
2515 assop = true;
kono
parents:
diff changeset
2516 break;
kono
parents:
diff changeset
2517 case CHARS2 ('m', 'I'): // operator -=
kono
parents:
diff changeset
2518 opcode = MINUS_EXPR;
kono
parents:
diff changeset
2519 assop = true;
kono
parents:
diff changeset
2520 break;
kono
parents:
diff changeset
2521 case CHARS2 ('m', 'L'): // operator *=
kono
parents:
diff changeset
2522 opcode = MULT_EXPR;
kono
parents:
diff changeset
2523 assop = true;
kono
parents:
diff changeset
2524 break;
kono
parents:
diff changeset
2525 case CHARS2 ('d', 'V'): // operator /=
kono
parents:
diff changeset
2526 opcode = TRUNC_DIV_EXPR;
kono
parents:
diff changeset
2527 assop = true;
kono
parents:
diff changeset
2528 break;
kono
parents:
diff changeset
2529 case CHARS2 ('r', 'M'): // operator %=
kono
parents:
diff changeset
2530 opcode = TRUNC_MOD_EXPR;
kono
parents:
diff changeset
2531 assop = true;
kono
parents:
diff changeset
2532 break;
kono
parents:
diff changeset
2533 case CHARS2 ('a', 'N'): // operator &=
kono
parents:
diff changeset
2534 opcode = BIT_AND_EXPR;
kono
parents:
diff changeset
2535 assop = true;
kono
parents:
diff changeset
2536 break;
kono
parents:
diff changeset
2537 case CHARS2 ('o', 'R'): // operator |=
kono
parents:
diff changeset
2538 opcode = BIT_IOR_EXPR;
kono
parents:
diff changeset
2539 assop = true;
kono
parents:
diff changeset
2540 break;
kono
parents:
diff changeset
2541 case CHARS2 ('e', 'O'): // operator ^=
kono
parents:
diff changeset
2542 opcode = BIT_XOR_EXPR;
kono
parents:
diff changeset
2543 assop = true;
kono
parents:
diff changeset
2544 break;
kono
parents:
diff changeset
2545 case CHARS2 ('l', 's'): // operator <<
kono
parents:
diff changeset
2546 opcode = LSHIFT_EXPR;
kono
parents:
diff changeset
2547 break;
kono
parents:
diff changeset
2548 case CHARS2 ('r', 's'): // operator >>
kono
parents:
diff changeset
2549 opcode = RSHIFT_EXPR;
kono
parents:
diff changeset
2550 break;
kono
parents:
diff changeset
2551 case CHARS2 ('l', 'S'): // operator <<=
kono
parents:
diff changeset
2552 opcode = LSHIFT_EXPR;
kono
parents:
diff changeset
2553 assop = true;
kono
parents:
diff changeset
2554 break;
kono
parents:
diff changeset
2555 case CHARS2 ('r', 'S'): // operator >>=
kono
parents:
diff changeset
2556 opcode = RSHIFT_EXPR;
kono
parents:
diff changeset
2557 assop = true;
kono
parents:
diff changeset
2558 break;
kono
parents:
diff changeset
2559 case CHARS2 ('e', 'q'): // operator ==
kono
parents:
diff changeset
2560 opcode = EQ_EXPR;
kono
parents:
diff changeset
2561 break;
kono
parents:
diff changeset
2562 case CHARS2 ('n', 'e'): // operator !=
kono
parents:
diff changeset
2563 opcode = NE_EXPR;
kono
parents:
diff changeset
2564 break;
kono
parents:
diff changeset
2565 case CHARS2 ('l', 't'): // operator <
kono
parents:
diff changeset
2566 opcode = LT_EXPR;
kono
parents:
diff changeset
2567 break;
kono
parents:
diff changeset
2568 case CHARS2 ('g', 't'): // operator >
kono
parents:
diff changeset
2569 opcode = GT_EXPR;
kono
parents:
diff changeset
2570 break;
kono
parents:
diff changeset
2571 case CHARS2 ('l', 'e'): // operator <=
kono
parents:
diff changeset
2572 opcode = LE_EXPR;
kono
parents:
diff changeset
2573 break;
kono
parents:
diff changeset
2574 case CHARS2 ('g', 'e'): // operator >=
kono
parents:
diff changeset
2575 opcode = GE_EXPR;
kono
parents:
diff changeset
2576 break;
kono
parents:
diff changeset
2577 case CHARS2 ('n', 't'): // operator !
kono
parents:
diff changeset
2578 opcode = TRUTH_NOT_EXPR;
kono
parents:
diff changeset
2579 break;
kono
parents:
diff changeset
2580 case CHARS2 ('a', 'a'): // operator &&
kono
parents:
diff changeset
2581 opcode = TRUTH_ANDIF_EXPR;
kono
parents:
diff changeset
2582 break;
kono
parents:
diff changeset
2583 case CHARS2 ('o', 'o'): // operator ||
kono
parents:
diff changeset
2584 opcode = TRUTH_ORIF_EXPR;
kono
parents:
diff changeset
2585 break;
kono
parents:
diff changeset
2586 case CHARS2 ('p', 'p'): // operator ++
kono
parents:
diff changeset
2587 opcode = POSTINCREMENT_EXPR;
kono
parents:
diff changeset
2588 break;
kono
parents:
diff changeset
2589 case CHARS2 ('m', 'm'): // operator --
kono
parents:
diff changeset
2590 opcode = PREDECREMENT_EXPR;
kono
parents:
diff changeset
2591 break;
kono
parents:
diff changeset
2592 case CHARS2 ('c', 'm'): // operator ,
kono
parents:
diff changeset
2593 opcode = COMPOUND_EXPR;
kono
parents:
diff changeset
2594 break;
kono
parents:
diff changeset
2595 case CHARS2 ('p', 'm'): // operator ->*
kono
parents:
diff changeset
2596 opcode = MEMBER_REF;
kono
parents:
diff changeset
2597 break;
kono
parents:
diff changeset
2598 case CHARS2 ('p', 't'): // operator ->
kono
parents:
diff changeset
2599 opcode = COMPONENT_REF;
kono
parents:
diff changeset
2600 break;
kono
parents:
diff changeset
2601 case CHARS2 ('c', 'l'): // operator ()
kono
parents:
diff changeset
2602 opcode = CALL_EXPR;
kono
parents:
diff changeset
2603 break;
kono
parents:
diff changeset
2604 case CHARS2 ('i', 'x'): // operator []
kono
parents:
diff changeset
2605 opcode = ARRAY_REF;
kono
parents:
diff changeset
2606 break;
kono
parents:
diff changeset
2607 case CHARS2 ('c', 'v'): // operator <T> (conversion operator)
kono
parents:
diff changeset
2608 convop = true;
kono
parents:
diff changeset
2609 identifier = make_conv_op_name (conv_type);
kono
parents:
diff changeset
2610 break;
kono
parents:
diff changeset
2611 // C++11-only:
kono
parents:
diff changeset
2612 case CHARS2 ('l', 'i'): // operator "" <id>
kono
parents:
diff changeset
2613 {
kono
parents:
diff changeset
2614 char *id = (char *)name + 2;
kono
parents:
diff changeset
2615 bool freeid = false;
kono
parents:
diff changeset
2616 if (*id >= '0' && *id <= '9')
kono
parents:
diff changeset
2617 {
kono
parents:
diff changeset
2618 unsigned len = 0;
kono
parents:
diff changeset
2619 do
kono
parents:
diff changeset
2620 {
kono
parents:
diff changeset
2621 len *= 10;
kono
parents:
diff changeset
2622 len += id[0] - '0';
kono
parents:
diff changeset
2623 id++;
kono
parents:
diff changeset
2624 }
kono
parents:
diff changeset
2625 while (*id && *id >= '0' && *id <= '9');
kono
parents:
diff changeset
2626 id = xstrndup (id, len);
kono
parents:
diff changeset
2627 freeid = true;
kono
parents:
diff changeset
2628 }
kono
parents:
diff changeset
2629 identifier = cp_literal_operator_id (id);
kono
parents:
diff changeset
2630 if (freeid)
kono
parents:
diff changeset
2631 free (id);
kono
parents:
diff changeset
2632 }
kono
parents:
diff changeset
2633 break;
kono
parents:
diff changeset
2634 case CHARS2 ('q', 'u'): // ternary operator, not overloadable.
kono
parents:
diff changeset
2635 default:
kono
parents:
diff changeset
2636 gcc_unreachable ();
kono
parents:
diff changeset
2637 }
kono
parents:
diff changeset
2638
kono
parents:
diff changeset
2639 gcc_assert (convop || !conv_type);
kono
parents:
diff changeset
2640
kono
parents:
diff changeset
2641 if (opcode != ERROR_MARK)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2642 identifier = ovl_op_identifier (assop, opcode);
111
kono
parents:
diff changeset
2643
kono
parents:
diff changeset
2644 gcc_assert (identifier);
kono
parents:
diff changeset
2645 }
kono
parents:
diff changeset
2646 else
kono
parents:
diff changeset
2647 {
kono
parents:
diff changeset
2648 gcc_assert (flags == GCC_CP_SYMBOL_MASK);
kono
parents:
diff changeset
2649 gcc_assert (!conv_type);
kono
parents:
diff changeset
2650 identifier = get_identifier (name);
kono
parents:
diff changeset
2651 }
kono
parents:
diff changeset
2652 tree res = identifier;
kono
parents:
diff changeset
2653 if (!scope)
kono
parents:
diff changeset
2654 res = lookup_name_real (res, 0, 0, true, 0, 0);
kono
parents:
diff changeset
2655 else if (!TYPE_P (scope) || !dependent_scope_p (scope))
kono
parents:
diff changeset
2656 {
kono
parents:
diff changeset
2657 res = lookup_qualified_name (scope, res, false, true);
kono
parents:
diff changeset
2658 /* We've already resolved the name in the scope, so skip the
kono
parents:
diff changeset
2659 build_qualified_name call below. */
kono
parents:
diff changeset
2660 scope = NULL;
kono
parents:
diff changeset
2661 }
kono
parents:
diff changeset
2662 if (targs)
kono
parents:
diff changeset
2663 res = lookup_template_function (res, targlist (targs));
kono
parents:
diff changeset
2664 if (scope)
kono
parents:
diff changeset
2665 res = build_qualified_name (NULL_TREE, scope, res, !!targs);
kono
parents:
diff changeset
2666 return convert_out (ctx->preserve (res));
kono
parents:
diff changeset
2667 }
kono
parents:
diff changeset
2668
kono
parents:
diff changeset
2669 gcc_expr
kono
parents:
diff changeset
2670 plugin_build_literal_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
2671 gcc_type type, unsigned long value)
kono
parents:
diff changeset
2672 {
kono
parents:
diff changeset
2673 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2674 tree t = convert_in (type);
kono
parents:
diff changeset
2675 tree val = build_int_cst_type (t, (unsigned HOST_WIDE_INT) value);
kono
parents:
diff changeset
2676 return convert_out (ctx->preserve (val));
kono
parents:
diff changeset
2677 }
kono
parents:
diff changeset
2678
kono
parents:
diff changeset
2679 gcc_expr
kono
parents:
diff changeset
2680 plugin_build_decl_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
2681 gcc_decl decl_in,
kono
parents:
diff changeset
2682 int qualified_p)
kono
parents:
diff changeset
2683 {
kono
parents:
diff changeset
2684 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2685 tree decl = convert_in (decl_in);
kono
parents:
diff changeset
2686 gcc_assert (DECL_P (decl));
kono
parents:
diff changeset
2687 tree result = decl;
kono
parents:
diff changeset
2688 if (qualified_p)
kono
parents:
diff changeset
2689 {
kono
parents:
diff changeset
2690 gcc_assert (DECL_CLASS_SCOPE_P (decl));
kono
parents:
diff changeset
2691 result = build_offset_ref (DECL_CONTEXT (decl), decl,
kono
parents:
diff changeset
2692 /*address_p=*/true, tf_error);
kono
parents:
diff changeset
2693 }
kono
parents:
diff changeset
2694 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
2695 }
kono
parents:
diff changeset
2696
kono
parents:
diff changeset
2697 gcc_expr
kono
parents:
diff changeset
2698 plugin_build_unary_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
2699 const char *unary_op,
kono
parents:
diff changeset
2700 gcc_expr operand)
kono
parents:
diff changeset
2701 {
kono
parents:
diff changeset
2702 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2703 tree op0 = convert_in (operand);
kono
parents:
diff changeset
2704 tree_code opcode = ERROR_MARK;
kono
parents:
diff changeset
2705 bool global_scope_p = false;
kono
parents:
diff changeset
2706
kono
parents:
diff changeset
2707 once_more:
kono
parents:
diff changeset
2708 switch (CHARS2 (unary_op[0], unary_op[1]))
kono
parents:
diff changeset
2709 {
kono
parents:
diff changeset
2710 case CHARS2 ('p', 's'): // operator + (unary)
kono
parents:
diff changeset
2711 opcode = UNARY_PLUS_EXPR;
kono
parents:
diff changeset
2712 break;
kono
parents:
diff changeset
2713 case CHARS2 ('n', 'g'): // operator - (unary)
kono
parents:
diff changeset
2714 opcode = NEGATE_EXPR;
kono
parents:
diff changeset
2715 break;
kono
parents:
diff changeset
2716 case CHARS2 ('a', 'd'): // operator & (unary)
kono
parents:
diff changeset
2717 opcode = ADDR_EXPR;
kono
parents:
diff changeset
2718 break;
kono
parents:
diff changeset
2719 case CHARS2 ('d', 'e'): // operator * (unary)
kono
parents:
diff changeset
2720 opcode = INDIRECT_REF;
kono
parents:
diff changeset
2721 break;
kono
parents:
diff changeset
2722 case CHARS2 ('c', 'o'): // operator ~
kono
parents:
diff changeset
2723 opcode = BIT_NOT_EXPR;
kono
parents:
diff changeset
2724 break;
kono
parents:
diff changeset
2725 case CHARS2 ('n', 't'): // operator !
kono
parents:
diff changeset
2726 opcode = TRUTH_NOT_EXPR;
kono
parents:
diff changeset
2727 break;
kono
parents:
diff changeset
2728 case CHARS2 ('p', 'p'): // operator ++
kono
parents:
diff changeset
2729 opcode = unary_op[2] == '_' ? PREINCREMENT_EXPR : POSTINCREMENT_EXPR;
kono
parents:
diff changeset
2730 break;
kono
parents:
diff changeset
2731 case CHARS2 ('m', 'm'): // operator --
kono
parents:
diff changeset
2732 opcode = unary_op[2] == '_' ? PREDECREMENT_EXPR : POSTDECREMENT_EXPR;
kono
parents:
diff changeset
2733 break;
kono
parents:
diff changeset
2734 case CHARS2 ('n', 'x'): // noexcept
kono
parents:
diff changeset
2735 opcode = NOEXCEPT_EXPR;
kono
parents:
diff changeset
2736 break;
kono
parents:
diff changeset
2737 case CHARS2 ('t', 'w'): // throw
kono
parents:
diff changeset
2738 gcc_assert (op0);
kono
parents:
diff changeset
2739 opcode = THROW_EXPR;
kono
parents:
diff changeset
2740 break;
kono
parents:
diff changeset
2741 case CHARS2 ('t', 'r'): // rethrow
kono
parents:
diff changeset
2742 gcc_assert (!op0);
kono
parents:
diff changeset
2743 opcode = THROW_EXPR;
kono
parents:
diff changeset
2744 break;
kono
parents:
diff changeset
2745 case CHARS2 ('t', 'e'): // typeid (value)
kono
parents:
diff changeset
2746 opcode = TYPEID_EXPR;
kono
parents:
diff changeset
2747 break;
kono
parents:
diff changeset
2748 case CHARS2 ('s', 'z'): // sizeof (value)
kono
parents:
diff changeset
2749 opcode = SIZEOF_EXPR;
kono
parents:
diff changeset
2750 break;
kono
parents:
diff changeset
2751 case CHARS2 ('a', 'z'): // alignof (value)
kono
parents:
diff changeset
2752 opcode = ALIGNOF_EXPR;
kono
parents:
diff changeset
2753 break;
kono
parents:
diff changeset
2754 case CHARS2 ('g', 's'): // global scope (for delete, delete[])
kono
parents:
diff changeset
2755 gcc_assert (!global_scope_p);
kono
parents:
diff changeset
2756 global_scope_p = true;
kono
parents:
diff changeset
2757 unary_op += 2;
kono
parents:
diff changeset
2758 goto once_more;
kono
parents:
diff changeset
2759 case CHARS2 ('d', 'l'): // delete
kono
parents:
diff changeset
2760 opcode = DELETE_EXPR;
kono
parents:
diff changeset
2761 break;
kono
parents:
diff changeset
2762 case CHARS2 ('d', 'a'): // delete[]
kono
parents:
diff changeset
2763 opcode = VEC_DELETE_EXPR;
kono
parents:
diff changeset
2764 break;
kono
parents:
diff changeset
2765 case CHARS2 ('s', 'p'): // pack...
kono
parents:
diff changeset
2766 opcode = EXPR_PACK_EXPANSION;
kono
parents:
diff changeset
2767 break;
kono
parents:
diff changeset
2768 case CHARS2 ('s', 'Z'): // sizeof...(pack)
kono
parents:
diff changeset
2769 opcode = TYPE_PACK_EXPANSION; // Not really, but let's use its code.
kono
parents:
diff changeset
2770 break;
kono
parents:
diff changeset
2771
kono
parents:
diff changeset
2772 /* FIXME: __real__, __imag__? */
kono
parents:
diff changeset
2773
kono
parents:
diff changeset
2774 default:
kono
parents:
diff changeset
2775 gcc_unreachable ();
kono
parents:
diff changeset
2776 }
kono
parents:
diff changeset
2777
kono
parents:
diff changeset
2778 gcc_assert (!global_scope_p
kono
parents:
diff changeset
2779 || opcode == DELETE_EXPR || opcode == VEC_DELETE_EXPR);
kono
parents:
diff changeset
2780
kono
parents:
diff changeset
2781 processing_template_decl++;
kono
parents:
diff changeset
2782 bool template_dependent_p = op0
kono
parents:
diff changeset
2783 && (type_dependent_expression_p (op0)
kono
parents:
diff changeset
2784 || value_dependent_expression_p (op0));
kono
parents:
diff changeset
2785 if (!template_dependent_p)
kono
parents:
diff changeset
2786 processing_template_decl--;
kono
parents:
diff changeset
2787
kono
parents:
diff changeset
2788 tree result;
kono
parents:
diff changeset
2789
kono
parents:
diff changeset
2790 gcc_assert (op0 || opcode == THROW_EXPR);
kono
parents:
diff changeset
2791
kono
parents:
diff changeset
2792 switch (opcode)
kono
parents:
diff changeset
2793 {
kono
parents:
diff changeset
2794 case NOEXCEPT_EXPR:
kono
parents:
diff changeset
2795 result = finish_noexcept_expr (op0, tf_error);
kono
parents:
diff changeset
2796 break;
kono
parents:
diff changeset
2797
kono
parents:
diff changeset
2798 case THROW_EXPR:
kono
parents:
diff changeset
2799 result = build_throw (op0);
kono
parents:
diff changeset
2800 break;
kono
parents:
diff changeset
2801
kono
parents:
diff changeset
2802 case TYPEID_EXPR:
kono
parents:
diff changeset
2803 result = build_typeid (op0, tf_error);
kono
parents:
diff changeset
2804 break;
kono
parents:
diff changeset
2805
kono
parents:
diff changeset
2806 case SIZEOF_EXPR:
kono
parents:
diff changeset
2807 case ALIGNOF_EXPR:
kono
parents:
diff changeset
2808 result = cxx_sizeof_or_alignof_expr (op0, opcode, true);
kono
parents:
diff changeset
2809 break;
kono
parents:
diff changeset
2810
kono
parents:
diff changeset
2811 case DELETE_EXPR:
kono
parents:
diff changeset
2812 case VEC_DELETE_EXPR:
kono
parents:
diff changeset
2813 result = delete_sanity (op0, NULL_TREE, opcode == VEC_DELETE_EXPR,
kono
parents:
diff changeset
2814 global_scope_p, tf_error);
kono
parents:
diff changeset
2815 break;
kono
parents:
diff changeset
2816
kono
parents:
diff changeset
2817 case EXPR_PACK_EXPANSION:
kono
parents:
diff changeset
2818 result = make_pack_expansion (op0);
kono
parents:
diff changeset
2819 break;
kono
parents:
diff changeset
2820
kono
parents:
diff changeset
2821 // We're using this for sizeof...(pack). */
kono
parents:
diff changeset
2822 case TYPE_PACK_EXPANSION:
kono
parents:
diff changeset
2823 result = make_pack_expansion (op0);
kono
parents:
diff changeset
2824 PACK_EXPANSION_SIZEOF_P (result) = true;
kono
parents:
diff changeset
2825 break;
kono
parents:
diff changeset
2826
kono
parents:
diff changeset
2827 default:
kono
parents:
diff changeset
2828 result = build_x_unary_op (/*loc=*/0, opcode, op0, tf_error);
kono
parents:
diff changeset
2829 break;
kono
parents:
diff changeset
2830 }
kono
parents:
diff changeset
2831
kono
parents:
diff changeset
2832 if (template_dependent_p)
kono
parents:
diff changeset
2833 processing_template_decl--;
kono
parents:
diff changeset
2834
kono
parents:
diff changeset
2835 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
2836 }
kono
parents:
diff changeset
2837
kono
parents:
diff changeset
2838 gcc_expr
kono
parents:
diff changeset
2839 plugin_build_binary_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
2840 const char *binary_op,
kono
parents:
diff changeset
2841 gcc_expr operand1,
kono
parents:
diff changeset
2842 gcc_expr operand2)
kono
parents:
diff changeset
2843 {
kono
parents:
diff changeset
2844 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2845 tree op0 = convert_in (operand1);
kono
parents:
diff changeset
2846 tree op1 = convert_in (operand2);
kono
parents:
diff changeset
2847 tree_code opcode = ERROR_MARK;
kono
parents:
diff changeset
2848
kono
parents:
diff changeset
2849 switch (CHARS2 (binary_op[0], binary_op[1]))
kono
parents:
diff changeset
2850 {
kono
parents:
diff changeset
2851 case CHARS2 ('p', 'l'): // operator +
kono
parents:
diff changeset
2852 opcode = PLUS_EXPR;
kono
parents:
diff changeset
2853 break;
kono
parents:
diff changeset
2854 case CHARS2 ('m', 'i'): // operator -
kono
parents:
diff changeset
2855 opcode = MINUS_EXPR;
kono
parents:
diff changeset
2856 break;
kono
parents:
diff changeset
2857 case CHARS2 ('m', 'l'): // operator *
kono
parents:
diff changeset
2858 opcode = MULT_EXPR;
kono
parents:
diff changeset
2859 break;
kono
parents:
diff changeset
2860 case CHARS2 ('d', 'v'): // operator /
kono
parents:
diff changeset
2861 opcode = TRUNC_DIV_EXPR;
kono
parents:
diff changeset
2862 break;
kono
parents:
diff changeset
2863 case CHARS2 ('r', 'm'): // operator %
kono
parents:
diff changeset
2864 opcode = TRUNC_MOD_EXPR;
kono
parents:
diff changeset
2865 break;
kono
parents:
diff changeset
2866 case CHARS2 ('a', 'n'): // operator &
kono
parents:
diff changeset
2867 opcode = BIT_AND_EXPR;
kono
parents:
diff changeset
2868 break;
kono
parents:
diff changeset
2869 case CHARS2 ('o', 'r'): // operator |
kono
parents:
diff changeset
2870 opcode = BIT_IOR_EXPR;
kono
parents:
diff changeset
2871 break;
kono
parents:
diff changeset
2872 case CHARS2 ('e', 'o'): // operator ^
kono
parents:
diff changeset
2873 opcode = BIT_XOR_EXPR;
kono
parents:
diff changeset
2874 break;
kono
parents:
diff changeset
2875 case CHARS2 ('l', 's'): // operator <<
kono
parents:
diff changeset
2876 opcode = LSHIFT_EXPR;
kono
parents:
diff changeset
2877 break;
kono
parents:
diff changeset
2878 case CHARS2 ('r', 's'): // operator >>
kono
parents:
diff changeset
2879 opcode = RSHIFT_EXPR;
kono
parents:
diff changeset
2880 break;
kono
parents:
diff changeset
2881 case CHARS2 ('e', 'q'): // operator ==
kono
parents:
diff changeset
2882 opcode = EQ_EXPR;
kono
parents:
diff changeset
2883 break;
kono
parents:
diff changeset
2884 case CHARS2 ('n', 'e'): // operator !=
kono
parents:
diff changeset
2885 opcode = NE_EXPR;
kono
parents:
diff changeset
2886 break;
kono
parents:
diff changeset
2887 case CHARS2 ('l', 't'): // operator <
kono
parents:
diff changeset
2888 opcode = LT_EXPR;
kono
parents:
diff changeset
2889 break;
kono
parents:
diff changeset
2890 case CHARS2 ('g', 't'): // operator >
kono
parents:
diff changeset
2891 opcode = GT_EXPR;
kono
parents:
diff changeset
2892 break;
kono
parents:
diff changeset
2893 case CHARS2 ('l', 'e'): // operator <=
kono
parents:
diff changeset
2894 opcode = LE_EXPR;
kono
parents:
diff changeset
2895 break;
kono
parents:
diff changeset
2896 case CHARS2 ('g', 'e'): // operator >=
kono
parents:
diff changeset
2897 opcode = GE_EXPR;
kono
parents:
diff changeset
2898 break;
kono
parents:
diff changeset
2899 case CHARS2 ('a', 'a'): // operator &&
kono
parents:
diff changeset
2900 opcode = TRUTH_ANDIF_EXPR;
kono
parents:
diff changeset
2901 break;
kono
parents:
diff changeset
2902 case CHARS2 ('o', 'o'): // operator ||
kono
parents:
diff changeset
2903 opcode = TRUTH_ORIF_EXPR;
kono
parents:
diff changeset
2904 break;
kono
parents:
diff changeset
2905 case CHARS2 ('c', 'm'): // operator ,
kono
parents:
diff changeset
2906 opcode = COMPOUND_EXPR;
kono
parents:
diff changeset
2907 break;
kono
parents:
diff changeset
2908 case CHARS2 ('p', 'm'): // operator ->*
kono
parents:
diff changeset
2909 opcode = MEMBER_REF;
kono
parents:
diff changeset
2910 break;
kono
parents:
diff changeset
2911 case CHARS2 ('p', 't'): // operator ->
kono
parents:
diff changeset
2912 opcode = INDIRECT_REF; // Not really! This will stand for
kono
parents:
diff changeset
2913 // INDIRECT_REF followed by COMPONENT_REF
kono
parents:
diff changeset
2914 // later on.
kono
parents:
diff changeset
2915 break;
kono
parents:
diff changeset
2916 case CHARS2 ('i', 'x'): // operator []
kono
parents:
diff changeset
2917 opcode = ARRAY_REF;
kono
parents:
diff changeset
2918 break;
kono
parents:
diff changeset
2919 case CHARS2 ('d', 's'): // operator .*
kono
parents:
diff changeset
2920 opcode = DOTSTAR_EXPR;
kono
parents:
diff changeset
2921 break;
kono
parents:
diff changeset
2922 case CHARS2 ('d', 't'): // operator .
kono
parents:
diff changeset
2923 opcode = COMPONENT_REF;
kono
parents:
diff changeset
2924 break;
kono
parents:
diff changeset
2925
kono
parents:
diff changeset
2926 default:
kono
parents:
diff changeset
2927 gcc_unreachable ();
kono
parents:
diff changeset
2928 }
kono
parents:
diff changeset
2929
kono
parents:
diff changeset
2930 processing_template_decl++;
kono
parents:
diff changeset
2931 bool template_dependent_p = type_dependent_expression_p (op0)
kono
parents:
diff changeset
2932 || value_dependent_expression_p (op0)
kono
parents:
diff changeset
2933 || type_dependent_expression_p (op1)
kono
parents:
diff changeset
2934 || value_dependent_expression_p (op1);
kono
parents:
diff changeset
2935 if (!template_dependent_p)
kono
parents:
diff changeset
2936 processing_template_decl--;
kono
parents:
diff changeset
2937
kono
parents:
diff changeset
2938 tree result;
kono
parents:
diff changeset
2939
kono
parents:
diff changeset
2940 switch (opcode)
kono
parents:
diff changeset
2941 {
kono
parents:
diff changeset
2942 case INDIRECT_REF: // This is actually a "->".
kono
parents:
diff changeset
2943 op0 = build_x_arrow (/*loc=*/0, op0, tf_error);
kono
parents:
diff changeset
2944 /* Fall through. */
kono
parents:
diff changeset
2945 case COMPONENT_REF:
kono
parents:
diff changeset
2946 result = finish_class_member_access_expr (op0, op1,
kono
parents:
diff changeset
2947 /*template_p=*/false,
kono
parents:
diff changeset
2948 tf_error);
kono
parents:
diff changeset
2949 break;
kono
parents:
diff changeset
2950
kono
parents:
diff changeset
2951 default:
kono
parents:
diff changeset
2952 result = build_x_binary_op (/*loc=*/0, opcode, op0, ERROR_MARK,
kono
parents:
diff changeset
2953 op1, ERROR_MARK, NULL, tf_error);
kono
parents:
diff changeset
2954 break;
kono
parents:
diff changeset
2955 }
kono
parents:
diff changeset
2956
kono
parents:
diff changeset
2957 if (template_dependent_p)
kono
parents:
diff changeset
2958 processing_template_decl--;
kono
parents:
diff changeset
2959
kono
parents:
diff changeset
2960 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
2961 }
kono
parents:
diff changeset
2962
kono
parents:
diff changeset
2963 gcc_expr
kono
parents:
diff changeset
2964 plugin_build_ternary_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
2965 const char *ternary_op,
kono
parents:
diff changeset
2966 gcc_expr operand1,
kono
parents:
diff changeset
2967 gcc_expr operand2,
kono
parents:
diff changeset
2968 gcc_expr operand3)
kono
parents:
diff changeset
2969 {
kono
parents:
diff changeset
2970 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
2971 tree op0 = convert_in (operand1);
kono
parents:
diff changeset
2972 tree op1 = convert_in (operand2);
kono
parents:
diff changeset
2973 tree op2 = convert_in (operand3);
kono
parents:
diff changeset
2974 gcc_assert (CHARS2 (ternary_op[0], ternary_op[1])
kono
parents:
diff changeset
2975 == CHARS2 ('q', 'u')); // ternary operator
kono
parents:
diff changeset
2976
kono
parents:
diff changeset
2977 processing_template_decl++;
kono
parents:
diff changeset
2978 bool template_dependent_p = type_dependent_expression_p (op0)
kono
parents:
diff changeset
2979 || value_dependent_expression_p (op0)
kono
parents:
diff changeset
2980 || type_dependent_expression_p (op1)
kono
parents:
diff changeset
2981 || value_dependent_expression_p (op1)
kono
parents:
diff changeset
2982 || type_dependent_expression_p (op2)
kono
parents:
diff changeset
2983 || value_dependent_expression_p (op2);
kono
parents:
diff changeset
2984 if (!template_dependent_p)
kono
parents:
diff changeset
2985 processing_template_decl--;
kono
parents:
diff changeset
2986
kono
parents:
diff changeset
2987 tree val = build_x_conditional_expr (/*loc=*/0, op0, op1, op2, tf_error);
kono
parents:
diff changeset
2988
kono
parents:
diff changeset
2989 if (template_dependent_p)
kono
parents:
diff changeset
2990 processing_template_decl--;
kono
parents:
diff changeset
2991
kono
parents:
diff changeset
2992 return convert_out (ctx->preserve (val));
kono
parents:
diff changeset
2993 }
kono
parents:
diff changeset
2994
kono
parents:
diff changeset
2995 gcc_expr
kono
parents:
diff changeset
2996 plugin_build_unary_type_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
2997 const char *unary_op,
kono
parents:
diff changeset
2998 gcc_type operand)
kono
parents:
diff changeset
2999 {
kono
parents:
diff changeset
3000 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3001 tree type = convert_in (operand);
kono
parents:
diff changeset
3002 tree_code opcode = ERROR_MARK;
kono
parents:
diff changeset
3003
kono
parents:
diff changeset
3004 switch (CHARS2 (unary_op[0], unary_op[1]))
kono
parents:
diff changeset
3005 {
kono
parents:
diff changeset
3006 case CHARS2 ('t', 'i'): // typeid (type)
kono
parents:
diff changeset
3007 opcode = TYPEID_EXPR;
kono
parents:
diff changeset
3008 break;
kono
parents:
diff changeset
3009
kono
parents:
diff changeset
3010 case CHARS2 ('s', 't'): // sizeof (type)
kono
parents:
diff changeset
3011 opcode = SIZEOF_EXPR;
kono
parents:
diff changeset
3012 break;
kono
parents:
diff changeset
3013 case CHARS2 ('a', 't'): // alignof (type)
kono
parents:
diff changeset
3014 opcode = ALIGNOF_EXPR;
kono
parents:
diff changeset
3015 break;
kono
parents:
diff changeset
3016
kono
parents:
diff changeset
3017 case CHARS2 ('s', 'Z'): // sizeof...(pack)
kono
parents:
diff changeset
3018 opcode = TYPE_PACK_EXPANSION; // Not really, but let's use its code.
kono
parents:
diff changeset
3019 break;
kono
parents:
diff changeset
3020
kono
parents:
diff changeset
3021 // FIXME: do we have to handle "sp", for the size of a captured
kono
parents:
diff changeset
3022 // template parameter pack from an alias template, taking
kono
parents:
diff changeset
3023 // multiple template arguments?
kono
parents:
diff changeset
3024
kono
parents:
diff changeset
3025 default:
kono
parents:
diff changeset
3026 gcc_unreachable ();
kono
parents:
diff changeset
3027 }
kono
parents:
diff changeset
3028
kono
parents:
diff changeset
3029 processing_template_decl++;
kono
parents:
diff changeset
3030 bool template_dependent_p = dependent_type_p (type);
kono
parents:
diff changeset
3031 if (!template_dependent_p)
kono
parents:
diff changeset
3032 processing_template_decl--;
kono
parents:
diff changeset
3033
kono
parents:
diff changeset
3034 tree result;
kono
parents:
diff changeset
3035
kono
parents:
diff changeset
3036 switch (opcode)
kono
parents:
diff changeset
3037 {
kono
parents:
diff changeset
3038 case TYPEID_EXPR:
kono
parents:
diff changeset
3039 result = get_typeid (type, tf_error);
kono
parents:
diff changeset
3040 break;
kono
parents:
diff changeset
3041
kono
parents:
diff changeset
3042 // We're using this for sizeof...(pack). */
kono
parents:
diff changeset
3043 case TYPE_PACK_EXPANSION:
kono
parents:
diff changeset
3044 result = make_pack_expansion (type);
kono
parents:
diff changeset
3045 PACK_EXPANSION_SIZEOF_P (result) = true;
kono
parents:
diff changeset
3046 break;
kono
parents:
diff changeset
3047
kono
parents:
diff changeset
3048 default:
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3049 /* Use the C++11 alignof semantics. */
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
3050 result = cxx_sizeof_or_alignof_type (type, opcode, true, true);
111
kono
parents:
diff changeset
3051 }
kono
parents:
diff changeset
3052
kono
parents:
diff changeset
3053 if (template_dependent_p)
kono
parents:
diff changeset
3054 processing_template_decl--;
kono
parents:
diff changeset
3055
kono
parents:
diff changeset
3056 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
3057 }
kono
parents:
diff changeset
3058
kono
parents:
diff changeset
3059 gcc_expr
kono
parents:
diff changeset
3060 plugin_build_cast_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
3061 const char *binary_op,
kono
parents:
diff changeset
3062 gcc_type operand1,
kono
parents:
diff changeset
3063 gcc_expr operand2)
kono
parents:
diff changeset
3064 {
kono
parents:
diff changeset
3065 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3066 tree (*build_cast)(tree type, tree expr, tsubst_flags_t complain) = NULL;
kono
parents:
diff changeset
3067 tree type = convert_in (operand1);
kono
parents:
diff changeset
3068 tree expr = convert_in (operand2);
kono
parents:
diff changeset
3069
kono
parents:
diff changeset
3070 switch (CHARS2 (binary_op[0], binary_op[1]))
kono
parents:
diff changeset
3071 {
kono
parents:
diff changeset
3072 case CHARS2 ('d', 'c'): // dynamic_cast
kono
parents:
diff changeset
3073 build_cast = build_dynamic_cast;
kono
parents:
diff changeset
3074 break;
kono
parents:
diff changeset
3075
kono
parents:
diff changeset
3076 case CHARS2 ('s', 'c'): // static_cast
kono
parents:
diff changeset
3077 build_cast = build_static_cast;
kono
parents:
diff changeset
3078 break;
kono
parents:
diff changeset
3079
kono
parents:
diff changeset
3080 case CHARS2 ('c', 'c'): // const_cast
kono
parents:
diff changeset
3081 build_cast = build_const_cast;
kono
parents:
diff changeset
3082 break;
kono
parents:
diff changeset
3083
kono
parents:
diff changeset
3084 case CHARS2 ('r', 'c'): // reinterpret_cast
kono
parents:
diff changeset
3085 build_cast = build_reinterpret_cast;
kono
parents:
diff changeset
3086 break;
kono
parents:
diff changeset
3087
kono
parents:
diff changeset
3088 case CHARS2 ('c', 'v'): // C cast, conversion with one argument
kono
parents:
diff changeset
3089 build_cast = cp_build_c_cast;
kono
parents:
diff changeset
3090 break;
kono
parents:
diff changeset
3091
kono
parents:
diff changeset
3092 default:
kono
parents:
diff changeset
3093 gcc_unreachable ();
kono
parents:
diff changeset
3094 }
kono
parents:
diff changeset
3095
kono
parents:
diff changeset
3096 processing_template_decl++;
kono
parents:
diff changeset
3097 bool template_dependent_p = dependent_type_p (type)
kono
parents:
diff changeset
3098 || type_dependent_expression_p (expr)
kono
parents:
diff changeset
3099 || value_dependent_expression_p (expr);
kono
parents:
diff changeset
3100 if (!template_dependent_p)
kono
parents:
diff changeset
3101 processing_template_decl--;
kono
parents:
diff changeset
3102
kono
parents:
diff changeset
3103 tree val = build_cast (type, expr, tf_error);
kono
parents:
diff changeset
3104
kono
parents:
diff changeset
3105 if (template_dependent_p)
kono
parents:
diff changeset
3106 processing_template_decl--;
kono
parents:
diff changeset
3107
kono
parents:
diff changeset
3108 return convert_out (ctx->preserve (val));
kono
parents:
diff changeset
3109 }
kono
parents:
diff changeset
3110
kono
parents:
diff changeset
3111 static inline vec<tree, va_gc> *
kono
parents:
diff changeset
3112 args_to_tree_vec (const struct gcc_cp_function_args *args_in)
kono
parents:
diff changeset
3113 {
kono
parents:
diff changeset
3114 vec<tree, va_gc> *args = make_tree_vector ();
kono
parents:
diff changeset
3115 for (int i = 0; i < args_in->n_elements; i++)
kono
parents:
diff changeset
3116 vec_safe_push (args, convert_in (args_in->elements[i]));
kono
parents:
diff changeset
3117 return args;
kono
parents:
diff changeset
3118 }
kono
parents:
diff changeset
3119
kono
parents:
diff changeset
3120 static inline tree
kono
parents:
diff changeset
3121 args_to_tree_list (const struct gcc_cp_function_args *args_in)
kono
parents:
diff changeset
3122 {
kono
parents:
diff changeset
3123 tree args, *tail = &args;
kono
parents:
diff changeset
3124 for (int i = 0; i < args_in->n_elements; i++)
kono
parents:
diff changeset
3125 {
kono
parents:
diff changeset
3126 *tail = build_tree_list (NULL, convert_in (args_in->elements[i]));
kono
parents:
diff changeset
3127 tail = &TREE_CHAIN (*tail);
kono
parents:
diff changeset
3128 }
kono
parents:
diff changeset
3129 return args;
kono
parents:
diff changeset
3130 }
kono
parents:
diff changeset
3131
kono
parents:
diff changeset
3132 static inline vec<constructor_elt, va_gc> *
kono
parents:
diff changeset
3133 args_to_ctor_elts (const struct gcc_cp_function_args *args_in)
kono
parents:
diff changeset
3134 {
kono
parents:
diff changeset
3135 vec<constructor_elt, va_gc> *args = NULL;
kono
parents:
diff changeset
3136 for (int i = 0; i < args_in->n_elements; i++)
kono
parents:
diff changeset
3137 CONSTRUCTOR_APPEND_ELT (args, NULL_TREE, convert_in (args_in->elements[i]));
kono
parents:
diff changeset
3138 return args;
kono
parents:
diff changeset
3139 }
kono
parents:
diff changeset
3140
kono
parents:
diff changeset
3141 gcc_expr
kono
parents:
diff changeset
3142 plugin_build_expression_list_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
3143 const char *conv_op,
kono
parents:
diff changeset
3144 gcc_type type_in,
kono
parents:
diff changeset
3145 const struct gcc_cp_function_args *values_in)
kono
parents:
diff changeset
3146 {
kono
parents:
diff changeset
3147 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3148 tree type = convert_in (type_in);
kono
parents:
diff changeset
3149 tree args;
kono
parents:
diff changeset
3150 tree result;
kono
parents:
diff changeset
3151
kono
parents:
diff changeset
3152 switch (CHARS2 (conv_op[0], conv_op[1]))
kono
parents:
diff changeset
3153 {
kono
parents:
diff changeset
3154 case CHARS2 ('c', 'v'): // conversion with parenthesized expression list
kono
parents:
diff changeset
3155 gcc_assert (TYPE_P (type));
kono
parents:
diff changeset
3156 args = args_to_tree_list (values_in);
kono
parents:
diff changeset
3157 result = build_functional_cast (type, args, tf_error);
kono
parents:
diff changeset
3158 break;
kono
parents:
diff changeset
3159
kono
parents:
diff changeset
3160 case CHARS2 ('t', 'l'): // conversion with braced expression list
kono
parents:
diff changeset
3161 gcc_assert (type);
kono
parents:
diff changeset
3162 gcc_assert (TYPE_P (type));
kono
parents:
diff changeset
3163 args = make_node (CONSTRUCTOR);
kono
parents:
diff changeset
3164 CONSTRUCTOR_ELTS (args) = args_to_ctor_elts (values_in);
kono
parents:
diff changeset
3165 CONSTRUCTOR_IS_DIRECT_INIT (args) = 1;
kono
parents:
diff changeset
3166 result = finish_compound_literal (type, args, tf_error);
kono
parents:
diff changeset
3167 break;
kono
parents:
diff changeset
3168
kono
parents:
diff changeset
3169 case CHARS2 ('i', 'l'): // untyped braced expression list
kono
parents:
diff changeset
3170 gcc_assert (!type);
kono
parents:
diff changeset
3171 result = make_node (CONSTRUCTOR);
kono
parents:
diff changeset
3172 CONSTRUCTOR_ELTS (result) = args_to_ctor_elts (values_in);
kono
parents:
diff changeset
3173 break;
kono
parents:
diff changeset
3174
kono
parents:
diff changeset
3175 default:
kono
parents:
diff changeset
3176 gcc_unreachable ();
kono
parents:
diff changeset
3177 }
kono
parents:
diff changeset
3178
kono
parents:
diff changeset
3179 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
3180 }
kono
parents:
diff changeset
3181
kono
parents:
diff changeset
3182 gcc_expr
kono
parents:
diff changeset
3183 plugin_build_new_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
3184 const char *new_op,
kono
parents:
diff changeset
3185 const struct gcc_cp_function_args *placement_in,
kono
parents:
diff changeset
3186 gcc_type type_in,
kono
parents:
diff changeset
3187 const struct gcc_cp_function_args *initializer_in)
kono
parents:
diff changeset
3188 {
kono
parents:
diff changeset
3189 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3190 tree type = convert_in (type_in);
kono
parents:
diff changeset
3191 vec<tree, va_gc> *placement = NULL, *initializer = NULL;
kono
parents:
diff changeset
3192 bool global_scope_p = false;
kono
parents:
diff changeset
3193 tree nelts = NULL;
kono
parents:
diff changeset
3194
kono
parents:
diff changeset
3195 if (placement_in)
kono
parents:
diff changeset
3196 placement = args_to_tree_vec (placement_in);
kono
parents:
diff changeset
3197 if (initializer_in)
kono
parents:
diff changeset
3198 initializer = args_to_tree_vec (initializer_in);
kono
parents:
diff changeset
3199
kono
parents:
diff changeset
3200 gcc_assert (TYPE_P (type));
kono
parents:
diff changeset
3201
kono
parents:
diff changeset
3202 once_more:
kono
parents:
diff changeset
3203 switch (CHARS2 (new_op[0], new_op[1]))
kono
parents:
diff changeset
3204 {
kono
parents:
diff changeset
3205 case CHARS2 ('g', 's'):
kono
parents:
diff changeset
3206 gcc_assert (!global_scope_p);
kono
parents:
diff changeset
3207 global_scope_p = true;
kono
parents:
diff changeset
3208 new_op += 2;
kono
parents:
diff changeset
3209 goto once_more;
kono
parents:
diff changeset
3210
kono
parents:
diff changeset
3211 case CHARS2 ('n', 'w'): // non-array new
kono
parents:
diff changeset
3212 gcc_assert (TREE_CODE (type) != ARRAY_TYPE);
kono
parents:
diff changeset
3213 break;
kono
parents:
diff changeset
3214
kono
parents:
diff changeset
3215 case CHARS2 ('n', 'a'): // array new
kono
parents:
diff changeset
3216 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
kono
parents:
diff changeset
3217 gcc_assert (TYPE_DOMAIN (type));
kono
parents:
diff changeset
3218 {
kono
parents:
diff changeset
3219 // Compute the length of the outermost array type, then discard it.
kono
parents:
diff changeset
3220 tree maxelt = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
kono
parents:
diff changeset
3221 tree eltype = TREE_TYPE (maxelt);
kono
parents:
diff changeset
3222 tree onecst = integer_one_node;
kono
parents:
diff changeset
3223
kono
parents:
diff changeset
3224 processing_template_decl++;
kono
parents:
diff changeset
3225 bool template_dependent_p = value_dependent_expression_p (maxelt)
kono
parents:
diff changeset
3226 || type_dependent_expression_p (maxelt);
kono
parents:
diff changeset
3227 if (!template_dependent_p)
kono
parents:
diff changeset
3228 {
kono
parents:
diff changeset
3229 processing_template_decl--;
kono
parents:
diff changeset
3230 onecst = fold_convert (eltype, onecst);
kono
parents:
diff changeset
3231 }
kono
parents:
diff changeset
3232
kono
parents:
diff changeset
3233 nelts = fold_build2 (PLUS_EXPR, eltype, nelts, onecst);
kono
parents:
diff changeset
3234
kono
parents:
diff changeset
3235 if (template_dependent_p)
kono
parents:
diff changeset
3236 processing_template_decl--;
kono
parents:
diff changeset
3237
kono
parents:
diff changeset
3238 type = TREE_TYPE (type);
kono
parents:
diff changeset
3239 }
kono
parents:
diff changeset
3240 break;
kono
parents:
diff changeset
3241
kono
parents:
diff changeset
3242 default:
kono
parents:
diff changeset
3243 gcc_unreachable ();
kono
parents:
diff changeset
3244 }
kono
parents:
diff changeset
3245
kono
parents:
diff changeset
3246 processing_template_decl++;
kono
parents:
diff changeset
3247 bool template_dependent_p = dependent_type_p (type)
kono
parents:
diff changeset
3248 || value_dependent_expression_p (nelts)
kono
parents:
diff changeset
3249 || (placement
kono
parents:
diff changeset
3250 && any_type_dependent_arguments_p (placement))
kono
parents:
diff changeset
3251 || (initializer
kono
parents:
diff changeset
3252 && any_type_dependent_arguments_p (initializer));
kono
parents:
diff changeset
3253 if (!template_dependent_p)
kono
parents:
diff changeset
3254 processing_template_decl--;
kono
parents:
diff changeset
3255
kono
parents:
diff changeset
3256 tree result = build_new (&placement, type, nelts, &initializer,
kono
parents:
diff changeset
3257 global_scope_p, tf_error);
kono
parents:
diff changeset
3258
kono
parents:
diff changeset
3259 if (template_dependent_p)
kono
parents:
diff changeset
3260 processing_template_decl--;
kono
parents:
diff changeset
3261
kono
parents:
diff changeset
3262 if (placement != NULL)
kono
parents:
diff changeset
3263 release_tree_vector (placement);
kono
parents:
diff changeset
3264 if (initializer != NULL)
kono
parents:
diff changeset
3265 release_tree_vector (initializer);
kono
parents:
diff changeset
3266
kono
parents:
diff changeset
3267 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
3268 }
kono
parents:
diff changeset
3269
kono
parents:
diff changeset
3270 gcc_expr
kono
parents:
diff changeset
3271 plugin_build_call_expr (cc1_plugin::connection *self,
kono
parents:
diff changeset
3272 gcc_expr callable_in, int qualified_p,
kono
parents:
diff changeset
3273 const struct gcc_cp_function_args *args_in)
kono
parents:
diff changeset
3274 {
kono
parents:
diff changeset
3275 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3276 tree callable = convert_in (callable_in);
kono
parents:
diff changeset
3277 tree call_expr;
kono
parents:
diff changeset
3278
kono
parents:
diff changeset
3279 vec<tree, va_gc> *args = args_to_tree_vec (args_in);
kono
parents:
diff changeset
3280
kono
parents:
diff changeset
3281 bool koenig_p = false;
kono
parents:
diff changeset
3282 if (!qualified_p && !args->is_empty ())
kono
parents:
diff changeset
3283 {
kono
parents:
diff changeset
3284 if (identifier_p (callable))
kono
parents:
diff changeset
3285 koenig_p = true;
kono
parents:
diff changeset
3286 else if (is_overloaded_fn (callable))
kono
parents:
diff changeset
3287 {
kono
parents:
diff changeset
3288 tree fn = get_first_fn (callable);
kono
parents:
diff changeset
3289 fn = STRIP_TEMPLATE (fn);
kono
parents:
diff changeset
3290
kono
parents:
diff changeset
3291 if (!DECL_FUNCTION_MEMBER_P (fn)
kono
parents:
diff changeset
3292 && !DECL_LOCAL_FUNCTION_P (fn))
kono
parents:
diff changeset
3293 koenig_p = true;
kono
parents:
diff changeset
3294 }
kono
parents:
diff changeset
3295 }
kono
parents:
diff changeset
3296
kono
parents:
diff changeset
3297 if (koenig_p && !any_type_dependent_arguments_p (args))
kono
parents:
diff changeset
3298 callable = perform_koenig_lookup (callable, args, tf_none);
kono
parents:
diff changeset
3299
kono
parents:
diff changeset
3300 if (TREE_CODE (callable) == COMPONENT_REF)
kono
parents:
diff changeset
3301 {
kono
parents:
diff changeset
3302 tree object = TREE_OPERAND (callable, 0);
kono
parents:
diff changeset
3303 tree memfn = TREE_OPERAND (callable, 1);
kono
parents:
diff changeset
3304
kono
parents:
diff changeset
3305 if (type_dependent_expression_p (object)
kono
parents:
diff changeset
3306 || (!BASELINK_P (memfn) && TREE_CODE (memfn) != FIELD_DECL)
kono
parents:
diff changeset
3307 || type_dependent_expression_p (memfn)
kono
parents:
diff changeset
3308 || any_type_dependent_arguments_p (args))
kono
parents:
diff changeset
3309 call_expr = build_nt_call_vec (callable, args);
kono
parents:
diff changeset
3310 else if (BASELINK_P (memfn))
kono
parents:
diff changeset
3311 call_expr = build_new_method_call (object, memfn, &args, NULL_TREE,
kono
parents:
diff changeset
3312 qualified_p
kono
parents:
diff changeset
3313 ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
kono
parents:
diff changeset
3314 : LOOKUP_NORMAL,
kono
parents:
diff changeset
3315 NULL, tf_none);
kono
parents:
diff changeset
3316 else
kono
parents:
diff changeset
3317 call_expr = finish_call_expr (callable, &args, false, false, tf_none);
kono
parents:
diff changeset
3318 }
kono
parents:
diff changeset
3319 else if (TREE_CODE (callable) == OFFSET_REF
kono
parents:
diff changeset
3320 || TREE_CODE (callable) == MEMBER_REF
kono
parents:
diff changeset
3321 || TREE_CODE (callable) == DOTSTAR_EXPR)
kono
parents:
diff changeset
3322 call_expr = build_offset_ref_call_from_tree (callable, &args, tf_none);
kono
parents:
diff changeset
3323 else
kono
parents:
diff changeset
3324 call_expr = finish_call_expr (callable, &args,
kono
parents:
diff changeset
3325 !!qualified_p, koenig_p, tf_none);
kono
parents:
diff changeset
3326
kono
parents:
diff changeset
3327 release_tree_vector (args);
kono
parents:
diff changeset
3328 return convert_out (ctx->preserve (call_expr));
kono
parents:
diff changeset
3329 }
kono
parents:
diff changeset
3330
kono
parents:
diff changeset
3331 gcc_type
kono
parents:
diff changeset
3332 plugin_get_expr_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
3333 gcc_expr operand)
kono
parents:
diff changeset
3334 {
kono
parents:
diff changeset
3335 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3336 tree op0 = convert_in (operand);
kono
parents:
diff changeset
3337 tree type;
kono
parents:
diff changeset
3338 if (op0)
kono
parents:
diff changeset
3339 type = TREE_TYPE (op0);
kono
parents:
diff changeset
3340 else
kono
parents:
diff changeset
3341 {
kono
parents:
diff changeset
3342 type = make_decltype_auto ();
kono
parents:
diff changeset
3343 AUTO_IS_DECLTYPE (type) = true;
kono
parents:
diff changeset
3344 }
kono
parents:
diff changeset
3345 return convert_out (ctx->preserve (type));
kono
parents:
diff changeset
3346 }
kono
parents:
diff changeset
3347
kono
parents:
diff changeset
3348 gcc_decl
kono
parents:
diff changeset
3349 plugin_build_function_template_specialization (cc1_plugin::connection *self,
kono
parents:
diff changeset
3350 gcc_decl template_decl,
kono
parents:
diff changeset
3351 const gcc_cp_template_args *targs,
kono
parents:
diff changeset
3352 gcc_address address,
kono
parents:
diff changeset
3353 const char *filename,
kono
parents:
diff changeset
3354 unsigned int line_number)
kono
parents:
diff changeset
3355 {
kono
parents:
diff changeset
3356 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3357 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
3358 tree name = convert_in (template_decl);
kono
parents:
diff changeset
3359 tree targsl = targlist (targs);
kono
parents:
diff changeset
3360
kono
parents:
diff changeset
3361 tree decl = tsubst (name, targsl, tf_error, NULL_TREE);
kono
parents:
diff changeset
3362 DECL_SOURCE_LOCATION (decl) = loc;
kono
parents:
diff changeset
3363
kono
parents:
diff changeset
3364 record_decl_address (ctx, build_decl_addr_value (decl, address));
kono
parents:
diff changeset
3365
kono
parents:
diff changeset
3366 return convert_out (ctx->preserve (decl));
kono
parents:
diff changeset
3367 }
kono
parents:
diff changeset
3368
kono
parents:
diff changeset
3369 gcc_decl
kono
parents:
diff changeset
3370 plugin_build_class_template_specialization (cc1_plugin::connection *self,
kono
parents:
diff changeset
3371 gcc_decl template_decl,
kono
parents:
diff changeset
3372 const gcc_cp_template_args *args,
kono
parents:
diff changeset
3373 const char *filename,
kono
parents:
diff changeset
3374 unsigned int line_number)
kono
parents:
diff changeset
3375 {
kono
parents:
diff changeset
3376 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3377 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
3378 tree name = convert_in (template_decl);
kono
parents:
diff changeset
3379
kono
parents:
diff changeset
3380 tree tdecl = finish_template_type (name, targlist (args), false);;
kono
parents:
diff changeset
3381 DECL_SOURCE_LOCATION (tdecl) = loc;
kono
parents:
diff changeset
3382
kono
parents:
diff changeset
3383 return convert_out (ctx->preserve (tdecl));
kono
parents:
diff changeset
3384 }
kono
parents:
diff changeset
3385
kono
parents:
diff changeset
3386 /* Return a builtin type associated with BUILTIN_NAME. */
kono
parents:
diff changeset
3387
kono
parents:
diff changeset
3388 static tree
kono
parents:
diff changeset
3389 safe_lookup_builtin_type (const char *builtin_name)
kono
parents:
diff changeset
3390 {
kono
parents:
diff changeset
3391 tree result = NULL_TREE;
kono
parents:
diff changeset
3392
kono
parents:
diff changeset
3393 if (!builtin_name)
kono
parents:
diff changeset
3394 return result;
kono
parents:
diff changeset
3395
kono
parents:
diff changeset
3396 result = identifier_global_value (get_identifier (builtin_name));
kono
parents:
diff changeset
3397
kono
parents:
diff changeset
3398 if (!result)
kono
parents:
diff changeset
3399 return result;
kono
parents:
diff changeset
3400
kono
parents:
diff changeset
3401 gcc_assert (TREE_CODE (result) == TYPE_DECL);
kono
parents:
diff changeset
3402 result = TREE_TYPE (result);
kono
parents:
diff changeset
3403 return result;
kono
parents:
diff changeset
3404 }
kono
parents:
diff changeset
3405
kono
parents:
diff changeset
3406 gcc_type
kono
parents:
diff changeset
3407 plugin_get_int_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
3408 int is_unsigned, unsigned long size_in_bytes,
kono
parents:
diff changeset
3409 const char *builtin_name)
kono
parents:
diff changeset
3410 {
kono
parents:
diff changeset
3411 tree result;
kono
parents:
diff changeset
3412
kono
parents:
diff changeset
3413 if (builtin_name)
kono
parents:
diff changeset
3414 {
kono
parents:
diff changeset
3415 result = safe_lookup_builtin_type (builtin_name);
kono
parents:
diff changeset
3416 gcc_assert (!result || TREE_CODE (result) == INTEGER_TYPE);
kono
parents:
diff changeset
3417 }
kono
parents:
diff changeset
3418 else
kono
parents:
diff changeset
3419 result = c_common_type_for_size (BITS_PER_UNIT * size_in_bytes,
kono
parents:
diff changeset
3420 is_unsigned);
kono
parents:
diff changeset
3421
kono
parents:
diff changeset
3422 if (result == NULL_TREE)
kono
parents:
diff changeset
3423 result = error_mark_node;
kono
parents:
diff changeset
3424 else
kono
parents:
diff changeset
3425 {
kono
parents:
diff changeset
3426 gcc_assert (!TYPE_UNSIGNED (result) == !is_unsigned);
kono
parents:
diff changeset
3427 gcc_assert (TREE_CODE (TYPE_SIZE (result)) == INTEGER_CST);
kono
parents:
diff changeset
3428 gcc_assert (TYPE_PRECISION (result) == BITS_PER_UNIT * size_in_bytes);
kono
parents:
diff changeset
3429
kono
parents:
diff changeset
3430 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3431 ctx->preserve (result);
kono
parents:
diff changeset
3432 }
kono
parents:
diff changeset
3433 return convert_out (result);
kono
parents:
diff changeset
3434 }
kono
parents:
diff changeset
3435
kono
parents:
diff changeset
3436 gcc_type
kono
parents:
diff changeset
3437 plugin_get_char_type (cc1_plugin::connection *)
kono
parents:
diff changeset
3438 {
kono
parents:
diff changeset
3439 return convert_out (char_type_node);
kono
parents:
diff changeset
3440 }
kono
parents:
diff changeset
3441
kono
parents:
diff changeset
3442 gcc_type
kono
parents:
diff changeset
3443 plugin_get_float_type (cc1_plugin::connection *,
kono
parents:
diff changeset
3444 unsigned long size_in_bytes,
kono
parents:
diff changeset
3445 const char *builtin_name)
kono
parents:
diff changeset
3446 {
kono
parents:
diff changeset
3447 if (builtin_name)
kono
parents:
diff changeset
3448 {
kono
parents:
diff changeset
3449 tree result = safe_lookup_builtin_type (builtin_name);
kono
parents:
diff changeset
3450
kono
parents:
diff changeset
3451 if (!result)
kono
parents:
diff changeset
3452 return convert_out (error_mark_node);
kono
parents:
diff changeset
3453
kono
parents:
diff changeset
3454 gcc_assert (TREE_CODE (result) == REAL_TYPE);
kono
parents:
diff changeset
3455 gcc_assert (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (result));
kono
parents:
diff changeset
3456
kono
parents:
diff changeset
3457 return convert_out (result);
kono
parents:
diff changeset
3458 }
kono
parents:
diff changeset
3459
kono
parents:
diff changeset
3460 if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (float_type_node))
kono
parents:
diff changeset
3461 return convert_out (float_type_node);
kono
parents:
diff changeset
3462 if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (double_type_node))
kono
parents:
diff changeset
3463 return convert_out (double_type_node);
kono
parents:
diff changeset
3464 if (BITS_PER_UNIT * size_in_bytes == TYPE_PRECISION (long_double_type_node))
kono
parents:
diff changeset
3465 return convert_out (long_double_type_node);
kono
parents:
diff changeset
3466 return convert_out (error_mark_node);
kono
parents:
diff changeset
3467 }
kono
parents:
diff changeset
3468
kono
parents:
diff changeset
3469 gcc_type
kono
parents:
diff changeset
3470 plugin_get_void_type (cc1_plugin::connection *)
kono
parents:
diff changeset
3471 {
kono
parents:
diff changeset
3472 return convert_out (void_type_node);
kono
parents:
diff changeset
3473 }
kono
parents:
diff changeset
3474
kono
parents:
diff changeset
3475 gcc_type
kono
parents:
diff changeset
3476 plugin_get_bool_type (cc1_plugin::connection *)
kono
parents:
diff changeset
3477 {
kono
parents:
diff changeset
3478 return convert_out (boolean_type_node);
kono
parents:
diff changeset
3479 }
kono
parents:
diff changeset
3480
kono
parents:
diff changeset
3481 gcc_type
kono
parents:
diff changeset
3482 plugin_get_nullptr_type (cc1_plugin::connection *)
kono
parents:
diff changeset
3483 {
kono
parents:
diff changeset
3484 return convert_out (nullptr_type_node);
kono
parents:
diff changeset
3485 }
kono
parents:
diff changeset
3486
kono
parents:
diff changeset
3487 gcc_expr
kono
parents:
diff changeset
3488 plugin_get_nullptr_constant (cc1_plugin::connection *)
kono
parents:
diff changeset
3489 {
kono
parents:
diff changeset
3490 return convert_out (nullptr_node);
kono
parents:
diff changeset
3491 }
kono
parents:
diff changeset
3492
kono
parents:
diff changeset
3493 gcc_type
kono
parents:
diff changeset
3494 plugin_build_array_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
3495 gcc_type element_type_in, int num_elements)
kono
parents:
diff changeset
3496 {
kono
parents:
diff changeset
3497 tree element_type = convert_in (element_type_in);
kono
parents:
diff changeset
3498 tree result;
kono
parents:
diff changeset
3499
kono
parents:
diff changeset
3500 if (num_elements == -1)
kono
parents:
diff changeset
3501 result = build_array_type (element_type, NULL_TREE);
kono
parents:
diff changeset
3502 else
kono
parents:
diff changeset
3503 result = build_array_type_nelts (element_type, num_elements);
kono
parents:
diff changeset
3504
kono
parents:
diff changeset
3505 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3506 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
3507 }
kono
parents:
diff changeset
3508
kono
parents:
diff changeset
3509 gcc_type
kono
parents:
diff changeset
3510 plugin_build_dependent_array_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
3511 gcc_type element_type_in,
kono
parents:
diff changeset
3512 gcc_expr num_elements_in)
kono
parents:
diff changeset
3513 {
kono
parents:
diff changeset
3514 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3515 tree element_type = convert_in (element_type_in);
kono
parents:
diff changeset
3516 tree size = convert_in (num_elements_in);
kono
parents:
diff changeset
3517 tree name = get_identifier ("dependent array type");
kono
parents:
diff changeset
3518
kono
parents:
diff changeset
3519 processing_template_decl++;
kono
parents:
diff changeset
3520 bool template_dependent_p = dependent_type_p (element_type)
kono
parents:
diff changeset
3521 || type_dependent_expression_p (size)
kono
parents:
diff changeset
3522 || value_dependent_expression_p (size);
kono
parents:
diff changeset
3523 if (!template_dependent_p)
kono
parents:
diff changeset
3524 processing_template_decl--;
kono
parents:
diff changeset
3525
kono
parents:
diff changeset
3526 tree itype = compute_array_index_type (name, size, tf_error);
kono
parents:
diff changeset
3527 tree type = build_cplus_array_type (element_type, itype);
kono
parents:
diff changeset
3528
kono
parents:
diff changeset
3529 if (template_dependent_p)
kono
parents:
diff changeset
3530 processing_template_decl--;
kono
parents:
diff changeset
3531
kono
parents:
diff changeset
3532 return convert_out (ctx->preserve (type));
kono
parents:
diff changeset
3533 }
kono
parents:
diff changeset
3534
kono
parents:
diff changeset
3535 gcc_type
kono
parents:
diff changeset
3536 plugin_build_vla_array_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
3537 gcc_type element_type_in,
kono
parents:
diff changeset
3538 const char *upper_bound_name)
kono
parents:
diff changeset
3539 {
kono
parents:
diff changeset
3540 tree element_type = convert_in (element_type_in);
kono
parents:
diff changeset
3541 tree upper_bound = lookup_name (get_identifier (upper_bound_name));
kono
parents:
diff changeset
3542 tree size = fold_build2 (PLUS_EXPR, TREE_TYPE (upper_bound), upper_bound,
kono
parents:
diff changeset
3543 build_one_cst (TREE_TYPE (upper_bound)));
kono
parents:
diff changeset
3544 tree range = compute_array_index_type (NULL_TREE, size,
kono
parents:
diff changeset
3545 tf_error);
kono
parents:
diff changeset
3546
kono
parents:
diff changeset
3547 tree result = build_cplus_array_type (element_type, range);
kono
parents:
diff changeset
3548
kono
parents:
diff changeset
3549 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3550 return convert_out (ctx->preserve (result));
kono
parents:
diff changeset
3551 }
kono
parents:
diff changeset
3552
kono
parents:
diff changeset
3553 gcc_type
kono
parents:
diff changeset
3554 plugin_build_qualified_type (cc1_plugin::connection *,
kono
parents:
diff changeset
3555 gcc_type unqualified_type_in,
kono
parents:
diff changeset
3556 enum gcc_cp_qualifiers qualifiers)
kono
parents:
diff changeset
3557 {
kono
parents:
diff changeset
3558 tree unqualified_type = convert_in (unqualified_type_in);
kono
parents:
diff changeset
3559 cp_cv_quals quals = 0;
kono
parents:
diff changeset
3560
kono
parents:
diff changeset
3561 if ((qualifiers & GCC_CP_QUALIFIER_CONST) != 0)
kono
parents:
diff changeset
3562 quals |= TYPE_QUAL_CONST;
kono
parents:
diff changeset
3563 if ((qualifiers & GCC_CP_QUALIFIER_VOLATILE) != 0)
kono
parents:
diff changeset
3564 quals |= TYPE_QUAL_VOLATILE;
kono
parents:
diff changeset
3565 if ((qualifiers & GCC_CP_QUALIFIER_RESTRICT) != 0)
kono
parents:
diff changeset
3566 quals |= TYPE_QUAL_RESTRICT;
kono
parents:
diff changeset
3567
kono
parents:
diff changeset
3568 gcc_assert ((TREE_CODE (unqualified_type) != METHOD_TYPE
kono
parents:
diff changeset
3569 && TREE_CODE (unqualified_type) != REFERENCE_TYPE)
kono
parents:
diff changeset
3570 || quals == 0);
kono
parents:
diff changeset
3571
kono
parents:
diff changeset
3572 return convert_out (build_qualified_type (unqualified_type, quals));
kono
parents:
diff changeset
3573 }
kono
parents:
diff changeset
3574
kono
parents:
diff changeset
3575 gcc_type
kono
parents:
diff changeset
3576 plugin_build_complex_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
3577 gcc_type base_type)
kono
parents:
diff changeset
3578 {
kono
parents:
diff changeset
3579 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3580 return convert_out (ctx->preserve (build_complex_type (convert_in (base_type))));
kono
parents:
diff changeset
3581 }
kono
parents:
diff changeset
3582
kono
parents:
diff changeset
3583 gcc_type
kono
parents:
diff changeset
3584 plugin_build_vector_type (cc1_plugin::connection *self,
kono
parents:
diff changeset
3585 gcc_type base_type, int nunits)
kono
parents:
diff changeset
3586 {
kono
parents:
diff changeset
3587 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3588 return convert_out (ctx->preserve (build_vector_type (convert_in (base_type),
kono
parents:
diff changeset
3589 nunits)));
kono
parents:
diff changeset
3590 }
kono
parents:
diff changeset
3591
kono
parents:
diff changeset
3592 int
kono
parents:
diff changeset
3593 plugin_build_constant (cc1_plugin::connection *self, gcc_type type_in,
kono
parents:
diff changeset
3594 const char *name, unsigned long value,
kono
parents:
diff changeset
3595 const char *filename, unsigned int line_number)
kono
parents:
diff changeset
3596 {
kono
parents:
diff changeset
3597 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3598 tree cst, decl;
kono
parents:
diff changeset
3599 tree type = convert_in (type_in);
kono
parents:
diff changeset
3600
kono
parents:
diff changeset
3601 cst = build_int_cst (type, value);
kono
parents:
diff changeset
3602 if (!TYPE_READONLY (type))
kono
parents:
diff changeset
3603 type = build_qualified_type (type, TYPE_QUAL_CONST);
kono
parents:
diff changeset
3604 decl = build_decl (ctx->get_source_location (filename, line_number),
kono
parents:
diff changeset
3605 VAR_DECL, get_identifier (name), type);
kono
parents:
diff changeset
3606 TREE_STATIC (decl) = 1;
kono
parents:
diff changeset
3607 TREE_READONLY (decl) = 1;
kono
parents:
diff changeset
3608 cp_finish_decl (decl, cst, true, NULL, LOOKUP_ONLYCONVERTING);
kono
parents:
diff changeset
3609 safe_pushdecl_maybe_friend (decl, false);
kono
parents:
diff changeset
3610
kono
parents:
diff changeset
3611 return 1;
kono
parents:
diff changeset
3612 }
kono
parents:
diff changeset
3613
kono
parents:
diff changeset
3614 gcc_type
kono
parents:
diff changeset
3615 plugin_error (cc1_plugin::connection *,
kono
parents:
diff changeset
3616 const char *message)
kono
parents:
diff changeset
3617 {
kono
parents:
diff changeset
3618 error ("%s", message);
kono
parents:
diff changeset
3619 return convert_out (error_mark_node);
kono
parents:
diff changeset
3620 }
kono
parents:
diff changeset
3621
kono
parents:
diff changeset
3622 int
kono
parents:
diff changeset
3623 plugin_add_static_assert (cc1_plugin::connection *self,
kono
parents:
diff changeset
3624 gcc_expr condition_in,
kono
parents:
diff changeset
3625 const char *errormsg,
kono
parents:
diff changeset
3626 const char *filename,
kono
parents:
diff changeset
3627 unsigned int line_number)
kono
parents:
diff changeset
3628 {
kono
parents:
diff changeset
3629 plugin_context *ctx = static_cast<plugin_context *> (self);
kono
parents:
diff changeset
3630 tree condition = convert_in (condition_in);
kono
parents:
diff changeset
3631
kono
parents:
diff changeset
3632 if (!errormsg)
kono
parents:
diff changeset
3633 errormsg = "";
kono
parents:
diff changeset
3634
kono
parents:
diff changeset
3635 tree message = build_string (strlen (errormsg) + 1, errormsg);
kono
parents:
diff changeset
3636
kono
parents:
diff changeset
3637 TREE_TYPE (message) = char_array_type_node;
kono
parents:
diff changeset
3638 fix_string_type (message);
kono
parents:
diff changeset
3639
kono
parents:
diff changeset
3640 source_location loc = ctx->get_source_location (filename, line_number);
kono
parents:
diff changeset
3641
kono
parents:
diff changeset
3642 bool member_p = at_class_scope_p ();
kono
parents:
diff changeset
3643
kono
parents:
diff changeset
3644 finish_static_assert (condition, message, loc, member_p);
kono
parents:
diff changeset
3645
kono
parents:
diff changeset
3646 return 1;
kono
parents:
diff changeset
3647 }
kono
parents:
diff changeset
3648
kono
parents:
diff changeset
3649
kono
parents:
diff changeset
3650
kono
parents:
diff changeset
3651 // Perform GC marking.
kono
parents:
diff changeset
3652
kono
parents:
diff changeset
3653 static void
kono
parents:
diff changeset
3654 gc_mark (void *, void *)
kono
parents:
diff changeset
3655 {
kono
parents:
diff changeset
3656 if (current_context != NULL)
kono
parents:
diff changeset
3657 current_context->mark ();
kono
parents:
diff changeset
3658 }
kono
parents:
diff changeset
3659
kono
parents:
diff changeset
3660 #ifdef __GNUC__
kono
parents:
diff changeset
3661 #pragma GCC visibility push(default)
kono
parents:
diff changeset
3662 #endif
kono
parents:
diff changeset
3663
kono
parents:
diff changeset
3664 int
kono
parents:
diff changeset
3665 plugin_init (struct plugin_name_args *plugin_info,
kono
parents:
diff changeset
3666 struct plugin_gcc_version *)
kono
parents:
diff changeset
3667 {
kono
parents:
diff changeset
3668 long fd = -1;
kono
parents:
diff changeset
3669 for (int i = 0; i < plugin_info->argc; ++i)
kono
parents:
diff changeset
3670 {
kono
parents:
diff changeset
3671 if (strcmp (plugin_info->argv[i].key, "fd") == 0)
kono
parents:
diff changeset
3672 {
kono
parents:
diff changeset
3673 char *tail;
kono
parents:
diff changeset
3674 errno = 0;
kono
parents:
diff changeset
3675 fd = strtol (plugin_info->argv[i].value, &tail, 0);
kono
parents:
diff changeset
3676 if (*tail != '\0' || errno != 0)
kono
parents:
diff changeset
3677 fatal_error (input_location,
kono
parents:
diff changeset
3678 "%s: invalid file descriptor argument to plugin",
kono
parents:
diff changeset
3679 plugin_info->base_name);
kono
parents:
diff changeset
3680 break;
kono
parents:
diff changeset
3681 }
kono
parents:
diff changeset
3682 }
kono
parents:
diff changeset
3683 if (fd == -1)
kono
parents:
diff changeset
3684 fatal_error (input_location,
kono
parents:
diff changeset
3685 "%s: required plugin argument %<fd%> is missing",
kono
parents:
diff changeset
3686 plugin_info->base_name);
kono
parents:
diff changeset
3687
kono
parents:
diff changeset
3688 current_context = new plugin_context (fd);
kono
parents:
diff changeset
3689
kono
parents:
diff changeset
3690 // Handshake.
kono
parents:
diff changeset
3691 cc1_plugin::protocol_int version;
kono
parents:
diff changeset
3692 if (!current_context->require ('H')
kono
parents:
diff changeset
3693 || ! ::cc1_plugin::unmarshall (current_context, &version))
kono
parents:
diff changeset
3694 fatal_error (input_location,
kono
parents:
diff changeset
3695 "%s: handshake failed", plugin_info->base_name);
kono
parents:
diff changeset
3696 if (version != GCC_CP_FE_VERSION_0)
kono
parents:
diff changeset
3697 fatal_error (input_location,
kono
parents:
diff changeset
3698 "%s: unknown version in handshake", plugin_info->base_name);
kono
parents:
diff changeset
3699
kono
parents:
diff changeset
3700 register_callback (plugin_info->base_name, PLUGIN_PRAGMAS,
kono
parents:
diff changeset
3701 plugin_init_extra_pragmas, NULL);
kono
parents:
diff changeset
3702 register_callback (plugin_info->base_name, PLUGIN_PRE_GENERICIZE,
kono
parents:
diff changeset
3703 rewrite_decls_to_addresses, NULL);
kono
parents:
diff changeset
3704 register_callback (plugin_info->base_name, PLUGIN_GGC_MARKING,
kono
parents:
diff changeset
3705 gc_mark, NULL);
kono
parents:
diff changeset
3706
kono
parents:
diff changeset
3707 lang_hooks.print_error_function = plugin_print_error_function;
kono
parents:
diff changeset
3708
kono
parents:
diff changeset
3709 #define GCC_METHOD0(R, N) \
kono
parents:
diff changeset
3710 { \
kono
parents:
diff changeset
3711 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
3712 = cc1_plugin::callback<R, plugin_ ## N>; \
kono
parents:
diff changeset
3713 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
3714 }
kono
parents:
diff changeset
3715 #define GCC_METHOD1(R, N, A) \
kono
parents:
diff changeset
3716 { \
kono
parents:
diff changeset
3717 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
3718 = cc1_plugin::callback<R, A, plugin_ ## N>; \
kono
parents:
diff changeset
3719 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
3720 }
kono
parents:
diff changeset
3721 #define GCC_METHOD2(R, N, A, B) \
kono
parents:
diff changeset
3722 { \
kono
parents:
diff changeset
3723 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
3724 = cc1_plugin::callback<R, A, B, plugin_ ## N>; \
kono
parents:
diff changeset
3725 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
3726 }
kono
parents:
diff changeset
3727 #define GCC_METHOD3(R, N, A, B, C) \
kono
parents:
diff changeset
3728 { \
kono
parents:
diff changeset
3729 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
3730 = cc1_plugin::callback<R, A, B, C, plugin_ ## N>; \
kono
parents:
diff changeset
3731 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
3732 }
kono
parents:
diff changeset
3733 #define GCC_METHOD4(R, N, A, B, C, D) \
kono
parents:
diff changeset
3734 { \
kono
parents:
diff changeset
3735 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
3736 = cc1_plugin::callback<R, A, B, C, D, \
kono
parents:
diff changeset
3737 plugin_ ## N>; \
kono
parents:
diff changeset
3738 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
3739 }
kono
parents:
diff changeset
3740 #define GCC_METHOD5(R, N, A, B, C, D, E) \
kono
parents:
diff changeset
3741 { \
kono
parents:
diff changeset
3742 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
3743 = cc1_plugin::callback<R, A, B, C, D, E, \
kono
parents:
diff changeset
3744 plugin_ ## N>; \
kono
parents:
diff changeset
3745 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
3746 }
kono
parents:
diff changeset
3747 #define GCC_METHOD7(R, N, A, B, C, D, E, F, G) \
kono
parents:
diff changeset
3748 { \
kono
parents:
diff changeset
3749 cc1_plugin::callback_ftype *fun \
kono
parents:
diff changeset
3750 = cc1_plugin::callback<R, A, B, C, D, E, F, G, \
kono
parents:
diff changeset
3751 plugin_ ## N>; \
kono
parents:
diff changeset
3752 current_context->add_callback (# N, fun); \
kono
parents:
diff changeset
3753 }
kono
parents:
diff changeset
3754
kono
parents:
diff changeset
3755 #include "gcc-cp-fe.def"
kono
parents:
diff changeset
3756
kono
parents:
diff changeset
3757 #undef GCC_METHOD0
kono
parents:
diff changeset
3758 #undef GCC_METHOD1
kono
parents:
diff changeset
3759 #undef GCC_METHOD2
kono
parents:
diff changeset
3760 #undef GCC_METHOD3
kono
parents:
diff changeset
3761 #undef GCC_METHOD4
kono
parents:
diff changeset
3762 #undef GCC_METHOD5
kono
parents:
diff changeset
3763 #undef GCC_METHOD7
kono
parents:
diff changeset
3764
kono
parents:
diff changeset
3765 return 0;
kono
parents:
diff changeset
3766 }