]>
Commit | Line | Data |
---|---|---|
8d08fdba | 1 | /* Separate lexical analyzer for GNU C++. |
d6a8bdff | 2 | Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
c58b209a | 3 | 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. |
8d08fdba MS |
4 | Hacked by Michael Tiemann (tiemann@cygnus.com) |
5 | ||
f5adbb8d | 6 | This file is part of GCC. |
8d08fdba | 7 | |
f5adbb8d | 8 | GCC is free software; you can redistribute it and/or modify |
8d08fdba MS |
9 | it under the terms of the GNU General Public License as published by |
10 | the Free Software Foundation; either version 2, or (at your option) | |
11 | any later version. | |
12 | ||
f5adbb8d | 13 | GCC is distributed in the hope that it will be useful, |
8d08fdba MS |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
f5adbb8d | 19 | along with GCC; see the file COPYING. If not, write to |
e9fa0c7c RK |
20 | the Free Software Foundation, 59 Temple Place - Suite 330, |
21 | Boston, MA 02111-1307, USA. */ | |
8d08fdba MS |
22 | |
23 | ||
24 | /* This file is the lexical analyzer for GNU C++. */ | |
25 | ||
da20811c | 26 | #include "config.h" |
8d052bc7 | 27 | #include "system.h" |
4977bab6 ZW |
28 | #include "coretypes.h" |
29 | #include "tm.h" | |
8d08fdba MS |
30 | #include "input.h" |
31 | #include "tree.h" | |
8d08fdba | 32 | #include "cp-tree.h" |
0e5921e8 | 33 | #include "cpplib.h" |
f09f1de5 | 34 | #include "lex.h" |
8d08fdba | 35 | #include "flags.h" |
3d6f7931 | 36 | #include "c-pragma.h" |
54f92bfb | 37 | #include "toplev.h" |
7dee3f36 | 38 | #include "output.h" |
7bdb32b9 | 39 | #include "tm_p.h" |
2a9a326b | 40 | #include "timevar.h" |
856b6244 | 41 | #include "diagnostic.h" |
8d08fdba | 42 | |
158991b7 | 43 | static int interface_strcmp PARAMS ((const char *)); |
0e5921e8 | 44 | static void init_cp_pragma PARAMS ((void)); |
0e5921e8 ZW |
45 | |
46 | static tree parse_strconst_pragma PARAMS ((const char *, int)); | |
47 | static void handle_pragma_vtable PARAMS ((cpp_reader *)); | |
48 | static void handle_pragma_unit PARAMS ((cpp_reader *)); | |
49 | static void handle_pragma_interface PARAMS ((cpp_reader *)); | |
50 | static void handle_pragma_implementation PARAMS ((cpp_reader *)); | |
1f730ff7 | 51 | static void handle_pragma_java_exceptions PARAMS ((cpp_reader *)); |
0e5921e8 | 52 | |
158991b7 | 53 | static int is_global PARAMS ((tree)); |
596ea4e5 | 54 | static void init_operators PARAMS ((void)); |
76648a8b | 55 | static void copy_lang_type PARAMS ((tree)); |
8d08fdba | 56 | |
0e5921e8 | 57 | /* A constraint that can be tested at compile time. */ |
0e5921e8 | 58 | #define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1] |
66a6250f | 59 | |
87e3dbc9 MM |
60 | /* Functions and data structures for #pragma interface. |
61 | ||
62 | `#pragma implementation' means that the main file being compiled | |
63 | is considered to implement (provide) the classes that appear in | |
64 | its main body. I.e., if this is file "foo.cc", and class `bar' | |
65 | is defined in "foo.cc", then we say that "foo.cc implements bar". | |
66 | ||
67 | All main input files "implement" themselves automagically. | |
68 | ||
69 | `#pragma interface' means that unless this file (of the form "foo.h" | |
70 | is not presently being included by file "foo.cc", the | |
71 | CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none | |
72 | of the vtables nor any of the inline functions defined in foo.h | |
73 | will ever be output. | |
74 | ||
75 | There are cases when we want to link files such as "defs.h" and | |
76 | "main.cc". In this case, we give "defs.h" a `#pragma interface', | |
77 | and "main.cc" has `#pragma implementation "defs.h"'. */ | |
78 | ||
79 | struct impl_files | |
80 | { | |
520a57c8 | 81 | const char *filename; |
87e3dbc9 MM |
82 | struct impl_files *next; |
83 | }; | |
84 | ||
85 | static struct impl_files *impl_file_chain; | |
86 | ||
8d08fdba MS |
87 | \f |
88 | /* Return something to represent absolute declarators containing a *. | |
89 | TARGET is the absolute declarator that the * contains. | |
c11b6f21 | 90 | CV_QUALIFIERS is a list of modifiers such as const or volatile |
8d08fdba MS |
91 | to apply to the pointer type, represented as identifiers. |
92 | ||
93 | We return an INDIRECT_REF whose "contents" are TARGET | |
94 | and whose type is the modifier list. */ | |
95 | ||
96 | tree | |
c11b6f21 MS |
97 | make_pointer_declarator (cv_qualifiers, target) |
98 | tree cv_qualifiers, target; | |
8d08fdba MS |
99 | { |
100 | if (target && TREE_CODE (target) == IDENTIFIER_NODE | |
101 | && ANON_AGGRNAME_P (target)) | |
8251199e | 102 | error ("type name expected before `*'"); |
718b8ea5 | 103 | target = build_nt (INDIRECT_REF, target); |
c11b6f21 | 104 | TREE_TYPE (target) = cv_qualifiers; |
8d08fdba MS |
105 | return target; |
106 | } | |
107 | ||
108 | /* Return something to represent absolute declarators containing a &. | |
109 | TARGET is the absolute declarator that the & contains. | |
c11b6f21 | 110 | CV_QUALIFIERS is a list of modifiers such as const or volatile |
8d08fdba MS |
111 | to apply to the reference type, represented as identifiers. |
112 | ||
113 | We return an ADDR_EXPR whose "contents" are TARGET | |
114 | and whose type is the modifier list. */ | |
5362b086 | 115 | |
8d08fdba | 116 | tree |
c11b6f21 MS |
117 | make_reference_declarator (cv_qualifiers, target) |
118 | tree cv_qualifiers, target; | |
8d08fdba | 119 | { |
718b8ea5 | 120 | target = build_nt (ADDR_EXPR, target); |
c11b6f21 | 121 | TREE_TYPE (target) = cv_qualifiers; |
8d08fdba MS |
122 | return target; |
123 | } | |
c11b6f21 MS |
124 | |
125 | tree | |
126 | make_call_declarator (target, parms, cv_qualifiers, exception_specification) | |
127 | tree target, parms, cv_qualifiers, exception_specification; | |
128 | { | |
718b8ea5 JM |
129 | target = build_nt (CALL_EXPR, target, |
130 | tree_cons (parms, cv_qualifiers, NULL_TREE), | |
131 | /* The third operand is really RTL. We | |
132 | shouldn't put anything there. */ | |
133 | NULL_TREE); | |
43f887f9 | 134 | CALL_DECLARATOR_EXCEPTION_SPEC (target) = exception_specification; |
c11b6f21 MS |
135 | return target; |
136 | } | |
137 | ||
138 | void | |
139 | set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification) | |
140 | tree call_declarator, cv_qualifiers, exception_specification; | |
141 | { | |
43f887f9 MM |
142 | CALL_DECLARATOR_QUALS (call_declarator) = cv_qualifiers; |
143 | CALL_DECLARATOR_EXCEPTION_SPEC (call_declarator) = exception_specification; | |
c11b6f21 | 144 | } |
8d08fdba | 145 | \f |
8d08fdba MS |
146 | int interface_only; /* whether or not current file is only for |
147 | interface definitions. */ | |
148 | int interface_unknown; /* whether or not we know this class | |
149 | to behave according to #pragma interface. */ | |
150 | ||
8d08fdba | 151 | \f |
4d6baafa | 152 | /* Initialization before switch parsing. */ |
2772ef3e | 153 | int |
ee811cfd | 154 | cxx_init_options () |
9116eca2 RH |
155 | { |
156 | /* Default exceptions on. */ | |
157 | flag_exceptions = 1; | |
24805e80 GDR |
158 | /* By default wrap lines at 80 characters. Is getenv ("COLUMNS") |
159 | preferable? */ | |
9596ddd6 | 160 | diagnostic_line_cutoff (global_dc) = 80; |
856b6244 GDR |
161 | /* By default, emit location information once for every |
162 | diagnostic message. */ | |
9596ddd6 | 163 | diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE; |
2772ef3e NB |
164 | |
165 | return c_common_init_options (clk_cplusplus); | |
9116eca2 RH |
166 | } |
167 | ||
19551f29 | 168 | void |
13c61421 | 169 | cxx_finish () |
8d08fdba | 170 | { |
22703ccc | 171 | c_common_finish (); |
8d08fdba MS |
172 | } |
173 | ||
596ea4e5 AS |
174 | /* A mapping from tree codes to operator name information. */ |
175 | operator_name_info_t operator_name_info[(int) LAST_CPLUS_TREE_CODE]; | |
176 | /* Similar, but for assignment operators. */ | |
177 | operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE]; | |
5362b086 | 178 | |
596ea4e5 AS |
179 | /* Initialize data structures that keep track of operator names. */ |
180 | ||
0c918ce5 | 181 | #define DEF_OPERATOR(NAME, C, M, AR, AP) \ |
0e5921e8 ZW |
182 | CONSTRAINT (C, sizeof "operator " + sizeof NAME <= 256); |
183 | #include "operators.def" | |
184 | #undef DEF_OPERATOR | |
185 | ||
596ea4e5 AS |
186 | static void |
187 | init_operators () | |
188 | { | |
189 | tree identifier; | |
190 | char buffer[256]; | |
191 | struct operator_name_info_t *oni; | |
5362b086 | 192 | |
0c918ce5 | 193 | #define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, ASSN_P) \ |
dba1acea | 194 | sprintf (buffer, ISALPHA (NAME[0]) ? "operator %s" : "operator%s", NAME); \ |
596ea4e5 AS |
195 | identifier = get_identifier (buffer); \ |
196 | IDENTIFIER_OPNAME_P (identifier) = 1; \ | |
197 | \ | |
198 | oni = (ASSN_P \ | |
199 | ? &assignment_operator_name_info[(int) CODE] \ | |
200 | : &operator_name_info[(int) CODE]); \ | |
201 | oni->identifier = identifier; \ | |
202 | oni->name = NAME; \ | |
3fa3c4bd MM |
203 | oni->mangled_name = MANGLING; \ |
204 | oni->arity = ARITY; | |
596ea4e5 AS |
205 | |
206 | #include "operators.def" | |
207 | #undef DEF_OPERATOR | |
208 | ||
5362b086 | 209 | operator_name_info[(int) ERROR_MARK].identifier |
596ea4e5 AS |
210 | = get_identifier ("<invalid operator>"); |
211 | ||
212 | /* Handle some special cases. These operators are not defined in | |
213 | the language, but can be produced internally. We may need them | |
214 | for error-reporting. (Eventually, we should ensure that this | |
215 | does not happen. Error messages involving these operators will | |
216 | be confusing to users.) */ | |
5362b086 EC |
217 | |
218 | operator_name_info [(int) INIT_EXPR].name | |
596ea4e5 AS |
219 | = operator_name_info [(int) MODIFY_EXPR].name; |
220 | operator_name_info [(int) EXACT_DIV_EXPR].name = "(ceiling /)"; | |
221 | operator_name_info [(int) CEIL_DIV_EXPR].name = "(ceiling /)"; | |
222 | operator_name_info [(int) FLOOR_DIV_EXPR].name = "(floor /)"; | |
223 | operator_name_info [(int) ROUND_DIV_EXPR].name = "(round /)"; | |
224 | operator_name_info [(int) CEIL_MOD_EXPR].name = "(ceiling %)"; | |
225 | operator_name_info [(int) FLOOR_MOD_EXPR].name = "(floor %)"; | |
226 | operator_name_info [(int) ROUND_MOD_EXPR].name = "(round %)"; | |
227 | operator_name_info [(int) ABS_EXPR].name = "abs"; | |
228 | operator_name_info [(int) FFS_EXPR].name = "ffs"; | |
229 | operator_name_info [(int) BIT_ANDTC_EXPR].name = "&~"; | |
230 | operator_name_info [(int) TRUTH_AND_EXPR].name = "strict &&"; | |
231 | operator_name_info [(int) TRUTH_OR_EXPR].name = "strict ||"; | |
232 | operator_name_info [(int) IN_EXPR].name = "in"; | |
233 | operator_name_info [(int) RANGE_EXPR].name = "..."; | |
234 | operator_name_info [(int) CONVERT_EXPR].name = "+"; | |
235 | ||
5362b086 | 236 | assignment_operator_name_info [(int) EXACT_DIV_EXPR].name |
596ea4e5 | 237 | = "(exact /=)"; |
5362b086 | 238 | assignment_operator_name_info [(int) CEIL_DIV_EXPR].name |
596ea4e5 | 239 | = "(ceiling /=)"; |
5362b086 | 240 | assignment_operator_name_info [(int) FLOOR_DIV_EXPR].name |
596ea4e5 | 241 | = "(floor /=)"; |
5362b086 | 242 | assignment_operator_name_info [(int) ROUND_DIV_EXPR].name |
596ea4e5 | 243 | = "(round /=)"; |
5362b086 | 244 | assignment_operator_name_info [(int) CEIL_MOD_EXPR].name |
596ea4e5 | 245 | = "(ceiling %=)"; |
5362b086 | 246 | assignment_operator_name_info [(int) FLOOR_MOD_EXPR].name |
596ea4e5 | 247 | = "(floor %=)"; |
5362b086 | 248 | assignment_operator_name_info [(int) ROUND_MOD_EXPR].name |
596ea4e5 AS |
249 | = "(round %=)"; |
250 | } | |
251 | ||
0e5921e8 ZW |
252 | /* The reserved keyword table. */ |
253 | struct resword | |
8d08fdba | 254 | { |
8b60264b KG |
255 | const char *const word; |
256 | const ENUM_BITFIELD(rid) rid : 16; | |
257 | const unsigned int disable : 16; | |
0e5921e8 | 258 | }; |
8d08fdba | 259 | |
0e5921e8 ZW |
260 | /* Disable mask. Keywords are disabled if (reswords[i].disable & mask) is |
261 | _true_. */ | |
262 | #define D_EXT 0x01 /* GCC extension */ | |
263 | #define D_ASM 0x02 /* in C99, but has a switch to turn it off */ | |
0e5921e8 ZW |
264 | |
265 | CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT); | |
266 | ||
267 | static const struct resword reswords[] = | |
268 | { | |
d9dbd9b1 | 269 | { "_Complex", RID_COMPLEX, 0 }, |
0ba8a114 NS |
270 | { "__FUNCTION__", RID_FUNCTION_NAME, 0 }, |
271 | { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 }, | |
0e5921e8 ZW |
272 | { "__alignof", RID_ALIGNOF, 0 }, |
273 | { "__alignof__", RID_ALIGNOF, 0 }, | |
274 | { "__asm", RID_ASM, 0 }, | |
275 | { "__asm__", RID_ASM, 0 }, | |
276 | { "__attribute", RID_ATTRIBUTE, 0 }, | |
277 | { "__attribute__", RID_ATTRIBUTE, 0 }, | |
278 | { "__builtin_va_arg", RID_VA_ARG, 0 }, | |
279 | { "__complex", RID_COMPLEX, 0 }, | |
280 | { "__complex__", RID_COMPLEX, 0 }, | |
281 | { "__const", RID_CONST, 0 }, | |
282 | { "__const__", RID_CONST, 0 }, | |
283 | { "__extension__", RID_EXTENSION, 0 }, | |
0ba8a114 | 284 | { "__func__", RID_C99_FUNCTION_NAME, 0 }, |
0e5921e8 ZW |
285 | { "__imag", RID_IMAGPART, 0 }, |
286 | { "__imag__", RID_IMAGPART, 0 }, | |
287 | { "__inline", RID_INLINE, 0 }, | |
288 | { "__inline__", RID_INLINE, 0 }, | |
289 | { "__label__", RID_LABEL, 0 }, | |
290 | { "__null", RID_NULL, 0 }, | |
291 | { "__real", RID_REALPART, 0 }, | |
292 | { "__real__", RID_REALPART, 0 }, | |
293 | { "__restrict", RID_RESTRICT, 0 }, | |
294 | { "__restrict__", RID_RESTRICT, 0 }, | |
295 | { "__signed", RID_SIGNED, 0 }, | |
296 | { "__signed__", RID_SIGNED, 0 }, | |
7a1f3f5f | 297 | { "__thread", RID_THREAD, 0 }, |
0e5921e8 ZW |
298 | { "__typeof", RID_TYPEOF, 0 }, |
299 | { "__typeof__", RID_TYPEOF, 0 }, | |
300 | { "__volatile", RID_VOLATILE, 0 }, | |
301 | { "__volatile__", RID_VOLATILE, 0 }, | |
0e5921e8 | 302 | { "asm", RID_ASM, D_ASM }, |
0e5921e8 | 303 | { "auto", RID_AUTO, 0 }, |
0e5921e8 ZW |
304 | { "bool", RID_BOOL, 0 }, |
305 | { "break", RID_BREAK, 0 }, | |
306 | { "case", RID_CASE, 0 }, | |
307 | { "catch", RID_CATCH, 0 }, | |
308 | { "char", RID_CHAR, 0 }, | |
309 | { "class", RID_CLASS, 0 }, | |
0e5921e8 ZW |
310 | { "const", RID_CONST, 0 }, |
311 | { "const_cast", RID_CONSTCAST, 0 }, | |
312 | { "continue", RID_CONTINUE, 0 }, | |
313 | { "default", RID_DEFAULT, 0 }, | |
314 | { "delete", RID_DELETE, 0 }, | |
315 | { "do", RID_DO, 0 }, | |
316 | { "double", RID_DOUBLE, 0 }, | |
317 | { "dynamic_cast", RID_DYNCAST, 0 }, | |
318 | { "else", RID_ELSE, 0 }, | |
319 | { "enum", RID_ENUM, 0 }, | |
320 | { "explicit", RID_EXPLICIT, 0 }, | |
321 | { "export", RID_EXPORT, 0 }, | |
322 | { "extern", RID_EXTERN, 0 }, | |
323 | { "false", RID_FALSE, 0 }, | |
324 | { "float", RID_FLOAT, 0 }, | |
325 | { "for", RID_FOR, 0 }, | |
326 | { "friend", RID_FRIEND, 0 }, | |
327 | { "goto", RID_GOTO, 0 }, | |
328 | { "if", RID_IF, 0 }, | |
329 | { "inline", RID_INLINE, 0 }, | |
330 | { "int", RID_INT, 0 }, | |
331 | { "long", RID_LONG, 0 }, | |
332 | { "mutable", RID_MUTABLE, 0 }, | |
333 | { "namespace", RID_NAMESPACE, 0 }, | |
334 | { "new", RID_NEW, 0 }, | |
0e5921e8 | 335 | { "operator", RID_OPERATOR, 0 }, |
0e5921e8 ZW |
336 | { "private", RID_PRIVATE, 0 }, |
337 | { "protected", RID_PROTECTED, 0 }, | |
338 | { "public", RID_PUBLIC, 0 }, | |
339 | { "register", RID_REGISTER, 0 }, | |
340 | { "reinterpret_cast", RID_REINTCAST, 0 }, | |
341 | { "return", RID_RETURN, 0 }, | |
342 | { "short", RID_SHORT, 0 }, | |
343 | { "signed", RID_SIGNED, 0 }, | |
344 | { "sizeof", RID_SIZEOF, 0 }, | |
345 | { "static", RID_STATIC, 0 }, | |
346 | { "static_cast", RID_STATCAST, 0 }, | |
347 | { "struct", RID_STRUCT, 0 }, | |
348 | { "switch", RID_SWITCH, 0 }, | |
349 | { "template", RID_TEMPLATE, 0 }, | |
350 | { "this", RID_THIS, 0 }, | |
351 | { "throw", RID_THROW, 0 }, | |
352 | { "true", RID_TRUE, 0 }, | |
353 | { "try", RID_TRY, 0 }, | |
354 | { "typedef", RID_TYPEDEF, 0 }, | |
355 | { "typename", RID_TYPENAME, 0 }, | |
356 | { "typeid", RID_TYPEID, 0 }, | |
357 | { "typeof", RID_TYPEOF, D_ASM|D_EXT }, | |
358 | { "union", RID_UNION, 0 }, | |
359 | { "unsigned", RID_UNSIGNED, 0 }, | |
360 | { "using", RID_USING, 0 }, | |
361 | { "virtual", RID_VIRTUAL, 0 }, | |
362 | { "void", RID_VOID, 0 }, | |
363 | { "volatile", RID_VOLATILE, 0 }, | |
5362b086 | 364 | { "wchar_t", RID_WCHAR, 0 }, |
0e5921e8 | 365 | { "while", RID_WHILE, 0 }, |
0d3ba739 | 366 | |
0e5921e8 | 367 | }; |
0e5921e8 | 368 | |
f5e99456 | 369 | void |
0e5921e8 ZW |
370 | init_reswords () |
371 | { | |
372 | unsigned int i; | |
373 | tree id; | |
c372b0fa | 374 | int mask = ((flag_no_asm ? D_ASM : 0) |
0e5921e8 ZW |
375 | | (flag_no_gnu_keywords ? D_EXT : 0)); |
376 | ||
17211ab5 | 377 | ridpointers = (tree *) ggc_calloc ((int) RID_MAX, sizeof (tree)); |
ca7558fc | 378 | for (i = 0; i < ARRAY_SIZE (reswords); i++) |
2b2a3531 | 379 | { |
0e5921e8 ZW |
380 | id = get_identifier (reswords[i].word); |
381 | C_RID_CODE (id) = reswords[i].rid; | |
382 | ridpointers [(int) reswords[i].rid] = id; | |
383 | if (! (reswords[i].disable & mask)) | |
384 | C_IS_RESERVED_WORD (id) = 1; | |
2b2a3531 | 385 | } |
0e5921e8 | 386 | } |
2b2a3531 | 387 | |
0e5921e8 ZW |
388 | static void |
389 | init_cp_pragma () | |
390 | { | |
c58b209a NB |
391 | c_register_pragma (0, "vtable", handle_pragma_vtable); |
392 | c_register_pragma (0, "unit", handle_pragma_unit); | |
393 | c_register_pragma (0, "interface", handle_pragma_interface); | |
394 | c_register_pragma (0, "implementation", handle_pragma_implementation); | |
395 | c_register_pragma ("GCC", "interface", handle_pragma_interface); | |
396 | c_register_pragma ("GCC", "implementation", handle_pragma_implementation); | |
397 | c_register_pragma ("GCC", "java_exceptions", handle_pragma_java_exceptions); | |
0e5921e8 | 398 | } |
009ed910 | 399 | \f |
f5e99456 NB |
400 | /* Initialize the C++ front end. This function is very sensitive to |
401 | the exact order that things are done here. It would be nice if the | |
402 | initialization done by this routine were moved to its subroutines, | |
403 | and the ordering dependencies clarified and reduced. */ | |
4bfec483 NB |
404 | bool |
405 | cxx_init (void) | |
0e5921e8 | 406 | { |
009ed910 SB |
407 | static const enum tree_code stmt_codes[] = { |
408 | c_common_stmt_codes, | |
409 | cp_stmt_codes | |
410 | }; | |
411 | ||
412 | INIT_STATEMENT_CODES (stmt_codes); | |
413 | ||
a8a05998 | 414 | input_filename = "<internal>"; |
0e5921e8 ZW |
415 | |
416 | init_reswords (); | |
87e3dbc9 | 417 | init_tree (); |
54f7877c | 418 | init_cp_semantics (); |
596ea4e5 | 419 | init_operators (); |
669ec2b4 | 420 | init_method (); |
8d08fdba | 421 | init_error (); |
f3cdb9c6 | 422 | |
8d08fdba MS |
423 | current_function_decl = NULL; |
424 | ||
8d08fdba MS |
425 | class_type_node = build_int_2 (class_type, 0); |
426 | TREE_TYPE (class_type_node) = class_type_node; | |
427 | ridpointers[(int) RID_CLASS] = class_type_node; | |
428 | ||
429 | record_type_node = build_int_2 (record_type, 0); | |
430 | TREE_TYPE (record_type_node) = record_type_node; | |
0e5921e8 | 431 | ridpointers[(int) RID_STRUCT] = record_type_node; |
8d08fdba MS |
432 | |
433 | union_type_node = build_int_2 (union_type, 0); | |
434 | TREE_TYPE (union_type_node) = union_type_node; | |
435 | ridpointers[(int) RID_UNION] = union_type_node; | |
436 | ||
437 | enum_type_node = build_int_2 (enum_type, 0); | |
438 | TREE_TYPE (enum_type_node) = enum_type_node; | |
439 | ridpointers[(int) RID_ENUM] = enum_type_node; | |
440 | ||
f5e99456 NB |
441 | cxx_init_decl_processing (); |
442 | ||
4d6baafa | 443 | /* Create the built-in __null node. */ |
03d0f4af | 444 | null_node = build_int_2 (0, 0); |
b0c48229 | 445 | TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0); |
d11ad92e | 446 | ridpointers[RID_NULL] = null_node; |
c73964b2 | 447 | |
8d08fdba | 448 | interface_unknown = 1; |
a755ad1c | 449 | |
4bfec483 NB |
450 | if (c_common_init () == false) |
451 | return false; | |
f5e99456 NB |
452 | |
453 | init_cp_pragma (); | |
454 | ||
4bfec483 | 455 | init_repo (main_input_filename); |
f5e99456 | 456 | |
4bfec483 | 457 | return true; |
8d08fdba | 458 | } |
8d08fdba | 459 | \f |
8d08fdba MS |
460 | /* Helper function to load global variables with interface |
461 | information. */ | |
e92cc029 | 462 | |
8d08fdba MS |
463 | void |
464 | extract_interface_info () | |
465 | { | |
0e5921e8 | 466 | struct c_fileinfo *finfo = 0; |
8d08fdba MS |
467 | |
468 | if (flag_alt_external_templates) | |
469 | { | |
3ae18eaf | 470 | tree til = tinst_for_decl (); |
5362b086 | 471 | |
8d08fdba | 472 | if (til) |
0e5921e8 | 473 | finfo = get_fileinfo (TINST_FILE (til)); |
8d08fdba | 474 | } |
0e5921e8 ZW |
475 | if (!finfo) |
476 | finfo = get_fileinfo (input_filename); | |
477 | ||
478 | interface_only = finfo->interface_only; | |
479 | interface_unknown = finfo->interface_unknown; | |
8d08fdba MS |
480 | } |
481 | ||
51c184be | 482 | /* Return nonzero if S is not considered part of an |
8d08fdba | 483 | INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */ |
e92cc029 | 484 | |
8d08fdba MS |
485 | static int |
486 | interface_strcmp (s) | |
d8e178a0 | 487 | const char *s; |
8d08fdba MS |
488 | { |
489 | /* Set the interface/implementation bits for this scope. */ | |
490 | struct impl_files *ifiles; | |
d8e178a0 | 491 | const char *s1; |
8d08fdba | 492 | |
8d08fdba MS |
493 | for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) |
494 | { | |
d8e178a0 | 495 | const char *t1 = ifiles->filename; |
8d08fdba MS |
496 | s1 = s; |
497 | ||
498 | if (*s1 != *t1 || *s1 == 0) | |
499 | continue; | |
500 | ||
501 | while (*s1 == *t1 && *s1 != 0) | |
502 | s1++, t1++; | |
503 | ||
504 | /* A match. */ | |
505 | if (*s1 == *t1) | |
506 | return 0; | |
507 | ||
508 | /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ | |
9473c522 | 509 | if (strchr (s1, '.') || strchr (t1, '.')) |
8d08fdba MS |
510 | continue; |
511 | ||
512 | if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') | |
513 | continue; | |
514 | ||
515 | /* A match. */ | |
516 | return 0; | |
517 | } | |
518 | ||
519 | /* No matches. */ | |
520 | return 1; | |
521 | } | |
522 | ||
0e5921e8 ZW |
523 | void |
524 | note_got_semicolon (type) | |
525 | tree type; | |
526 | { | |
527 | if (!TYPE_P (type)) | |
a98facb0 | 528 | abort (); |
0e5921e8 ZW |
529 | if (CLASS_TYPE_P (type)) |
530 | CLASSTYPE_GOT_SEMICOLON (type) = 1; | |
531 | } | |
532 | ||
533 | void | |
534 | note_list_got_semicolon (declspecs) | |
535 | tree declspecs; | |
536 | { | |
537 | tree link; | |
538 | ||
539 | for (link = declspecs; link; link = TREE_CHAIN (link)) | |
540 | { | |
541 | tree type = TREE_VALUE (link); | |
7437519c | 542 | if (type && TYPE_P (type)) |
0e5921e8 ZW |
543 | note_got_semicolon (type); |
544 | } | |
545 | clear_anon_tags (); | |
546 | } | |
547 | \f | |
548 | ||
549 | /* Parse a #pragma whose sole argument is a string constant. | |
550 | If OPT is true, the argument is optional. */ | |
551 | static tree | |
552 | parse_strconst_pragma (name, opt) | |
553 | const char *name; | |
554 | int opt; | |
555 | { | |
556 | tree result, x; | |
557 | enum cpp_ttype t; | |
558 | ||
559 | t = c_lex (&x); | |
560 | if (t == CPP_STRING) | |
561 | { | |
562 | result = x; | |
563 | if (c_lex (&x) != CPP_EOF) | |
564 | warning ("junk at end of #pragma %s", name); | |
565 | return result; | |
566 | } | |
567 | ||
568 | if (t == CPP_EOF && opt) | |
569 | return 0; | |
570 | ||
571 | error ("invalid #pragma %s", name); | |
572 | return (tree)-1; | |
573 | } | |
5362b086 | 574 | |
0e5921e8 ZW |
575 | static void |
576 | handle_pragma_vtable (dfile) | |
577 | cpp_reader *dfile ATTRIBUTE_UNUSED; | |
578 | { | |
46ccf50a JM |
579 | parse_strconst_pragma ("vtable", 0); |
580 | sorry ("#pragma vtable no longer supported"); | |
0e5921e8 ZW |
581 | } |
582 | ||
1d02ac83 | 583 | static void |
0e5921e8 ZW |
584 | handle_pragma_unit (dfile) |
585 | cpp_reader *dfile ATTRIBUTE_UNUSED; | |
1d02ac83 | 586 | { |
0e5921e8 ZW |
587 | /* Validate syntax, but don't do anything. */ |
588 | parse_strconst_pragma ("unit", 0); | |
589 | } | |
590 | ||
591 | static void | |
592 | handle_pragma_interface (dfile) | |
593 | cpp_reader *dfile ATTRIBUTE_UNUSED; | |
594 | { | |
595 | tree fname = parse_strconst_pragma ("interface", 1); | |
596 | struct c_fileinfo *finfo; | |
597 | const char *main_filename; | |
598 | ||
599 | if (fname == (tree)-1) | |
600 | return; | |
601 | else if (fname == 0) | |
b3e68a79 | 602 | main_filename = lbasename (input_filename); |
0e5921e8 ZW |
603 | else |
604 | main_filename = TREE_STRING_POINTER (fname); | |
605 | ||
606 | finfo = get_fileinfo (input_filename); | |
1d02ac83 JM |
607 | |
608 | if (impl_file_chain == 0) | |
609 | { | |
610 | /* If this is zero at this point, then we are | |
611 | auto-implementing. */ | |
612 | if (main_input_filename == 0) | |
613 | main_input_filename = input_filename; | |
1d02ac83 JM |
614 | } |
615 | ||
616 | interface_only = interface_strcmp (main_filename); | |
617 | #ifdef MULTIPLE_SYMBOL_SPACES | |
618 | if (! interface_only) | |
0e5921e8 | 619 | #endif |
1d02ac83 | 620 | interface_unknown = 0; |
0e5921e8 ZW |
621 | |
622 | finfo->interface_only = interface_only; | |
623 | finfo->interface_unknown = interface_unknown; | |
1d02ac83 JM |
624 | } |
625 | ||
777ffbda JM |
626 | /* Note that we have seen a #pragma implementation for the key MAIN_FILENAME. |
627 | We used to only allow this at toplevel, but that restriction was buggy | |
628 | in older compilers and it seems reasonable to allow it in the headers | |
629 | themselves, too. It only needs to precede the matching #p interface. | |
630 | ||
631 | We don't touch interface_only or interface_unknown; the user must specify | |
632 | a matching #p interface for this to have any effect. */ | |
633 | ||
1d02ac83 | 634 | static void |
0e5921e8 ZW |
635 | handle_pragma_implementation (dfile) |
636 | cpp_reader *dfile ATTRIBUTE_UNUSED; | |
1d02ac83 | 637 | { |
0e5921e8 ZW |
638 | tree fname = parse_strconst_pragma ("implementation", 1); |
639 | const char *main_filename; | |
777ffbda | 640 | struct impl_files *ifiles = impl_file_chain; |
0e5921e8 ZW |
641 | |
642 | if (fname == (tree)-1) | |
643 | return; | |
644 | ||
645 | if (fname == 0) | |
646 | { | |
647 | if (main_input_filename) | |
648 | main_filename = main_input_filename; | |
649 | else | |
650 | main_filename = input_filename; | |
b3e68a79 | 651 | main_filename = lbasename (main_filename); |
0e5921e8 ZW |
652 | } |
653 | else | |
654 | { | |
655 | main_filename = TREE_STRING_POINTER (fname); | |
cf44ea52 | 656 | if (cpp_included (parse_in, main_filename)) |
0e5921e8 ZW |
657 | warning ("#pragma implementation for %s appears after file is included", |
658 | main_filename); | |
0e5921e8 ZW |
659 | } |
660 | ||
777ffbda | 661 | for (; ifiles; ifiles = ifiles->next) |
1d02ac83 | 662 | { |
777ffbda JM |
663 | if (! strcmp (ifiles->filename, main_filename)) |
664 | break; | |
1d02ac83 | 665 | } |
777ffbda | 666 | if (ifiles == 0) |
1d02ac83 | 667 | { |
777ffbda | 668 | ifiles = (struct impl_files*) xmalloc (sizeof (struct impl_files)); |
a8a05998 | 669 | ifiles->filename = main_filename; |
777ffbda JM |
670 | ifiles->next = impl_file_chain; |
671 | impl_file_chain = ifiles; | |
1d02ac83 | 672 | } |
1d02ac83 | 673 | } |
f181d4ae | 674 | |
1f730ff7 ZW |
675 | /* Indicate that this file uses Java-personality exception handling. */ |
676 | static void | |
677 | handle_pragma_java_exceptions (dfile) | |
678 | cpp_reader *dfile ATTRIBUTE_UNUSED; | |
679 | { | |
680 | tree x; | |
681 | if (c_lex (&x) != CPP_EOF) | |
682 | warning ("junk at end of #pragma GCC java_exceptions"); | |
683 | ||
684 | choose_personality_routine (lang_java); | |
685 | } | |
686 | ||
c6002625 | 687 | /* Return true if d is in a global scope. */ |
e92cc029 | 688 | |
0e5921e8 ZW |
689 | static int |
690 | is_global (d) | |
691 | tree d; | |
8d08fdba | 692 | { |
0e5921e8 ZW |
693 | while (1) |
694 | switch (TREE_CODE (d)) | |
695 | { | |
696 | case ERROR_MARK: | |
697 | return 1; | |
f376e137 | 698 | |
0e5921e8 ZW |
699 | case OVERLOAD: d = OVL_FUNCTION (d); continue; |
700 | case TREE_LIST: d = TREE_VALUE (d); continue; | |
701 | default: | |
702 | my_friendly_assert (DECL_P (d), 980629); | |
f376e137 | 703 | |
0e5921e8 | 704 | return DECL_NAMESPACE_SCOPE_P (d); |
eac293a1 | 705 | } |
8d08fdba MS |
706 | } |
707 | ||
15c7fb9c MM |
708 | /* Issue an error message indicating that the lookup of NAME (an |
709 | IDENTIFIER_NODE) failed. */ | |
710 | ||
711 | void | |
712 | unqualified_name_lookup_error (tree name) | |
713 | { | |
714 | if (IDENTIFIER_OPNAME_P (name)) | |
715 | { | |
716 | if (name != ansi_opname (ERROR_MARK)) | |
717 | error ("`%D' not defined", name); | |
718 | } | |
719 | else if (current_function_decl == 0) | |
720 | error ("`%D' was not declared in this scope", name); | |
721 | else | |
722 | { | |
723 | if (IDENTIFIER_NAMESPACE_VALUE (name) != error_mark_node | |
724 | || IDENTIFIER_ERROR_LOCUS (name) != current_function_decl) | |
725 | { | |
726 | static int undeclared_variable_notice; | |
727 | ||
728 | error ("`%D' undeclared (first use this function)", name); | |
729 | ||
730 | if (! undeclared_variable_notice) | |
731 | { | |
732 | error ("(Each undeclared identifier is reported only once for each function it appears in.)"); | |
733 | undeclared_variable_notice = 1; | |
734 | } | |
735 | } | |
736 | /* Prevent repeated error messages. */ | |
737 | SET_IDENTIFIER_NAMESPACE_VALUE (name, error_mark_node); | |
738 | SET_IDENTIFIER_ERROR_LOCUS (name, current_function_decl); | |
739 | } | |
740 | } | |
741 | ||
0e5921e8 | 742 | tree |
afd9b9dd | 743 | do_identifier (token, args) |
0e5921e8 | 744 | register tree token; |
0e5921e8 | 745 | tree args; |
8d08fdba | 746 | { |
0e5921e8 | 747 | register tree id; |
e92cc029 | 748 | |
fd295cb2 | 749 | timevar_push (TV_NAME_LOOKUP); |
afd9b9dd | 750 | id = lookup_name (token, 0); |
e23bd218 | 751 | |
0e5921e8 ZW |
752 | /* Do Koenig lookup if appropriate (inside templates we build lookup |
753 | expressions instead). | |
8d08fdba | 754 | |
0e5921e8 ZW |
755 | [basic.lookup.koenig]: If the ordinary unqualified lookup of the name |
756 | finds the declaration of a class member function, the associated | |
757 | namespaces and classes are not considered. */ | |
2c169bab | 758 | |
a759e627 | 759 | if (args && !current_template_parms && (!id || is_global (id))) |
f181d4ae | 760 | id = lookup_arg_dependent (token, id, args); |
a759e627 | 761 | |
5b163de4 JM |
762 | if (id == error_mark_node) |
763 | { | |
764 | /* lookup_name quietly returns error_mark_node if we're parsing, | |
765 | as we don't want to complain about an identifier that ends up | |
766 | being used as a declarator. So we call it again to get the error | |
767 | message. */ | |
768 | id = lookup_name (token, 0); | |
fd295cb2 | 769 | POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); |
5b163de4 | 770 | } |
935d1834 ZW |
771 | |
772 | if (!id || (TREE_CODE (id) == FUNCTION_DECL | |
773 | && DECL_ANTICIPATED (id))) | |
5b163de4 | 774 | { |
5566b478 | 775 | if (current_template_parms) |
fd295cb2 GDR |
776 | POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, |
777 | build_min_nt (LOOKUP_EXPR, token)); | |
5dd236e2 NS |
778 | else if (IDENTIFIER_TYPENAME_P (token)) |
779 | /* A templated conversion operator might exist. */ | |
fd295cb2 | 780 | POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, token); |
8d08fdba MS |
781 | else |
782 | { | |
15c7fb9c | 783 | unqualified_name_lookup_error (token); |
fd295cb2 | 784 | POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); |
8d08fdba MS |
785 | } |
786 | } | |
f3be9e3c | 787 | |
5f261ba9 MM |
788 | id = check_for_out_of_scope_variable (id); |
789 | ||
8d08fdba MS |
790 | /* TREE_USED is set in `hack_identifier'. */ |
791 | if (TREE_CODE (id) == CONST_DECL) | |
792 | { | |
d6479fe7 | 793 | /* Check access. */ |
8d08fdba | 794 | if (IDENTIFIER_CLASS_VALUE (token) == id) |
78757caa | 795 | perform_or_defer_access_check (CP_DECL_CONTEXT(id), id); |
50714e79 | 796 | if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id)) |
5566b478 | 797 | id = DECL_INITIAL (id); |
8d08fdba MS |
798 | } |
799 | else | |
5566b478 MS |
800 | id = hack_identifier (id, token); |
801 | ||
ed44da02 MM |
802 | /* We must look up dependent names when the template is |
803 | instantiated, not while parsing it. For now, we don't | |
804 | distinguish between dependent and independent names. So, for | |
805 | example, we look up all overloaded functions at | |
806 | instantiation-time, even though in some cases we should just use | |
807 | the DECL we have here. We also use LOOKUP_EXPRs to find things | |
c0a483c7 | 808 | like local variables, rather than creating TEMPLATE_DECLs for the |
ed44da02 | 809 | local variables and then finding matching instantiations. */ |
672476cb | 810 | if (current_template_parms |
5362b086 EC |
811 | && (is_overloaded_fn (id) |
812 | || (TREE_CODE (id) == VAR_DECL | |
ed44da02 MM |
813 | && CP_DECL_CONTEXT (id) |
814 | && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL) | |
672476cb | 815 | || TREE_CODE (id) == PARM_DECL |
c6882a35 | 816 | || TREE_CODE (id) == RESULT_DECL |
672476cb MM |
817 | || TREE_CODE (id) == USING_DECL)) |
818 | id = build_min_nt (LOOKUP_EXPR, token); | |
5362b086 | 819 | |
fd295cb2 | 820 | POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id); |
5566b478 MS |
821 | } |
822 | ||
823 | tree | |
80b1331c | 824 | do_scoped_id (token, id) |
5566b478 | 825 | tree token; |
80b1331c | 826 | tree id; |
5566b478 | 827 | { |
fd295cb2 | 828 | timevar_push (TV_NAME_LOOKUP); |
d52e4867 RS |
829 | if (!id || (TREE_CODE (id) == FUNCTION_DECL |
830 | && DECL_ANTICIPATED (id))) | |
5566b478 | 831 | { |
5156628f | 832 | if (processing_template_decl) |
5566b478 | 833 | { |
672476cb | 834 | id = build_min_nt (LOOKUP_EXPR, token); |
5566b478 | 835 | LOOKUP_EXPR_GLOBAL (id) = 1; |
fd295cb2 | 836 | POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id); |
5566b478 | 837 | } |
8b27e9ef | 838 | if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node) |
33bd39a2 | 839 | error ("`::%D' undeclared (first use here)", token); |
8b27e9ef NS |
840 | id = error_mark_node; |
841 | /* Prevent repeated error messages. */ | |
842 | SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node); | |
5566b478 MS |
843 | } |
844 | else | |
845 | { | |
846 | if (TREE_CODE (id) == ADDR_EXPR) | |
847 | mark_used (TREE_OPERAND (id, 0)); | |
2c73f9f5 | 848 | else if (TREE_CODE (id) != OVERLOAD) |
5566b478 MS |
849 | mark_used (id); |
850 | } | |
5156628f | 851 | if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl) |
5566b478 MS |
852 | { |
853 | /* XXX CHS - should we set TREE_USED of the constant? */ | |
854 | id = DECL_INITIAL (id); | |
855 | /* This is to prevent an enum whose value is 0 | |
856 | from being considered a null pointer constant. */ | |
857 | id = build1 (NOP_EXPR, TREE_TYPE (id), id); | |
858 | TREE_CONSTANT (id) = 1; | |
859 | } | |
860 | ||
5156628f | 861 | if (processing_template_decl) |
5566b478 MS |
862 | { |
863 | if (is_overloaded_fn (id)) | |
864 | { | |
672476cb | 865 | id = build_min_nt (LOOKUP_EXPR, token); |
5566b478 | 866 | LOOKUP_EXPR_GLOBAL (id) = 1; |
fd295cb2 | 867 | POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, id); |
5566b478 MS |
868 | } |
869 | /* else just use the decl */ | |
870 | } | |
fd295cb2 | 871 | POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, convert_from_reference (id)); |
8d08fdba MS |
872 | } |
873 | ||
874 | tree | |
875 | identifier_typedecl_value (node) | |
876 | tree node; | |
877 | { | |
878 | tree t, type; | |
879 | type = IDENTIFIER_TYPE_VALUE (node); | |
880 | if (type == NULL_TREE) | |
881 | return NULL_TREE; | |
f181d4ae MM |
882 | |
883 | if (IDENTIFIER_BINDING (node)) | |
884 | { | |
885 | t = IDENTIFIER_VALUE (node); | |
886 | if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) | |
887 | return t; | |
888 | } | |
889 | if (IDENTIFIER_NAMESPACE_VALUE (node)) | |
890 | { | |
891 | t = IDENTIFIER_NAMESPACE_VALUE (node); | |
892 | if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) | |
893 | return t; | |
894 | } | |
895 | ||
8d08fdba | 896 | /* Will this one ever happen? */ |
d2e5ee5c MS |
897 | if (TYPE_MAIN_DECL (type)) |
898 | return TYPE_MAIN_DECL (type); | |
8d08fdba MS |
899 | |
900 | /* We used to do an internal error of 62 here, but instead we will | |
901 | handle the return of a null appropriately in the callers. */ | |
902 | return NULL_TREE; | |
903 | } | |
904 | ||
5566b478 | 905 | #ifdef GATHER_STATISTICS |
5156628f MS |
906 | /* The original for tree_node_kind is in the toplevel tree.c; changes there |
907 | need to be brought into here, unless this were actually put into a header | |
908 | instead. */ | |
909 | /* Statistics-gathering stuff. */ | |
910 | typedef enum | |
911 | { | |
912 | d_kind, | |
913 | t_kind, | |
914 | b_kind, | |
915 | s_kind, | |
916 | r_kind, | |
917 | e_kind, | |
918 | c_kind, | |
919 | id_kind, | |
920 | op_id_kind, | |
921 | perm_list_kind, | |
922 | temp_list_kind, | |
923 | vec_kind, | |
924 | x_kind, | |
925 | lang_decl, | |
926 | lang_type, | |
927 | all_kinds | |
928 | } tree_node_kind; | |
929 | ||
8d08fdba MS |
930 | extern int tree_node_counts[]; |
931 | extern int tree_node_sizes[]; | |
5566b478 | 932 | #endif |
8d08fdba | 933 | |
8d08fdba MS |
934 | tree |
935 | build_lang_decl (code, name, type) | |
936 | enum tree_code code; | |
937 | tree name; | |
938 | tree type; | |
939 | { | |
4ce3d537 MM |
940 | tree t; |
941 | ||
4ce3d537 | 942 | t = build_decl (code, name, type); |
fcfcdfc8 | 943 | retrofit_lang_decl (t); |
4ce3d537 | 944 | |
fcfcdfc8 JM |
945 | return t; |
946 | } | |
947 | ||
948 | /* Add DECL_LANG_SPECIFIC info to T. Called from build_lang_decl | |
949 | and pushdecl (for functions generated by the backend). */ | |
950 | ||
951 | void | |
952 | retrofit_lang_decl (t) | |
953 | tree t; | |
954 | { | |
9188c363 | 955 | struct lang_decl *ld; |
4ce3d537 | 956 | size_t size; |
8d08fdba | 957 | |
4ce3d537 MM |
958 | if (CAN_HAVE_FULL_LANG_DECL_P (t)) |
959 | size = sizeof (struct lang_decl); | |
960 | else | |
961 | size = sizeof (struct lang_decl_flags); | |
b0d06515 | 962 | |
f8a83ee3 | 963 | ld = (struct lang_decl *) ggc_alloc_cleared (size); |
8d08fdba | 964 | |
e2500fed GK |
965 | ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0; |
966 | ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0; | |
967 | ld->decl_flags.u2sel = 0; | |
968 | if (ld->decl_flags.can_be_full) | |
969 | ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0; | |
970 | ||
9188c363 | 971 | DECL_LANG_SPECIFIC (t) = ld; |
8d08fdba | 972 | if (current_lang_name == lang_name_cplusplus) |
5d2ed28c | 973 | SET_DECL_LANGUAGE (t, lang_cplusplus); |
8d08fdba | 974 | else if (current_lang_name == lang_name_c) |
5d2ed28c | 975 | SET_DECL_LANGUAGE (t, lang_c); |
a1774733 | 976 | else if (current_lang_name == lang_name_java) |
5d2ed28c | 977 | SET_DECL_LANGUAGE (t, lang_java); |
a98facb0 | 978 | else abort (); |
8d08fdba | 979 | |
8d08fdba MS |
980 | #ifdef GATHER_STATISTICS |
981 | tree_node_counts[(int)lang_decl] += 1; | |
4ce3d537 | 982 | tree_node_sizes[(int)lang_decl] += size; |
8d08fdba | 983 | #endif |
8d08fdba MS |
984 | } |
985 | ||
8d08fdba | 986 | void |
63e1b1c4 | 987 | cxx_dup_lang_specific_decl (node) |
8d08fdba MS |
988 | tree node; |
989 | { | |
990 | int size; | |
d60f72ae | 991 | struct lang_decl *ld; |
8d08fdba | 992 | |
5566b478 MS |
993 | if (! DECL_LANG_SPECIFIC (node)) |
994 | return; | |
995 | ||
b0d06515 | 996 | if (!CAN_HAVE_FULL_LANG_DECL_P (node)) |
8d08fdba MS |
997 | size = sizeof (struct lang_decl_flags); |
998 | else | |
999 | size = sizeof (struct lang_decl); | |
d60f72ae | 1000 | ld = (struct lang_decl *) ggc_alloc (size); |
4e135bdd | 1001 | memcpy (ld, DECL_LANG_SPECIFIC (node), size); |
d60f72ae | 1002 | DECL_LANG_SPECIFIC (node) = ld; |
11e74ea6 KL |
1003 | |
1004 | #ifdef GATHER_STATISTICS | |
1005 | tree_node_counts[(int)lang_decl] += 1; | |
1006 | tree_node_sizes[(int)lang_decl] += size; | |
1007 | #endif | |
8d08fdba MS |
1008 | } |
1009 | ||
0acf7199 MM |
1010 | /* Copy DECL, including any language-specific parts. */ |
1011 | ||
1012 | tree | |
1013 | copy_decl (decl) | |
1014 | tree decl; | |
1015 | { | |
1016 | tree copy; | |
1017 | ||
1018 | copy = copy_node (decl); | |
63e1b1c4 | 1019 | cxx_dup_lang_specific_decl (copy); |
0acf7199 MM |
1020 | return copy; |
1021 | } | |
1022 | ||
11e74ea6 KL |
1023 | /* Replace the shared language-specific parts of NODE with a new copy. */ |
1024 | ||
76648a8b | 1025 | static void |
11e74ea6 KL |
1026 | copy_lang_type (node) |
1027 | tree node; | |
1028 | { | |
1029 | int size; | |
1030 | struct lang_type *lt; | |
1031 | ||
1032 | if (! TYPE_LANG_SPECIFIC (node)) | |
1033 | return; | |
1034 | ||
e2500fed GK |
1035 | if (TYPE_LANG_SPECIFIC (node)->u.h.is_lang_type_class) |
1036 | size = sizeof (struct lang_type); | |
1037 | else | |
1038 | size = sizeof (struct lang_type_ptrmem); | |
11e74ea6 KL |
1039 | lt = (struct lang_type *) ggc_alloc (size); |
1040 | memcpy (lt, TYPE_LANG_SPECIFIC (node), size); | |
1041 | TYPE_LANG_SPECIFIC (node) = lt; | |
1042 | ||
1043 | #ifdef GATHER_STATISTICS | |
1044 | tree_node_counts[(int)lang_type] += 1; | |
1045 | tree_node_sizes[(int)lang_type] += size; | |
1046 | #endif | |
1047 | } | |
1048 | ||
1049 | /* Copy TYPE, including any language-specific parts. */ | |
1050 | ||
1051 | tree | |
1052 | copy_type (type) | |
1053 | tree type; | |
1054 | { | |
1055 | tree copy; | |
1056 | ||
1057 | copy = copy_node (type); | |
1058 | copy_lang_type (copy); | |
1059 | return copy; | |
1060 | } | |
1061 | ||
8d08fdba | 1062 | tree |
f1e639b1 | 1063 | cxx_make_type (code) |
8d08fdba MS |
1064 | enum tree_code code; |
1065 | { | |
8d08fdba | 1066 | register tree t = make_node (code); |
8d08fdba | 1067 | |
11e74ea6 KL |
1068 | /* Create lang_type structure. */ |
1069 | if (IS_AGGR_TYPE_CODE (code) | |
1070 | || code == BOUND_TEMPLATE_TEMPLATE_PARM) | |
7ddedda4 | 1071 | { |
32201ce4 AS |
1072 | struct lang_type *pi; |
1073 | ||
5362b086 | 1074 | pi = ((struct lang_type *) |
f15b9af9 | 1075 | ggc_alloc_cleared (sizeof (struct lang_type))); |
8d08fdba | 1076 | |
32201ce4 | 1077 | TYPE_LANG_SPECIFIC (t) = pi; |
e2500fed | 1078 | pi->u.c.h.is_lang_type_class = 1; |
11e74ea6 KL |
1079 | |
1080 | #ifdef GATHER_STATISTICS | |
1081 | tree_node_counts[(int)lang_type] += 1; | |
1082 | tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); | |
1083 | #endif | |
1084 | } | |
1085 | ||
1086 | /* Set up some flags that give proper default behavior. */ | |
1087 | if (IS_AGGR_TYPE_CODE (code)) | |
1088 | { | |
7ddedda4 MM |
1089 | SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); |
1090 | CLASSTYPE_INTERFACE_ONLY (t) = interface_only; | |
8d08fdba | 1091 | |
7ddedda4 MM |
1092 | /* Make sure this is laid out, for ease of use later. In the |
1093 | presence of parse errors, the normal was of assuring this | |
1094 | might not ever get executed, so we lay it out *immediately*. */ | |
1095 | build_pointer_type (t); | |
7ddedda4 MM |
1096 | } |
1097 | else | |
1098 | /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But, | |
1099 | TYPE_ALIAS_SET is initialized to -1 by default, so we must | |
1100 | clear it here. */ | |
1101 | TYPE_ALIAS_SET (t) = 0; | |
8d08fdba | 1102 | |
807625cf | 1103 | /* We need to allocate a TYPE_BINFO even for TEMPLATE_TYPE_PARMs |
f6a7cfd2 MM |
1104 | since they can be virtual base types, and we then need a |
1105 | canonical binfo for them. Ideally, this would be done lazily for | |
1106 | all types. */ | |
11e74ea6 KL |
1107 | if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM |
1108 | || code == BOUND_TEMPLATE_TEMPLATE_PARM | |
1109 | || code == TYPENAME_TYPE) | |
fed3cef0 | 1110 | TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE); |
f6a7cfd2 | 1111 | |
8d08fdba MS |
1112 | return t; |
1113 | } | |
1114 | ||
33848bb0 RH |
1115 | tree |
1116 | make_aggr_type (code) | |
1117 | enum tree_code code; | |
1118 | { | |
f1e639b1 | 1119 | tree t = cxx_make_type (code); |
33848bb0 RH |
1120 | |
1121 | if (IS_AGGR_TYPE_CODE (code)) | |
1122 | SET_IS_AGGR_TYPE (t, 1); | |
1123 | ||
1124 | return t; | |
1125 | } | |
1126 | ||
91063b51 MM |
1127 | /* Return the type-qualifier corresponding to the identifier given by |
1128 | RID. */ | |
1129 | ||
1130 | int | |
1131 | cp_type_qual_from_rid (rid) | |
1132 | tree rid; | |
1133 | { | |
1134 | if (rid == ridpointers[(int) RID_CONST]) | |
1135 | return TYPE_QUAL_CONST; | |
1136 | else if (rid == ridpointers[(int) RID_VOLATILE]) | |
1137 | return TYPE_QUAL_VOLATILE; | |
1138 | else if (rid == ridpointers[(int) RID_RESTRICT]) | |
1139 | return TYPE_QUAL_RESTRICT; | |
1140 | ||
a98facb0 | 1141 | abort (); |
91063b51 MM |
1142 | return TYPE_UNQUALIFIED; |
1143 | } |