diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/Make-lang.in | 4 | ||||
-rw-r--r-- | gcc/cp/call.c | 8 | ||||
-rw-r--r-- | gcc/cp/class.c | 3 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 24 | ||||
-rw-r--r-- | gcc/cp/decl.c | 156 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 50 | ||||
-rw-r--r-- | gcc/cp/g++spec.c | 16 | ||||
-rw-r--r-- | gcc/cp/init.c | 3 | ||||
-rw-r--r-- | gcc/cp/lang-specs.h | 22 | ||||
-rw-r--r-- | gcc/cp/lex.c | 225 | ||||
-rw-r--r-- | gcc/cp/linkage.c | 341 | ||||
-rw-r--r-- | gcc/cp/parse.y | 10 | ||||
-rw-r--r-- | gcc/cp/pch.c | 56 | ||||
-rw-r--r-- | gcc/cp/pt.c | 9 | ||||
-rw-r--r-- | gcc/cp/repo.c | 6 | ||||
-rw-r--r-- | gcc/cp/spew.c | 21 | ||||
-rw-r--r-- | gcc/cp/tree.c | 2 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 4 |
18 files changed, 871 insertions, 89 deletions
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 4fe7e8752b4..3f2845d0a2f 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -101,7 +101,7 @@ CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \ cp/class.o cp/decl2.o cp/error.o cp/lex.o cp/parse.o cp/ptree.o cp/rtti.o \ cp/spew.o cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \ cp/search.o cp/semantics.o cp/tree.o cp/xref.o cp/repo.o cp/dump.o \ - cp/optimize.o cp/mangle.o + cp/optimize.o cp/mangle.o cp/linkage.o # Use loose warnings for this front end. cp-warn = @@ -242,7 +242,7 @@ cp/lex.o: cp/lex.c $(CXX_TREE_H) cp/parse.h flags.h cp/lex.h c-pragma.h \ toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h cp/operators.def \ $(TM_P_H) cp/decl.o: cp/decl.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h stack.h \ - output.h $(EXPR_H) except.h toplev.h hash.h $(GGC_H) $(RTL_H) \ + output.h $(EXPR_H) except.h hash.h toplev.h $(GGC_H) $(RTL_H) \ cp/operators.def $(TM_P_H) cp/decl2.o: cp/decl2.c $(CXX_TREE_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \ output.h except.h toplev.h $(GGC_H) $(RTL_H) diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 42731487892..bbf340811e5 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -4204,9 +4204,9 @@ build_over_call (cand, args, flags) converted_args = nreverse (converted_args); - if (warn_format && (DECL_NAME (fn) || DECL_ASSEMBLER_NAME (fn))) - check_function_format (NULL, DECL_NAME (fn), DECL_ASSEMBLER_NAME (fn), - converted_args); + if (warn_format) + check_function_format (NULL, TYPE_ATTRIBUTES (TREE_TYPE (fn)), + converted_args); /* Avoid actually calling copy constructors and copy assignment operators, if possible. */ @@ -4381,7 +4381,7 @@ build_java_interface_fn_ref (fn, instance) = builtin_function ("_Jv_LookupInterfaceMethodIdx", build_function_type (ptr_type_node, t), 0, NOT_BUILT_IN, NULL); - ggc_add_tree_root (&java_iface_lookup_fn, 1); + ggc_add_tree_root (&java_iface_lookup_fn, 1 , "java_iface"); } /* Look up the pointer to the runtime java.lang.Class object for `instance'. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index ac71fc5baa5..565891e3055 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -5501,7 +5501,8 @@ init_class_processing () = (class_stack_node_t) xmalloc (current_class_stack_size * sizeof (struct class_stack_node)); VARRAY_TREE_INIT (local_classes, 8, "local_classes"); - ggc_add_tree_varray_root (&local_classes, 1); + ggc_add_tree_varray_root (&local_classes, 1, "local_classes"); + add_varray_tree_addresses (&data_to_save, &local_classes, 1, "local_classes"); access_default_node = build_int_2 (0, 0); access_public_node = build_int_2 (ak_public, 0); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index de58ee4b890..583d3abc94f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -152,6 +152,11 @@ Boston, MA 02111-1307, USA. */ the virtual function this one overrides, and whose TREE_CHAIN is the old DECL_VINDEX. */ +#define cp_binding_level_type_def lang1_type_def +#define cp_lang_id2_type_def lang2_type_def +#define cpf_tree_node_type_def lang3_type_def +#define cp_fileinfo_type_def lang4_type_def + /* Language-specific tree checkers. */ #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) @@ -1012,6 +1017,7 @@ extern int flag_signed_bitfields; for exporting definitions that others might need. */ extern int interface_only, interface_unknown; + /* Nonzero means we should attempt to elide constructors when possible. */ extern int flag_elide_constructors; @@ -1361,6 +1367,11 @@ struct lang_type #define CLASSTYPE_DESTRUCTORS(NODE) \ (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), CLASSTYPE_DESTRUCTOR_SLOT)) +/* Whether or not the methods for the class have been sorted yet. */ +#define METHOD_VEC_SORTED_P(NODE) (TREE_LANG_FLAG_0 (NODE)) +#define CLASSTYPE_METHOD_VEC_SORTED_P(NODE) \ + (TREE_LANG_FLAG_0 (CLASSTYPE_METHOD_VEC (NODE))) + /* Mark bits for depth-first and breath-first searches. */ /* Get the value of the Nth mark bit. */ @@ -3525,6 +3536,10 @@ extern tree build_vtbl_ref PARAMS ((tree, tree)); extern tree build_vfn_ref PARAMS ((tree, tree)); extern tree get_vtable_decl PARAMS ((tree, int)); extern void add_method PARAMS ((tree, tree, int)); +#if 0 +extern void sort_methods PARAMS ((tree)); +extern void sort_fields PARAMS ((tree)); +#endif extern int currently_open_class PARAMS ((tree)); extern tree currently_open_derived_class PARAMS ((tree)); extern void duplicate_tag_error PARAMS ((tree)); @@ -3805,6 +3820,7 @@ extern int cp_line_of PARAMS ((tree)); extern const char *language_to_string PARAMS ((enum languages, int)); extern void print_instantiation_context PARAMS ((void)); + /* in except.c */ extern void init_exception_processing PARAMS ((void)); extern tree expand_start_catch_block PARAMS ((tree)); @@ -3887,6 +3903,13 @@ extern void clear_inline_text_obstack PARAMS ((void)); extern void yyhook PARAMS ((int)); extern int cp_type_qual_from_rid PARAMS ((tree)); +/* in linkage.c */ +extern void do_pragma_interface PARAMS ((tree)); +extern void do_pragma_implementation PARAMS ((tree)); +extern void maybe_add_interface_item PARAMS ((tree)); +extern void process_interface_items PARAMS ((void)); +extern void init_linkage PARAMS ((void)); + /* in method.c */ extern void init_method PARAMS ((void)); extern void set_mangled_name_for_decl PARAMS ((tree)); @@ -4142,6 +4165,7 @@ extern void do_pending_defargs PARAMS ((void)); extern void done_pending_defargs PARAMS ((void)); extern void unprocessed_defarg_fn PARAMS ((tree)); extern void replace_defarg PARAMS ((tree, tree)); +extern void end_input PARAMS ((void)); /* in tree.c */ extern void init_tree PARAMS ((void)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index dc4eb8116e9..3e12b4fb678 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -47,6 +47,8 @@ Boston, MA 02111-1307, USA. */ extern const struct attribute_spec *lang_attribute_table; + + #ifndef BOOL_TYPE_SIZE /* `bool' has size and alignment `1', on all platforms. */ #define BOOL_TYPE_SIZE CHAR_TYPE_SIZE @@ -5533,7 +5535,7 @@ build_typename_type (context, name, fullname, base_type) static struct hash_table *h = &ht; hash_table_init (&ht, &hash_newfunc, &typename_hash, &typename_compare); - ggc_add_tree_hash_table_root (&h, 1); + ggc_add_tree_hash_table_root (&h, 1, "h"); } /* Build the TYPENAME_TYPE. */ @@ -6276,6 +6278,23 @@ initialize_predefined_identifiers () Initialize the global binding level. Make definitions for built-in primitive functions. */ +static const struct field_definition_s cp_binding_level_field_defs[] = { + { 0, 0, offsetof (struct binding_level, level_chain), + cp_binding_level_type_def }, + { 0, 0, offsetof (struct binding_level, names), tree_type_def }, + { 0, 0, offsetof (struct binding_level, tags), tree_type_def }, + { 0, 0, offsetof (struct binding_level, usings), tree_type_def }, + { 0, 0, offsetof (struct binding_level, using_directives), tree_type_def }, + { 0, 0, offsetof (struct binding_level, class_shadowed), tree_type_def }, + { 0, 0, offsetof (struct binding_level, type_shadowed), tree_type_def }, + { 0, 0, offsetof (struct binding_level, shadowed_labels), tree_type_def }, + { 0, 0, offsetof (struct binding_level, blocks), tree_type_def }, + { 0, 0, offsetof (struct binding_level, this_class), tree_type_def }, + { 0, 0, offsetof (struct binding_level, incomplete), tree_type_def }, + { 0, 0, offsetof (struct binding_level, dead_vars_from_for), tree_type_def }, + NO_MORE_FIELDS +}; + void init_decl_processing () { @@ -6285,6 +6304,12 @@ init_decl_processing () /* Create all the identifiers we need. */ initialize_predefined_identifiers (); + /* Set up cp_binding_level_type_def. */ + cp_binding_level_type_def->size = sizeof (struct binding_level); + cp_binding_level_type_def->field_definitions = cp_binding_level_field_defs; + cp_binding_level_type_def->ggc_p = -1; + + /* Fill in back-end hooks. */ init_lang_status = &push_cp_function_context; free_lang_status = &pop_cp_function_context; @@ -6350,6 +6375,8 @@ init_decl_processing () std_node = current_namespace; pop_namespace (); + lang_attribute_table = cp_attribute_table; + c_common_nodes_and_builtins (); java_byte_type_node = record_builtin_java_type ("__java_byte", 8); @@ -6487,47 +6514,67 @@ init_decl_processing () make_fname_decl = cp_make_fname_decl; start_fname_decls (); - /* Prepare to check format strings against argument lists. */ - init_function_format_info (); - /* Show we use EH for cleanups. */ using_eh_for_cleanups (); - lang_attribute_table = cp_attribute_table; - /* Maintain consistency. Perhaps we should just complain if they say -fwritable-strings? */ if (flag_writable_strings) flag_const_strings = 0; /* Add GC roots for all of our global variables. */ - ggc_add_tree_root (c_global_trees, sizeof c_global_trees / sizeof(tree)); - ggc_add_tree_root (cp_global_trees, sizeof cp_global_trees / sizeof(tree)); - ggc_add_tree_root (&integer_three_node, 1); - ggc_add_tree_root (&integer_two_node, 1); - ggc_add_tree_root (&signed_size_zero_node, 1); - ggc_add_tree_root (&size_one_node, 1); - ggc_add_tree_root (&size_zero_node, 1); - ggc_add_root (&global_binding_level, 1, sizeof global_binding_level, - mark_binding_level); - ggc_add_root (&scope_chain, 1, sizeof scope_chain, &mark_saved_scope); - ggc_add_tree_root (&static_ctors, 1); - ggc_add_tree_root (&static_dtors, 1); - ggc_add_tree_root (&lastiddecl, 1); - - ggc_add_tree_root (&last_function_parms, 1); - ggc_add_tree_root (&error_mark_list, 1); - - ggc_add_tree_root (&global_namespace, 1); - ggc_add_tree_root (&global_type_node, 1); - ggc_add_tree_root (&anonymous_namespace_name, 1); - - ggc_add_tree_root (&got_object, 1); - ggc_add_tree_root (&got_scope, 1); - - ggc_add_tree_root (¤t_lang_name, 1); - ggc_add_tree_root (&static_aggregates, 1); - ggc_add_tree_root (&free_bindings, 1); + ggc_add_tree_root (c_global_trees, CTI_MAX ,"c_global_trees"); + add_tree_addresses (&data_to_save, c_global_trees , CTI_MAX , "c_global_trees"); + ggc_add_tree_root (cp_global_trees, CPTI_MAX , "cp_global_trees"); + add_tree_addresses (&data_to_save, cp_global_trees, CPTI_MAX , "cp_global_trees"); + add_tree_addresses (&data_to_save, ridpointers, RID_MAX, "ridpointers"); + ggc_add_tree_root (&integer_three_node, 1, "integer_three_node"); + add_tree_addresses (&data_to_save, &integer_three_node, 1, "integer_three_node"); + ggc_add_tree_root (&integer_two_node, 1, "integer_two_node"); + add_tree_addresses (&data_to_save, &integer_two_node, 1, "integer_two_node"); + ggc_add_tree_root (&signed_size_zero_node, 1, "signed_size_zero_node"); + add_tree_addresses (&data_to_save, &signed_size_zero_node, 1, "signed_size_zero_node"); + ggc_add_tree_root (&size_one_node, 1, "size_one_node"); + add_tree_addresses (&data_to_save, &size_one_node, 1, "size_one_node"); + ggc_add_tree_root (&size_zero_node, 1, "size_zero_node"); + add_tree_addresses (&data_to_save, &size_zero_node, 1, "size_zero_node"); + ggc_add_typed_root (&global_binding_level, cp_binding_level_type_def, 1, "global_binding_level"); + add_typed_addresses (&data_to_save, (void **)&global_binding_level, + cp_binding_level_type_def, 1, "global_binding_level"); + add_typed_addresses (&data_to_save, (void **)¤t_binding_level, + cp_binding_level_type_def, 1, "current_binding_level"); + ggc_add_root (&scope_chain, 1, sizeof scope_chain, &mark_saved_scope, "scope_chain"); + ggc_add_tree_root (&static_ctors, 1, "static_ctors"); + add_tree_addresses (&data_to_save, &static_ctors, 1, "static_ctors"); + ggc_add_tree_root (&static_dtors, 1, "static_dtors"); + add_tree_addresses (&data_to_save, &static_dtors, 1, "static_dtors"); + ggc_add_tree_root (&lastiddecl, 1, "lastiddecl"); + + ggc_add_tree_root (&last_function_parms, 1 , "last_function_parms" ); + ggc_add_tree_root (&error_mark_list, 1 , "error_mark_list" ); + add_tree_addresses (&data_to_save, &error_mark_list, 1 , "error_mark_list" ); + + ggc_add_tree_root (&global_namespace, 1 , "global_namespace" ); + add_tree_addresses (&data_to_save, &global_namespace, 1 , "global_namespace" ); + add_tree_addresses (&data_to_save, ¤t_namespace, 1 , "current_namespace" ); + ggc_add_tree_root (&global_type_node, 1 , "global_type_node" ); + add_tree_addresses (&data_to_save, &global_type_node, 1 , "global_type_node" ); + ggc_add_tree_root (&anonymous_namespace_name, 1 , "anonymous_namespace_name" ); + add_tree_addresses (&data_to_save, &anonymous_namespace_name, 1 , "anonymous_namespace_name" ); + + ggc_add_tree_root (&got_object, 1 , "got_object" ); + + ggc_add_tree_root (&got_scope, 1 , "got_scope" ); + + ggc_add_tree_root (¤t_lang_name, 1 , "current_lang_name" ); + add_tree_addresses (&data_to_save, ¤t_lang_name, 1 , "current_lang_name" ); + ggc_add_tree_root (&static_aggregates, 1 , "static_aggregates" ); + add_tree_addresses (&data_to_save, &static_aggregates, 1 , "static_aggregates" ); + + add_untyped_address (&data_to_save, &anon_cnt, sizeof (anon_cnt) , "anon_cnt" ); + + ggc_add_tree_root (&free_bindings, 1 , "free_bindings" ); + add_tree_addresses (&data_to_save, &free_bindings, 1 , "free_bindings" ); } /* Generate an initializer for a function naming variable from @@ -6643,6 +6690,9 @@ builtin_function (name, type, code, class, libname) if (name[0] != '_' || name[1] != '_') DECL_ANTICIPATED (decl) = 1; + /* Possibly apply some default attributes to this built-in function. */ + decl_attributes (&decl, NULL_TREE, 0); + return decl; } @@ -6765,6 +6815,20 @@ push_throw_library_fn (name, type) TREE_NOTHROW (fn) = 0; return fn; } + +/* Apply default attributes to a function, if a system function with default + attributes. */ + +void +insert_default_attributes (decl) + tree decl; +{ + if (!DECL_EXTERN_C_FUNCTION_P (decl)) + return; + if (!TREE_PUBLIC (decl)) + return; + c_common_insert_default_attributes (decl); +} /* When we call finish_struct for an anonymous union, we create default copy constructors and such. But, an anonymous union @@ -11019,13 +11083,13 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) } else if (quals) { - if (ctype == NULL_TREE) - { - if (TREE_CODE (type) != METHOD_TYPE) + if (ctype == NULL_TREE) + { + if (TREE_CODE (type) != METHOD_TYPE) cp_error_at ("invalid type qualifier for non-member function type", decl); else - ctype = TYPE_METHOD_BASETYPE (type); - } + ctype = TYPE_METHOD_BASETYPE (type); + } if (ctype != NULL_TREE) grok_method_quals (ctype, decl, quals); } @@ -13451,7 +13515,7 @@ start_function (declspecs, declarator, attrs, flags) if (!DECL_PENDING_INLINE_P (decl1) && DECL_SAVED_FUNCTION_DATA (decl1)) { - free (DECL_SAVED_FUNCTION_DATA (decl1)); + free(DECL_SAVED_FUNCTION_DATA (decl1)); DECL_SAVED_FUNCTION_DATA (decl1) = NULL; } @@ -13527,14 +13591,14 @@ start_function (declspecs, declarator, attrs, flags) DECL_INTERFACE_KNOWN (decl1) = 1; } else if (interface_unknown && interface_only - && (! DECL_TEMPLATE_INSTANTIATION (decl1) - || flag_alt_external_templates)) + && (! DECL_TEMPLATE_INSTANTIATION (decl1) + || flag_alt_external_templates)) { /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma - interface, we will have interface_only set but not - interface_known. In that case, we don't want to use the normal - heuristics because someone will supply a #pragma implementation - elsewhere, and deducing it here would produce a conflict. */ + interface, we will have interface_only set but not + interface_known. In that case, we don't want to use the normal + heuristics because someone will supply a #pragma implementation + elsewhere, and deducing it here would produce a conflict. */ comdat_linkage (decl1); DECL_EXTERNAL (decl1) = 0; DECL_INTERFACE_KNOWN (decl1) = 1; @@ -13551,7 +13615,7 @@ start_function (declspecs, declarator, attrs, flags) && ! DECL_INTERFACE_KNOWN (decl1) /* Don't try to defer nested functions for now. */ && ! decl_function_context (decl1)) - DECL_DEFER_OUTPUT (decl1) = 1; + DECL_DEFER_OUTPUT (decl1) = 1; else DECL_INTERFACE_KNOWN (decl1) = 1; } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 372b8ee8139..9f9af519f1c 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -42,6 +42,7 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "ggc.h" #include "timevar.h" +#include "cpphash.h" #include "cpplib.h" #include "target.h" extern cpp_reader *parse_in; @@ -429,6 +430,7 @@ lang_f_options[] = {"short-double", &flag_short_double, 1}, {"short-wchar", &flag_short_wchar, 1}, {"asm", &flag_no_asm, 0}, + {"auto-pch", &flag_auto_pch, 1}, {"builtin", &flag_no_builtin, 0}, /* C++-only options. */ @@ -562,6 +564,11 @@ cxx_decode_option (argc, argv) flag_external_templates = 1; cp_deprecated ("-fexternal-templates"); } + else if (!strcmp (p, "auto-pch")) + { + flag_auto_pch = 1; + CPP_OPTION (parse_in, gen_deps) = 1; + } else if ((option_value = skip_leading_substring (p, "template-depth-"))) max_tinst_depth @@ -572,6 +579,12 @@ cxx_decode_option (argc, argv) warning ("-fname-mangling-version is no longer supported"); return 1; } + else if ((option_value + = skip_leading_substring (p, "output-pch="))) + { + pch_file = option_value; + CPP_OPTION (parse_in, gen_deps) = 1; + } else if (dump_switch_p (p)) ; else @@ -590,14 +603,14 @@ cxx_decode_option (argc, argv) but breaks the VAX pcc. */ found = 1; } - if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' - && ! strcmp (p+3, lang_f_options[j].string)) + else if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' + && ! strcmp (p+3, lang_f_options[j].string)) { *lang_f_options[j].variable = ! lang_f_options[j].on_value; found = 1; } } - + return found; } } @@ -2181,7 +2194,7 @@ mark_vtable_entries (decl) we know all the thunks we'll need when we emit a virtual function, so we emit the thunks there instead. */ if (DECL_THUNK_P (fn)) - use_thunk (fn, /*emit_p=*/0); + use_thunk (fn, /*emit_p=*/0); mark_used (fn); } } @@ -2328,7 +2341,8 @@ import_export_vtable (decl, type, final) functions in our class, or if we come from a template. */ int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type) - || key_method (type)); + || key_method (type)); + if (final || ! found) { @@ -3358,6 +3372,9 @@ finish_file () int reconsider; size_t i; + if (pch_file) + lang_write_pch (); + at_eof = 1; /* Bad parse errors. Just forget about it. */ @@ -3389,6 +3406,8 @@ finish_file () timevar_push (TV_VARCONST); + process_interface_items (); + emit_support_tinfos (); do @@ -4852,6 +4871,7 @@ validate_nonmember_using_decl (decl, scope, name) *scope = TREE_OPERAND (decl, 0); *name = TREE_OPERAND (decl, 1); + if (!processing_template_decl) { /* [namespace.udecl] @@ -5253,10 +5273,18 @@ handle_class_head (aggr, scope, id) void init_decl2 () { - ggc_add_tree_varray_root (&deferred_fns, 1); - ggc_add_tree_varray_root (&pending_statics, 1); - ggc_add_tree_varray_root (&ssdf_decls, 1); - ggc_add_tree_root (&ssdf_decl, 1); - ggc_add_tree_root (&priority_decl, 1); - ggc_add_tree_root (&initialize_p_decl, 1); + ggc_add_tree_varray_root (&deferred_fns, 1 , "deferred_fns" ); + add_varray_tree_addresses (&data_to_save, &deferred_fns, 1 , "deferred_fns" ); + ggc_add_tree_varray_root (&pending_statics, 1 , "pending_statics" ); + add_varray_tree_addresses (&data_to_save, &pending_statics, 1 , "pending_statics" ); + ggc_add_tree_varray_root (&ssdf_decls, 1 , "ssdf_decls" ); + add_varray_tree_addresses (&data_to_save, &ssdf_decls, 1 , "ssdf_decls" ); + ggc_add_tree_root (&ssdf_decl, 1 , "ssdf_decl" ); + add_tree_addresses (&data_to_save, &ssdf_decl, 1 , "ssdf_decl" ); + ggc_add_tree_root (&priority_decl, 1 , "priority_decl" ); + add_tree_addresses (&data_to_save, &priority_decl, 1 , "priority_decl" ); + ggc_add_tree_root (&initialize_p_decl, 1 , "initialize_p_decl" ); + add_tree_addresses (&data_to_save, &initialize_p_decl, 1 , "initialize_p_decl" ); + + } diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c index fbbe5990d0c..13ca2c6a44c 100644 --- a/gcc/cp/g++spec.c +++ b/gcc/cp/g++spec.c @@ -185,12 +185,22 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) But not if a specified -x option is currently active. */ len = strlen (argv[i]); if (len > 2 - && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i') + && (argv[i][len - 1] == 'c' + || argv[i][len - 1] == 'i' + || argv[i][len - 1] == 'h') && argv[i][len - 2] == '.') { args[i] |= LANGSPEC; added += 2; - } + + /* Compiling a header doesn't involve linking. */ + if (library && argv[i][len - 1] == 'h') + { + library = 0; + added -= 2; + + } + } } } @@ -246,6 +256,8 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries) int len = strlen (argv[i]); if (argv[i][len - 1] == 'i') arglist[j++] = "-xc++-cpp-output"; + else if (argv[i][len - 1] == 'h') + arglist[j++] = "-xc++-header"; else arglist[j++] = "-xc++"; arglist[j++] = argv[i]; diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 487543e6386..c0828dce033 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -73,7 +73,8 @@ void init_init_processing () finish_builtin_type (BI_header_type, "__new_cookie", fields, 0, double_type_node); - ggc_add_tree_root (&BI_header_type, 1); + ggc_add_tree_root (&BI_header_type, 1, "BI_header_type"); + add_tree_addresses (&data_to_save, &BI_header_type, 1, "BI_header_type"); } /* We are about to generate some complex initialization code. diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h index 67a3ecbe3e8..d54731203a9 100644 --- a/gcc/cp/lang-specs.h +++ b/gcc/cp/lang-specs.h @@ -32,6 +32,20 @@ Boston, MA 02111-1307, USA. */ {".cpp", "@c++", 0}, {".c++", "@c++", 0}, {".C", "@c++", 0}, + {"@c++-header", + "%{E|M|MM:%(cpp0) -lang-c++ %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ + %{!no-gcc:-D__GNUG__=%v1}\ + %{fnew-abi:-D__GXX_ABI_VERSION=100}\ + %{fembedded-cxx:-D__EMBEDDED_CXX__} \ + %(cpp_options)} " + "%{!E:cc1plus -lang-c++ %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ + %{!no-gcc:-D__GNUG__=%v1}\ + %{fnew-abi:-D__GXX_ABI_VERSION=100}\ + %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ + %{fembedded-cxx:-D__EMBEDDED_CXX__} \ + %(cpp_options) %(cc1_options)\ + -o %g.s %{!o*:-foutput-pch=%i.pch} %W{^o*:-foutput-pch=%*}%V} " + }, {"@c++", /* cc1plus has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps is given. */ @@ -48,6 +62,14 @@ Boston, MA 02111-1307, USA. */ -D__GXX_ABI_VERSION=100\ %{ansi:-D__STRICT_ANSI__ -trigraphs -$}\ %(cpp_options) %b.ii \n}\ + %{fauto-pch:%{!fsyntax-only:%{!save-temps: %{<fauto-pch} \ + cc1plus -lang-c++\ + %{!no-gcc:-D__GNUG__=%v1}\ + %{fnew-abi:-D__GXX_ABI_VERSION=100}\ + %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ + %{fembedded-cxx:-D__EMBEDDED_CXX__} \ + %(cpp_options) %(cc1_options) %{+e*} \ + -fauto-pch %{!S:-o %g.s}\n}}}\ cc1plus %{save-temps:-fpreprocessed %b.ii}\ %{!save-temps:%(cpp_options)\ %{!no-gcc:-D__GNUG__=%v1} \ diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 6d8fcb36ad7..2f039d58271 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -52,6 +52,17 @@ Boston, MA 02111-1307, USA. */ extern void yyprint PARAMS ((FILE *, int, YYSTYPE)); static int interface_strcmp PARAMS ((const char *)); +static void cp_tree_prewrite_hook PARAMS ((const void *)); +static code_type cp_tree_code_fetcher PARAMS ((const void *)); +static size_t cp_lang_decl_size_fetcher PARAMS ((const void *, + type_definition_p)); +static int cp_lang_decl_more_fields PARAMS ((struct field_definition_s *fp, + const void *t_v, + unsigned n, + code_type c, + type_definition_p td)); + + static int *init_cpp_parse PARAMS ((void)); static void init_reswords PARAMS ((void)); static void init_cp_pragma PARAMS ((void)); @@ -85,6 +96,12 @@ static void init_operators PARAMS ((void)); #include "cpplib.h" + +/* Pending language change. + Positive is push count, negative is pop count. */ +int pending_lang_change = 0; + + extern int yychar; /* the lookahead symbol */ extern YYSTYPE yylval; /* the semantic value of the */ /* lookahead symbol */ @@ -103,6 +120,7 @@ tree lastiddecl; /* Array for holding counts of the numbers of tokens seen. */ extern int *token_count; + /* Functions and data structures for #pragma interface. `#pragma implementation' means that the main file being compiled @@ -275,13 +293,195 @@ cxx_init_options () diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE; } +static code_type +cp_tree_code_fetcher (t_v) + const void *t_v; +{ + tree t = (tree)t_v; + enum tree_code code = TREE_CODE (t); + + code_type r = code << 8 | TREE_CODE_CLASS (code); + + if (code == POINTER_TYPE) +#if 0 + && TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE) +#endif + r |= 0x20000; + if (code == CPLUS_BINDING + && BINDING_HAS_LEVEL_P (t)) + r |= 0x10000; + return r; +} + +/* A function to be called for each tree node before they are written out by + the precompiled headers mechanism. Currently we use this to note that + the fields and methods are not sorted, as PCH fails to preserve address + order for identifiers. */ + +static void +cp_tree_prewrite_hook (t_v) + const void *t_v; +{ + tree t = (tree)t_v; + if (TREE_CODE (t) == TYPE_DECL && DECL_LANG_SPECIFIC (t)) + DECL_SORTED_FIELDS (t) = NULL_TREE; + else if (CLASS_TYPE_P (t) && CLASSTYPE_METHOD_VEC (t)) + CLASSTYPE_METHOD_VEC_SORTED_P (t) = 0; +} + +static const struct field_definition_s cp_tree_field_defs[] = { + { 't', 0x200FF, offsetof (union tree_node, type.lang_specific), + lang_type_type_def }, + /* In the case of pointer-to-member function types, the + TYPE_LANG_SPECIFIC is really just a tree. */ + { 't' | 0x20000, 0x200FF, offsetof (union tree_node, type.lang_specific), + tree_type_def }, + { IDENTIFIER_NODE << 8, 0xFF00, + offsetof (struct lang_identifier, namespace_bindings), tree_type_def }, + { IDENTIFIER_NODE << 8, 0xFF00, + offsetof (struct lang_identifier, bindings), tree_type_def }, + { IDENTIFIER_NODE << 8, 0xFF00, + offsetof (struct lang_identifier, class_value), tree_type_def }, + { IDENTIFIER_NODE << 8, 0xFF00, + offsetof (struct lang_identifier, class_template_info), tree_type_def }, + { IDENTIFIER_NODE << 8, 0xFF00, + offsetof (struct lang_identifier, x), cp_lang_id2_type_def }, + { CPLUS_BINDING << 8 | 0x10000, 0x1FF00, + offsetof (struct tree_binding, scope.level), cp_binding_level_type_def }, + { CPLUS_BINDING << 8 | 0x00000, 0x1FF00, + offsetof (struct tree_binding, scope.scope), tree_type_def }, + { CPLUS_BINDING << 8, 0xFF00, + offsetof (struct tree_binding, value), tree_type_def }, + { OVERLOAD << 8, 0xFF00, + offsetof (struct tree_overload, function), tree_type_def }, + { TEMPLATE_PARM_INDEX << 8, 0xFF00, + offsetof (template_parm_index, decl), tree_type_def }, + + NO_MORE_FIELDS +}; + +static size_t +cp_lang_decl_size_fetcher (v, td) + const void *v; + type_definition_p td ATTRIBUTE_UNUSED; +{ + tree t = (tree)v; + if (CAN_HAVE_FULL_LANG_DECL_P (t)) + return sizeof (struct lang_decl); + else + return sizeof (struct lang_decl_flags); +} + +static int +cp_lang_decl_more_fields (fp, t_v, n, c, td) + struct field_definition_s *fp; + const void *t_v; + unsigned n; + code_type c ATTRIBUTE_UNUSED; + type_definition_p td ATTRIBUTE_UNUSED; +{ + tree t = (tree)t_v; + fp->type = tree_type_def; + switch (n) + { + case 0: + fp->offset = offsetof (struct lang_decl, decl_flags.base.saved_tree); + return 1; + case 1: + if (TREE_CODE (t) == NAMESPACE_DECL) + fp->type = cp_binding_level_type_def; + fp->offset = offsetof (struct lang_decl, decl_flags.u); + return 1; + case 2: + if (! DECL_THUNK_P (t) + && (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))) + fp->type = NULL; + fp->offset = offsetof (struct lang_decl, decl_flags.u2); + return 1; + case 3: + if (! CAN_HAVE_FULL_LANG_DECL_P (t)) + return 0; + + fp->offset = offsetof (struct lang_decl, befriending_classes); + return 1; + case 4: + fp->offset = offsetof (struct lang_decl, context); + return 1; + case 5: + fp->offset = offsetof (struct lang_decl, cloned_function); + return 1; + case 6: + if (TREE_CODE (t) == FUNCTION_DECL + && ! DECL_PENDING_INLINE_P (t)) + fp->type = lang_function_type_def; + else if (TREE_CODE (t) != TYPE_DECL) + fp->type = NULL; + fp->offset = offsetof (struct lang_decl, u); + return 1; + case 7: + if (DECL_OVERLOADED_OPERATOR_P (t)) + fp->type = NULL; + fp->offset = offsetof (struct lang_decl, u2.operator_code); + return 1; + default: + return 0; + } +} + +static const struct subobject_definition_s cp_tree_subobjects[] = { + { + 'd', + 0xFF, + offsetof (union tree_node, decl.lang_specific), + cp_lang_decl_size_fetcher, + cp_lang_decl_more_fields + }, + NO_MORE_SUBOBJECTS +}; + +static const struct field_definition_s cp_lang_id2_field_defs[] = { + { 0, 0, offsetof (struct lang_id2, label_value), tree_type_def }, + { 0, 0, offsetof (struct lang_id2, implicit_decl), tree_type_def }, + { 0, 0, offsetof (struct lang_id2, error_locus), tree_type_def }, + NO_MORE_FIELDS +}; + +static const struct field_definition_s cp_lang_type_field_defs[] = { + { 0, 0, offsetof (struct lang_type, primary_base), tree_type_def }, + { 0, 0, offsetof (struct lang_type, vfields), tree_type_def }, + { 0, 0, offsetof (struct lang_type, vbases), tree_type_def }, + { 0, 0, offsetof (struct lang_type, tags), tree_type_def }, + { 0, 0, offsetof (struct lang_type, size), tree_type_def }, + { 0, 0, offsetof (struct lang_type, size_unit), tree_type_def }, + { 0, 0, offsetof (struct lang_type, pure_virtuals), tree_type_def }, + { 0, 0, offsetof (struct lang_type, friend_classes), tree_type_def }, + { 0, 0, offsetof (struct lang_type, rtti), tree_type_def }, + { 0, 0, offsetof (struct lang_type, methods), tree_type_def }, + { 0, 0, offsetof (struct lang_type, template_info), tree_type_def }, + { 0, 0, offsetof (struct lang_type, befriending_classes), tree_type_def }, + NO_MORE_FIELDS +}; + + + static void cxx_init () { c_common_lang_init (); + add_tree_fields (cp_tree_field_defs); + tree_type_def->code_fetcher = cp_tree_code_fetcher; + tree_type_def->subobject_definitions = cp_tree_subobjects; + tree_type_def->prewrite_hook = cp_tree_prewrite_hook; + lang_type_type_def->size = sizeof (struct lang_type); + lang_type_type_def->field_definitions = cp_lang_type_field_defs; + lang_function_type_def->size = sizeof (struct cp_language_function); + cp_lang_id2_type_def->size = sizeof (struct lang_id2); + cp_lang_id2_type_def->field_definitions = cp_lang_id2_field_defs; + if (flag_gnu_xref) GNU_xref_begin (input_filename); init_repo (input_filename); + pch_init(); } static void @@ -296,6 +496,27 @@ lang_identify () return "cplusplus"; } +void +lang_write_pch () +{ + invalidate_class_lookup_cache (); + c_write_pch (); +} + +/* Returns nonzero if we are not nested inside any incomplete scopes. + Used by the PCH machinery. */ + +int +lang_toplevel_p () +{ + if (! global_bindings_p ()) + return 0; + if (current_lang_depth () != 0) + return 0; + return 1; +} + + static int * init_cpp_parse () { @@ -710,6 +931,7 @@ init_parse (filename) init_tree (); init_cplus_expand (); init_cp_semantics (); + init_linkage (); add_c_tree_codes (); @@ -940,6 +1162,7 @@ set_yydebug (value) /* Helper function to load global variables with interface information. */ + void extract_interface_info () { @@ -965,7 +1188,7 @@ extract_interface_info () /* Return nonzero if S is not considered part of an INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */ -static int +int interface_strcmp (s) const char *s; { diff --git a/gcc/cp/linkage.c b/gcc/cp/linkage.c new file mode 100644 index 00000000000..21960dd81b3 --- /dev/null +++ b/gcc/cp/linkage.c @@ -0,0 +1,341 @@ +/* Code for handling linkage of vtables, inlines et al in GNU C++. + Copyright (C) 2001 Free Software Foundation, Inc. + Hacked by Jason Merrill (jason@redhat.com) + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" +#include "tree.h" +#include "cp-tree.h" +#include "ggc.h" +#include "flags.h" +#include "toplev.h" + +#include "splay-tree.h" +#include "varray.h" + +/* Functions and data structures for #pragma interface. + + `#pragma implementation' means that the main file being compiled + is considered to implement (provide) the classes that appear in + its main body. I.e., if this is file "foo.cc", and class `bar' + is defined in "foo.cc", then we say that "foo.cc implements bar". + + All main input files "implement" themselves automagically. + + `#pragma interface' means that unless this file (of the form "foo.h" + is presently being included by file "foo.cc", the FIXME FIXME + CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none + of the vtables nor any of the inline functions defined in foo.h + will ever be output. + + There are cases when we want to link files such as "defs.h" and + "main.cc". In this case, we give "defs.h" a `#pragma interface', + and "main.cc" has `#pragma implementation "defs.h"'. */ + +struct cp_fileinfo +{ + varray_type items; + int implemented; +}; +static splay_tree cp_fileinfo_tree; + +/* The list of entities with vague linkage in the current file, if we've + seen #pragma interface. */ + +varray_type *interface_itemsptr; + +static varray_type impl_files; + +static int interface_strcmp PARAMS ((const char *, const char *)); + +/* Helper function to load global variables with interface + information. */ + +#if 0 +void +extract_interface_info () +{ + struct c_fileinfo *finfo = 0; + struct cp_fileinfo *ifile = 0; + + if (flag_alt_external_templates) + { + tree til = tinst_for_decl (); + + if (til) + finfo = get_fileinfo (TINST_FILE (til)); + } + if (!finfo) + finfo = get_fileinfo (input_filename); + + ifile = (struct cp_fileinfo *) (finfo->lang_data); + + interface_unknown = 1; + if (ifile) + { + interface_itemsptr = &(ifile->items); + interface_only = 1; + } + else + { + interface_itemsptr = NULL; + interface_only = 0; + } + + /* This happens to be a convenient place to put this. */ + if (flag_gnu_xref) GNU_xref_file (input_filename); +} +#endif + +/* Return zero if S and T work as an INTERFACE/IMPLEMENTATION pair. + Basically, this is a strcmp ignoring the file extension, so that foo.C and + foo.h will match. + + Otherwise, return as strcmp. */ + +static int +interface_strcmp (s1, t1) + const char *s1; + const char *t1; +{ + while (*s1 == *t1 && *s1 != 0) + s1++, t1++; + + /* A match. */ + if (*s1 == *t1) + return 0; + + /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ + if (strchr (s1, '.') || strchr (t1, '.')) + return *s1 - *t1; + + if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') + return *s1 - *t1; + + /* A match. */ + return 0; +} + +static struct cp_fileinfo * +maybe_get_cp_fileinfo (name) + const char *name; +{ + splay_tree_node n; + + n = splay_tree_lookup (cp_fileinfo_tree, (splay_tree_key) name); + if (n) + return (struct cp_fileinfo *) n->value; + return NULL; +} + +static struct cp_fileinfo * +insert_cp_fileinfo (name) + const char *name; +{ + struct cp_fileinfo *fi + = (struct cp_fileinfo *) xcalloc (1, sizeof (struct cp_fileinfo)); + VARRAY_TREE_INIT (fi->items, 5, "interface items"); + splay_tree_insert (cp_fileinfo_tree, (splay_tree_key) name, + (splay_tree_value) fi); + return fi; +} + +void +do_pragma_interface (fname) + tree fname; +{ + struct c_fileinfo *finfo; + struct cp_fileinfo *cp_finfo; + const char *main_filename; + + if (fname == 0) + main_filename = file_name_nondirectory (input_filename); + else + main_filename = TREE_STRING_POINTER (fname); + + finfo = get_fileinfo (input_filename); + + cp_finfo = maybe_get_cp_fileinfo (ggc_strdup (main_filename)); + if (cp_finfo) + warning ("duplicate #pragma interface for %s", main_filename); + else + cp_finfo = insert_cp_fileinfo (main_filename); + + finfo->lang_data = cp_finfo; + + extract_interface_info (); +} + +/* Note that we have seen a #pragma implementation for the key MAIN_FILENAME. + We used to only allow this at toplevel, but that restriction was buggy + in older compilers and it seems reasonable to allow it in the headers + themselves, too. */ + +void +do_pragma_implementation (fname) + tree fname; +{ + const char *main_filename; + + if (fname == 0) + main_filename = file_name_nondirectory (main_input_filename); + else + main_filename = TREE_STRING_POINTER (fname); + + VARRAY_PUSH_CHAR_PTR (impl_files, ggc_strdup (main_filename)); +} + +void +maybe_add_interface_item (item) + tree item; +{ + if (interface_itemsptr) + VARRAY_PUSH_TREE (*interface_itemsptr, item); +} + +static int +foreach_process_interface (node, data) + splay_tree_node node; + void *data ATTRIBUTE_UNUSED; +{ + struct cp_fileinfo *cp_finfo = (struct cp_fileinfo *) node->value; + varray_type items = cp_finfo->items; + int impl = cp_finfo->implemented; + unsigned i; + + for (i = 0; i < VARRAY_ACTIVE_SIZE (items); ++i) + { + tree item = VARRAY_TREE (items, i); + if (TYPE_P (item)) + { + SET_CLASSTYPE_INTERFACE_KNOWN (item); + CLASSTYPE_INTERFACE_ONLY (item) = !impl; +#if 0 + CLASSTYPE_VTABLE_NEEDS_WRITING (item) = impl; +#endif + TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (item)) = !impl; + if (impl && !uses_template_parms (item)) + { + CLASSTYPE_DEBUG_REQUESTED (item) = 1; + rest_of_type_compilation (item, 1); + } + if (flag_external_templates && !flag_alt_external_templates + && uses_template_parms (item)) + { + tree s + = DECL_TEMPLATE_INSTANTIATIONS (CLASSTYPE_TI_TEMPLATE (item)); + for (; s; s = TREE_CHAIN (s)) + { + tree t = TREE_VALUE (s); + SET_CLASSTYPE_INTERFACE_KNOWN (t); + CLASSTYPE_INTERFACE_ONLY (t) = !impl; +#if 0 + CLASSTYPE_VTABLE_NEEDS_WRITING (t) = impl; +#endif + TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = !impl; + if (impl && !uses_template_parms (t)) + { + CLASSTYPE_DEBUG_REQUESTED (t) = 1; + rest_of_type_compilation (t, 1); + } + } + } + } + else + { + DECL_INTERFACE_KNOWN (item) = 1; + if (DECL_LANG_SPECIFIC (item)) + DECL_NOT_REALLY_EXTERN (item) = impl; + else + DECL_EXTERNAL (item) = !impl; + if (flag_external_templates && !flag_alt_external_templates + && uses_template_parms (item)) + { + tree s = DECL_TEMPLATE_SPECIALIZATIONS (DECL_TI_TEMPLATE (item)); + for (; s; s = TREE_CHAIN (s)) + { + tree d = TREE_VALUE (s); + DECL_INTERFACE_KNOWN (d) = 1; + DECL_NOT_REALLY_EXTERN (d) = impl; + } + } + } + } + return 0; +} + +void +process_interface_items () +{ + unsigned int i; + for (i = 0; i < VARRAY_ACTIVE_SIZE (impl_files); ++i) + { + char *file = VARRAY_CHAR_PTR (impl_files, i); + struct cp_fileinfo *cp_finfo = maybe_get_cp_fileinfo (file); + if (! cp_finfo) + warning ("\ +#pragma implementation for %s does not match any #pragma interface", + file); + else + { + if (cp_finfo->implemented) + warning ("duplicate #pragma implementation for %s", file); + cp_finfo->implemented = 1; + } + } + splay_tree_foreach (cp_fileinfo_tree, foreach_process_interface, NULL); +} + +/* Type layout information for cp_fileinfo_tree for the gtype machinery. */ + +static const struct field_definition_s cpf_tree_node_field_defs[] = { + { 0, 0, offsetof (struct splay_tree_node_s, key), string_type_def }, + { 0, 0, offsetof (struct splay_tree_node_s, value), cp_fileinfo_type_def }, + { 0, 0, offsetof (struct splay_tree_node_s, left), cpf_tree_node_type_def }, + { 0, 0, offsetof (struct splay_tree_node_s, right), cpf_tree_node_type_def }, + NO_MORE_FIELDS +}; +static const struct field_definition_s cp_fileinfo_field_defs[] = { + { 0, 0, offsetof (struct cp_fileinfo, items), varray_tree_type_def }, + NO_MORE_FIELDS +}; + +void +init_linkage () +{ + cpf_tree_node_type_def->size = sizeof (struct splay_tree_node_s); + cpf_tree_node_type_def->field_definitions = cpf_tree_node_field_defs; + cpf_tree_node_type_def->ggc_p = -1; + cp_fileinfo_type_def->size = sizeof (struct cp_fileinfo); + cp_fileinfo_type_def->field_definitions = cp_fileinfo_field_defs; + cp_fileinfo_type_def->ggc_p = -1; + + cp_fileinfo_tree = splay_tree_new ((splay_tree_compare_fn)interface_strcmp, + 0, + (splay_tree_delete_value_fn)free); + + ggc_add_typed_root (&cp_fileinfo_tree->root, cpf_tree_node_type_def, 1, "cp_fileinfo_tree->root"); + add_typed_addresses (&data_to_save, (void **)&cp_fileinfo_tree->root, + cpf_tree_node_type_def, 1, "cp_fileinfo_tree->root"); + + /* Not saved in PCH. */ + VARRAY_CHAR_PTR_INIT (impl_files, 1, "impl_files"); + ggc_add_string_varray_root (&impl_files, 1, "impl_files"); +} diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y index 9801c3817fa..2735fc9870e 100644 --- a/gcc/cp/parse.y +++ b/gcc/cp/parse.y @@ -209,10 +209,10 @@ parse_method (declarator, specs_attrs, lookups) void cp_parse_init () { - ggc_add_tree_root (¤t_declspecs, 1); - ggc_add_tree_root (&prefix_attributes, 1); - ggc_add_tree_root (¤t_enum_type, 1); - ggc_add_tree_root (&saved_scopes, 1); + ggc_add_tree_root (¤t_declspecs, 1, "current_declspecs"); + ggc_add_tree_root (&prefix_attributes, 1, "prefix_attributes"); + ggc_add_tree_root (¤t_enum_type, 1, "current_enum_type"); + ggc_add_tree_root (&saved_scopes, 1, "saved_scopes"); } /* Rename the "yyparse" function so that we can override it elsewhere. */ @@ -736,6 +736,8 @@ datadef: } | error ';' | error '}' + | error END_OF_SAVED_INPUT + { end_input (); } | ';' | bad_decl ; diff --git a/gcc/cp/pch.c b/gcc/cp/pch.c new file mode 100644 index 00000000000..15f2f192326 --- /dev/null +++ b/gcc/cp/pch.c @@ -0,0 +1,56 @@ +/* Precompiled header implementation for C++ + Copyright (C) 2000 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" +#include "intl.h" +#include "tree.h" +#include "rtl.h" +#include "flags.h" +#include "function.h" +#include "expr.h" +#include "toplev.h" +#include "cpplib.h" +#include "defaults.h" +#include "ggc.h" +#include "tm_p.h" + +void +lang_write_pch (name) + const char *name; +{ +} + +int +lang_valid_pch (pfile, name, fd) + cpp_reader *pfile ATTRIBUTE_UNUSED; + const char *name; + int fd; +{ + return 2; +} + +void +lang_read_pch (pfile, fd) + cpp_reader *pfile; + int fd; +{ + abort (); +} diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 292513fb43e..9b3fbdac629 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -172,9 +172,12 @@ static int invalid_nontype_parm_type_p PARAMS ((tree, int)); void init_pt () { - ggc_add_tree_root (&pending_templates, 1); - ggc_add_tree_root (&saved_trees, 1); - ggc_add_tree_root (¤t_tinst_level, 1); + ggc_add_tree_root (&pending_templates, 1 , "pending_templates" ); + add_tree_addresses (&data_to_save, &pending_templates, 1 , "pending_templates" ); + add_tree_addresses (&data_to_save, &last_pending_template, 1 , "last_pending_template" ); + ggc_add_tree_root (&saved_trees, 1 , "saved_trees" ); + add_tree_addresses (&data_to_save, &saved_trees, 1 , "saved_trees" ); + ggc_add_tree_root (¤t_tinst_level, 1 , "current_tinst_level" ); } /* Do any processing required when DECL (a member template declaration diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c index 796add92952..d03581be013 100644 --- a/gcc/cp/repo.c +++ b/gcc/cp/repo.c @@ -320,8 +320,10 @@ init_repo (filename) if (! flag_use_repository) return; - ggc_add_tree_root (&pending_repo, 1); - ggc_add_tree_root (&original_repo, 1); + ggc_add_tree_root (&pending_repo, 1, "pending_repo" ); + add_tree_addresses (&data_to_save, &pending_repo, 1, "pending_repo" ); + ggc_add_tree_root (&original_repo, 1, "original_repo" ); + add_tree_addresses (&data_to_save, &original_repo, 1, "original_repo" ); gcc_obstack_init (&temporary_obstack); open_repo_file (filename); diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c index 64cf48dd160..b44b185881f 100644 --- a/gcc/cp/spew.c +++ b/gcc/cp/spew.c @@ -113,7 +113,6 @@ static SPEW_INLINE void consume_token PARAMS ((void)); static SPEW_INLINE int read_process_identifier PARAMS ((YYSTYPE *)); static SPEW_INLINE void feed_input PARAMS ((struct unparsed_text *)); -static SPEW_INLINE void end_input PARAMS ((void)); static SPEW_INLINE void snarf_block PARAMS ((const char *, int)); static tree snarf_defarg PARAMS ((void)); static int frob_id PARAMS ((int, int, tree *)); @@ -183,15 +182,19 @@ init_spew () inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); gcc_obstack_init (&token_obstack); gcc_obstack_init (&feed_obstack); - ggc_add_tree_root (&defarg_fns, 1); - ggc_add_tree_root (&defarg_parm, 1); - ggc_add_tree_root (&defarg_depfns, 1); - ggc_add_tree_root (&defarg_fnsdone, 1); + ggc_add_tree_root (&defarg_fns, 1 , "defarg_fns" ); + add_tree_addresses (&data_to_save, &defarg_fns, 1 , "defarg_fns" ); + ggc_add_tree_root (&defarg_parm, 1 , "defarg_parm" ); + add_tree_addresses (&data_to_save, &defarg_parm, 1 , "defarg_parm" ); + ggc_add_tree_root (&defarg_depfns, 1 , "defarg_depfns" ); + add_tree_addresses (&data_to_save, &defarg_depfns, 1 , "defarg_depfns" ); + ggc_add_tree_root (&defarg_fnsdone, 1 , "defarg_fnsdone" ); + add_tree_addresses (&data_to_save, &defarg_fnsdone, 1 , "defarg_fnsdone" ); ggc_add_root (&pending_inlines, 1, sizeof (struct unparsed_text *), - mark_pending_inlines); + mark_pending_inlines , "pending_inlines" ); ggc_add_root (&processing_these_inlines, 1, sizeof (struct unparsed_text *), - mark_pending_inlines); + mark_pending_inlines , "processing_these_inlines" ); } void @@ -358,7 +361,7 @@ read_token (t) return t->yychar; } -static SPEW_INLINE void +static void feed_input (input) struct unparsed_text *input; { @@ -397,7 +400,7 @@ feed_input (input) feed = f; } -static SPEW_INLINE void +void end_input () { struct feed *f = feed; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 32783adc728..8a2537412a5 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2356,7 +2356,7 @@ init_tree () list_hash_table = htab_create (31, list_hash, list_hash_eq, NULL); ggc_add_root (&list_hash_table, 1, sizeof (list_hash_table), - mark_tree_hashtable); + mark_tree_hashtable, "list_hash_table"); } /* The SAVE_EXPR pointed to by TP is being copied. If ST contains diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 54dc0ed3df5..c57bb08ab3e 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3035,8 +3035,8 @@ build_function_call_real (function, params, require_complete, flags) /* Check for errors in format strings. */ - if (warn_format && (name || assembler_name)) - check_function_format (NULL, name, assembler_name, coerced_params); + if (warn_format) + check_function_format (NULL, TYPE_ATTRIBUTES (fntype), coerced_params); /* Recognize certain built-in functions so we can make tree-codes other than CALL_EXPR. We do this when it enables fold-const.c |