aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/Make-lang.in4
-rw-r--r--gcc/cp/call.c8
-rw-r--r--gcc/cp/class.c3
-rw-r--r--gcc/cp/cp-tree.h24
-rw-r--r--gcc/cp/decl.c156
-rw-r--r--gcc/cp/decl2.c50
-rw-r--r--gcc/cp/g++spec.c16
-rw-r--r--gcc/cp/init.c3
-rw-r--r--gcc/cp/lang-specs.h22
-rw-r--r--gcc/cp/lex.c225
-rw-r--r--gcc/cp/linkage.c341
-rw-r--r--gcc/cp/parse.y10
-rw-r--r--gcc/cp/pch.c56
-rw-r--r--gcc/cp/pt.c9
-rw-r--r--gcc/cp/repo.c6
-rw-r--r--gcc/cp/spew.c21
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/cp/typeck.c4
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 (&current_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 **)&current_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, &current_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 (&current_lang_name, 1 , "current_lang_name" );
+ add_tree_addresses (&data_to_save, &current_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 (&current_declspecs, 1);
- ggc_add_tree_root (&prefix_attributes, 1);
- ggc_add_tree_root (&current_enum_type, 1);
- ggc_add_tree_root (&saved_scopes, 1);
+ ggc_add_tree_root (&current_declspecs, 1, "current_declspecs");
+ ggc_add_tree_root (&prefix_attributes, 1, "prefix_attributes");
+ ggc_add_tree_root (&current_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 (&current_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 (&current_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