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