From c01b12b9845867a08d2e1d208af03e7e469ae2ce Mon Sep 17 00:00:00 2001 From: Ollie Wild Date: Tue, 29 Apr 2008 18:47:31 +0000 Subject: gcc/ * lto-tags.h (enum LTO_tags): Add LTO_namespace_decl. * lto-tree-tags.def (LTO_namespace_decl): New tag. * lto-section-out.c (lto_get_out_decl_state): Initialize out_state->namespace_decl_hash_table. (produce_asm_for_decls): Write assembly for namespace declarations. * lto-section-out.h (struct lto_out_decl_state): Add namespace_decl_hash_table, next_namespace_decl_index, and namespace_decls. * lto-section.h (struct lto_decl_header): Add num_namespace_decls. * lto-function-out.c (output_expr_operand): Add NAMESPACE_DECL case. (lto_static_init): Clear lto_flags_needed_for and lto_types_needed_for entries for NAMESPACE_DECL. (output_constructors_and_inits): Output initializer if DECL_CONTEXT (var) is not a FUNCTION_DECL. * dwarf2out.c (lto_namespacedecl_ref): New function. * dwarf2out.h (lto_namespacedecl_ref): New function. gcc/lto/ * lto.c (lto_read_namespace_DIE): New function. (lto_read_DIE): Add lto_read_namespace_DIE callback. Cache NAMESPACE_DECL DIE's. (lto_resolve_namespacedecl_ref): New function. * lto.h (lto_resolve_namespacedecl_ref): New function. * lto-section-in.c (lto_read_decls): Read namespace declarations. * lto-section-in.h (struct lto_file_decl_data): Add namespace_decls and num_namespace_decls. * lto-function-in.c (input_expr_operand): Add NAMESPACE_DECL case. * lto-lang.c (lto_init_ts): New function. (LANG_HOOKS_INIT_TS): Set as lto_init_ts. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/lto@134803 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog.lto | 19 ++++++++++ gcc/dwarf2out.c | 15 ++++++++ gcc/dwarf2out.h | 4 ++ gcc/lto-function-out.c | 20 +++++++++- gcc/lto-section-out.c | 8 ++++ gcc/lto-section-out.h | 6 +++ gcc/lto-section.h | 1 + gcc/lto-tags.h | 1 + gcc/lto-tree-tags.def | 2 + gcc/lto/ChangeLog | 14 +++++++ gcc/lto/lto-function-in.c | 5 +++ gcc/lto/lto-lang.c | 9 +++++ gcc/lto/lto-section-in.c | 12 +++++- gcc/lto/lto-section-in.h | 2 + gcc/lto/lto.c | 94 ++++++++++++++++++++++++++++++++++++++++++----- gcc/lto/lto.h | 5 +++ 16 files changed, 206 insertions(+), 11 deletions(-) diff --git a/gcc/ChangeLog.lto b/gcc/ChangeLog.lto index 436f08094ea..d9b939fa8e5 100644 --- a/gcc/ChangeLog.lto +++ b/gcc/ChangeLog.lto @@ -1,3 +1,22 @@ +2008-04-29 Ollie Wild + + * lto-tags.h (enum LTO_tags): Add LTO_namespace_decl. + * lto-tree-tags.def (LTO_namespace_decl): New tag. + * lto-section-out.c (lto_get_out_decl_state): Initialize + out_state->namespace_decl_hash_table. + (produce_asm_for_decls): Write assembly for namespace declarations. + * lto-section-out.h (struct lto_out_decl_state): Add + namespace_decl_hash_table, next_namespace_decl_index, and + namespace_decls. + * lto-section.h (struct lto_decl_header): Add num_namespace_decls. + * lto-function-out.c (output_expr_operand): Add NAMESPACE_DECL case. + (lto_static_init): Clear lto_flags_needed_for and lto_types_needed_for + entries for NAMESPACE_DECL. + (output_constructors_and_inits): Output initializer if + DECL_CONTEXT (var) is not a FUNCTION_DECL. + * dwarf2out.c (lto_namespacedecl_ref): New function. + * dwarf2out.h (lto_namespacedecl_ref): New function. + 2008-04-24 Kenneth Zadeck Merge with mainline @134626. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index b0bd6044052..37c98b98ef5 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -15715,6 +15715,21 @@ lto_typedecl_ref (tree decl, lto_out_ref *ref) lto_type_ref (TREE_TYPE (decl), ref); } +/* Initialize REF as a reference to the DIE for DECL (which must be a + NAMESPACE_DECL). */ + +void +lto_namespacedecl_ref (tree decl, lto_out_ref *ref) +{ + dw_die_ref die; + + gcc_assert (TREE_CODE (decl) == NAMESPACE_DECL); + /* Generate the DIE for VAR. */ + die = force_decl_die (decl); + /* Construct the reference. */ + lto_init_ref (ref, die, DECL_CONTEXT (decl)); +} + #else /* This should never be used, but its address is needed for comparisons. */ diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index 6f9ab185756..ad54ac6dee9 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -78,6 +78,10 @@ extern void lto_field_ref (tree field, lto_out_ref *ref); TYPE_DECL. */ extern void lto_typedecl_ref (tree tdecl, lto_out_ref *ref); +/* Upon return, *REF contains a reference to DECL, which must be a + NAMESPACE_DECL. */ +extern void lto_namespacedecl_ref (tree decl, lto_out_ref *ref); + struct array_descr_info { int ndimensions; diff --git a/gcc/lto-function-out.c b/gcc/lto-function-out.c index 6fbd8a81e28..a8f017a1c65 100644 --- a/gcc/lto-function-out.c +++ b/gcc/lto-function-out.c @@ -1096,6 +1096,21 @@ output_expr_operand (struct output_block *ob, tree expr) } break; + case NAMESPACE_DECL: + { + unsigned int index; + bool new; + output_record_start (ob, NULL, NULL, tag); + + new = lto_output_decl_index (ob->main_stream, + ob->decl_state->namespace_decl_hash_table, + &ob->decl_state->next_namespace_decl_index, + expr, &index); + if (new) + VEC_safe_push (tree, heap, ob->decl_state->namespace_decls, expr); + } + break; + case PARM_DECL: gcc_assert (!DECL_RTL_SET_P (expr)); output_record_start (ob, NULL, NULL, tag); @@ -1866,6 +1881,7 @@ lto_static_init (void) RESET_BIT (lto_flags_needed_for, VAR_DECL); RESET_BIT (lto_flags_needed_for, TREE_LIST); RESET_BIT (lto_flags_needed_for, TYPE_DECL); + RESET_BIT (lto_flags_needed_for, NAMESPACE_DECL); lto_types_needed_for = sbitmap_alloc (NUM_TREE_CODES); @@ -1888,6 +1904,7 @@ lto_static_init (void) RESET_BIT (lto_types_needed_for, VAR_DECL); RESET_BIT (lto_types_needed_for, TREE_LIST); RESET_BIT (lto_types_needed_for, TYPE_DECL); + RESET_BIT (lto_types_needed_for, NAMESPACE_DECL); #else /* These forms will need types, even when the type system is fixed. */ SET_BIT (lto_types_needed_for, COMPLEX_CST); @@ -2081,7 +2098,8 @@ output_constructors_and_inits (void) FOR_EACH_STATIC_INITIALIZER (vnode) { tree var = vnode->decl; - if (DECL_CONTEXT (var) == NULL_TREE) + tree context = DECL_CONTEXT (var); + if (!context || TREE_CODE (context) != FUNCTION_DECL) { output_expr_operand (ob, var); diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c index 3f627880fda..fd7c1c98c82 100644 --- a/gcc/lto-section-out.c +++ b/gcc/lto-section-out.c @@ -406,6 +406,8 @@ lto_get_out_decl_state (void) = htab_create (37, lto_hash_type_slot_node, lto_eq_type_slot_node, free); out_state->type_decl_hash_table = htab_create (37, lto_hash_decl_slot_node, lto_eq_decl_slot_node, free); + out_state->namespace_decl_hash_table + = htab_create (37, lto_hash_decl_slot_node, lto_eq_decl_slot_node, free); out_state->var_decl_hash_table = htab_create (37, lto_hash_decl_slot_node, lto_eq_decl_slot_node, free); } @@ -460,6 +462,7 @@ produce_asm_for_decls (void) header.num_fn_decls = VEC_length (tree, out_state->fn_decls); header.num_var_decls = VEC_length (tree, out_state->var_decls); header.num_type_decls = VEC_length (tree, out_state->type_decls); + header.num_namespace_decls = VEC_length (tree, out_state->namespace_decls); header.num_types = VEC_length (tree, out_state->types); assemble_string ((const char *)&header, @@ -477,6 +480,9 @@ produce_asm_for_decls (void) /* Write the global type_decl references. */ write_references (out_state->type_decls, section, lto_typedecl_ref); + /* Write the global namespace_decl references. */ + write_references (out_state->namespace_decls, section, lto_namespacedecl_ref); + /* Write the global type references. */ write_references (out_state->types, section, lto_type_ref); @@ -484,12 +490,14 @@ produce_asm_for_decls (void) htab_delete (out_state->fn_decl_hash_table); htab_delete (out_state->var_decl_hash_table); htab_delete (out_state->type_decl_hash_table); + htab_delete (out_state->namespace_decl_hash_table); htab_delete (out_state->type_hash_table); VEC_free (tree, heap, out_state->field_decls); VEC_free (tree, heap, out_state->fn_decls); VEC_free (tree, heap, out_state->var_decls); VEC_free (tree, heap, out_state->type_decls); + VEC_free (tree, heap, out_state->namespace_decls); VEC_free (tree, heap, out_state->types); free (out_state); diff --git a/gcc/lto-section-out.h b/gcc/lto-section-out.h index 8c20197abb3..001f2c93c83 100644 --- a/gcc/lto-section-out.h +++ b/gcc/lto-section-out.h @@ -102,6 +102,12 @@ struct lto_out_decl_state unsigned int next_type_decl_index; VEC(tree,heap) *type_decls; + /* The hash table that contains the set of namespace_decls we have + seen so far and the indexes assigned to them. */ + htab_t namespace_decl_hash_table; + unsigned int next_namespace_decl_index; + VEC(tree,heap) *namespace_decls; + /* The hash table that contains the set of type we have seen so far and the indexes assigned to them. */ htab_t type_hash_table; diff --git a/gcc/lto-section.h b/gcc/lto-section.h index 52c11d9ec9c..d5ea6e40893 100644 --- a/gcc/lto-section.h +++ b/gcc/lto-section.h @@ -33,6 +33,7 @@ struct lto_decl_header int32_t num_fn_decls; /* Number of FUNCTION_DECLS. */ int32_t num_var_decls; /* Number of non local VAR_DECLS. */ int32_t num_type_decls; /* Number of TYPE_DECLs. */ + int32_t num_namespace_decls; /* Number of NAMESPACE_DECLs. */ int32_t num_types; /* Number of types. */ }; diff --git a/gcc/lto-tags.h b/gcc/lto-tags.h index 3c1d3996f0d..d31efa109f8 100644 --- a/gcc/lto-tags.h +++ b/gcc/lto-tags.h @@ -398,6 +398,7 @@ enum LTO_tags { LTO_truth_or_expr, LTO_truth_xor_expr, LTO_type_decl, + LTO_namespace_decl, LTO_uneq_expr, LTO_unge_expr, LTO_ungt_expr, diff --git a/gcc/lto-tree-tags.def b/gcc/lto-tree-tags.def index aa6f47af9ab..da3090108a2 100644 --- a/gcc/lto-tree-tags.def +++ b/gcc/lto-tree-tags.def @@ -88,6 +88,7 @@ MAP_EXPR_TAG(SWITCH_EXPR, LTO_switch_expr) MAP_EXPR_TAG(TREE_LIST, LTO_tree_list) MAP_EXPR_TAG(TYPE_DECL, LTO_type_decl) + MAP_EXPR_TAG(NAMESPACE_DECL, LTO_namespace_decl) #endif /* TREE_SINGLE_MECHANICAL_FALSE */ #ifdef TREE_SINGLE_MECHANICAL_TRUE @@ -284,6 +285,7 @@ SET_NAME (LTO_truth_or_expr, "truth_or_expr") SET_NAME (LTO_truth_xor_expr, "truth_xor_expr") SET_NAME (LTO_type_decl, "type_decl") + SET_NAME (LTO_namespace_decl, "namespace_decl") SET_NAME (LTO_uneq_expr, "uneq_expr") SET_NAME (LTO_unge_expr, "unge_expr") SET_NAME (LTO_ungt_expr, "ungt_expr") diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 008cb296753..3d3221aae0c 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,17 @@ +2008-04-29 Ollie Wild + + * lto.c (lto_read_namespace_DIE): New function. + (lto_read_DIE): Add lto_read_namespace_DIE callback. Cache + NAMESPACE_DECL DIE's. + (lto_resolve_namespacedecl_ref): New function. + * lto.h (lto_resolve_namespacedecl_ref): New function. + * lto-section-in.c (lto_read_decls): Read namespace declarations. + * lto-section-in.h (struct lto_file_decl_data): Add namespace_decls + and num_namespace_decls. + * lto-function-in.c (input_expr_operand): Add NAMESPACE_DECL case. + * lto-lang.c (lto_init_ts): New function. + (LANG_HOOKS_INIT_TS): Set as lto_init_ts. + 2008-04-16 Ollie Wild * lto-function-in.c (input_type_ref): Updated function description. diff --git a/gcc/lto/lto-function-in.c b/gcc/lto/lto-function-in.c index b376ba7b108..a989ad951da 100644 --- a/gcc/lto/lto-function-in.c +++ b/gcc/lto/lto-function-in.c @@ -604,6 +604,11 @@ input_expr_operand (struct lto_input_block *ib, struct data_in *data_in, gcc_assert (result); break; + case NAMESPACE_DECL: + result = data_in->file_data->namespace_decls [lto_input_uleb128 (ib)]; + gcc_assert (result); + break; + case VAR_DECL: case PARM_DECL: if (tag == LTO_var_decl1) diff --git a/gcc/lto/lto-lang.c b/gcc/lto/lto-lang.c index 590f3ed15f5..151e980c1ae 100644 --- a/gcc/lto/lto-lang.c +++ b/gcc/lto/lto-lang.c @@ -574,6 +574,13 @@ lto_init (void) return true; } +/* Initialize tree structures required by the LTO front end. */ + +static void lto_init_ts (void) +{ + tree_contains_struct[NAMESPACE_DECL][TS_DECL_MINIMAL] = 1; +} + /* rs6000.c wants to look at this and we really only do C for the time being. */ #undef LANG_HOOKS_NAME @@ -607,6 +614,8 @@ lto_init (void) #define LANG_HOOKS_REDUCE_BIT_FIELD_OPERATIONS true #undef LANG_HOOKS_TYPES_COMPATIBLE_P #define LANG_HOOKS_TYPES_COMPATIBLE_P lto_types_compatible_p +#undef LANG_HOOKS_INIT_TS +#define LANG_HOOKS_INIT_TS lto_init_ts const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; diff --git a/gcc/lto/lto-section-in.c b/gcc/lto/lto-section-in.c index d8d13c46fd8..2455a86a78a 100644 --- a/gcc/lto/lto-section-in.c +++ b/gcc/lto/lto-section-in.c @@ -276,13 +276,16 @@ lto_read_decls (lto_info_fd *fd, = fns_offset + (header->num_fn_decls * sizeof (lto_ref)); int32_t type_decls_offset = vars_offset + (header->num_var_decls * sizeof (lto_ref)); - int32_t types_offset + int32_t namespace_decls_offset = type_decls_offset + (header->num_type_decls * sizeof (lto_ref)); + int32_t types_offset + = namespace_decls_offset + (header->num_namespace_decls * sizeof (lto_ref)); lto_ref *in_field_decls = (lto_ref*)(data + fields_offset); lto_ref *in_fn_decls = (lto_ref*)(data + fns_offset); lto_ref *in_var_decls = (lto_ref*)(data + vars_offset); lto_ref *in_type_decls = (lto_ref*)(data + type_decls_offset); + lto_ref *in_namespace_decls = (lto_ref*)(data + namespace_decls_offset); lto_ref *in_types = (lto_ref*)(data + types_offset); int i; @@ -290,6 +293,8 @@ lto_read_decls (lto_info_fd *fd, data_in->fn_decls = xcalloc (header->num_fn_decls, sizeof (tree*)); data_in->var_decls = xcalloc (header->num_var_decls, sizeof (tree*)); data_in->type_decls = xcalloc (header->num_type_decls, sizeof (tree*)); + data_in->namespace_decls + = xcalloc (header->num_namespace_decls, sizeof (tree*)); data_in->types = xcalloc (header->num_types, sizeof (tree*)); for (i=0; inum_field_decls; i++) @@ -312,6 +317,11 @@ lto_read_decls (lto_info_fd *fd, = lto_resolve_typedecl_ref (fd, context, &in_type_decls[i]); data_in->num_type_decls = header->num_type_decls; + for (i = 0; i < header->num_namespace_decls; i++) + data_in->namespace_decls[i] + = lto_resolve_namespacedecl_ref (fd, context, &in_namespace_decls[i]); + data_in->num_namespace_decls = header->num_namespace_decls; + for (i=0; inum_types; i++) data_in->types[i] = lto_resolve_type_ref (fd, context, &in_types[i]); data_in->num_types = header->num_types; diff --git a/gcc/lto/lto-section-in.h b/gcc/lto/lto-section-in.h index 5ccd03316f3..389d9423d1a 100644 --- a/gcc/lto/lto-section-in.h +++ b/gcc/lto/lto-section-in.h @@ -49,11 +49,13 @@ struct lto_file_decl_data tree *fn_decls; /* The function decls. */ tree *var_decls; /* The global or static var_decls. */ tree *type_decls; /* The type_decls. */ + tree *namespace_decls; /* The namespace_decls. */ tree *types; /* All of the types. */ unsigned int num_field_decls; /* The number of field decls. */ unsigned int num_fn_decls; /* The number of function decls. */ unsigned int num_var_decls; /* The number of global or static var_decls. */ unsigned int num_type_decls; /* The number of type_decls. */ + unsigned int num_namespace_decls; /* The number of namespace_decls. */ unsigned int num_types; /* All number of of the types. */ /* The .o file that these offsets relate to. diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 4d2b21bc417..f11fe9b0b8d 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -3216,6 +3216,45 @@ lto_read_const_volatile_restrict_type_DIE (lto_info_fd *fd, return type; } +/* Read a namespace DIE from FD. ABBREV is a DWARF2 abbreviation-table entry. + CONTEXT provides information about the current state of the compilation + unit. Returns a tree representing the NAMESPACE_DECL read. */ + +static tree +lto_read_namespace_DIE (lto_info_fd *fd, + lto_die_ptr die ATTRIBUTE_UNUSED, + const DWARF2_abbrev *abbrev, + lto_context *context) +{ + tree name = NULL_TREE; + tree namespace_decl; + tree parentdata; + + LTO_BEGIN_READ_ATTRS () + { + case DW_AT_name: + name = lto_get_identifier (&attr_data); + break; + + case DW_AT_decl_file: + case DW_AT_decl_line: + /* Ignore. */ + break; + } + LTO_END_READ_ATTRS (); + + gcc_assert (name); + namespace_decl = build_decl (NAMESPACE_DECL, name, void_type_node); + DECL_CONTEXT (namespace_decl) = context->parentdata; + + parentdata = context->parentdata; + context->parentdata = namespace_decl; + lto_read_child_DIEs (fd, abbrev, context); + context->parentdata = parentdata; + + return namespace_decl; +} + static tree lto_read_unspecified_type_DIE (lto_info_fd *fd, lto_die_ptr die ATTRIBUTE_UNUSED, @@ -3312,7 +3351,7 @@ lto_read_DIE (lto_info_fd *fd, lto_context *context, bool *more) NULL, /* dwarf_procedure */ lto_read_const_volatile_restrict_type_DIE, NULL, /* interface_type */ - NULL, /* namespace */ + lto_read_namespace_DIE, NULL, /* imported_module */ lto_read_unspecified_type_DIE, NULL, /* partial_unit */ @@ -3375,16 +3414,21 @@ lto_read_DIE (lto_info_fd *fd, lto_context *context, bool *more) /* If there is a reader, use it. */ val = reader (fd, die, abbrev, context); - /* If this DIE refers to a type, cache the value so that future - references to the type can be processed quickly. */ - if (val && TYPE_P (val)) - { - /* In the absence of a better solution, say that we alias - everything FIXME. */ - TYPE_ALIAS_SET (val) = 0; + if (val) + /* If this DIE refers to a type, cache the value so that future + references to the type can be processed quickly. */ + if (TYPE_P (val)) + { + /* In the absence of a better solution, say that we alias + everything FIXME. */ + TYPE_ALIAS_SET (val) = 0; + lto_cache_store_DIE (fd, die, val); + } + /* If this DIE refers to a namespace, we must cache the value + or future references will not properly set DECL_CONTEXT. */ + else if (TREE_CODE (val) == NAMESPACE_DECL) lto_cache_store_DIE (fd, die, val); - } context->skip_non_parameters = saved_skip_non_parameters; } @@ -3746,6 +3790,38 @@ lto_resolve_typedecl_ref (lto_info_fd *info_fd, return build_decl (TYPE_DECL, NULL_TREE, type); } +/* Returns the NAMESPACE_DECL corresponding to the DIE located at REF from + INFO_FD. CONTEXT is the current context within the compilation unit. + Note: Skipping around in the DWARF tree is buggy for NAMESPACE_DECL's + because the context parentdata needed to properly set DECL_CONTEXT + is missing. Consequently, we generate an error if the result is not + cached. */ +tree +lto_resolve_namespacedecl_ref (lto_info_fd *info_fd, + lto_context *context, + const lto_ref *ref) +{ + lto_die_ptr die; + lto_context *new_context = context; + tree decl; + + /* At present, we only support a single DWARF section. */ + if (ref->section != 0) + lto_abi_mismatch_error (); + /* Map REF to a DIE. */ + die = lto_resolve_reference (info_fd, ref->offset, context, &new_context); + /* Map DIE to a namespace decl. */ + decl = lto_cache_lookup_DIE (info_fd, die, /*skip=*/false); + if (!decl || TREE_CODE (decl) != NAMESPACE_DECL) + lto_file_corrupt_error ((lto_fd *)info_fd); + + /* Clean up. */ + if (new_context != context) + XDELETE (new_context); + + return decl; +} + /* Needed so the garbage collector knows to root around in functions we have not yet materialized and the huge DIE -> tree table we keep around. */ diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h index 4bf3917240f..40fbb03035e 100644 --- a/gcc/lto/lto.h +++ b/gcc/lto/lto.h @@ -224,6 +224,11 @@ extern tree lto_resolve_typedecl_ref (lto_info_fd *info_fd, lto_context *context, const lto_ref *ref); +/* Return the NAMESPACE_DECL referred to by REF. */ +extern tree lto_resolve_namespacedecl_ref (lto_info_fd *info_fd, + lto_context *context, + const lto_ref *ref); + /* Get the file name associated with INFO_FD. */ extern const char *lto_get_file_name (lto_info_fd *info_fd); -- cgit v1.2.3