00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #include "system.h"
00029 #ifdef SGI_MONGOOSE
00030
00031 #include "rtl.h"
00032 #endif
00033 #include "tree.h"
00034 #ifndef SGI_MONGOOSE
00035 #include "rtl.h"
00036 #endif
00037 #include "insn-config.h"
00038 #include "integrate.h"
00039 #include "expr.h"
00040 #include "c-tree.h"
00041 #include "function.h"
00042 #include "flags.h"
00043 #include "toplev.h"
00044 #include "diagnostic.h"
00045 #include "tree-inline.h"
00046 #include "varray.h"
00047 #include "ggc.h"
00048 #include "langhooks.h"
00049 #include "target.h"
00050
00051 static bool c_tree_printer PARAMS ((output_buffer *, text_info *));
00052 static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
00053 static void expand_deferred_fns PARAMS ((void));
00054 static tree start_cdtor PARAMS ((int));
00055 static void finish_cdtor PARAMS ((tree));
00056
00057 static GTY(()) varray_type deferred_fns;
00058
00059 int
00060 c_missing_noreturn_ok_p (decl)
00061 tree decl;
00062 {
00063
00064
00065 return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
00066 }
00067
00068
00069
00070
00071
00072 int
00073 c_disregard_inline_limits (fn)
00074 tree fn;
00075 {
00076 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
00077 return 1;
00078
00079 return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
00080 }
00081
00082 static tree
00083 inline_forbidden_p (nodep, walk_subtrees, fn)
00084 tree *nodep;
00085 int *walk_subtrees ATTRIBUTE_UNUSED;
00086 void *fn;
00087 {
00088 tree node = *nodep;
00089 tree t;
00090
00091 switch (TREE_CODE (node))
00092 {
00093 case CALL_EXPR:
00094 t = get_callee_fndecl (node);
00095
00096 if (! t)
00097 break;
00098
00099
00100 if (setjmp_call_p (t))
00101 return node;
00102
00103 switch (DECL_FUNCTION_CODE (t))
00104 {
00105
00106
00107 case BUILT_IN_VA_START:
00108 case BUILT_IN_STDARG_START:
00109 #if 0
00110
00111
00112 case BUILT_IN_RETURN_ADDRESS:
00113 #endif
00114 return node;
00115
00116 default:
00117 break;
00118 }
00119
00120 break;
00121
00122 case DECL_STMT:
00123
00124 if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
00125 && DECL_INITIAL (TREE_OPERAND (node, 0)))
00126 return node;
00127 break;
00128
00129 case GOTO_STMT:
00130 case GOTO_EXPR:
00131 t = TREE_OPERAND (node, 0);
00132
00133
00134
00135
00136
00137 if (TREE_CODE (t) != LABEL_DECL)
00138 return node;
00139
00140
00141
00142 if (TREE_CODE (t) == LABEL_DECL
00143 && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
00144 return node;
00145
00146 break;
00147
00148 case RECORD_TYPE:
00149 case UNION_TYPE:
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
00161 if (variably_modified_type_p (TREE_TYPE (t)))
00162 return node;
00163
00164 default:
00165 break;
00166 }
00167
00168 return NULL_TREE;
00169 }
00170
00171 int
00172 c_cannot_inline_tree_fn (fnp)
00173 tree *fnp;
00174 {
00175 tree fn = *fnp;
00176 tree t;
00177
00178 if (flag_really_no_inline
00179 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
00180 return 1;
00181
00182
00183
00184 if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
00185 goto cannot_inline;
00186
00187 if (! function_attribute_inlinable_p (fn))
00188 goto cannot_inline;
00189
00190
00191
00192 if (fn == current_function_decl)
00193 {
00194 t = get_pending_sizes ();
00195 put_pending_sizes (t);
00196
00197 if (t)
00198 goto cannot_inline;
00199 }
00200
00201 if (DECL_CONTEXT (fn))
00202 {
00203
00204
00205 if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
00206 goto cannot_inline;
00207 }
00208 else
00209 {
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 t = current_function_decl;
00221
00222 while (t && t != fn)
00223 t = DECL_CONTEXT (t);
00224 if (! t)
00225 return 0;
00226 }
00227
00228 if (walk_tree_without_duplicates
00229 (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn))
00230 goto cannot_inline;
00231
00232 return 0;
00233
00234 cannot_inline:
00235 DECL_UNINLINABLE (fn) = 1;
00236 return 1;
00237 }
00238
00239
00240
00241 bool
00242 c_warn_unused_global_decl (decl)
00243 tree decl;
00244 {
00245 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
00246 return false;
00247 if (DECL_IN_SYSTEM_HEADER (decl))
00248 return false;
00249
00250 return true;
00251 }
00252
00253
00254 const char *
00255 c_objc_common_init (filename)
00256 const char *filename;
00257 {
00258 c_init_decl_processing ();
00259
00260 filename = c_common_init (filename);
00261 if (filename == NULL)
00262 return NULL;
00263
00264 lang_expand_decl_stmt = c_expand_decl_stmt;
00265
00266
00267
00268
00269 diagnostic_format_decoder (global_dc) = &c_tree_printer;
00270 lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
00271
00272
00273
00274 if (mesg_implicit_function_declaration < 0)
00275 {
00276 if (flag_isoc99)
00277 mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
00278 else
00279 mesg_implicit_function_declaration = 0;
00280 }
00281
00282 VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
00283
00284 return filename;
00285 }
00286
00287
00288
00289
00290 int
00291 defer_fn (fn)
00292 tree fn;
00293 {
00294 VARRAY_PUSH_TREE (deferred_fns, fn);
00295
00296 return 1;
00297 }
00298
00299
00300
00301 static void
00302 expand_deferred_fns ()
00303 {
00304 unsigned int i;
00305
00306 for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
00307 {
00308 tree decl = VARRAY_TREE (deferred_fns, i);
00309
00310 if (! TREE_ASM_WRITTEN (decl))
00311 {
00312
00313
00314 if (! TREE_PUBLIC (decl))
00315 DECL_DEFER_OUTPUT (decl) = 1;
00316 c_expand_deferred_function (decl);
00317 }
00318 }
00319
00320 deferred_fns = 0;
00321 }
00322
00323 static tree
00324 start_cdtor (method_type)
00325 int method_type;
00326 {
00327 tree fnname = get_file_function_name (method_type);
00328 tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
00329 tree body;
00330
00331 start_function (void_list_node_1,
00332 build_nt (CALL_EXPR, fnname,
00333 tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
00334 NULL_TREE),
00335 NULL_TREE);
00336 store_parm_decls ();
00337
00338 current_function_cannot_inline
00339 = "static constructors and destructors cannot be inlined";
00340
00341 body = c_begin_compound_stmt ();
00342
00343 pushlevel (0);
00344 clear_last_expr ();
00345 add_scope_stmt (1, 0);
00346
00347 return body;
00348 }
00349
00350 static void
00351 finish_cdtor (body)
00352 tree body;
00353 {
00354 tree scope;
00355 tree block;
00356
00357 scope = add_scope_stmt (0, 0);
00358 block = poplevel (0, 0, 0);
00359 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
00360 SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
00361
00362 RECHAIN_STMTS (body, COMPOUND_BODY (body));
00363
00364 finish_function (0, 0);
00365 }
00366
00367
00368
00369 void
00370 c_objc_common_finish_file ()
00371 {
00372 expand_deferred_fns ();
00373
00374 if (static_ctors)
00375 {
00376 tree body = start_cdtor ('I');
00377
00378 for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
00379 c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
00380 NULL_TREE));
00381
00382 finish_cdtor (body);
00383 }
00384
00385 if (static_dtors)
00386 {
00387 tree body = start_cdtor ('D');
00388
00389 for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
00390 c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
00391 NULL_TREE));
00392
00393 finish_cdtor (body);
00394 }
00395
00396 {
00397 int flags;
00398 FILE *stream = dump_begin (TDI_all, &flags);
00399
00400 if (stream)
00401 {
00402 dump_node (getdecls (), flags & ~TDF_SLIM, stream);
00403 dump_end (TDI_all, stream);
00404 }
00405 }
00406 }
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 static bool
00420 c_tree_printer (buffer, text)
00421 output_buffer *buffer;
00422 text_info *text;
00423 {
00424 tree t = va_arg (*text->args_ptr, tree);
00425
00426 switch (*text->format_spec)
00427 {
00428 case 'D':
00429 case 'F':
00430 case 'T':
00431 {
00432 const char *n = DECL_NAME (t)
00433 ? (*lang_hooks.decl_printable_name) (t, 2)
00434 : "({anonymous})";
00435 output_add_string (buffer, n);
00436 }
00437 return true;
00438
00439 default:
00440 return false;
00441 }
00442 }
00443
00444 #include "gt-c-objc-common.h"