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