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"
|
| |