]>
Commit | Line | Data |
---|---|---|
0abc6a6a | 1 | /* Some code common to C and ObjC front ends. |
f93089d2 | 2 | Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. |
0abc6a6a NB |
3 | |
4 | This file is part of GCC. | |
5 | ||
6 | GCC is free software; you can redistribute it and/or modify it under | |
7 | the terms of the GNU General Public License as published by the Free | |
8 | Software Foundation; either version 2, or (at your option) any later | |
9 | version. | |
10 | ||
11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 | for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GCC; see the file COPYING. If not, write to the Free | |
366ccddb KC |
18 | Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA |
19 | 02110-1301, USA. */ | |
0abc6a6a NB |
20 | |
21 | #include "config.h" | |
22 | #include "system.h" | |
4977bab6 ZW |
23 | #include "coretypes.h" |
24 | #include "tm.h" | |
0abc6a6a NB |
25 | #include "tree.h" |
26 | #include "rtl.h" | |
27 | #include "insn-config.h" | |
28 | #include "integrate.h" | |
0abc6a6a | 29 | #include "c-tree.h" |
ede1a387 | 30 | #include "c-pretty-print.h" |
0abc6a6a NB |
31 | #include "function.h" |
32 | #include "flags.h" | |
33 | #include "toplev.h" | |
34 | #include "diagnostic.h" | |
35 | #include "tree-inline.h" | |
3b27886e NB |
36 | #include "varray.h" |
37 | #include "ggc.h" | |
7afff7cf | 38 | #include "langhooks.h" |
6de9cd9a | 39 | #include "tree-mudflap.h" |
38ec83b1 | 40 | #include "target.h" |
9a4d6480 | 41 | #include "c-objc-common.h" |
0abc6a6a | 42 | |
39ce81c9 ZW |
43 | static bool c_tree_printer (pretty_printer *, text_info *, const char *, |
44 | int, bool, bool, bool); | |
3b27886e | 45 | |
6de9cd9a | 46 | bool |
2f6e4e97 | 47 | c_missing_noreturn_ok_p (tree decl) |
0abc6a6a NB |
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 | ||
58 | int | |
2f6e4e97 | 59 | c_disregard_inline_limits (tree fn) |
0abc6a6a | 60 | { |
6aa77e6c AH |
61 | if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL) |
62 | return 1; | |
63 | ||
b684a3df JH |
64 | return (!flag_really_no_inline && DECL_DECLARED_INLINE_P (fn) |
65 | && DECL_EXTERNAL (fn)); | |
0abc6a6a NB |
66 | } |
67 | ||
0abc6a6a | 68 | int |
2f6e4e97 | 69 | c_cannot_inline_tree_fn (tree *fnp) |
0abc6a6a NB |
70 | { |
71 | tree fn = *fnp; | |
f08545a8 JH |
72 | bool do_warning = (warn_inline |
73 | && DECL_INLINE (fn) | |
74 | && DECL_DECLARED_INLINE_P (fn) | |
75 | && !DECL_IN_SYSTEM_HEADER (fn)); | |
0abc6a6a | 76 | |
2cb921f4 | 77 | if (flag_really_no_inline |
6aa77e6c | 78 | && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL) |
f08545a8 JH |
79 | { |
80 | if (do_warning) | |
d2fcbf6f | 81 | warning (OPT_Winline, "function %q+F can never be inlined because it " |
dee15844 | 82 | "is suppressed using -fno-inline", fn); |
f08545a8 JH |
83 | goto cannot_inline; |
84 | } | |
6aa77e6c | 85 | |
2f6e4e97 | 86 | /* Don't auto-inline anything that might not be bound within |
38ec83b1 | 87 | this unit of translation. */ |
5fd9b178 | 88 | if (!DECL_DECLARED_INLINE_P (fn) && !targetm.binds_local_p (fn)) |
f08545a8 JH |
89 | { |
90 | if (do_warning) | |
d2fcbf6f DD |
91 | warning (OPT_Winline, "function %q+F can never be inlined because it " |
92 | "might not be bound within this unit of translation", fn); | |
f08545a8 JH |
93 | goto cannot_inline; |
94 | } | |
38ec83b1 | 95 | |
3f75a254 | 96 | if (!function_attribute_inlinable_p (fn)) |
f08545a8 JH |
97 | { |
98 | if (do_warning) | |
d2fcbf6f DD |
99 | warning (OPT_Winline, "function %q+F can never be inlined because it " |
100 | "uses attributes conflicting with inlining", fn); | |
f08545a8 JH |
101 | goto cannot_inline; |
102 | } | |
0abc6a6a | 103 | |
0abc6a6a | 104 | return 0; |
38ec83b1 RH |
105 | |
106 | cannot_inline: | |
107 | DECL_UNINLINABLE (fn) = 1; | |
108 | return 1; | |
0abc6a6a NB |
109 | } |
110 | ||
ef4f94ac RH |
111 | /* Called from check_global_declarations. */ |
112 | ||
113 | bool | |
2f6e4e97 | 114 | c_warn_unused_global_decl (tree decl) |
ef4f94ac RH |
115 | { |
116 | if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl)) | |
117 | return false; | |
118 | if (DECL_IN_SYSTEM_HEADER (decl)) | |
119 | return false; | |
120 | ||
121 | return true; | |
122 | } | |
123 | ||
0abc6a6a | 124 | /* Initialization common to C and Objective-C front ends. */ |
4bfec483 | 125 | bool |
2f6e4e97 | 126 | c_objc_common_init (void) |
0abc6a6a NB |
127 | { |
128 | c_init_decl_processing (); | |
129 | ||
4bfec483 NB |
130 | if (c_common_init () == false) |
131 | return false; | |
0abc6a6a | 132 | |
0abc6a6a NB |
133 | /* These were not defined in the Objective-C front end, but I'm |
134 | putting them here anyway. The diagnostic format decoder might | |
135 | want an enhanced ObjC implementation. */ | |
136 | diagnostic_format_decoder (global_dc) = &c_tree_printer; | |
0abc6a6a NB |
137 | |
138 | /* If still unspecified, make it match -std=c99 | |
139 | (allowing for -pedantic-errors). */ | |
140 | if (mesg_implicit_function_declaration < 0) | |
141 | { | |
142 | if (flag_isoc99) | |
143 | mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1; | |
144 | else | |
145 | mesg_implicit_function_declaration = 0; | |
146 | } | |
147 | ||
4bfec483 | 148 | return true; |
0abc6a6a NB |
149 | } |
150 | ||
151 | /* Called during diagnostic message formatting process to print a | |
152 | source-level entity onto BUFFER. The meaning of the format specifiers | |
153 | is as follows: | |
154 | %D: a general decl, | |
7848dfca | 155 | %E: an identifier or expression, |
0abc6a6a NB |
156 | %F: a function declaration, |
157 | %T: a type. | |
158 | ||
159 | These format specifiers form a subset of the format specifiers set used | |
160 | by the C++ front-end. | |
161 | Please notice when called, the `%' part was already skipped by the | |
162 | diagnostic machinery. */ | |
47b69537 | 163 | static bool |
39ce81c9 | 164 | c_tree_printer (pretty_printer *pp, text_info *text, const char *spec, |
dee15844 | 165 | int precision, bool wide, bool set_locus, bool hash) |
0abc6a6a | 166 | { |
47b69537 | 167 | tree t = va_arg (*text->args_ptr, tree); |
ede1a387 | 168 | tree name; |
c157f85c | 169 | const char *n = "({anonymous})"; |
ede1a387 JM |
170 | c_pretty_printer *cpp = (c_pretty_printer *) pp; |
171 | pp->padding = pp_none; | |
0abc6a6a | 172 | |
dee15844 | 173 | if (precision != 0 || wide || hash) |
39ce81c9 ZW |
174 | return false; |
175 | ||
dee15844 JM |
176 | if (set_locus && text->locus) |
177 | *text->locus = DECL_SOURCE_LOCATION (t); | |
178 | ||
39ce81c9 | 179 | switch (*spec) |
0abc6a6a NB |
180 | { |
181 | case 'D': | |
f991abd1 | 182 | if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t)) |
dad2a933 RH |
183 | { |
184 | t = DECL_DEBUG_EXPR (t); | |
185 | if (!DECL_P (t)) | |
186 | { | |
187 | pp_c_expression (cpp, t); | |
188 | return true; | |
189 | } | |
190 | } | |
191 | /* FALLTHRU */ | |
192 | ||
0abc6a6a | 193 | case 'F': |
c157f85c | 194 | if (DECL_NAME (t)) |
ae2bcd98 | 195 | n = lang_hooks.decl_printable_name (t, 2); |
c157f85c RH |
196 | break; |
197 | ||
0abc6a6a | 198 | case 'T': |
366de0ce NS |
199 | gcc_assert (TYPE_P (t)); |
200 | name = TYPE_NAME (t); | |
201 | ||
ede1a387 | 202 | if (name && TREE_CODE (name) == TYPE_DECL) |
c157f85c | 203 | { |
ede1a387 JM |
204 | if (DECL_NAME (name)) |
205 | pp_string (cpp, lang_hooks.decl_printable_name (name, 2)); | |
206 | else | |
207 | pp_type_id (cpp, t); | |
208 | return true; | |
209 | } | |
210 | else | |
211 | { | |
212 | pp_type_id (cpp, t); | |
213 | return true; | |
c157f85c | 214 | } |
c157f85c | 215 | break; |
0abc6a6a | 216 | |
eb8221ea | 217 | case 'E': |
c157f85c RH |
218 | if (TREE_CODE (t) == IDENTIFIER_NODE) |
219 | n = IDENTIFIER_POINTER (t); | |
220 | else | |
7848dfca JM |
221 | { |
222 | pp_expression (cpp, t); | |
223 | return true; | |
224 | } | |
c157f85c | 225 | break; |
eb8221ea | 226 | |
0abc6a6a | 227 | default: |
47b69537 | 228 | return false; |
0abc6a6a | 229 | } |
c157f85c | 230 | |
ede1a387 | 231 | pp_string (cpp, n); |
c157f85c | 232 | return true; |
0abc6a6a | 233 | } |
e57e265b | 234 | |
84b8b0e0 ZW |
235 | /* In C and ObjC, all decls have "C" linkage. */ |
236 | bool | |
237 | has_c_linkage (tree decl ATTRIBUTE_UNUSED) | |
238 | { | |
239 | return true; | |
240 | } | |
ede1a387 JM |
241 | |
242 | void | |
243 | c_initialize_diagnostics (diagnostic_context *context) | |
244 | { | |
245 | pretty_printer *base = context->printer; | |
5d038c4c | 246 | c_pretty_printer *pp = XNEW (c_pretty_printer); |
ede1a387 JM |
247 | memcpy (pp_base (pp), base, sizeof (pretty_printer)); |
248 | pp_c_pretty_printer_init (pp); | |
249 | context->printer = (pretty_printer *) pp; | |
250 | ||
5d038c4c BI |
251 | /* It is safe to free this object because it was previously XNEW()'d. */ |
252 | XDELETE (base); | |
ede1a387 | 253 | } |
65958285 ZL |
254 | |
255 | int | |
256 | c_types_compatible_p (tree x, tree y) | |
257 | { | |
258 | return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y)); | |
259 | } |