Deleted Added
full compact
c-objc-common.c (107590) c-objc-common.c (117395)
1/* Some code common to C and ObjC front ends.
2 Copyright (C) 2001 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 2, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING. If not, write to the Free
18Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include "config.h"
22#include "system.h"
23#include "tree.h"
24#include "rtl.h"
25#include "insn-config.h"
26#include "integrate.h"
27#include "expr.h"
28#include "c-tree.h"
29#include "function.h"
30#include "flags.h"
31#include "toplev.h"
32#include "diagnostic.h"
33#include "tree-inline.h"
34#include "varray.h"
35#include "ggc.h"
1/* Some code common to C and ObjC front ends.
2 Copyright (C) 2001 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 2, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING. If not, write to the Free
18Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include "config.h"
22#include "system.h"
23#include "tree.h"
24#include "rtl.h"
25#include "insn-config.h"
26#include "integrate.h"
27#include "expr.h"
28#include "c-tree.h"
29#include "function.h"
30#include "flags.h"
31#include "toplev.h"
32#include "diagnostic.h"
33#include "tree-inline.h"
34#include "varray.h"
35#include "ggc.h"
36#include "langhooks.h"
37#include "target.h"
36
38
37static int c_tree_printer PARAMS ((output_buffer *));
39static bool c_tree_printer PARAMS ((output_buffer *, text_info *));
38static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
39static void expand_deferred_fns PARAMS ((void));
40static tree start_cdtor PARAMS ((int));
41static void finish_cdtor PARAMS ((tree));
42
40static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
41static void expand_deferred_fns PARAMS ((void));
42static tree start_cdtor PARAMS ((int));
43static void finish_cdtor PARAMS ((tree));
44
43static varray_type deferred_fns;
45static GTY(()) varray_type deferred_fns;
44
45int
46c_missing_noreturn_ok_p (decl)
47 tree decl;
48{
49 /* A missing noreturn is not ok for freestanding implementations and
50 ok for the `main' function in hosted implementations. */
51 return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
52}
53
54/* We want to inline `extern inline' functions even if this would
55 violate inlining limits. Some glibc and linux constructs depend on
56 such functions always being inlined when optimizing. */
57
58int
59c_disregard_inline_limits (fn)
60 tree fn;
61{
62 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
63 return 1;
64
65 return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
66}
67
68static tree
69inline_forbidden_p (nodep, walk_subtrees, fn)
70 tree *nodep;
71 int *walk_subtrees ATTRIBUTE_UNUSED;
72 void *fn;
73{
74 tree node = *nodep;
75 tree t;
76
77 switch (TREE_CODE (node))
78 {
79 case CALL_EXPR:
80 t = get_callee_fndecl (node);
81
82 if (! t)
83 break;
84
85 /* We cannot inline functions that call setjmp. */
86 if (setjmp_call_p (t))
87 return node;
88
89 switch (DECL_FUNCTION_CODE (t))
90 {
91 /* We cannot inline functions that take a variable number of
92 arguments. */
46
47int
48c_missing_noreturn_ok_p (decl)
49 tree decl;
50{
51 /* A missing noreturn is not ok for freestanding implementations and
52 ok for the `main' function in hosted implementations. */
53 return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
54}
55
56/* We want to inline `extern inline' functions even if this would
57 violate inlining limits. Some glibc and linux constructs depend on
58 such functions always being inlined when optimizing. */
59
60int
61c_disregard_inline_limits (fn)
62 tree fn;
63{
64 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
65 return 1;
66
67 return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
68}
69
70static tree
71inline_forbidden_p (nodep, walk_subtrees, fn)
72 tree *nodep;
73 int *walk_subtrees ATTRIBUTE_UNUSED;
74 void *fn;
75{
76 tree node = *nodep;
77 tree t;
78
79 switch (TREE_CODE (node))
80 {
81 case CALL_EXPR:
82 t = get_callee_fndecl (node);
83
84 if (! t)
85 break;
86
87 /* We cannot inline functions that call setjmp. */
88 if (setjmp_call_p (t))
89 return node;
90
91 switch (DECL_FUNCTION_CODE (t))
92 {
93 /* We cannot inline functions that take a variable number of
94 arguments. */
93 case BUILT_IN_VARARGS_START:
95 case BUILT_IN_VA_START:
94 case BUILT_IN_STDARG_START:
95#if 0
96 /* Functions that need information about the address of the
97 caller can't (shouldn't?) be inlined. */
98 case BUILT_IN_RETURN_ADDRESS:
99#endif
100 return node;
101
102 default:
103 break;
104 }
105
106 break;
107
108 case DECL_STMT:
109 /* We cannot inline functions that contain other functions. */
110 if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
111 && DECL_INITIAL (TREE_OPERAND (node, 0)))
112 return node;
113 break;
114
115 case GOTO_STMT:
116 case GOTO_EXPR:
117 t = TREE_OPERAND (node, 0);
118
119 /* We will not inline a function which uses computed goto. The
120 addresses of its local labels, which may be tucked into
121 global storage, are of course not constant across
96 case BUILT_IN_STDARG_START:
97#if 0
98 /* Functions that need information about the address of the
99 caller can't (shouldn't?) be inlined. */
100 case BUILT_IN_RETURN_ADDRESS:
101#endif
102 return node;
103
104 default:
105 break;
106 }
107
108 break;
109
110 case DECL_STMT:
111 /* We cannot inline functions that contain other functions. */
112 if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
113 && DECL_INITIAL (TREE_OPERAND (node, 0)))
114 return node;
115 break;
116
117 case GOTO_STMT:
118 case GOTO_EXPR:
119 t = TREE_OPERAND (node, 0);
120
121 /* We will not inline a function which uses computed goto. The
122 addresses of its local labels, which may be tucked into
123 global storage, are of course not constant across
122 instantiations, which causes unexpected behaviour. */
124 instantiations, which causes unexpected behavior. */
123 if (TREE_CODE (t) != LABEL_DECL)
124 return node;
125
126 /* We cannot inline a nested function that jumps to a nonlocal
127 label. */
128 if (TREE_CODE (t) == LABEL_DECL
129 && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
130 return node;
131
132 break;
133
134 case RECORD_TYPE:
135 case UNION_TYPE:
136 /* We cannot inline a function of the form
137
138 void F (int i) { struct S { int ar[i]; } s; }
139
140 Attempting to do so produces a catch-22 in tree-inline.c.
141 If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
142 UNION_TYPE nodes, then it goes into infinite recursion on a
143 structure containing a pointer to its own type. If it doesn't,
144 then the type node for S doesn't get adjusted properly when
145 F is inlined, and we abort in find_function_data. */
146 for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
147 if (variably_modified_type_p (TREE_TYPE (t)))
148 return node;
149
150 default:
151 break;
152 }
153
154 return NULL_TREE;
155}
156
157int
158c_cannot_inline_tree_fn (fnp)
159 tree *fnp;
160{
161 tree fn = *fnp;
162 tree t;
163
164 if (flag_really_no_inline
165 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
166 return 1;
167
168 /* Don't auto-inline anything that might not be bound within
169 this unit of translation. */
125 if (TREE_CODE (t) != LABEL_DECL)
126 return node;
127
128 /* We cannot inline a nested function that jumps to a nonlocal
129 label. */
130 if (TREE_CODE (t) == LABEL_DECL
131 && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
132 return node;
133
134 break;
135
136 case RECORD_TYPE:
137 case UNION_TYPE:
138 /* We cannot inline a function of the form
139
140 void F (int i) { struct S { int ar[i]; } s; }
141
142 Attempting to do so produces a catch-22 in tree-inline.c.
143 If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
144 UNION_TYPE nodes, then it goes into infinite recursion on a
145 structure containing a pointer to its own type. If it doesn't,
146 then the type node for S doesn't get adjusted properly when
147 F is inlined, and we abort in find_function_data. */
148 for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
149 if (variably_modified_type_p (TREE_TYPE (t)))
150 return node;
151
152 default:
153 break;
154 }
155
156 return NULL_TREE;
157}
158
159int
160c_cannot_inline_tree_fn (fnp)
161 tree *fnp;
162{
163 tree fn = *fnp;
164 tree t;
165
166 if (flag_really_no_inline
167 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
168 return 1;
169
170 /* Don't auto-inline anything that might not be bound within
171 this unit of translation. */
170 if (!DECL_DECLARED_INLINE_P (fn) && flag_pic && TREE_PUBLIC (fn))
171 {
172 DECL_UNINLINABLE (fn) = 1;
173 return 1;
174 }
172 if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
173 goto cannot_inline;
175
176 if (! function_attribute_inlinable_p (fn))
174
175 if (! function_attribute_inlinable_p (fn))
177 {
178 DECL_UNINLINABLE (fn) = 1;
179 return 1;
180 }
176 goto cannot_inline;
181
182 /* If a function has pending sizes, we must not defer its
183 compilation, and we can't inline it as a tree. */
184 if (fn == current_function_decl)
185 {
186 t = get_pending_sizes ();
187 put_pending_sizes (t);
188
189 if (t)
177
178 /* If a function has pending sizes, we must not defer its
179 compilation, and we can't inline it as a tree. */
180 if (fn == current_function_decl)
181 {
182 t = get_pending_sizes ();
183 put_pending_sizes (t);
184
185 if (t)
190 {
191 DECL_UNINLINABLE (fn) = 1;
192 return 1;
193 }
186 goto cannot_inline;
194 }
195
196 if (DECL_CONTEXT (fn))
197 {
198 /* If a nested function has pending sizes, we may have already
199 saved them. */
200 if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
187 }
188
189 if (DECL_CONTEXT (fn))
190 {
191 /* If a nested function has pending sizes, we may have already
192 saved them. */
193 if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
201 {
202 DECL_UNINLINABLE (fn) = 1;
203 return 1;
204 }
194 goto cannot_inline;
205 }
206 else
207 {
208 /* We rely on the fact that this function is called upfront,
209 just before we start expanding a function. If FN is active
210 (i.e., it's the current_function_decl or a parent thereof),
211 we have to walk FN's saved tree. Otherwise, we can safely
212 assume we have done it before and, if we didn't mark it as
213 uninlinable (in which case we wouldn't have been called), it
214 is inlinable. Unfortunately, this strategy doesn't work for
215 nested functions, because they're only expanded as part of
216 their enclosing functions, so the inlinability test comes in
217 late. */
218 t = current_function_decl;
219
220 while (t && t != fn)
221 t = DECL_CONTEXT (t);
222 if (! t)
223 return 0;
224 }
225
195 }
196 else
197 {
198 /* We rely on the fact that this function is called upfront,
199 just before we start expanding a function. If FN is active
200 (i.e., it's the current_function_decl or a parent thereof),
201 we have to walk FN's saved tree. Otherwise, we can safely
202 assume we have done it before and, if we didn't mark it as
203 uninlinable (in which case we wouldn't have been called), it
204 is inlinable. Unfortunately, this strategy doesn't work for
205 nested functions, because they're only expanded as part of
206 their enclosing functions, so the inlinability test comes in
207 late. */
208 t = current_function_decl;
209
210 while (t && t != fn)
211 t = DECL_CONTEXT (t);
212 if (! t)
213 return 0;
214 }
215
226 if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
227 {
228 DECL_UNINLINABLE (fn) = 1;
229 return 1;
230 }
216 if (walk_tree_without_duplicates
217 (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn))
218 goto cannot_inline;
231
232 return 0;
219
220 return 0;
221
222 cannot_inline:
223 DECL_UNINLINABLE (fn) = 1;
224 return 1;
233}
234
225}
226
227/* Called from check_global_declarations. */
228
229bool
230c_warn_unused_global_decl (decl)
231 tree decl;
232{
233 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
234 return false;
235 if (DECL_IN_SYSTEM_HEADER (decl))
236 return false;
237
238 return true;
239}
240
235/* Initialization common to C and Objective-C front ends. */
236const char *
237c_objc_common_init (filename)
238 const char *filename;
239{
240 c_init_decl_processing ();
241
242 filename = c_common_init (filename);
241/* Initialization common to C and Objective-C front ends. */
242const char *
243c_objc_common_init (filename)
244 const char *filename;
245{
246 c_init_decl_processing ();
247
248 filename = c_common_init (filename);
249 if (filename == NULL)
250 return NULL;
243
251
244 add_c_tree_codes ();
245
246 save_lang_status = &push_c_function_context;
247 restore_lang_status = &pop_c_function_context;
248 mark_lang_status = &mark_c_function_context;
249 lang_expand_expr = c_expand_expr;
250 lang_expand_decl_stmt = c_expand_decl_stmt;
251
252 /* These were not defined in the Objective-C front end, but I'm
253 putting them here anyway. The diagnostic format decoder might
254 want an enhanced ObjC implementation. */
255 diagnostic_format_decoder (global_dc) = &c_tree_printer;
256 lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
257
258 /* If still unspecified, make it match -std=c99
259 (allowing for -pedantic-errors). */
260 if (mesg_implicit_function_declaration < 0)
261 {
262 if (flag_isoc99)
263 mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
264 else
265 mesg_implicit_function_declaration = 0;
266 }
267
268 VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
252 lang_expand_decl_stmt = c_expand_decl_stmt;
253
254 /* These were not defined in the Objective-C front end, but I'm
255 putting them here anyway. The diagnostic format decoder might
256 want an enhanced ObjC implementation. */
257 diagnostic_format_decoder (global_dc) = &c_tree_printer;
258 lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
259
260 /* If still unspecified, make it match -std=c99
261 (allowing for -pedantic-errors). */
262 if (mesg_implicit_function_declaration < 0)
263 {
264 if (flag_isoc99)
265 mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
266 else
267 mesg_implicit_function_declaration = 0;
268 }
269
270 VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
269 ggc_add_tree_varray_root (&deferred_fns, 1);
270
271 return filename;
272}
273
274/* Register a function tree, so that its optimization and conversion
275 to RTL is only done at the end of the compilation. */
276
277int
278defer_fn (fn)
279 tree fn;
280{
281 VARRAY_PUSH_TREE (deferred_fns, fn);
282
283 return 1;
284}
285
286/* Expand deferred functions for C and ObjC. */
287
288static void
289expand_deferred_fns ()
290{
291 unsigned int i;
292
293 for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
294 {
295 tree decl = VARRAY_TREE (deferred_fns, i);
296
297 if (! TREE_ASM_WRITTEN (decl))
298 {
299 /* For static inline functions, delay the decision whether to
300 emit them or not until wrapup_global_declarations. */
301 if (! TREE_PUBLIC (decl))
302 DECL_DEFER_OUTPUT (decl) = 1;
303 c_expand_deferred_function (decl);
304 }
305 }
306
271
272 return filename;
273}
274
275/* Register a function tree, so that its optimization and conversion
276 to RTL is only done at the end of the compilation. */
277
278int
279defer_fn (fn)
280 tree fn;
281{
282 VARRAY_PUSH_TREE (deferred_fns, fn);
283
284 return 1;
285}
286
287/* Expand deferred functions for C and ObjC. */
288
289static void
290expand_deferred_fns ()
291{
292 unsigned int i;
293
294 for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
295 {
296 tree decl = VARRAY_TREE (deferred_fns, i);
297
298 if (! TREE_ASM_WRITTEN (decl))
299 {
300 /* For static inline functions, delay the decision whether to
301 emit them or not until wrapup_global_declarations. */
302 if (! TREE_PUBLIC (decl))
303 DECL_DEFER_OUTPUT (decl) = 1;
304 c_expand_deferred_function (decl);
305 }
306 }
307
307 VARRAY_FREE (deferred_fns);
308 deferred_fns = 0;
308}
309
310static tree
311start_cdtor (method_type)
312 int method_type;
313{
314 tree fnname = get_file_function_name (method_type);
315 tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
316 tree body;
317
318 start_function (void_list_node_1,
319 build_nt (CALL_EXPR, fnname,
320 tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
321 NULL_TREE),
322 NULL_TREE);
323 store_parm_decls ();
324
325 current_function_cannot_inline
326 = "static constructors and destructors cannot be inlined";
327
328 body = c_begin_compound_stmt ();
329
330 pushlevel (0);
331 clear_last_expr ();
332 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
333
334 return body;
335}
336
337static void
338finish_cdtor (body)
339 tree body;
340{
341 tree scope;
342 tree block;
343
344 scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
345 block = poplevel (0, 0, 0);
346 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
347 SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
348
349 RECHAIN_STMTS (body, COMPOUND_BODY (body));
350
351 finish_function (0, 0);
352}
353
354/* Called at end of parsing, but before end-of-file processing. */
355
356void
357c_objc_common_finish_file ()
358{
359 expand_deferred_fns ();
360
361 if (static_ctors)
362 {
363 tree body = start_cdtor ('I');
364
365 for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
366 c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
367 NULL_TREE));
368
369 finish_cdtor (body);
370 }
371
372 if (static_dtors)
373 {
374 tree body = start_cdtor ('D');
375
376 for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
377 c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
378 NULL_TREE));
379
380 finish_cdtor (body);
381 }
382
383 {
384 int flags;
385 FILE *stream = dump_begin (TDI_all, &flags);
386
387 if (stream)
388 {
389 dump_node (getdecls (), flags & ~TDF_SLIM, stream);
390 dump_end (TDI_all, stream);
391 }
392 }
393}
394
395/* Called during diagnostic message formatting process to print a
396 source-level entity onto BUFFER. The meaning of the format specifiers
397 is as follows:
398 %D: a general decl,
399 %F: a function declaration,
400 %T: a type.
401
402 These format specifiers form a subset of the format specifiers set used
403 by the C++ front-end.
404 Please notice when called, the `%' part was already skipped by the
405 diagnostic machinery. */
309}
310
311static tree
312start_cdtor (method_type)
313 int method_type;
314{
315 tree fnname = get_file_function_name (method_type);
316 tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
317 tree body;
318
319 start_function (void_list_node_1,
320 build_nt (CALL_EXPR, fnname,
321 tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
322 NULL_TREE),
323 NULL_TREE);
324 store_parm_decls ();
325
326 current_function_cannot_inline
327 = "static constructors and destructors cannot be inlined";
328
329 body = c_begin_compound_stmt ();
330
331 pushlevel (0);
332 clear_last_expr ();
333 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
334
335 return body;
336}
337
338static void
339finish_cdtor (body)
340 tree body;
341{
342 tree scope;
343 tree block;
344
345 scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
346 block = poplevel (0, 0, 0);
347 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
348 SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
349
350 RECHAIN_STMTS (body, COMPOUND_BODY (body));
351
352 finish_function (0, 0);
353}
354
355/* Called at end of parsing, but before end-of-file processing. */
356
357void
358c_objc_common_finish_file ()
359{
360 expand_deferred_fns ();
361
362 if (static_ctors)
363 {
364 tree body = start_cdtor ('I');
365
366 for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
367 c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
368 NULL_TREE));
369
370 finish_cdtor (body);
371 }
372
373 if (static_dtors)
374 {
375 tree body = start_cdtor ('D');
376
377 for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
378 c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
379 NULL_TREE));
380
381 finish_cdtor (body);
382 }
383
384 {
385 int flags;
386 FILE *stream = dump_begin (TDI_all, &flags);
387
388 if (stream)
389 {
390 dump_node (getdecls (), flags & ~TDF_SLIM, stream);
391 dump_end (TDI_all, stream);
392 }
393 }
394}
395
396/* Called during diagnostic message formatting process to print a
397 source-level entity onto BUFFER. The meaning of the format specifiers
398 is as follows:
399 %D: a general decl,
400 %F: a function declaration,
401 %T: a type.
402
403 These format specifiers form a subset of the format specifiers set used
404 by the C++ front-end.
405 Please notice when called, the `%' part was already skipped by the
406 diagnostic machinery. */
406static int
407c_tree_printer (buffer)
407static bool
408c_tree_printer (buffer, text)
408 output_buffer *buffer;
409 output_buffer *buffer;
410 text_info *text;
409{
411{
410 tree t = va_arg (output_buffer_format_args (buffer), tree);
412 tree t = va_arg (*text->args_ptr, tree);
411
413
412 switch (*output_buffer_text_cursor (buffer))
414 switch (*text->format_spec)
413 {
414 case 'D':
415 case 'F':
416 case 'T':
417 {
418 const char *n = DECL_NAME (t)
415 {
416 case 'D':
417 case 'F':
418 case 'T':
419 {
420 const char *n = DECL_NAME (t)
419 ? (*decl_printable_name) (t, 2)
421 ? (*lang_hooks.decl_printable_name) (t, 2)
420 : "({anonymous})";
421 output_add_string (buffer, n);
422 }
422 : "({anonymous})";
423 output_add_string (buffer, n);
424 }
423 return 1;
425 return true;
424
425 default:
426
427 default:
426 return 0;
428 return false;
427 }
428}
429 }
430}
431
432#include "gt-c-objc-common.h"