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