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
00028
00029 #include "config.h"
00030 #include "system.h"
00031 #include "coretypes.h"
00032 #include "tm.h"
00033 #include "input.h"
00034 #include "tree.h"
00035 #include "cp-tree.h"
00036 #include "cpplib.h"
00037 #include "flags.h"
00038 #include "c-pragma.h"
00039 #include "toplev.h"
00040 #include "output.h"
00041 #include "tm_p.h"
00042 #include "timevar.h"
00043 #ifdef KEY
00044 #include "gspin-gcc-interface.h"
00045 #endif
00046
00047 static int interface_strcmp (const char *);
00048 static void init_cp_pragma (void);
00049
00050 static tree parse_strconst_pragma (const char *, int);
00051 static void handle_pragma_vtable (cpp_reader *);
00052 static void handle_pragma_unit (cpp_reader *);
00053 static void handle_pragma_interface (cpp_reader *);
00054 static void handle_pragma_implementation (cpp_reader *);
00055 static void handle_pragma_java_exceptions (cpp_reader *);
00056
00057 static void init_operators (void);
00058 static void copy_lang_type (tree);
00059
00060
00061 #define CONSTRAINT(name, expr) extern int constraint_##name [(expr) ? 1 : -1]
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 struct impl_files
00083 {
00084 const char *filename;
00085 struct impl_files *next;
00086 };
00087
00088 static struct impl_files *impl_file_chain;
00089
00090
00091 void
00092 cxx_finish (void)
00093 {
00094 c_common_finish ();
00095 }
00096
00097
00098 operator_name_info_t operator_name_info[(int) LAST_CPLUS_TREE_CODE];
00099
00100 operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE];
00101
00102
00103
00104 #define DEF_OPERATOR(NAME, C, M, AR, AP) \
00105 CONSTRAINT (C, sizeof "operator " + sizeof NAME <= 256);
00106 #include "operators.def"
00107 #undef DEF_OPERATOR
00108
00109 static void
00110 init_operators (void)
00111 {
00112 tree identifier;
00113 char buffer[256];
00114 struct operator_name_info_t *oni;
00115
00116 #define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, ASSN_P) \
00117 sprintf (buffer, ISALPHA (NAME[0]) ? "operator %s" : "operator%s", NAME); \
00118 identifier = get_identifier (buffer); \
00119 IDENTIFIER_OPNAME_P (identifier) = 1; \
00120 \
00121 oni = (ASSN_P \
00122 ? &assignment_operator_name_info[(int) CODE] \
00123 : &operator_name_info[(int) CODE]); \
00124 oni->identifier = identifier; \
00125 oni->name = NAME; \
00126 oni->mangled_name = MANGLING; \
00127 oni->arity = ARITY;
00128
00129 #include "operators.def"
00130 #undef DEF_OPERATOR
00131
00132 operator_name_info[(int) ERROR_MARK].identifier
00133 = get_identifier ("<invalid operator>");
00134
00135
00136
00137
00138
00139
00140
00141 operator_name_info [(int) INIT_EXPR].name
00142 = operator_name_info [(int) MODIFY_EXPR].name;
00143 operator_name_info [(int) EXACT_DIV_EXPR].name = "(ceiling /)";
00144 operator_name_info [(int) CEIL_DIV_EXPR].name = "(ceiling /)";
00145 operator_name_info [(int) FLOOR_DIV_EXPR].name = "(floor /)";
00146 operator_name_info [(int) ROUND_DIV_EXPR].name = "(round /)";
00147 operator_name_info [(int) CEIL_MOD_EXPR].name = "(ceiling %)";
00148 operator_name_info [(int) FLOOR_MOD_EXPR].name = "(floor %)";
00149 operator_name_info [(int) ROUND_MOD_EXPR].name = "(round %)";
00150 operator_name_info [(int) ABS_EXPR].name = "abs";
00151 operator_name_info [(int) TRUTH_AND_EXPR].name = "strict &&";
00152 operator_name_info [(int) TRUTH_OR_EXPR].name = "strict ||";
00153 operator_name_info [(int) RANGE_EXPR].name = "...";
00154 operator_name_info [(int) UNARY_PLUS_EXPR].name = "+";
00155
00156 assignment_operator_name_info [(int) EXACT_DIV_EXPR].name
00157 = "(exact /=)";
00158 assignment_operator_name_info [(int) CEIL_DIV_EXPR].name
00159 = "(ceiling /=)";
00160 assignment_operator_name_info [(int) FLOOR_DIV_EXPR].name
00161 = "(floor /=)";
00162 assignment_operator_name_info [(int) ROUND_DIV_EXPR].name
00163 = "(round /=)";
00164 assignment_operator_name_info [(int) CEIL_MOD_EXPR].name
00165 = "(ceiling %=)";
00166 assignment_operator_name_info [(int) FLOOR_MOD_EXPR].name
00167 = "(floor %=)";
00168 assignment_operator_name_info [(int) ROUND_MOD_EXPR].name
00169 = "(round %=)";
00170 }
00171
00172
00173 struct resword
00174 {
00175 const char *const word;
00176 ENUM_BITFIELD(rid) const rid : 16;
00177 const unsigned int disable : 16;
00178 };
00179
00180
00181
00182 #define D_EXT 0x01
00183 #define D_ASM 0x02
00184 #define D_OBJC 0x04
00185
00186 CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT);
00187
00188 static const struct resword reswords[] =
00189 {
00190 { "_Complex", RID_COMPLEX, 0 },
00191 { "__FUNCTION__", RID_FUNCTION_NAME, 0 },
00192 { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
00193 { "__alignof", RID_ALIGNOF, 0 },
00194 { "__alignof__", RID_ALIGNOF, 0 },
00195 { "__asm", RID_ASM, 0 },
00196 { "__asm__", RID_ASM, 0 },
00197 { "__attribute", RID_ATTRIBUTE, 0 },
00198 { "__attribute__", RID_ATTRIBUTE, 0 },
00199 { "__builtin_offsetof", RID_OFFSETOF, 0 },
00200 { "__builtin_va_arg", RID_VA_ARG, 0 },
00201 { "__complex", RID_COMPLEX, 0 },
00202 { "__complex__", RID_COMPLEX, 0 },
00203 { "__const", RID_CONST, 0 },
00204 { "__const__", RID_CONST, 0 },
00205 { "__extension__", RID_EXTENSION, 0 },
00206 { "__func__", RID_C99_FUNCTION_NAME, 0 },
00207 { "__imag", RID_IMAGPART, 0 },
00208 { "__imag__", RID_IMAGPART, 0 },
00209 { "__inline", RID_INLINE, 0 },
00210 { "__inline__", RID_INLINE, 0 },
00211 { "__label__", RID_LABEL, 0 },
00212 { "__null", RID_NULL, 0 },
00213 { "__real", RID_REALPART, 0 },
00214 { "__real__", RID_REALPART, 0 },
00215 { "__restrict", RID_RESTRICT, 0 },
00216 { "__restrict__", RID_RESTRICT, 0 },
00217 { "__signed", RID_SIGNED, 0 },
00218 { "__signed__", RID_SIGNED, 0 },
00219 { "__thread", RID_THREAD, 0 },
00220 { "__typeof", RID_TYPEOF, 0 },
00221 { "__typeof__", RID_TYPEOF, 0 },
00222 { "__volatile", RID_VOLATILE, 0 },
00223 { "__volatile__", RID_VOLATILE, 0 },
00224 { "asm", RID_ASM, D_ASM },
00225 { "auto", RID_AUTO, 0 },
00226 { "bool", RID_BOOL, 0 },
00227 { "break", RID_BREAK, 0 },
00228 { "case", RID_CASE, 0 },
00229 { "catch", RID_CATCH, 0 },
00230 { "char", RID_CHAR, 0 },
00231 { "class", RID_CLASS, 0 },
00232 { "const", RID_CONST, 0 },
00233 { "const_cast", RID_CONSTCAST, 0 },
00234 { "continue", RID_CONTINUE, 0 },
00235 { "default", RID_DEFAULT, 0 },
00236 { "delete", RID_DELETE, 0 },
00237 { "do", RID_DO, 0 },
00238 { "double", RID_DOUBLE, 0 },
00239 { "dynamic_cast", RID_DYNCAST, 0 },
00240 { "else", RID_ELSE, 0 },
00241 { "enum", RID_ENUM, 0 },
00242 { "explicit", RID_EXPLICIT, 0 },
00243 { "export", RID_EXPORT, 0 },
00244 { "extern", RID_EXTERN, 0 },
00245 { "false", RID_FALSE, 0 },
00246 { "float", RID_FLOAT, 0 },
00247 { "for", RID_FOR, 0 },
00248 { "friend", RID_FRIEND, 0 },
00249 { "goto", RID_GOTO, 0 },
00250 { "if", RID_IF, 0 },
00251 { "inline", RID_INLINE, 0 },
00252 { "int", RID_INT, 0 },
00253 { "long", RID_LONG, 0 },
00254 { "mutable", RID_MUTABLE, 0 },
00255 { "namespace", RID_NAMESPACE, 0 },
00256 { "new", RID_NEW, 0 },
00257 { "operator", RID_OPERATOR, 0 },
00258 { "private", RID_PRIVATE, 0 },
00259 { "protected", RID_PROTECTED, 0 },
00260 { "public", RID_PUBLIC, 0 },
00261 { "register", RID_REGISTER, 0 },
00262 { "reinterpret_cast", RID_REINTCAST, 0 },
00263 { "return", RID_RETURN, 0 },
00264 { "short", RID_SHORT, 0 },
00265 { "signed", RID_SIGNED, 0 },
00266 { "sizeof", RID_SIZEOF, 0 },
00267 { "static", RID_STATIC, 0 },
00268 { "static_cast", RID_STATCAST, 0 },
00269 { "struct", RID_STRUCT, 0 },
00270 { "switch", RID_SWITCH, 0 },
00271 { "template", RID_TEMPLATE, 0 },
00272 { "this", RID_THIS, 0 },
00273 { "throw", RID_THROW, 0 },
00274 { "true", RID_TRUE, 0 },
00275 { "try", RID_TRY, 0 },
00276 { "typedef", RID_TYPEDEF, 0 },
00277 { "typename", RID_TYPENAME, 0 },
00278 { "typeid", RID_TYPEID, 0 },
00279 { "typeof", RID_TYPEOF, D_ASM|D_EXT },
00280 { "union", RID_UNION, 0 },
00281 { "unsigned", RID_UNSIGNED, 0 },
00282 { "using", RID_USING, 0 },
00283 { "virtual", RID_VIRTUAL, 0 },
00284 { "void", RID_VOID, 0 },
00285 { "volatile", RID_VOLATILE, 0 },
00286 { "wchar_t", RID_WCHAR, 0 },
00287 { "while", RID_WHILE, 0 },
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 { "compatibility_alias", RID_AT_ALIAS, D_OBJC },
00298 { "defs", RID_AT_DEFS, D_OBJC },
00299 { "encode", RID_AT_ENCODE, D_OBJC },
00300 { "end", RID_AT_END, D_OBJC },
00301 { "implementation", RID_AT_IMPLEMENTATION, D_OBJC },
00302 { "interface", RID_AT_INTERFACE, D_OBJC },
00303 { "protocol", RID_AT_PROTOCOL, D_OBJC },
00304 { "selector", RID_AT_SELECTOR, D_OBJC },
00305 { "finally", RID_AT_FINALLY, D_OBJC },
00306 { "synchronized", RID_AT_SYNCHRONIZED, D_OBJC },
00307
00308 { "bycopy", RID_BYCOPY, D_OBJC },
00309 { "byref", RID_BYREF, D_OBJC },
00310 { "in", RID_IN, D_OBJC },
00311 { "inout", RID_INOUT, D_OBJC },
00312 { "oneway", RID_ONEWAY, D_OBJC },
00313 { "out", RID_OUT, D_OBJC },
00314 };
00315
00316 void
00317 init_reswords (void)
00318 {
00319 unsigned int i;
00320 tree id;
00321 int mask = ((flag_no_asm ? D_ASM : 0)
00322 | D_OBJC
00323 | (flag_no_gnu_keywords ? D_EXT : 0));
00324
00325 ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
00326 for (i = 0; i < ARRAY_SIZE (reswords); i++)
00327 {
00328 id = get_identifier (reswords[i].word);
00329 C_RID_CODE (id) = reswords[i].rid;
00330 ridpointers [(int) reswords[i].rid] = id;
00331 if (! (reswords[i].disable & mask))
00332 C_IS_RESERVED_WORD (id) = 1;
00333 }
00334 }
00335
00336 static void
00337 init_cp_pragma (void)
00338 {
00339 c_register_pragma (0, "vtable", handle_pragma_vtable);
00340 c_register_pragma (0, "unit", handle_pragma_unit);
00341 c_register_pragma (0, "interface", handle_pragma_interface);
00342 c_register_pragma (0, "implementation", handle_pragma_implementation);
00343 c_register_pragma ("GCC", "interface", handle_pragma_interface);
00344 c_register_pragma ("GCC", "implementation", handle_pragma_implementation);
00345 c_register_pragma ("GCC", "java_exceptions", handle_pragma_java_exceptions);
00346 }
00347
00348
00349
00350 bool statement_code_p[MAX_TREE_CODES];
00351
00352
00353
00354
00355
00356 bool
00357 cxx_init (void)
00358 {
00359 unsigned int i;
00360 static const enum tree_code stmt_codes[] = {
00361 CTOR_INITIALIZER, TRY_BLOCK, HANDLER,
00362 EH_SPEC_BLOCK, USING_STMT, TAG_DEFN,
00363 IF_STMT, CLEANUP_STMT, FOR_STMT,
00364 WHILE_STMT, DO_STMT, BREAK_STMT,
00365 CONTINUE_STMT, SWITCH_STMT, EXPR_STMT
00366 };
00367
00368 memset (&statement_code_p, 0, sizeof (statement_code_p));
00369 for (i = 0; i < ARRAY_SIZE (stmt_codes); i++)
00370 statement_code_p[stmt_codes[i]] = true;
00371
00372
00373
00374
00375 #ifdef USE_MAPPED_LOCATION
00376 push_srcloc (BUILTINS_LOCATION);
00377 #else
00378 push_srcloc ("<built-in>", 0);
00379 #endif
00380
00381 init_reswords ();
00382 init_tree ();
00383 init_cp_semantics ();
00384 init_operators ();
00385 init_method ();
00386 init_error ();
00387
00388 current_function_decl = NULL;
00389
00390 class_type_node = ridpointers[(int) RID_CLASS];
00391
00392 cxx_init_decl_processing ();
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 flag_unit_at_a_time = 1;
00404
00405 if (c_common_init () == false)
00406 {
00407 pop_srcloc();
00408 return false;
00409 }
00410
00411 init_cp_pragma ();
00412
00413 init_repo ();
00414
00415 pop_srcloc();
00416 return true;
00417 }
00418
00419
00420
00421
00422 static int
00423 interface_strcmp (const char* s)
00424 {
00425
00426 struct impl_files *ifiles;
00427 const char *s1;
00428
00429 for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next)
00430 {
00431 const char *t1 = ifiles->filename;
00432 s1 = s;
00433
00434 if (*s1 != *t1 || *s1 == 0)
00435 continue;
00436
00437 while (*s1 == *t1 && *s1 != 0)
00438 s1++, t1++;
00439
00440
00441 if (*s1 == *t1)
00442 return 0;
00443
00444
00445 if (strchr (s1, '.') || strchr (t1, '.'))
00446 continue;
00447
00448 if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.')
00449 continue;
00450
00451
00452 return 0;
00453 }
00454
00455
00456 return 1;
00457 }
00458
00459
00460
00461
00462
00463 static tree
00464 parse_strconst_pragma (const char* name, int opt)
00465 {
00466 tree result, x;
00467 enum cpp_ttype t;
00468
00469 t = pragma_lex (&result);
00470 if (t == CPP_STRING)
00471 {
00472 if (pragma_lex (&x) != CPP_EOF)
00473 warning (0, "junk at end of #pragma %s", name);
00474 return result;
00475 }
00476
00477 if (t == CPP_EOF && opt)
00478 return NULL_TREE;
00479
00480 error ("invalid #pragma %s", name);
00481 return error_mark_node;
00482 }
00483
00484 static void
00485 handle_pragma_vtable (cpp_reader* dfile ATTRIBUTE_UNUSED )
00486 {
00487 parse_strconst_pragma ("vtable", 0);
00488 sorry ("#pragma vtable no longer supported");
00489 }
00490
00491 static void
00492 handle_pragma_unit (cpp_reader* dfile ATTRIBUTE_UNUSED )
00493 {
00494
00495 parse_strconst_pragma ("unit", 0);
00496 }
00497
00498 static void
00499 handle_pragma_interface (cpp_reader* dfile ATTRIBUTE_UNUSED )
00500 {
00501 tree fname = parse_strconst_pragma ("interface", 1);
00502 struct c_fileinfo *finfo;
00503 const char *filename;
00504
00505 if (fname == error_mark_node)
00506 return;
00507 else if (fname == 0)
00508 filename = lbasename (input_filename);
00509 else
00510 filename = ggc_strdup (TREE_STRING_POINTER (fname));
00511
00512 finfo = get_fileinfo (input_filename);
00513
00514 if (impl_file_chain == 0)
00515 {
00516
00517
00518 if (main_input_filename == 0)
00519 main_input_filename = input_filename;
00520 }
00521
00522 finfo->interface_only = interface_strcmp (filename);
00523
00524
00525 if (!MULTIPLE_SYMBOL_SPACES || !finfo->interface_only)
00526 finfo->interface_unknown = 0;
00527
00528 #ifdef KEY
00529 gs_set_program_flag_value (GS_PRAGMA_INTERFACE, 1);
00530 #endif
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 static void
00543 handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED )
00544 {
00545 tree fname = parse_strconst_pragma ("implementation", 1);
00546 const char *filename;
00547 struct impl_files *ifiles = impl_file_chain;
00548
00549 if (fname == error_mark_node)
00550 return;
00551
00552 if (fname == 0)
00553 {
00554 if (main_input_filename)
00555 filename = main_input_filename;
00556 else
00557 filename = input_filename;
00558 filename = lbasename (filename);
00559 }
00560 else
00561 {
00562 filename = ggc_strdup (TREE_STRING_POINTER (fname));
00563 #if 0
00564
00565
00566
00567
00568
00569
00570 if (cpp_included (parse_in, filename))
00571 warning (0, "#pragma implementation for %qs appears after "
00572 "file is included", filename);
00573 #endif
00574 }
00575
00576 for (; ifiles; ifiles = ifiles->next)
00577 {
00578 if (! strcmp (ifiles->filename, filename))
00579 break;
00580 }
00581 if (ifiles == 0)
00582 {
00583 ifiles = XNEW (struct impl_files);
00584 ifiles->filename = filename;
00585 ifiles->next = impl_file_chain;
00586 impl_file_chain = ifiles;
00587 }
00588
00589 #ifdef KEY
00590 gs_set_program_flag_value (GS_PRAGMA_IMPLEMENTATION, 1);
00591 #endif
00592 }
00593
00594
00595 static void
00596 handle_pragma_java_exceptions (cpp_reader* dfile ATTRIBUTE_UNUSED)
00597 {
00598 tree x;
00599 if (pragma_lex (&x) != CPP_EOF)
00600 warning (0, "junk at end of #pragma GCC java_exceptions");
00601
00602 choose_personality_routine (lang_java);
00603 }
00604
00605
00606
00607
00608 tree
00609 unqualified_name_lookup_error (tree name)
00610 {
00611 if (IDENTIFIER_OPNAME_P (name))
00612 {
00613 if (name != ansi_opname (ERROR_MARK))
00614 error ("%qD not defined", name);
00615 }
00616 else
00617 {
00618 error ("%qD was not declared in this scope", name);
00619
00620
00621 if (current_function_decl)
00622 {
00623 tree decl;
00624 decl = build_decl (VAR_DECL, name, error_mark_node);
00625 DECL_CONTEXT (decl) = current_function_decl;
00626 push_local_binding (name, decl, 0);
00627
00628
00629 TREE_USED (decl) = 1;
00630 }
00631 }
00632
00633 return error_mark_node;
00634 }
00635
00636
00637
00638
00639
00640 tree
00641 unqualified_fn_lookup_error (tree name)
00642 {
00643 if (processing_template_decl)
00644 {
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 pedwarn ("there are no arguments to %qD that depend on a template "
00656 "parameter, so a declaration of %qD must be available",
00657 name, name);
00658
00659 if (!flag_permissive)
00660 {
00661 static bool hint;
00662 if (!hint)
00663 {
00664 error ("(if you use %<-fpermissive%>, G++ will accept your "
00665 "code, but allowing the use of an undeclared name is "
00666 "deprecated)");
00667 hint = true;
00668 }
00669 }
00670 return name;
00671 }
00672
00673 return unqualified_name_lookup_error (name);
00674 }
00675
00676 tree
00677 build_lang_decl (enum tree_code code, tree name, tree type)
00678 {
00679 tree t;
00680
00681 t = build_decl (code, name, type);
00682 retrofit_lang_decl (t);
00683
00684
00685
00686 if (code == FUNCTION_DECL)
00687 DECL_NO_STATIC_CHAIN (t) = 1;
00688
00689 return t;
00690 }
00691
00692
00693
00694
00695 void
00696 retrofit_lang_decl (tree t)
00697 {
00698 struct lang_decl *ld;
00699 size_t size;
00700
00701 if (CAN_HAVE_FULL_LANG_DECL_P (t))
00702 size = sizeof (struct lang_decl);
00703 else
00704 size = sizeof (struct lang_decl_flags);
00705
00706 ld = GGC_CNEWVAR (struct lang_decl, size);
00707
00708 ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0;
00709 ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;
00710 ld->decl_flags.u2sel = 0;
00711 if (ld->decl_flags.can_be_full)
00712 ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0;
00713
00714 DECL_LANG_SPECIFIC (t) = ld;
00715 if (current_lang_name == lang_name_cplusplus
00716 || decl_linkage (t) == lk_none)
00717 SET_DECL_LANGUAGE (t, lang_cplusplus);
00718 else if (current_lang_name == lang_name_c)
00719 SET_DECL_LANGUAGE (t, lang_c);
00720 else if (current_lang_name == lang_name_java)
00721 SET_DECL_LANGUAGE (t, lang_java);
00722 else
00723 gcc_unreachable ();
00724
00725 #ifdef GATHER_STATISTICS
00726 tree_node_counts[(int)lang_decl] += 1;
00727 tree_node_sizes[(int)lang_decl] += size;
00728 #endif
00729 }
00730
00731 void
00732 cxx_dup_lang_specific_decl (tree node)
00733 {
00734 int size;
00735 struct lang_decl *ld;
00736
00737 if (! DECL_LANG_SPECIFIC (node))
00738 return;
00739
00740 if (!CAN_HAVE_FULL_LANG_DECL_P (node))
00741 size = sizeof (struct lang_decl_flags);
00742 else
00743 size = sizeof (struct lang_decl);
00744 ld = GGC_NEWVAR (struct lang_decl, size);
00745 memcpy (ld, DECL_LANG_SPECIFIC (node), size);
00746 DECL_LANG_SPECIFIC (node) = ld;
00747
00748 #ifdef GATHER_STATISTICS
00749 tree_node_counts[(int)lang_decl] += 1;
00750 tree_node_sizes[(int)lang_decl] += size;
00751 #endif
00752 }
00753
00754
00755
00756 tree
00757 copy_decl (tree decl)
00758 {
00759 tree copy;
00760
00761 copy = copy_node (decl);
00762 cxx_dup_lang_specific_decl (copy);
00763 return copy;
00764 }
00765
00766
00767
00768 static void
00769 copy_lang_type (tree node)
00770 {
00771 int size;
00772 struct lang_type *lt;
00773
00774 if (! TYPE_LANG_SPECIFIC (node))
00775 return;
00776
00777 if (TYPE_LANG_SPECIFIC (node)->u.h.is_lang_type_class)
00778 size = sizeof (struct lang_type);
00779 else
00780 size = sizeof (struct lang_type_ptrmem);
00781 lt = GGC_NEWVAR (struct lang_type, size);
00782 memcpy (lt, TYPE_LANG_SPECIFIC (node), size);
00783 TYPE_LANG_SPECIFIC (node) = lt;
00784
00785 #ifdef GATHER_STATISTICS
00786 tree_node_counts[(int)lang_type] += 1;
00787 tree_node_sizes[(int)lang_type] += size;
00788 #endif
00789 }
00790
00791
00792
00793 tree
00794 copy_type (tree type)
00795 {
00796 tree copy;
00797
00798 copy = copy_node (type);
00799 copy_lang_type (copy);
00800 return copy;
00801 }
00802
00803 tree
00804 cxx_make_type (enum tree_code code)
00805 {
00806 tree t = make_node (code);
00807
00808
00809 if (IS_AGGR_TYPE_CODE (code)
00810 || code == BOUND_TEMPLATE_TEMPLATE_PARM)
00811 {
00812 struct lang_type *pi = GGC_CNEW (struct lang_type);
00813
00814 TYPE_LANG_SPECIFIC (t) = pi;
00815 pi->u.c.h.is_lang_type_class = 1;
00816
00817 #ifdef GATHER_STATISTICS
00818 tree_node_counts[(int)lang_type] += 1;
00819 tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
00820 #endif
00821 }
00822
00823
00824 if (IS_AGGR_TYPE_CODE (code))
00825 {
00826 struct c_fileinfo *finfo = get_fileinfo (input_filename);
00827 SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
00828 CLASSTYPE_INTERFACE_ONLY (t) = finfo->interface_only;
00829 }
00830
00831 return t;
00832 }
00833
00834 tree
00835 make_aggr_type (enum tree_code code)
00836 {
00837 tree t = cxx_make_type (code);
00838
00839 if (IS_AGGR_TYPE_CODE (code))
00840 SET_IS_AGGR_TYPE (t, 1);
00841
00842 return t;
00843 }