c-objc-common.c revision 117395
190075Sobrien/* Some code common to C and ObjC front ends. 290075Sobrien Copyright (C) 2001 Free Software Foundation, Inc. 390075Sobrien 490075SobrienThis file is part of GCC. 590075Sobrien 690075SobrienGCC is free software; you can redistribute it and/or modify it under 790075Sobrienthe terms of the GNU General Public License as published by the Free 890075SobrienSoftware Foundation; either version 2, or (at your option) any later 990075Sobrienversion. 1090075Sobrien 1190075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1290075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1390075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1490075Sobrienfor more details. 1590075Sobrien 1690075SobrienYou should have received a copy of the GNU General Public License 1790075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 1890075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 1990075Sobrien02111-1307, USA. */ 2090075Sobrien 2190075Sobrien#include "config.h" 2290075Sobrien#include "system.h" 2390075Sobrien#include "tree.h" 2490075Sobrien#include "rtl.h" 2590075Sobrien#include "insn-config.h" 2690075Sobrien#include "integrate.h" 2790075Sobrien#include "expr.h" 2890075Sobrien#include "c-tree.h" 2990075Sobrien#include "function.h" 3090075Sobrien#include "flags.h" 3190075Sobrien#include "toplev.h" 3290075Sobrien#include "diagnostic.h" 3390075Sobrien#include "tree-inline.h" 3490075Sobrien#include "varray.h" 3590075Sobrien#include "ggc.h" 36117395Skan#include "langhooks.h" 37117395Skan#include "target.h" 3890075Sobrien 39117395Skanstatic bool c_tree_printer PARAMS ((output_buffer *, text_info *)); 4090075Sobrienstatic tree inline_forbidden_p PARAMS ((tree *, int *, void *)); 4190075Sobrienstatic void expand_deferred_fns PARAMS ((void)); 4290075Sobrienstatic tree start_cdtor PARAMS ((int)); 4390075Sobrienstatic void finish_cdtor PARAMS ((tree)); 4490075Sobrien 45117395Skanstatic GTY(()) varray_type deferred_fns; 4690075Sobrien 4790075Sobrienint 4890075Sobrienc_missing_noreturn_ok_p (decl) 4990075Sobrien tree decl; 5090075Sobrien{ 5190075Sobrien /* A missing noreturn is not ok for freestanding implementations and 5290075Sobrien ok for the `main' function in hosted implementations. */ 5390075Sobrien return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl)); 5490075Sobrien} 5590075Sobrien 5690075Sobrien/* We want to inline `extern inline' functions even if this would 5790075Sobrien violate inlining limits. Some glibc and linux constructs depend on 5890075Sobrien such functions always being inlined when optimizing. */ 5990075Sobrien 6090075Sobrienint 6190075Sobrienc_disregard_inline_limits (fn) 6290075Sobrien tree fn; 6390075Sobrien{ 6496263Sobrien if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL) 6596263Sobrien return 1; 6696263Sobrien 6790075Sobrien return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn); 6890075Sobrien} 6990075Sobrien 7090075Sobrienstatic tree 7190075Sobrieninline_forbidden_p (nodep, walk_subtrees, fn) 7290075Sobrien tree *nodep; 7390075Sobrien int *walk_subtrees ATTRIBUTE_UNUSED; 7490075Sobrien void *fn; 7590075Sobrien{ 7690075Sobrien tree node = *nodep; 7790075Sobrien tree t; 7890075Sobrien 7990075Sobrien switch (TREE_CODE (node)) 8090075Sobrien { 8190075Sobrien case CALL_EXPR: 8290075Sobrien t = get_callee_fndecl (node); 8390075Sobrien 8490075Sobrien if (! t) 8590075Sobrien break; 8690075Sobrien 8790075Sobrien /* We cannot inline functions that call setjmp. */ 8890075Sobrien if (setjmp_call_p (t)) 8990075Sobrien return node; 9090075Sobrien 9190075Sobrien switch (DECL_FUNCTION_CODE (t)) 9290075Sobrien { 9390075Sobrien /* We cannot inline functions that take a variable number of 9490075Sobrien arguments. */ 95117395Skan case BUILT_IN_VA_START: 9690075Sobrien case BUILT_IN_STDARG_START: 9790075Sobrien#if 0 9890075Sobrien /* Functions that need information about the address of the 9990075Sobrien caller can't (shouldn't?) be inlined. */ 10090075Sobrien case BUILT_IN_RETURN_ADDRESS: 10190075Sobrien#endif 10290075Sobrien return node; 10390075Sobrien 10490075Sobrien default: 10590075Sobrien break; 10690075Sobrien } 10790075Sobrien 10890075Sobrien break; 10990075Sobrien 11090075Sobrien case DECL_STMT: 11190075Sobrien /* We cannot inline functions that contain other functions. */ 11290075Sobrien if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL 11390075Sobrien && DECL_INITIAL (TREE_OPERAND (node, 0))) 11490075Sobrien return node; 11590075Sobrien break; 11690075Sobrien 11790075Sobrien case GOTO_STMT: 11890075Sobrien case GOTO_EXPR: 11990075Sobrien t = TREE_OPERAND (node, 0); 12090075Sobrien 12190075Sobrien /* We will not inline a function which uses computed goto. The 12290075Sobrien addresses of its local labels, which may be tucked into 12390075Sobrien global storage, are of course not constant across 124117395Skan instantiations, which causes unexpected behavior. */ 12590075Sobrien if (TREE_CODE (t) != LABEL_DECL) 12690075Sobrien return node; 12790075Sobrien 12890075Sobrien /* We cannot inline a nested function that jumps to a nonlocal 12990075Sobrien label. */ 13090075Sobrien if (TREE_CODE (t) == LABEL_DECL 13190075Sobrien && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn) 13290075Sobrien return node; 13390075Sobrien 13490075Sobrien break; 13590075Sobrien 136107590Sobrien case RECORD_TYPE: 137107590Sobrien case UNION_TYPE: 138107590Sobrien /* We cannot inline a function of the form 139107590Sobrien 140107590Sobrien void F (int i) { struct S { int ar[i]; } s; } 141107590Sobrien 142107590Sobrien Attempting to do so produces a catch-22 in tree-inline.c. 143107590Sobrien If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/ 144107590Sobrien UNION_TYPE nodes, then it goes into infinite recursion on a 145107590Sobrien structure containing a pointer to its own type. If it doesn't, 146107590Sobrien then the type node for S doesn't get adjusted properly when 147107590Sobrien F is inlined, and we abort in find_function_data. */ 148107590Sobrien for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t)) 149107590Sobrien if (variably_modified_type_p (TREE_TYPE (t))) 150107590Sobrien return node; 151107590Sobrien 15290075Sobrien default: 15390075Sobrien break; 15490075Sobrien } 15590075Sobrien 15690075Sobrien return NULL_TREE; 15790075Sobrien} 15890075Sobrien 15990075Sobrienint 16090075Sobrienc_cannot_inline_tree_fn (fnp) 16190075Sobrien tree *fnp; 16290075Sobrien{ 16390075Sobrien tree fn = *fnp; 16490075Sobrien tree t; 16590075Sobrien 16696263Sobrien if (flag_really_no_inline 16796263Sobrien && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL) 16896263Sobrien return 1; 16996263Sobrien 170104752Skan /* Don't auto-inline anything that might not be bound within 171104752Skan this unit of translation. */ 172117395Skan if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn)) 173117395Skan goto cannot_inline; 174104752Skan 17590075Sobrien if (! function_attribute_inlinable_p (fn)) 176117395Skan goto cannot_inline; 17790075Sobrien 17890075Sobrien /* If a function has pending sizes, we must not defer its 17990075Sobrien compilation, and we can't inline it as a tree. */ 18090075Sobrien if (fn == current_function_decl) 18190075Sobrien { 18290075Sobrien t = get_pending_sizes (); 18390075Sobrien put_pending_sizes (t); 18490075Sobrien 18590075Sobrien if (t) 186117395Skan goto cannot_inline; 18790075Sobrien } 18890075Sobrien 18990075Sobrien if (DECL_CONTEXT (fn)) 19090075Sobrien { 19190075Sobrien /* If a nested function has pending sizes, we may have already 19290075Sobrien saved them. */ 19390075Sobrien if (DECL_LANG_SPECIFIC (fn)->pending_sizes) 194117395Skan goto cannot_inline; 19590075Sobrien } 19690075Sobrien else 19790075Sobrien { 19890075Sobrien /* We rely on the fact that this function is called upfront, 19990075Sobrien just before we start expanding a function. If FN is active 20090075Sobrien (i.e., it's the current_function_decl or a parent thereof), 20190075Sobrien we have to walk FN's saved tree. Otherwise, we can safely 20290075Sobrien assume we have done it before and, if we didn't mark it as 20390075Sobrien uninlinable (in which case we wouldn't have been called), it 20490075Sobrien is inlinable. Unfortunately, this strategy doesn't work for 20590075Sobrien nested functions, because they're only expanded as part of 20690075Sobrien their enclosing functions, so the inlinability test comes in 20790075Sobrien late. */ 20890075Sobrien t = current_function_decl; 20990075Sobrien 21090075Sobrien while (t && t != fn) 21190075Sobrien t = DECL_CONTEXT (t); 21290075Sobrien if (! t) 21390075Sobrien return 0; 21490075Sobrien } 21590075Sobrien 216117395Skan if (walk_tree_without_duplicates 217117395Skan (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn)) 218117395Skan goto cannot_inline; 21990075Sobrien 22090075Sobrien return 0; 221117395Skan 222117395Skan cannot_inline: 223117395Skan DECL_UNINLINABLE (fn) = 1; 224117395Skan return 1; 22590075Sobrien} 22690075Sobrien 227117395Skan/* Called from check_global_declarations. */ 228117395Skan 229117395Skanbool 230117395Skanc_warn_unused_global_decl (decl) 231117395Skan tree decl; 232117395Skan{ 233117395Skan if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)) 234117395Skan return false; 235117395Skan if (DECL_IN_SYSTEM_HEADER (decl)) 236117395Skan return false; 237117395Skan 238117395Skan return true; 239117395Skan} 240117395Skan 24190075Sobrien/* Initialization common to C and Objective-C front ends. */ 24290075Sobrienconst char * 24390075Sobrienc_objc_common_init (filename) 24490075Sobrien const char *filename; 24590075Sobrien{ 24690075Sobrien c_init_decl_processing (); 24790075Sobrien 24890075Sobrien filename = c_common_init (filename); 249117395Skan if (filename == NULL) 250117395Skan return NULL; 25190075Sobrien 25290075Sobrien lang_expand_decl_stmt = c_expand_decl_stmt; 25390075Sobrien 25490075Sobrien /* These were not defined in the Objective-C front end, but I'm 25590075Sobrien putting them here anyway. The diagnostic format decoder might 25690075Sobrien want an enhanced ObjC implementation. */ 25790075Sobrien diagnostic_format_decoder (global_dc) = &c_tree_printer; 25890075Sobrien lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p; 25990075Sobrien 26090075Sobrien /* If still unspecified, make it match -std=c99 26190075Sobrien (allowing for -pedantic-errors). */ 26290075Sobrien if (mesg_implicit_function_declaration < 0) 26390075Sobrien { 26490075Sobrien if (flag_isoc99) 26590075Sobrien mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1; 26690075Sobrien else 26790075Sobrien mesg_implicit_function_declaration = 0; 26890075Sobrien } 26990075Sobrien 27090075Sobrien VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns"); 27190075Sobrien 27290075Sobrien return filename; 27390075Sobrien} 27490075Sobrien 27590075Sobrien/* Register a function tree, so that its optimization and conversion 27690075Sobrien to RTL is only done at the end of the compilation. */ 27790075Sobrien 27890075Sobrienint 27990075Sobriendefer_fn (fn) 28090075Sobrien tree fn; 28190075Sobrien{ 28290075Sobrien VARRAY_PUSH_TREE (deferred_fns, fn); 28390075Sobrien 28490075Sobrien return 1; 28590075Sobrien} 28690075Sobrien 28790075Sobrien/* Expand deferred functions for C and ObjC. */ 28890075Sobrien 28990075Sobrienstatic void 29090075Sobrienexpand_deferred_fns () 29190075Sobrien{ 29290075Sobrien unsigned int i; 29390075Sobrien 29490075Sobrien for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++) 29590075Sobrien { 29690075Sobrien tree decl = VARRAY_TREE (deferred_fns, i); 29790075Sobrien 29890075Sobrien if (! TREE_ASM_WRITTEN (decl)) 29990075Sobrien { 30090075Sobrien /* For static inline functions, delay the decision whether to 30190075Sobrien emit them or not until wrapup_global_declarations. */ 30290075Sobrien if (! TREE_PUBLIC (decl)) 30390075Sobrien DECL_DEFER_OUTPUT (decl) = 1; 30490075Sobrien c_expand_deferred_function (decl); 30590075Sobrien } 30690075Sobrien } 30790075Sobrien 308117395Skan deferred_fns = 0; 30990075Sobrien} 31090075Sobrien 31190075Sobrienstatic tree 31290075Sobrienstart_cdtor (method_type) 31390075Sobrien int method_type; 31490075Sobrien{ 31590075Sobrien tree fnname = get_file_function_name (method_type); 31690075Sobrien tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node); 31790075Sobrien tree body; 31890075Sobrien 31990075Sobrien start_function (void_list_node_1, 32090075Sobrien build_nt (CALL_EXPR, fnname, 32190075Sobrien tree_cons (NULL_TREE, NULL_TREE, void_list_node_1), 32290075Sobrien NULL_TREE), 32390075Sobrien NULL_TREE); 32490075Sobrien store_parm_decls (); 32590075Sobrien 32690075Sobrien current_function_cannot_inline 32790075Sobrien = "static constructors and destructors cannot be inlined"; 32890075Sobrien 32990075Sobrien body = c_begin_compound_stmt (); 33090075Sobrien 33190075Sobrien pushlevel (0); 33290075Sobrien clear_last_expr (); 33390075Sobrien add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0); 33490075Sobrien 33590075Sobrien return body; 33690075Sobrien} 33790075Sobrien 33890075Sobrienstatic void 33990075Sobrienfinish_cdtor (body) 34090075Sobrien tree body; 34190075Sobrien{ 34290075Sobrien tree scope; 34390075Sobrien tree block; 34490075Sobrien 34590075Sobrien scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0); 34690075Sobrien block = poplevel (0, 0, 0); 34790075Sobrien SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block; 34890075Sobrien SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block; 34990075Sobrien 35090075Sobrien RECHAIN_STMTS (body, COMPOUND_BODY (body)); 35190075Sobrien 35296263Sobrien finish_function (0, 0); 35390075Sobrien} 35490075Sobrien 35590075Sobrien/* Called at end of parsing, but before end-of-file processing. */ 35690075Sobrien 35790075Sobrienvoid 35890075Sobrienc_objc_common_finish_file () 35990075Sobrien{ 36090075Sobrien expand_deferred_fns (); 36190075Sobrien 36290075Sobrien if (static_ctors) 36390075Sobrien { 36490075Sobrien tree body = start_cdtor ('I'); 36590075Sobrien 36690075Sobrien for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors)) 36790075Sobrien c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors), 36890075Sobrien NULL_TREE)); 36990075Sobrien 37090075Sobrien finish_cdtor (body); 37190075Sobrien } 37290075Sobrien 37390075Sobrien if (static_dtors) 37490075Sobrien { 37590075Sobrien tree body = start_cdtor ('D'); 37690075Sobrien 37790075Sobrien for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors)) 37890075Sobrien c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors), 37990075Sobrien NULL_TREE)); 38090075Sobrien 38190075Sobrien finish_cdtor (body); 38290075Sobrien } 38390075Sobrien 38490075Sobrien { 38590075Sobrien int flags; 38690075Sobrien FILE *stream = dump_begin (TDI_all, &flags); 38790075Sobrien 38890075Sobrien if (stream) 38990075Sobrien { 39090075Sobrien dump_node (getdecls (), flags & ~TDF_SLIM, stream); 39190075Sobrien dump_end (TDI_all, stream); 39290075Sobrien } 39390075Sobrien } 39490075Sobrien} 39590075Sobrien 39690075Sobrien/* Called during diagnostic message formatting process to print a 39790075Sobrien source-level entity onto BUFFER. The meaning of the format specifiers 39890075Sobrien is as follows: 39990075Sobrien %D: a general decl, 40090075Sobrien %F: a function declaration, 40190075Sobrien %T: a type. 40290075Sobrien 40390075Sobrien These format specifiers form a subset of the format specifiers set used 40490075Sobrien by the C++ front-end. 40590075Sobrien Please notice when called, the `%' part was already skipped by the 40690075Sobrien diagnostic machinery. */ 407117395Skanstatic bool 408117395Skanc_tree_printer (buffer, text) 40990075Sobrien output_buffer *buffer; 410117395Skan text_info *text; 41190075Sobrien{ 412117395Skan tree t = va_arg (*text->args_ptr, tree); 41390075Sobrien 414117395Skan switch (*text->format_spec) 41590075Sobrien { 41690075Sobrien case 'D': 41790075Sobrien case 'F': 41890075Sobrien case 'T': 41990075Sobrien { 42090075Sobrien const char *n = DECL_NAME (t) 421117395Skan ? (*lang_hooks.decl_printable_name) (t, 2) 42290075Sobrien : "({anonymous})"; 42390075Sobrien output_add_string (buffer, n); 42490075Sobrien } 425117395Skan return true; 42690075Sobrien 42790075Sobrien default: 428117395Skan return false; 42990075Sobrien } 43090075Sobrien} 431117395Skan 432117395Skan#include "gt-c-objc-common.h" 433