Merge from pch-branch.
From-SVN: r61136
This commit is contained in:
parent
5f7c78d8a4
commit
17211ab553
130 changed files with 5541 additions and 1594 deletions
520
gcc/ChangeLog
520
gcc/ChangeLog
|
@ -1,3 +1,519 @@
|
|||
2003-01-09 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
Merge from pch-branch:
|
||||
|
||||
2003-01-06 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* ggc-page.c (ggc_pch_read): Update the statistics after a PCH
|
||||
load.
|
||||
|
||||
2002-12-24 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* cpplib.c (count_registered_pragmas): New function.
|
||||
(save_registered_pragmas): New function.
|
||||
(_cpp_save_pragma_names): New function.
|
||||
(restore_registered_pragmas): New function.
|
||||
(_cpp_restore_pragma_names): New function.
|
||||
* cpphash.h (_cpp_save_pragma_names): Prototype.
|
||||
(_cpp_restore_pragma_names): Likewise.
|
||||
* cpppch.c (struct save_macro_item): Split from save_macro_data.
|
||||
(struct save_macro_data): New field 'saved_pragmas'.
|
||||
(save_macros): Update for changes to struct save_macro_data.
|
||||
(cpp_prepare_state): Call _cpp_save_pragma_names, update
|
||||
for changes to struct save_macro_data.
|
||||
(cpp_read_state): Call _cpp_restore_pragma_names, update
|
||||
for changes to struct save_macro_data.
|
||||
|
||||
* cpppch.c (cpp_read_state): Restore the hashtable references
|
||||
in the cpp_reader.
|
||||
|
||||
* tree.h (built_in_decls): Mark for PCH.
|
||||
|
||||
* dbxout.c (lastfile): Don't mark for PCH.
|
||||
|
||||
* ggc.h: Document PCH calls into memory managers.
|
||||
|
||||
2002-12-18 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* doc/invoke.texi (Precompiled Headers): Document the
|
||||
directory form of PCH.
|
||||
* cppfiles.c (validate_pch): New function.
|
||||
(open_file_pch): Search suitably-named directories for PCH files.
|
||||
|
||||
2002-12-14 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* doc/gty.texi (GTY Options): Document chain_next, chain_prev,
|
||||
reorder options.
|
||||
(Type Information): Mention that the information is also
|
||||
used to implement PCH.
|
||||
* doc/passes.texi (Passes): Improve documentation of
|
||||
language-specific files.
|
||||
|
||||
2002-12-11 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gengtype.c (struct write_types_data): Add reorder_note_routine field.
|
||||
(struct walk_type_data): Add reorder_fn field.
|
||||
(walk_type): Process 'reorder' option.
|
||||
(write_types_process_field): Reorder parameters to gt_pch_note_object,
|
||||
call reorder_note_routine.
|
||||
(write_func_for_structure): Reorder parameters to gt_pch_note_object.
|
||||
(ggc_wtd): Update for change to struct write_types_data.
|
||||
(pch_wtd): Likewise.
|
||||
* ggc.h (gt_pch_note_object): Reorder parameters.
|
||||
(gt_handle_reorder): New definition.
|
||||
(gt_pch_note_reorder): New prototype.
|
||||
* ggc-common.c (struct ptr_data): Add reorder_fn.
|
||||
(gt_pch_note_object): Reorder parameters.
|
||||
(gt_pch_note_reorder): New.
|
||||
(gt_pch_save): Call reorder_fn.
|
||||
* stringpool.c (gt_pch_n_S): Update for change to gt_pch_note_object.
|
||||
|
||||
* dbxout.c (cwd): Don't mark for PCH.
|
||||
|
||||
2002-12-09 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gengtype.c (finish_root_table): Fix some warnings.
|
||||
(write_root): Handle TYPE_STRING.
|
||||
* ggc.h (gt_ggc_m_S): Add prototype.
|
||||
* stringpool.c (gt_ggc_m_S): New function.
|
||||
|
||||
2002-11-30 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* dwarf2out.c (dw2_string_counter): New.
|
||||
(AT_string_form): Use it.
|
||||
(same_dw_val_p): Update for removal of hashtable.h hash tables.
|
||||
|
||||
2002-11-22 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* dbxout.c: Include gt-dbxout.h.
|
||||
(lastfile): Mark for PCH/GGC.
|
||||
(cwd): Likewise.
|
||||
(struct typeinfo): Likewise.
|
||||
(typevec): Likewise.
|
||||
(typevec_len): Likewise.
|
||||
(next_type_number): Likewise.
|
||||
(struct dbx_file): Likewise.
|
||||
(current_file): Likewise.
|
||||
(next_file_number): Likewise.
|
||||
(dbxout_init): Allocate typevec, struct dbx_file with GGC.
|
||||
(dbxout_start_source_file): Allocate struct dbx_file with GGC.
|
||||
(dbxout_end_source_file): Don't free struct dbx_file.
|
||||
(dbxout_type): Use GGC to allocate typevec.
|
||||
* Makefile.in (dbxout.o): Depend on gt-dbxout.h, $(GGC_H).
|
||||
(GTFILES): Add dbxout.c.
|
||||
(gt-dbxout.h): New rule.
|
||||
|
||||
* Makefile.in (c-pch.o): Add debug.h as dependency.
|
||||
* c-pch.c: Include debug.h.
|
||||
(pch_init): Call start_source_file to keep nesting right.
|
||||
(c_common_read_pch): Add orig_name parameter. Call
|
||||
start_source_file debug hook. Call end_source_file debug hook.
|
||||
* c-common.h (c_common_read_pch): Update prototype.
|
||||
* cpplib.h (struct cpp_callbacks): Add fourth field to read_pch
|
||||
callback.
|
||||
* cppfiles.c (struct include_file): Add new field `header_name'.
|
||||
(find_or_create_entry): Default it to `name'.
|
||||
(open_file_pch): Set it to the original header file searched for.
|
||||
(stack_include_file): Don't stack an empty buffer, just handle
|
||||
PCH files immediately. Pass header_name field to read_pch callback.
|
||||
|
||||
2002-11-19 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* function.c (funcdef_no): Mark to be saved in a PCH.
|
||||
|
||||
2002-11-15 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* ggc-page.c (ggc_pch_read): Remove unused 'bmap_size'.
|
||||
|
||||
* cpppch.c (cpp_read_state): Correct size reallocated for 'defn'.
|
||||
|
||||
2002-11-14 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* optabs.h (code_to_optab): Add GTY marker.
|
||||
|
||||
2002-11-13 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* Makefile.in (GTFILES): Add cpplib.h.
|
||||
* c-common.h (struct c_common_identifier): Don't skip 'node' field.
|
||||
* c-decl.c (build_compound_literal): Don't use var_labelno.
|
||||
* cpplib.h (struct cpp_hashnode): Use gengtype to mark.
|
||||
* dwarf2asm.c (dw2_force_const_mem): Don't use const_labelno.
|
||||
* varasm.c (const_labelno): Use gengtype to mark.
|
||||
(var_labelno): Likewise.
|
||||
(in_section): Likewise.
|
||||
(in_named_name): Likewise.
|
||||
(struct in_named_entry): Likewise.
|
||||
(in_named_htab): Likewise.
|
||||
(set_named_section_flags): Use GGC to allocate struct in_named_entry.
|
||||
(init_varasm_once): Use GGC to allocate in_named_htab.
|
||||
* config/darwin.c (current_pic_label_num): Mark for PCH.
|
||||
|
||||
2002-11-11 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* ggc-simple.c (init_ggc_pch): New stub procedure.
|
||||
(ggc_pch_count_object): Likewise.
|
||||
(ggc_pch_total_size): Likewise.
|
||||
(ggc_pch_this_base): Likewise.
|
||||
(ggc_pch_alloc_object): Likewise.
|
||||
(ggc_pch_prepare_write): Likewise.
|
||||
(ggc_pch_write_object): Likewise
|
||||
(ggc_pch_finish): Likewise.
|
||||
(ggc_pch_read): Likewise.
|
||||
|
||||
2002-11-08 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* c-pch.c (c_common_write_pch): Write the macro definitions after
|
||||
the GCed data.
|
||||
(c_common_read_pch): Call cpp_prepare_state. Restore the macro
|
||||
definitions after the GCed data.
|
||||
* cpplib.c (save_macros): New.
|
||||
(reset_ht): New.
|
||||
(cpp_write_pch_deps): Split out of cpp_write_pch.
|
||||
(cpp_write_pch_state): Split out of cpp_write_pch.
|
||||
(cpp_write_pch): Delete.
|
||||
(struct save_macro_data): Delete.
|
||||
(cpp_prepare_state): New.
|
||||
(cpp_read_state): Erase and restore initial macro definitions.
|
||||
* cpplib.h (struct save_macro_data): Forward-declare.
|
||||
(cpp_write_pch_deps): Prototype.
|
||||
(cpp_write_pch_state): Prototype.
|
||||
(cpp_write_pch): Delete prototype.
|
||||
(cpp_prepare_state): Prototype.
|
||||
(cpp_read_state): Add fourth argument.
|
||||
|
||||
2002-11-04 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gengtype.c (adjust_field_rtx_def): Don't use skip on valid fields.
|
||||
(write_array): Remove warning.
|
||||
|
||||
* gengtype.c (contains_scalar_p): New.
|
||||
(finish_root_table): Add the table to all languages, even if it's
|
||||
empty.
|
||||
(write_roots): Output gt_pch_scalar_rtab.
|
||||
* ggc-common.c (gt_pch_save): Write out scalars.
|
||||
(gt_pch_restore): Read scalars back.
|
||||
|
||||
* ggc-page.c (OBJECTS_IN_PAGE): New macro.
|
||||
(struct page_entry): Delete pch_page field.
|
||||
(ggc_recalculate_in_use_p): Use OBJECTS_IN_PAGE.
|
||||
(clear_marks): Likewise.
|
||||
(sweep_pages): Likewise.
|
||||
(poison_pages): Likewise.
|
||||
(ggc_print_statistics): Likewise.
|
||||
(ggc_pch_read): Don't free objects read from a PCH.
|
||||
Properly set up in_use_p and page_tails.
|
||||
|
||||
2002-10-25 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gengtype.c (struct write_types_data): New.
|
||||
(struct walk_type_data): Make `cookie' const; add extra
|
||||
prev_val item; add `orig_s' field.
|
||||
(walk_type): Update prev_val[3].
|
||||
(write_types_process_field): New.
|
||||
(write_func_for_structure): Take write_types_data structure.
|
||||
(write_types): New.
|
||||
(ggc_wtd): New.
|
||||
(pch_wtd): New.
|
||||
(write_types_local_process_field): New.
|
||||
(gc_mark_process_field): Delete.
|
||||
(write_local_func_for_structure): New.
|
||||
(gc_mark_func_name): Delete.
|
||||
(write_gc_types): Delete.
|
||||
(write_local): New.
|
||||
(finish_root_table): Don't include 'ggc_' in PFX.
|
||||
(write_root): Rename from write_root. Fill pchw field of structures.
|
||||
(write_array): New.
|
||||
(write_roots): Rename from write_gc_roots. Split out to write_array.
|
||||
Update to changes to other routines. Write gt_pch_cache_rtab table.
|
||||
(main): Write PCH walking routines.
|
||||
* ggc-common.c: Include toplev.h, sys/mman.h.
|
||||
(ggc_mark_roots): For cache hashtables, also mark the hash table
|
||||
and the array of entries.
|
||||
(saving_htab): New.
|
||||
(struct ptr_data): New.
|
||||
(POINTER_HASH): New.
|
||||
(gt_pch_note_object): New.
|
||||
(saving_htab_hash): New.
|
||||
(saving_htab_eq): New.
|
||||
(struct traversal_state): New.
|
||||
(call_count): New.
|
||||
(call_alloc): New.
|
||||
(compare_ptr_data): New.
|
||||
(relocate_ptrs): New.
|
||||
(write_pch_globals): New.
|
||||
(struct mmap_info): New.
|
||||
(gt_pch_save): New.
|
||||
(gt_pch_restore): New.
|
||||
* ggc-page.c (ROUND_UP_VALUE): New.
|
||||
(ROUND_UP): New.
|
||||
(struct page_entry): Add field `pch_page'.
|
||||
(init_ggc): Use ROUND_UP.
|
||||
(struct ggc_pch_data): Declare.
|
||||
(init_ggc_pch): New.
|
||||
(ggc_pch_count_object): New.
|
||||
(ggc_pch_total_size): New.
|
||||
(ggc_pch_this_base): New.
|
||||
(ggc_pch_alloc_object): New.
|
||||
(ggc_pch_prepare_write): New.
|
||||
(ggc_pch_write_object): New.
|
||||
(ggc_pch_finish): New.
|
||||
(ggc_pch_read): New.
|
||||
* ggc.h (gt_pointer_operator): New.
|
||||
(gt_note_pointers): New.
|
||||
(gt_pch_note_object): New prototype.
|
||||
(gt_pointer_walker): New.
|
||||
(struct ggc_root_tab): Use gt_pointer_walker, add `pchw' field.
|
||||
(LAST_GGC_ROOT_TAB): Update.
|
||||
(gt_pch_cache_rtab): Declare.
|
||||
(gt_pch_scalar_rtab): Declare.
|
||||
(struct ggc_cache_tab): Use gt_pointer_walker, add `pchw' field.
|
||||
(LAST_GGC_CACHE_TAB): Update.
|
||||
(gt_pch_save_stringpool): Declare.
|
||||
(gt_pch_restore_stringpool): Declare.
|
||||
(gt_pch_p_S): Declare.
|
||||
(gt_pch_n_S): Declare.
|
||||
(struct ggc_pch_data): Forward-declare.
|
||||
(init_ggc_pch): Declare.
|
||||
(ggc_pch_count_object): Declare.
|
||||
(ggc_pch_total_size): Declare.
|
||||
(ggc_pch_this_base): Declare.
|
||||
(ggc_pch_alloc_object): Declare.
|
||||
(ggc_pch_prepare_write): Declare.
|
||||
(ggc_pch_write_object): Declare.
|
||||
(ggc_pch_finish): Declare.
|
||||
(ggc_pch_read): Declare.
|
||||
(gt_pch_save): Declare.
|
||||
(gt_pch_restore): Declare.
|
||||
* fold-const.c (size_int_type_wide): Allocate size_htab using GGC.
|
||||
* emit-rtl.c (init_emit_once): Allocate const_int_htab,
|
||||
const_double_htab, mem_attrs_htab using GGC.
|
||||
* c-pch.c: Include ggc.h.
|
||||
(pch_init): Allow reading PCH file back.
|
||||
(c_common_write_pch): Call gt_pch_save.
|
||||
(c_common_read_pch): Call gt_pch_restore.
|
||||
* c-parse.in (init_reswords): Delete now-untrue comment.
|
||||
Allocate ridpointers using GGC.
|
||||
* c-objc-common.c (c_objc_common_finish_file): Write PCH before
|
||||
calling expand_deferred_fns.
|
||||
* c-common.h (ridpointers): Mark for GTY machinery.
|
||||
* Makefile.in (stringpool.o): Update dependencies.
|
||||
(c-pch.o): Update dependencies.
|
||||
(ggc-common.o): Update dependencies.
|
||||
* stringpool.c: Include gt-stringpool.h.
|
||||
(gt_pch_p_S): New.
|
||||
(gt_pch_n_S): New.
|
||||
(struct string_pool_data): New.
|
||||
(spd): New.
|
||||
(gt_pch_save_stringpool): New.
|
||||
(gt_pch_restore_stringpool): New.
|
||||
* tree.c (init_ttree): Make type_hash_table allocated using GC.
|
||||
|
||||
2002-10-04 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gengtype.c (adjust_field_rtx_def): Don't pass size_t to printf.
|
||||
(output_mangled_typename): Don't pass size_t to printf.
|
||||
|
||||
* tree.h (union tree_type_symtab): Add tag to `address' field.
|
||||
(union tree_decl_u2): Add tag to 'i' field.
|
||||
* varasm.c (union rtx_const_un): Add tags to all fields.
|
||||
* gengtype.c (struct walk_type_data): New.
|
||||
(output_escaped_param): Take struct walk_type_data parameter.
|
||||
(write_gc_structure_fields): Delete.
|
||||
(walk_type): New.
|
||||
(write_gc_marker_routine_for_structure): Delete.
|
||||
(write_func_for_structure): New.
|
||||
(gc_mark_process_field): New.
|
||||
(gc_mark_func_name): New.
|
||||
(gc_counter): Delete.
|
||||
(write_gc_types): Use write_func_for_structure.
|
||||
(write_gc_roots): Use walk_type.
|
||||
|
||||
2002-10-02 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* ggc-common.c (ggc_mark_roots): Delete 'x'.
|
||||
(ggc_splay_dont_free): Fix warning about unused 'x'.
|
||||
(ggc_print_common_statistics): Remove warnings.
|
||||
|
||||
2002-10-01 Mike Stump <mrs@apple.com>
|
||||
|
||||
* ggc-common.c (ggc_splay_alloc): Actually return the allocated area.
|
||||
* gengtype.c (write_gc_structure_fields): Handle param[digit]_is.
|
||||
|
||||
2002-09-01 Geoffrey Keating <geoffk@redhat.com>
|
||||
Catherine Moore <clm@redhat.com>
|
||||
|
||||
* Makefile (c-pch.o): Update dependencies.
|
||||
(LIBCPP_OBJS): Add cpppch.o.
|
||||
(cpppch.o): New.
|
||||
* c-common.c (c_common_init): Don't call pch_init here.
|
||||
* c-common.h (c_common_read_pch): Update prototype.
|
||||
* c-lex.c (c_common_parse_file): Call pch_init here.
|
||||
* c-opts.c (COMMAND_LINE_OPTIONS): Add -Winvalid-pch, -fpch-deps.
|
||||
(c_common_decode_option): Handle them.
|
||||
* c-pch.c: Include c-pragma.h.
|
||||
(save_asm_offset): Delete.
|
||||
(pch_init): Move contents of save_asm_offset into here, call
|
||||
cpp_save_state.
|
||||
(c_common_write_pch): Call cpp_write_pch.
|
||||
(c_common_valid_pch): Warn only when -Winvalid-pch. Call
|
||||
cpp_valid_state.
|
||||
(c_common_read_pch): Add NAME parameter. Call cpp_read_state.
|
||||
* cppfiles.c (stack_include_file): Update for change to
|
||||
parameters of cb.read_pch.
|
||||
* cpphash.h (struct cpp_reader): Add `savedstate' field.
|
||||
* cpplib.h (struct cpp_options): Add `warn_invalid_pch' and
|
||||
`restore_pch_deps' fields.
|
||||
(struct cpp_callbacks): Add NAME parameter to `read_pch'.
|
||||
(cpp_save_state): Prototype.
|
||||
(cpp_write_pch): Prototype.
|
||||
(cpp_valid_state): Prototype.
|
||||
(cpp_read_state): Prototype.
|
||||
* cpppch.c: New file.
|
||||
* flags.h (version_flag): Remove prototype.
|
||||
* mkdeps.c (deps_save): New.
|
||||
(deps_restore): New.
|
||||
* mkdeps.h (deps_save): Prototype.
|
||||
(deps_restore): Prototype.
|
||||
* toplev.c (late_init_hook): Delete.
|
||||
(version_flag): Make static again.
|
||||
(compile_file): Don't call late_init_hook.
|
||||
* toplev.h (late_init_hook): Delete.
|
||||
* doc/cppopts.texi: Document -fpch-deps.
|
||||
* doc/invoke.texi (Warning Options): Document -Winvalid-pch.
|
||||
|
||||
2002-08-27 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* c-pch.c (c_common_write_pch): Rename from c_write_pch, change
|
||||
callers.
|
||||
(c_common_valid_pch): Rename from c_valid_pch, change callers.
|
||||
(c_common_read_pch): Rename from c_read_pch, change callers.
|
||||
|
||||
* c-opts.c (COMMAND_LINE_OPTIONS): Allow -output-pch= to have
|
||||
a space between it and its argument.
|
||||
|
||||
2002-08-24 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* c-pch.c: New file.
|
||||
* toplev.h (late_init_hook): Declare.
|
||||
* toplev.c (late_init_hook): Define.
|
||||
(version_flag): Make globally visible.
|
||||
(compile_file): Call late_init_hook.
|
||||
(init_asm_output): Make output file seekable.
|
||||
* gcc.c (default_compilers): Update c-header rule.
|
||||
* flags.h (version_flag): Declare.
|
||||
* cpplib.h (struct cpp_callbacks): Add 'valid_pch' and 'read_pch'
|
||||
fields.
|
||||
* cppfiles.c (struct include_file): Add 'pch' field.
|
||||
(INCLUDE_PCH_P): New.
|
||||
(open_file_pch): New.
|
||||
(stack_include_file): Handle PCH files specially.
|
||||
(find_include_file): Call open_file_pch instead of open_file.
|
||||
(_cpp_read_file): Explain why open_file is used instead of
|
||||
open_file_pch.
|
||||
* c-opts.c (c_common_decode_option): Correct OPT__output_pch case.
|
||||
* c-objc-common.c (c_objc_common_finish_file): Call c_write_pch.
|
||||
* c-lex.c (init_c_lex): Set valid_pch and read_pch fields
|
||||
in cpplib callbacks.
|
||||
* c-common.c (pch_file): Correct comment.
|
||||
(allow_pch): Define.
|
||||
(c_common_init): Call pch_init.
|
||||
* c-common.h (allow_pch): Declare.
|
||||
(pch_init): Declare.
|
||||
(c_valid_pch): Declare.
|
||||
(c_read_pch): Declare.
|
||||
(c_write_pch): Declare.
|
||||
* Makefile.in (c-pch.o): New.
|
||||
(C_AND_OBJC_OBJS): Add c-pch.o.
|
||||
* doc/invoke.texi (Precompiled Headers): Add index entries,
|
||||
complete truncated paragraph.
|
||||
|
||||
2002-08-17 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* c-common.c: (pch_file): Define.
|
||||
* c-common.h (pch_file): Declare.
|
||||
* c-opts.c (COMMAND_LINE_OPTIONS): Add --output-pch=.
|
||||
(missing_arg): Require --output-pch= to have an argument.
|
||||
(c_common_decode_option): Handle --output-pch=.
|
||||
* gcc.c: Document new %V.
|
||||
(default_compilers): Handle compiling C header files.
|
||||
(do_spec_1): Implement %V.
|
||||
(main): Handle "gcc foo.h" without trying to run linker.
|
||||
* doc/invoke.texi (Invoking GCC): Add new menu item for PCH.
|
||||
(Overall Options): Document what the driver does with header files,
|
||||
document new -x option possibilities.
|
||||
(Invoking G++): More documentation for PCH.
|
||||
(Precompiled Headers): New.
|
||||
|
||||
2002-08-09 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* ggc.h: Don't include varray.h. Rearrange functions to be more
|
||||
organized.
|
||||
(ggc_add_root): Delete.
|
||||
(ggc_mark_rtx): Delete.
|
||||
(ggc_mark_tree): Delete.
|
||||
(struct ggc_statistics): Remove contents.
|
||||
* ggc-common.c: Remove unneeded includes.
|
||||
(struct ggc_root): Delete.
|
||||
(roots): Delete.
|
||||
(ggc_add_root): Delete.
|
||||
(ggc_mark_roots): Don't mark `roots'. Call ggc_mark_stringpool.
|
||||
(ggc_print_common_statistics): Remove most of the contents.
|
||||
* Makefile.in (GGC_H): No longer uses varray.h.
|
||||
(ggc-common.o): Update dependencies.
|
||||
(c-parse.o): Add varray.h to dependencies.
|
||||
(c-common.o): Add varray.h.
|
||||
* stringpool.c (mark_ident): Use mangled name for tree marker routine.
|
||||
(mark_ident_hash): Rename to ggc_mark_stringpool.
|
||||
(init_stringpool): Don't use ggc_add_root.
|
||||
* c-parse.in: Include varray.h.
|
||||
* c-common.c: Include varray.h.
|
||||
* objc/Make-lang.in (objc-act.o): Add varray.h.
|
||||
* objc/objc-act.c: Include varray.h.
|
||||
|
||||
2002-07-25 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* dwarf2out.c (dw_cfi_oprnd2_desc): Fix ISO-only function definition.
|
||||
(dw_cfi_oprnd1_desc): Likewise.
|
||||
|
||||
2002-07-17 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* config/alpha/alpha.c (struct alpha_links): Use gengtype to mark;
|
||||
move out of ifdef.
|
||||
(alpha_links): Use gengtype to mark; move out of ifdef.
|
||||
(mark_alpha_links_node): Delete.
|
||||
(mark_alpha_links): Delete.
|
||||
(alpha_need_linkage): Use GGC to allocate splay tree, struct
|
||||
alpha_links, strings. Don't use ggc_add_root.
|
||||
* ggc-common.c (ggc_splay_alloc): New.
|
||||
(ggc_splay_dont_free): New.
|
||||
* ggc.h (ggc_mark_rtx): Update for changed name mangling.
|
||||
(ggc_mark_tree): Likewise.
|
||||
(splay_tree_new_ggc): New.
|
||||
(ggc_splay_alloc): Declare.
|
||||
(ggc_splay_dont_free): Declare.
|
||||
* dwarf2asm.c: Include gt-dwarf2asm.h.
|
||||
(mark_indirect_pool_entry): Delete.
|
||||
(mark_indirect_pool): Delete.
|
||||
(indirect_pool): Use gengtype to mark.
|
||||
(dw2_force_const_mem): Don't use ggc_add_root.
|
||||
* Makefile.in (dwarf2asm.o): Depend on gt-dwarf2asm.h.
|
||||
(GTFILES): Add SPLAY_TREE_H, dwarf2asm.c.
|
||||
(gt-dwarf2asm.h): Depend on s-gtype.
|
||||
|
||||
2002-07-08 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* tree.h (union tree_type_symtab): Mark `die' field.
|
||||
* Makefile.in (dwarf2out.o): Update dependencies.
|
||||
* dwarf2out.c: Use GGC to allocate all structures. Convert to htab_t
|
||||
hash tables.
|
||||
(dw_cfi_oprnd1_desc): New function.
|
||||
(dw_cfi_oprnd2_desc): New function.
|
||||
(indirect_string_alloc): Delete.
|
||||
(debug_str_do_hash): New function.
|
||||
(debug_str_eq): New function.
|
||||
(mark_limbo_die_list): Delete.
|
||||
(dwarf2out_init): Don't call ggc_add_root.
|
||||
|
||||
2003-01-09 Vladimir Makarov <vmakarov@redhat.com>
|
||||
|
||||
The following changes are merged from itanium-sched-branch:
|
||||
|
@ -438,10 +954,10 @@
|
|||
the generated code.
|
||||
(write_automata): Call the new function.
|
||||
|
||||
|
||||
Thu Jan 9 22:47:38 CET 2003 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* i386.md (unit, prefix_0f, memory attributes): Hanlde sseicvt correctly.
|
||||
* i386.md (unit, prefix_0f, memory attributes): Hanlde sseicvt
|
||||
correctly.
|
||||
|
||||
2003-01-09 Paolo Carlini <pcarlini@unitus.it>
|
||||
|
||||
|
|
|
@ -587,7 +587,7 @@ REGS_H = regs.h varray.h $(MACHMODE_H)
|
|||
INTEGRATE_H = integrate.h varray.h
|
||||
LOOP_H = loop.h varray.h bitmap.h
|
||||
GCC_H = gcc.h version.h
|
||||
GGC_H = ggc.h varray.h gtype-desc.h
|
||||
GGC_H = ggc.h gtype-desc.h
|
||||
TIMEVAR_H = timevar.h timevar.def
|
||||
INSN_ATTR_H = insn-attr.h $(srcdir)/insn-addr.h $(srcdir)/varray.h
|
||||
C_COMMON_H = c-common.h $(SPLAY_TREE_H) $(CPPLIB_H)
|
||||
|
@ -739,7 +739,7 @@ CXX_TARGET_OBJS=@cxx_target_objs@
|
|||
# Language-specific object files for C and Objective C.
|
||||
C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
|
||||
c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
|
||||
c-objc-common.o c-dump.o libcpp.a $(C_TARGET_OBJS)
|
||||
c-objc-common.o c-dump.o c-pch.o libcpp.a $(C_TARGET_OBJS)
|
||||
|
||||
# Language-specific object files for C.
|
||||
C_OBJS = c-parse.o c-lang.o c-pretty-print.o $(C_AND_OBJC_OBJS)
|
||||
|
@ -1175,7 +1175,7 @@ c-errors.o: c-errors.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
|||
$(C_TREE_H) flags.h diagnostic.h $(TM_P_H)
|
||||
c-parse.o : $(srcdir)/c-parse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(GGC_H) intl.h $(C_TREE_H) input.h flags.h toplev.h output.h $(CPPLIB_H) \
|
||||
gt-c-parse.h
|
||||
varray.h gt-c-parse.h
|
||||
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
|
||||
-c $(srcdir)/c-parse.c $(OUTPUT_OPTION)
|
||||
|
||||
|
@ -1246,7 +1246,7 @@ tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h
|
|||
c-common.o : c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(OBSTACK_H) $(C_COMMON_H) flags.h toplev.h output.h c-pragma.h $(RTL_H) \
|
||||
$(GGC_H) $(EXPR_H) $(TM_P_H) builtin-types.def builtin-attrs.def $(TARGET_H) \
|
||||
diagnostic.h except.h gt-c-common.h real.h langhooks.h
|
||||
diagnostic.h except.h gt-c-common.h real.h langhooks.h varray.h
|
||||
c-pretty-print.o : c-pretty-print.c c-pretty-print.h pretty-print.h \
|
||||
$(C_COMMON_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) real.h
|
||||
|
||||
|
@ -1270,6 +1270,9 @@ c-semantics.o : c-semantics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE
|
|||
c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(C_TREE_H) tree-dump.h
|
||||
|
||||
c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) $(TREE_H) \
|
||||
c-common.h output.h toplev.h c-pragma.h $(GGC_H) debug.h
|
||||
|
||||
# Language-independent files.
|
||||
|
||||
DRIVER_DEFINES = \
|
||||
|
@ -1349,18 +1352,17 @@ gtype-desc.o: gtype-desc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h
|
|||
libfuncs.h debug.h $(GGC_H) bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h \
|
||||
ssa.h cselib.h insn-addr.h
|
||||
|
||||
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
|
||||
flags.h $(GGC_H) varray.h $(HASHTAB_H) $(TM_P_H) langhooks.h \
|
||||
$(PARAMS_H)
|
||||
ggc-common.o: ggc-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
|
||||
$(HASHTAB_H) toplev.h
|
||||
|
||||
ggc-simple.o: ggc-simple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
|
||||
flags.h $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H)
|
||||
|
||||
ggc-page.o: ggc-page.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
|
||||
flags.h toplev.h $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H)
|
||||
flags.h toplev.h $(GGC_H) varray.h $(TIMEVAR_H) $(TM_P_H) $(PARAMS_H)
|
||||
|
||||
stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(OBSTACK_H) flags.h toplev.h $(GGC_H)
|
||||
stringpool.o: stringpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(GGC_H) gt-stringpool.h
|
||||
|
||||
hashtable.o: hashtable.c hashtable.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(OBSTACK_H)
|
||||
|
||||
|
@ -1466,11 +1468,12 @@ optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_
|
|||
toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h $(BASIC_BLOCK_H)
|
||||
dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
|
||||
flags.h $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) function.h langhooks.h \
|
||||
insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h
|
||||
insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h \
|
||||
$(GGC_H) gt-dbxout.h
|
||||
debug.o : debug.c debug.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
|
||||
sdbout.o : sdbout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
|
||||
flags.h function.h $(EXPR_H) output.h hard-reg-set.h $(REGS_H) real.h \
|
||||
insn-config.h xcoffout.h c-pragma.h ggc.h $(TARGET_H) \
|
||||
insn-config.h xcoffout.h c-pragma.h $(GGC_H) $(TARGET_H) \
|
||||
sdbout.h toplev.h $(TM_P_H) except.h debug.h langhooks.h gt-sdbout.h
|
||||
dwarfout.o : dwarfout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(RTL_H) dwarf.h flags.h insn-config.h reload.h output.h toplev.h $(TM_P_H) \
|
||||
|
@ -1480,7 +1483,7 @@ dwarf2out.o : dwarf2out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
|
|||
hard-reg-set.h $(REGS_H) $(EXPR_H) libfuncs.h toplev.h dwarf2out.h varray.h \
|
||||
$(GGC_H) except.h dwarf2asm.h $(TM_P_H) langhooks.h $(HASHTAB_H) gt-dwarf2out.h
|
||||
dwarf2asm.o : dwarf2asm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) flags.h $(RTL_H) \
|
||||
$(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H)
|
||||
$(TREE_H) output.h dwarf2asm.h $(TM_P_H) $(GGC_H) gt-dwarf2asm.h
|
||||
vmsdbgout.o : vmsdbgout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
|
||||
$(RTL_H) flags.h output.h vmsdbg.h debug.h langhooks.h function.h $(TARGET_H)
|
||||
xcoffout.o : xcoffout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
|
||||
|
@ -1862,22 +1865,22 @@ s-preds: genpreds$(build_exeext) $(srcdir)/move-if-change
|
|||
$(SHELL) $(srcdir)/move-if-change tmp-preds.h tm-preds.h
|
||||
$(STAMP) s-preds
|
||||
|
||||
GTFILES = $(srcdir)/location.h $(srcdir)/coretypes.h \
|
||||
$(host_xm_file_list) $(tm_file_list) $(HASHTAB_H) \
|
||||
GTFILES = $(srcdir)/location.h $(srcdir)/coretypes.h $(srcdir)/cpplib.h \
|
||||
$(host_xm_file_list) $(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) \
|
||||
$(srcdir)/bitmap.h $(srcdir)/function.h $(srcdir)/rtl.h $(srcdir)/optabs.h \
|
||||
$(srcdir)/tree.h $(srcdir)/libfuncs.h $(srcdir)/hashtable.h $(srcdir)/real.h \
|
||||
$(srcdir)/varray.h $(srcdir)/ssa.h $(srcdir)/insn-addr.h $(srcdir)/cselib.h \
|
||||
$(srcdir)/basic-block.h $(srcdir)/location.h \
|
||||
$(srcdir)/c-common.h $(srcdir)/c-tree.h \
|
||||
$(srcdir)/basic-block.h \
|
||||
$(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c \
|
||||
$(srcdir)/dwarf2out.c $(srcdir)/emit-rtl.c \
|
||||
$(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
|
||||
$(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \
|
||||
$(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \
|
||||
$(srcdir)/fold-const.c $(srcdir)/function.c \
|
||||
$(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \
|
||||
$(srcdir)/profile.c $(srcdir)/ra-build.c $(srcdir)/regclass.c \
|
||||
$(srcdir)/reg-stack.c \
|
||||
$(srcdir)/sdbout.c $(srcdir)/stmt.c $(srcdir)/stor-layout.c \
|
||||
$(srcdir)/tree.c $(srcdir)/varasm.c \
|
||||
$(srcdir)/stringpool.c $(srcdir)/tree.c $(srcdir)/varasm.c \
|
||||
$(out_file) \
|
||||
@all_gtfiles@
|
||||
|
||||
|
@ -1891,9 +1894,9 @@ gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h gt-emit-rtl.h : s-gtype; @true
|
|||
gt-explow.h gt-stor-layout.h gt-regclass.h gt-lists.h : s-gtype; @true
|
||||
gt-alias.h gt-cselib.h gt-fold-const.h gt-gcse.h gt-profile.h : s-gtype; @true
|
||||
gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h gt-dwarf2out.h : s-gtype ; @true
|
||||
gt-ra-build.h gt-reg-stack.h : s-gtype ; @true
|
||||
gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h gt-dbxout.h : s-gtype ; @true
|
||||
gt-c-common.h gt-c-decl.h gt-c-parse.h gt-c-pragma.h : s-gtype; @true
|
||||
gt-c-objc-common.h gtype-c.h gt-location.h : s-gtype ; @true
|
||||
gt-c-objc-common.h gtype-c.h gt-location.h gt-stringpool.h : s-gtype ; @true
|
||||
|
||||
gtyp-gen.h: Makefile
|
||||
echo "/* This file is machine generated. Do not edit. */" > tmp-gtyp.h
|
||||
|
@ -2215,7 +2218,7 @@ PREPROCESSOR_DEFINES = \
|
|||
|
||||
LIBCPP_OBJS = cpplib.o cpplex.o cppmacro.o cppexp.o cppfiles.o cpptrad.o \
|
||||
cpphash.o cpperror.o cppinit.o cppdefault.o cppmain.o \
|
||||
hashtable.o line-map.o mkdeps.o prefix.o mbchar.o
|
||||
hashtable.o line-map.o mkdeps.o prefix.o mbchar.o cpppch.o
|
||||
|
||||
LIBCPP_DEPS = $(CPPLIB_H) cpphash.h line-map.h hashtable.h intl.h \
|
||||
$(OBSTACK_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
|
||||
|
@ -2238,6 +2241,7 @@ cpphash.o: cpphash.c $(LIBCPP_DEPS)
|
|||
cpptrad.o: cpptrad.c $(LIBCPP_DEPS)
|
||||
cppfiles.o: cppfiles.c $(LIBCPP_DEPS) $(SPLAY_TREE_H) mkdeps.h
|
||||
cppinit.o: cppinit.c $(LIBCPP_DEPS) cppdefault.h mkdeps.h prefix.h
|
||||
cpppch.o: cpppch.c $(LIBCPP_DEPS) mkdeps.h
|
||||
|
||||
cppdefault.o: cppdefault.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) cppdefault.h \
|
||||
Makefile
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2003-01-09 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gnat_rm.texi: Remove RCS version number.
|
||||
|
||||
* ada-tree.h (union lang_tree_node): Add chain_next option.
|
||||
|
||||
2003-01-09 Christian Cornelssen <ccorn@cs.tu-berlin.de>
|
||||
|
||||
* Make-lang.in (ada.install-info, ada.install-common,
|
||||
|
|
|
@ -43,7 +43,8 @@ struct tree_loop_id GTY(())
|
|||
|
||||
/* The language-specific tree. */
|
||||
union lang_tree_node
|
||||
GTY((desc ("TREE_CODE (&%h.generic) == GNAT_LOOP_ID")))
|
||||
GTY((desc ("TREE_CODE (&%h.generic) == GNAT_LOOP_ID"),
|
||||
chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
|
||||
{
|
||||
union tree_node GTY ((tag ("0"),
|
||||
desc ("tree_node_structure (&%h)")))
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
@c o
|
||||
@c G N A T _ RM o
|
||||
@c o
|
||||
@c $Revision: 1.9 $
|
||||
@c o
|
||||
@c Copyright (C) 1995-2002 Free Software Foundation o
|
||||
@c o
|
||||
@c o
|
||||
|
|
|
@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "c-pragma.h"
|
||||
#include "rtl.h"
|
||||
#include "ggc.h"
|
||||
#include "varray.h"
|
||||
#include "expr.h"
|
||||
#include "c-common.h"
|
||||
#include "diagnostic.h"
|
||||
|
@ -190,11 +191,20 @@ enum c_language_kind c_language;
|
|||
|
||||
tree c_global_trees[CTI_MAX];
|
||||
|
||||
/* Nonzero if we can read a PCH file now. */
|
||||
|
||||
int allow_pch = 1;
|
||||
|
||||
/* Switches common to the C front ends. */
|
||||
|
||||
/* Nonzero if prepreprocessing only. */
|
||||
int flag_preprocess_only;
|
||||
|
||||
/* The file name to which we should write a precompiled header, or
|
||||
NULL if no header will be written in this compile. */
|
||||
|
||||
const char *pch_file;
|
||||
|
||||
/* Nonzero if an ISO standard was selected. It rejects macros in the
|
||||
user's namespace. */
|
||||
int flag_iso;
|
||||
|
|
|
@ -121,7 +121,7 @@ enum rid
|
|||
|
||||
/* The elements of `ridpointers' are identifier nodes for the reserved
|
||||
type names and storage classes. It is indexed by a RID_... value. */
|
||||
extern tree *ridpointers;
|
||||
extern GTY ((length ("(int)RID_MAX"))) tree *ridpointers;
|
||||
|
||||
/* Standard named or nameless data types of the C compiler. */
|
||||
|
||||
|
@ -177,7 +177,7 @@ enum c_tree_index
|
|||
struct c_common_identifier GTY(())
|
||||
{
|
||||
struct tree_common common;
|
||||
struct cpp_hashnode GTY ((skip (""))) node;
|
||||
struct cpp_hashnode node;
|
||||
};
|
||||
|
||||
#define wchar_type_node c_global_trees[CTI_WCHAR_TYPE]
|
||||
|
@ -360,13 +360,24 @@ struct c_lang_decl GTY(()) {
|
|||
|
||||
extern c_language_kind c_language;
|
||||
|
||||
/* Nonzero if we can read a PCH file now. */
|
||||
|
||||
extern int allow_pch;
|
||||
|
||||
/* Switches common to the C front ends. */
|
||||
|
||||
/* Nonzero if prepreprocessing only. */
|
||||
|
||||
extern int flag_preprocess_only;
|
||||
|
||||
/* The file name to which we should write a precompiled header, or
|
||||
NULL if no header will be written in this compile. */
|
||||
|
||||
extern const char *pch_file;
|
||||
|
||||
/* Nonzero if an ISO standard was selected. It rejects macros in the
|
||||
user's namespace. */
|
||||
|
||||
extern int flag_iso;
|
||||
|
||||
/* Nonzero whenever Objective-C functionality is being used. */
|
||||
|
@ -374,6 +385,7 @@ extern int flag_objc;
|
|||
|
||||
/* Nonzero if -undef was given. It suppresses target built-in macros
|
||||
and assertions. */
|
||||
|
||||
extern int flag_undef;
|
||||
|
||||
/* Nonzero means don't recognize the non-ANSI builtin functions. */
|
||||
|
@ -1253,4 +1265,14 @@ extern void dump_time_statistics PARAMS ((void));
|
|||
|
||||
extern int c_dump_tree PARAMS ((void *, tree));
|
||||
|
||||
extern void pch_init PARAMS ((void));
|
||||
extern int c_common_valid_pch PARAMS ((cpp_reader *pfile,
|
||||
const char *name,
|
||||
int fd));
|
||||
extern void c_common_read_pch PARAMS ((cpp_reader *pfile,
|
||||
const char *name,
|
||||
int fd,
|
||||
const char *orig));
|
||||
extern void c_common_write_pch PARAMS ((void));
|
||||
|
||||
#endif /* ! GCC_C_COMMON_H */
|
||||
|
|
|
@ -3226,6 +3226,8 @@ clear_parm_order ()
|
|||
current_binding_level->parm_order = NULL_TREE;
|
||||
}
|
||||
|
||||
static GTY(()) int compound_literal_number;
|
||||
|
||||
/* Build a COMPOUND_LITERAL_EXPR. TYPE is the type given in the compound
|
||||
literal, which may be an incomplete array type completed by the
|
||||
initializer; INIT is a CONSTRUCTOR that initializes the compound
|
||||
|
@ -3273,10 +3275,10 @@ build_compound_literal (type, init)
|
|||
/* This decl needs a name for the assembler output. We also need
|
||||
a unique suffix to be added to the name. */
|
||||
char *name;
|
||||
extern int var_labelno;
|
||||
|
||||
ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal", var_labelno);
|
||||
var_labelno++;
|
||||
ASM_FORMAT_PRIVATE_NAME (name, "__compound_literal",
|
||||
compound_literal_number);
|
||||
compound_literal_number++;
|
||||
DECL_NAME (decl) = get_identifier (name);
|
||||
DECL_DEFER_OUTPUT (decl) = 1;
|
||||
DECL_COMDAT (decl) = 1;
|
||||
|
|
|
@ -124,6 +124,8 @@ init_c_lex (filename)
|
|||
cb->ident = cb_ident;
|
||||
cb->file_change = cb_file_change;
|
||||
cb->def_pragma = cb_def_pragma;
|
||||
cb->valid_pch = c_common_valid_pch;
|
||||
cb->read_pch = c_common_read_pch;
|
||||
|
||||
/* Set the debug callbacks if we can use them. */
|
||||
if (debug_info_level == DINFO_LEVEL_VERBOSE
|
||||
|
@ -158,6 +160,8 @@ c_common_parse_file (set_yydebug)
|
|||
(*debug_hooks->start_source_file) (lineno, input_filename);
|
||||
cpp_finish_options (parse_in);
|
||||
|
||||
pch_init();
|
||||
|
||||
yyparse ();
|
||||
free_parser_stacks ();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Some code common to C and ObjC front ends.
|
||||
Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -358,6 +358,9 @@ finish_cdtor (body)
|
|||
void
|
||||
c_objc_common_finish_file ()
|
||||
{
|
||||
if (pch_file)
|
||||
c_common_write_pch ();
|
||||
|
||||
expand_deferred_fns ();
|
||||
|
||||
if (static_ctors)
|
||||
|
|
16
gcc/c-opts.c
16
gcc/c-opts.c
|
@ -112,6 +112,7 @@ static void sanitize_cpp_opts PARAMS ((void));
|
|||
|
||||
#define COMMAND_LINE_OPTIONS \
|
||||
OPT("-help", CL_ALL, OPT__help) \
|
||||
OPT("-output-pch=", CL_ALL | CL_ARG, OPT__output_pch) \
|
||||
OPT("C", CL_ALL, OPT_C) \
|
||||
OPT("CC", CL_ALL, OPT_CC) \
|
||||
OPT("E", CL_ALL, OPT_E) \
|
||||
|
@ -154,6 +155,7 @@ static void sanitize_cpp_opts PARAMS ((void));
|
|||
OPT("Wimplicit-function-declaration", CL_C, OPT_Wimplicit_function_decl) \
|
||||
OPT("Wimplicit-int", CL_C, OPT_Wimplicit_int) \
|
||||
OPT("Wimport", CL_ALL, OPT_Wimport) \
|
||||
OPT("Winvalid-pch", CL_ALL, OPT_Winvalid_pch) \
|
||||
OPT("Wlong-long", CL_ALL, OPT_Wlong_long) \
|
||||
OPT("Wmain", CL_C, OPT_Wmain) \
|
||||
OPT("Wmissing-braces", CL_ALL, OPT_Wmissing_braces) \
|
||||
|
@ -231,6 +233,7 @@ static void sanitize_cpp_opts PARAMS ((void));
|
|||
OPT("fnonnull-objects", CL_CXX, OPT_fnonnull_objects) \
|
||||
OPT("foperator-names", CL_CXX, OPT_foperator_names) \
|
||||
OPT("foptional-diags", CL_CXX, OPT_foptional_diags) \
|
||||
OPT("fpch-deps", CL_ALL, OPT_fpch_deps) \
|
||||
OPT("fpermissive", CL_CXX, OPT_fpermissive) \
|
||||
OPT("fpreprocessed", CL_ALL, OPT_fpreprocessed) \
|
||||
OPT("frepo", CL_CXX, OPT_frepo) \
|
||||
|
@ -343,6 +346,7 @@ missing_arg (opt_index)
|
|||
|
||||
switch (cl_options[opt_index].opt_code)
|
||||
{
|
||||
case OPT__output_pch:
|
||||
case OPT_Wformat_eq:
|
||||
case OPT_d:
|
||||
case OPT_fabi_version:
|
||||
|
@ -627,6 +631,10 @@ c_common_decode_option (argc, argv)
|
|||
print_help ();
|
||||
break;
|
||||
|
||||
case OPT__output_pch:
|
||||
pch_file = arg;
|
||||
break;
|
||||
|
||||
case OPT_C:
|
||||
cpp_opts->discard_comments = 0;
|
||||
break;
|
||||
|
@ -832,6 +840,10 @@ c_common_decode_option (argc, argv)
|
|||
cpp_opts->warn_import = on;
|
||||
break;
|
||||
|
||||
case OPT_Winvalid_pch:
|
||||
cpp_opts->warn_invalid_pch = on;
|
||||
break;
|
||||
|
||||
case OPT_Wlong_long:
|
||||
warn_long_long = on;
|
||||
break;
|
||||
|
@ -1178,6 +1190,10 @@ c_common_decode_option (argc, argv)
|
|||
flag_optional_diags = on;
|
||||
break;
|
||||
|
||||
case OPT_fpch_deps:
|
||||
cpp_opts->restore_pch_deps = on;
|
||||
break;
|
||||
|
||||
case OPT_fpermissive:
|
||||
flag_permissive = on;
|
||||
break;
|
||||
|
|
|
@ -48,6 +48,7 @@ end ifc
|
|||
#include "c-pragma.h" /* For YYDEBUG definition, and parse_in. */
|
||||
#include "c-tree.h"
|
||||
#include "flags.h"
|
||||
#include "varray.h"
|
||||
#include "output.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
|
@ -3555,10 +3556,7 @@ init_reswords ()
|
|||
if (!flag_objc)
|
||||
mask |= D_OBJC;
|
||||
|
||||
/* It is not necessary to register ridpointers as a GC root, because
|
||||
all the trees it points to are permanently interned in the
|
||||
get_identifier hash anyway. */
|
||||
ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree));
|
||||
ridpointers = (tree *) ggc_calloc ((int) RID_MAX, sizeof (tree));
|
||||
for (i = 0; i < N_reswords; i++)
|
||||
{
|
||||
/* If a keyword is disabled, do not enter it into the table
|
||||
|
|
226
gcc/c-pch.c
Normal file
226
gcc/c-pch.c
Normal file
|
@ -0,0 +1,226 @@
|
|||
/* Precompiled header implementation for the C languages.
|
||||
Copyright (C) 2000, 2002 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 "coretypes.h"
|
||||
#include "cpplib.h"
|
||||
#include "tree.h"
|
||||
#include "c-common.h"
|
||||
#include "output.h"
|
||||
#include "toplev.h"
|
||||
#include "debug.h"
|
||||
#include "c-pragma.h"
|
||||
#include "ggc.h"
|
||||
|
||||
struct c_pch_header
|
||||
{
|
||||
unsigned long asm_size;
|
||||
};
|
||||
|
||||
static const char pch_ident[8] = "gpchC010";
|
||||
|
||||
static FILE *pch_outfile;
|
||||
|
||||
extern char *asm_file_name;
|
||||
static off_t asm_file_startpos;
|
||||
|
||||
void
|
||||
pch_init ()
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if (pch_file)
|
||||
{
|
||||
/* We're precompiling a header file, so when it's actually used,
|
||||
it'll be at least one level deep. */
|
||||
(*debug_hooks->start_source_file) (lineno, input_filename);
|
||||
|
||||
f = fopen (pch_file, "w+b");
|
||||
if (f == NULL)
|
||||
fatal_io_error ("can't open %s", pch_file);
|
||||
pch_outfile = f;
|
||||
|
||||
if (fwrite (pch_ident, sizeof (pch_ident), 1, f) != 1)
|
||||
fatal_io_error ("can't write to %s", pch_file);
|
||||
|
||||
/* We need to be able to re-read the output. */
|
||||
/* The driver always provides a valid -o option. */
|
||||
if (asm_file_name == NULL
|
||||
|| strcmp (asm_file_name, "-") == 0)
|
||||
fatal_error ("`%s' is not a valid output file", asm_file_name);
|
||||
|
||||
asm_file_startpos = ftello (asm_out_file);
|
||||
|
||||
cpp_save_state (parse_in, f);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
c_common_write_pch ()
|
||||
{
|
||||
char *buf;
|
||||
off_t asm_file_end;
|
||||
off_t written;
|
||||
struct c_pch_header h;
|
||||
|
||||
cpp_write_pch_deps (parse_in, pch_outfile);
|
||||
|
||||
asm_file_end = ftello (asm_out_file);
|
||||
h.asm_size = asm_file_end - asm_file_startpos;
|
||||
|
||||
if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
|
||||
fatal_io_error ("can't write %s", pch_file);
|
||||
|
||||
buf = xmalloc (16384);
|
||||
fflush (asm_out_file);
|
||||
|
||||
if (fseeko (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
|
||||
fatal_io_error ("can't seek in %s", asm_file_name);
|
||||
|
||||
for (written = asm_file_startpos; written < asm_file_end; )
|
||||
{
|
||||
off_t size = asm_file_end - written;
|
||||
if (size > 16384)
|
||||
size = 16384;
|
||||
if (fread (buf, size, 1, asm_out_file) != 1)
|
||||
fatal_io_error ("can't read %s", asm_file_name);
|
||||
if (fwrite (buf, size, 1, pch_outfile) != 1)
|
||||
fatal_io_error ("can't write %s", pch_file);
|
||||
written += size;
|
||||
}
|
||||
free (buf);
|
||||
|
||||
gt_pch_save (pch_outfile);
|
||||
cpp_write_pch_state (parse_in, pch_outfile);
|
||||
|
||||
fclose (pch_outfile);
|
||||
}
|
||||
|
||||
int
|
||||
c_common_valid_pch (pfile, name, fd)
|
||||
cpp_reader *pfile;
|
||||
const char *name;
|
||||
int fd;
|
||||
{
|
||||
int sizeread;
|
||||
int result;
|
||||
char ident[sizeof (pch_ident)];
|
||||
|
||||
if (! allow_pch)
|
||||
return 2;
|
||||
|
||||
/* Perform a quick test of whether this is a valid
|
||||
precompiled header for C. */
|
||||
|
||||
sizeread = read (fd, ident, sizeof (pch_ident));
|
||||
if (sizeread == -1)
|
||||
{
|
||||
fatal_io_error ("can't read %s", name);
|
||||
return 2;
|
||||
}
|
||||
else if (sizeread != sizeof (pch_ident))
|
||||
return 2;
|
||||
|
||||
if (memcmp (ident, pch_ident, sizeof (pch_ident)) != 0)
|
||||
{
|
||||
if (cpp_get_options (pfile)->warn_invalid_pch)
|
||||
{
|
||||
if (memcmp (ident, pch_ident, 5) == 0)
|
||||
/* It's a PCH, for the right language, but has the wrong version.
|
||||
*/
|
||||
cpp_error (pfile, DL_WARNING,
|
||||
"%s: not compatible with this GCC version", name);
|
||||
else if (memcmp (ident, pch_ident, 4) == 0)
|
||||
/* It's a PCH for the wrong language. */
|
||||
cpp_error (pfile, DL_WARNING, "%s: not for C language", name);
|
||||
else
|
||||
/* Not any kind of PCH. */
|
||||
cpp_error (pfile, DL_WARNING, "%s: not a PCH file", name);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Check the preprocessor macros are the same as when the PCH was
|
||||
generated. */
|
||||
|
||||
result = cpp_valid_state (pfile, name, fd);
|
||||
if (result == -1)
|
||||
return 2;
|
||||
else
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
void
|
||||
c_common_read_pch (pfile, name, fd, orig_name)
|
||||
cpp_reader *pfile;
|
||||
const char *name;
|
||||
int fd;
|
||||
const char *orig_name;
|
||||
{
|
||||
FILE *f;
|
||||
struct c_pch_header h;
|
||||
char *buf;
|
||||
unsigned long written;
|
||||
struct save_macro_data *smd;
|
||||
|
||||
/* Before we wrote the file, we started a source file, so we have to start
|
||||
one here to match. */
|
||||
(*debug_hooks->start_source_file) (lineno, orig_name);
|
||||
|
||||
f = fdopen (fd, "rb");
|
||||
if (f == NULL)
|
||||
{
|
||||
cpp_errno (pfile, DL_ERROR, "calling fdopen");
|
||||
return;
|
||||
}
|
||||
|
||||
allow_pch = 0;
|
||||
|
||||
if (fread (&h, sizeof (h), 1, f) != 1)
|
||||
{
|
||||
cpp_errno (pfile, DL_ERROR, "reading");
|
||||
return;
|
||||
}
|
||||
|
||||
buf = xmalloc (16384);
|
||||
for (written = 0; written < h.asm_size; )
|
||||
{
|
||||
off_t size = h.asm_size - written;
|
||||
if (size > 16384)
|
||||
size = 16384;
|
||||
if (fread (buf, size, 1, f) != 1
|
||||
|| fwrite (buf, size, 1, asm_out_file) != 1)
|
||||
cpp_errno (pfile, DL_ERROR, "reading");
|
||||
written += size;
|
||||
}
|
||||
free (buf);
|
||||
|
||||
cpp_prepare_state (pfile, &smd);
|
||||
|
||||
gt_pch_restore (f);
|
||||
|
||||
if (cpp_read_state (pfile, name, f, smd) != 0)
|
||||
return;
|
||||
|
||||
fclose (f);
|
||||
|
||||
(*debug_hooks->end_source_file) (lineno);
|
||||
}
|
|
@ -50,6 +50,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "target-def.h"
|
||||
#include "debug.h"
|
||||
#include "langhooks.h"
|
||||
#include <splay-tree.h>
|
||||
|
||||
/* Specify which cpu to schedule for. */
|
||||
|
||||
|
@ -9023,6 +9024,20 @@ alpha_elf_select_rtx_section (mode, x, align)
|
|||
|
||||
#endif /* OBJECT_FORMAT_ELF */
|
||||
|
||||
/* Structure to collect function names for final output
|
||||
in link section. */
|
||||
|
||||
enum links_kind {KIND_UNUSED, KIND_LOCAL, KIND_EXTERN};
|
||||
|
||||
struct alpha_links GTY(())
|
||||
{
|
||||
rtx linkage;
|
||||
enum links_kind kind;
|
||||
};
|
||||
|
||||
static GTY ((param1_is (char *), param2_is (struct alpha_links *)))
|
||||
splay_tree alpha_links;
|
||||
|
||||
#if TARGET_ABI_OPEN_VMS
|
||||
|
||||
/* Return the VMS argument type corresponding to MODE. */
|
||||
|
@ -9058,26 +9073,6 @@ alpha_arg_info_reg_val (cum)
|
|||
return GEN_INT (regval);
|
||||
}
|
||||
|
||||
/* Protect alpha_links from garbage collection. */
|
||||
|
||||
static int
|
||||
mark_alpha_links_node (node, data)
|
||||
splay_tree_node node;
|
||||
void *data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
struct alpha_links *links = (struct alpha_links *) node->value;
|
||||
ggc_mark_rtx (links->linkage);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
mark_alpha_links (ptr)
|
||||
void *ptr;
|
||||
{
|
||||
splay_tree tree = *(splay_tree *) ptr;
|
||||
splay_tree_foreach (tree, mark_alpha_links_node, NULL);
|
||||
}
|
||||
|
||||
/* Make (or fake) .linkage entry for function call.
|
||||
|
||||
IS_LOCAL is 0 if name is used in call, 1 if name is used in definition.
|
||||
|
@ -9139,16 +9134,11 @@ alpha_need_linkage (name, is_local)
|
|||
}
|
||||
else
|
||||
{
|
||||
alpha_links_tree = splay_tree_new
|
||||
((splay_tree_compare_fn) strcmp,
|
||||
(splay_tree_delete_key_fn) free,
|
||||
(splay_tree_delete_key_fn) free);
|
||||
|
||||
ggc_add_root (&alpha_links_tree, 1, 1, mark_alpha_links);
|
||||
alpha_links = splay_tree_new_ggc ((splay_tree_compare_fn) strcmp);
|
||||
}
|
||||
|
||||
al = (struct alpha_links *) xmalloc (sizeof (struct alpha_links));
|
||||
name = xstrdup (name);
|
||||
al = (struct alpha_links *) ggc_alloc (sizeof (struct alpha_links));
|
||||
name = ggc_strdup (name);
|
||||
|
||||
/* Assume external if no definition. */
|
||||
al->lkind = (is_local ? KIND_UNUSED : KIND_EXTERN);
|
||||
|
|
|
@ -223,7 +223,7 @@ machopic_define_name (name)
|
|||
|
||||
static char function_base[32];
|
||||
|
||||
static int current_pic_label_num;
|
||||
static GTY(()) int current_pic_label_num;
|
||||
|
||||
const char *
|
||||
machopic_function_base_name ()
|
||||
|
|
|
@ -168,7 +168,6 @@ struct builtin_description
|
|||
};
|
||||
|
||||
static bool rs6000_function_ok_for_sibcall PARAMS ((tree, tree));
|
||||
static void rs6000_add_gc_roots PARAMS ((void));
|
||||
static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
|
||||
static void validate_condition_mode
|
||||
PARAMS ((enum rtx_code, enum machine_mode));
|
||||
|
@ -183,8 +182,6 @@ static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
|
|||
static unsigned rs6000_hash_constant PARAMS ((rtx));
|
||||
static unsigned toc_hash_function PARAMS ((const void *));
|
||||
static int toc_hash_eq PARAMS ((const void *, const void *));
|
||||
static int toc_hash_mark_entry PARAMS ((void **, void *));
|
||||
static void toc_hash_mark_table PARAMS ((void *));
|
||||
static int constant_pool_expr_1 PARAMS ((rtx, int *, int *));
|
||||
static struct machine_function * rs6000_init_machine_status PARAMS ((void));
|
||||
static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
|
||||
|
@ -267,6 +264,19 @@ static void is_altivec_return_reg PARAMS ((rtx, void *));
|
|||
static rtx generate_set_vrsave PARAMS ((rtx, rs6000_stack_t *, int));
|
||||
static void altivec_frame_fixup PARAMS ((rtx, rtx, HOST_WIDE_INT));
|
||||
static int easy_vector_constant PARAMS ((rtx));
|
||||
|
||||
/* Hash table stuff for keeping track of TOC entries. */
|
||||
|
||||
struct toc_hash_struct GTY(())
|
||||
{
|
||||
/* `key' will satisfy CONSTANT_P; in fact, it will satisfy
|
||||
ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
|
||||
rtx key;
|
||||
enum machine_mode key_mode;
|
||||
int labelno;
|
||||
};
|
||||
|
||||
static GTY ((param_is (struct toc_hash_struct))) htab_t toc_hash_table;
|
||||
|
||||
/* Default register names. */
|
||||
char rs6000_reg_names[][8] =
|
||||
|
@ -708,9 +718,6 @@ rs6000_override_options (default_cpu)
|
|||
&& (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_DARWIN))
|
||||
real_format_for_mode[TFmode - QFmode] = &ibm_extended_format;
|
||||
|
||||
/* Register global variables with the garbage collector. */
|
||||
rs6000_add_gc_roots ();
|
||||
|
||||
/* Allocate an alias set for register saves & restores from stack. */
|
||||
rs6000_sr_alias_set = new_alias_set ();
|
||||
|
||||
|
@ -11457,19 +11464,6 @@ rs6000_output_mi_thunk (file, thunk_fndecl, delta, vcall_offset, function)
|
|||
|
||||
*/
|
||||
|
||||
/* Hash table stuff for keeping track of TOC entries. */
|
||||
|
||||
struct toc_hash_struct
|
||||
{
|
||||
/* `key' will satisfy CONSTANT_P; in fact, it will satisfy
|
||||
ASM_OUTPUT_SPECIAL_POOL_ENTRY_P. */
|
||||
rtx key;
|
||||
enum machine_mode key_mode;
|
||||
int labelno;
|
||||
};
|
||||
|
||||
static htab_t toc_hash_table;
|
||||
|
||||
/* Hash functions for the hash table. */
|
||||
|
||||
static unsigned
|
||||
|
@ -11570,39 +11564,6 @@ toc_hash_eq (h1, h2)
|
|||
return rtx_equal_p (r1, r2);
|
||||
}
|
||||
|
||||
/* Mark the hash table-entry HASH_ENTRY. */
|
||||
|
||||
static int
|
||||
toc_hash_mark_entry (hash_slot, unused)
|
||||
void ** hash_slot;
|
||||
void * unused ATTRIBUTE_UNUSED;
|
||||
{
|
||||
const struct toc_hash_struct * hash_entry =
|
||||
*(const struct toc_hash_struct **) hash_slot;
|
||||
rtx r = hash_entry->key;
|
||||
ggc_set_mark (hash_entry);
|
||||
/* For CODE_LABELS, we don't want to drag in the whole insn chain... */
|
||||
if (GET_CODE (r) == LABEL_REF)
|
||||
{
|
||||
ggc_set_mark (r);
|
||||
ggc_set_mark (XEXP (r, 0));
|
||||
}
|
||||
else
|
||||
ggc_mark_rtx (r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Mark all the elements of the TOC hash-table *HT. */
|
||||
|
||||
static void
|
||||
toc_hash_mark_table (vht)
|
||||
void *vht;
|
||||
{
|
||||
htab_t *ht = vht;
|
||||
|
||||
htab_traverse (*ht, toc_hash_mark_entry, (void *)0);
|
||||
}
|
||||
|
||||
/* These are the names given by the C++ front-end to vtables, and
|
||||
vtable-like objects. Ideally, this logic should not be here;
|
||||
instead, there should be some programmatic way of inquiring as
|
||||
|
@ -11656,12 +11617,19 @@ output_toc (file, x, labelno, mode)
|
|||
|
||||
/* When the linker won't eliminate them, don't output duplicate
|
||||
TOC entries (this happens on AIX if there is any kind of TOC,
|
||||
and on SVR4 under -fPIC or -mrelocatable). */
|
||||
if (TARGET_TOC)
|
||||
and on SVR4 under -fPIC or -mrelocatable). Don't do this for
|
||||
CODE_LABELs. */
|
||||
if (TARGET_TOC && GET_CODE (x) != LABEL_REF)
|
||||
{
|
||||
struct toc_hash_struct *h;
|
||||
void * * found;
|
||||
|
||||
/* Create toc_hash_table. This can't be done at OVERRIDE_OPTIONS
|
||||
time because GGC is not initialised at that point. */
|
||||
if (toc_hash_table == NULL)
|
||||
toc_hash_table = htab_create_ggc (1021, toc_hash_function,
|
||||
toc_hash_eq, NULL);
|
||||
|
||||
h = ggc_alloc (sizeof (*h));
|
||||
h->key = x;
|
||||
h->key_mode = mode;
|
||||
|
@ -12685,17 +12653,6 @@ rs6000_fatal_bad_address (op)
|
|||
fatal_insn ("bad address", op);
|
||||
}
|
||||
|
||||
/* Called to register all of our global variables with the garbage
|
||||
collector. */
|
||||
|
||||
static void
|
||||
rs6000_add_gc_roots ()
|
||||
{
|
||||
toc_hash_table = htab_create (1021, toc_hash_function, toc_hash_eq, NULL);
|
||||
ggc_add_root (&toc_hash_table, 1, sizeof (toc_hash_table),
|
||||
toc_hash_mark_table);
|
||||
}
|
||||
|
||||
#if TARGET_MACHO
|
||||
|
||||
#if 0
|
||||
|
@ -13312,3 +13269,4 @@ rs6000_memory_move_cost (mode, class, in)
|
|||
return 4 + rs6000_register_move_cost (mode, class, GENERAL_REGS);
|
||||
}
|
||||
|
||||
#include "gt-rs6000.h"
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
# General rules that all rs6000/ targets must have.
|
||||
|
||||
gt-rs6000.h: s-gtype ; @true
|
||||
|
||||
rs6000.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(RTL_H) $(REGS_H) hard-reg-set.h \
|
||||
real.h insn-config.h conditions.h insn-attr.h flags.h $(RECOG_H) \
|
||||
$(OBSTACK_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) except.h function.h \
|
||||
output.h $(BASIC_BLOCK_H) $(INTEGRATE_H) toplev.h $(GGC_H) $(HASHTAB_H) \
|
||||
$(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h
|
||||
$(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h gt-rs6000.h
|
||||
|
||||
rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \
|
||||
$(srcdir)/config/rs6000/rs6000-protos.h \
|
||||
$(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(CPPLIB_H) \
|
||||
$(TM_P_H) c-pragma.h errors.h coretypes.h $(TM_H)
|
||||
$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/rs6000/rs6000-c.c
|
||||
|
||||
|
|
|
@ -1,3 +1,93 @@
|
|||
2003-01-09 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
Merge from pch-branch:
|
||||
|
||||
2003-01-09 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
Merge to tag pch-merge-20030102:
|
||||
|
||||
* semantics.c (finish_translation_unit): Don't call finish_file.
|
||||
* parser.c: Don't include ggc.h.
|
||||
(cp_lexer_new_main): Rename from cp_lexer_new, only create main lexer,
|
||||
read first token here. Don't allow PCH files after the first
|
||||
token is read.
|
||||
(cp_lexer_new_from_tokens): Duplicate functionality from cp_lexer_new.
|
||||
(cp_lexer_get_preprocessor_token): Allow LEXER to be NULL.
|
||||
(cp_parser_new): Call cp_lexer_new_main before allocating GCed memory.
|
||||
(cp_parser_late_parsing_for_member): Don't duplicate call to
|
||||
cp_lexer_set_source_position_from_token.
|
||||
(cp_parser_late_parsing_default_args): Likewise.
|
||||
(yyparse): Call finish_file after clearing the_parser.
|
||||
|
||||
2002-12-11 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* Make-lang.in: Remove $(GGC_H) from all dependencies.
|
||||
(CXX_TREE_H): Add $(GGC_H).
|
||||
* class.c: Don't include ggc.h.
|
||||
(field_decl_cmp): Make parameters be 'const void *' to match qsort.
|
||||
(method_name_cmp): Likewise.
|
||||
(resort_data): New variable.
|
||||
(resort_field_decl_cmp): New.
|
||||
(resort_method_name_cmp): New.
|
||||
(resort_sorted_fields): New.
|
||||
(resort_type_method_vec): New.
|
||||
(finish_struct_methods): Delete cast.
|
||||
(finish_struct_1): Delete cast.
|
||||
* cp-tree.h: Include ggc.h.
|
||||
(struct lang_type_class): Add reorder attribute to field `methods'.
|
||||
(union lang_decl_u3): Add reorder attribute to field `sorted_fields'.
|
||||
(resort_sorted_fields): New prototype.
|
||||
(resort_type_method_vec): New prototype.
|
||||
* call.c: Don't include ggc.h.
|
||||
* decl.c: Likewise.
|
||||
* decl2.c: Likewise.
|
||||
* init.c: Likewise.
|
||||
* lex.c: Likewise.
|
||||
* method.c: Likewise.
|
||||
* optimize.c: Likewise.
|
||||
* parse.y: Likewise.
|
||||
* pt.c: Likewise.
|
||||
* repo.c: Likewise.
|
||||
* search.c: Likewise.
|
||||
* semantics.c: Likewise.
|
||||
* spew.c: Likewise.
|
||||
* tree.c: Likewise.
|
||||
|
||||
* lang-specs.h: Remove comment.
|
||||
|
||||
2002-12-03 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* cp-tree.h (struct operator_name_info_t): Mark for GTY machinery.
|
||||
(operator_name_info): Mark to be saved for PCH, specify size.
|
||||
(assignment_operator_name_info): Likewise.
|
||||
|
||||
2002-11-19 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* decl.c (anon_cnt): Mark to be saved for PCH.
|
||||
|
||||
2002-10-25 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* lex.c (init_reswords): Delete now-untrue comment.
|
||||
Allocate ridpointers using GGC.
|
||||
|
||||
2002-10-04 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* cp-tree.h (union lang_decl_u2): Add tags to all fields.
|
||||
|
||||
* g++spec.c (lang_specific_driver): Don't include standard
|
||||
libraries in `added'.
|
||||
|
||||
2002-08-27 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* decl2.c (finish_file): Call c_common_write_pch.
|
||||
* Make-lang.in (CXX_C_OBJS): Add c-pch.o.
|
||||
|
||||
2002-08-17 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* g++spec.c (lang_specific_driver): Treat .h files as C++ header
|
||||
files when using g++.
|
||||
* lang-specs.h: Handle compiling C++ header files.
|
||||
|
||||
2003-01-09 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* decl.c (start_decl): Only check DECL_THREAD_LOCAL for VAR_DECLs.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Top level -*- makefile -*- fragment for GNU C++.
|
||||
# Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
# Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
|
||||
# Free Software Foundation, Inc.
|
||||
|
||||
#This file is part of GCC.
|
||||
|
@ -79,7 +79,7 @@ g++-cross$(exeext): g++$(exeext)
|
|||
# The compiler itself.
|
||||
# Shared with C front end:
|
||||
CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
|
||||
c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o
|
||||
c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o
|
||||
|
||||
# Language-specific object files.
|
||||
CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
|
||||
|
@ -210,34 +210,35 @@ c++.stage4: stage4-start
|
|||
# .o: .h dependencies.
|
||||
CXX_TREE_H = $(TREE_H) cp/cp-tree.h c-common.h cp/cp-tree.def c-common.def \
|
||||
function.h varray.h $(SYSTEM_H) coretypes.h $(CONFIG_H) $(TARGET_H) \
|
||||
$(GGC_H) \
|
||||
$(srcdir)/../include/hashtab.h $(srcdir)/../include/splay-tree.h
|
||||
|
||||
cp/lex.o: cp/lex.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h \
|
||||
c-pragma.h toplev.h output.h mbchar.h $(GGC_H) input.h diagnostic.h \
|
||||
c-pragma.h toplev.h output.h mbchar.h input.h diagnostic.h \
|
||||
cp/operators.def $(TM_P_H)
|
||||
cp/cp-lang.o: cp/cp-lang.c $(CXX_TREE_H) $(TM_H) toplev.h langhooks.h \
|
||||
$(LANGHOOKS_DEF_H) c-common.h
|
||||
cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h stack.h \
|
||||
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(GGC_H) $(RTL_H) \
|
||||
output.h $(EXPR_H) except.h toplev.h $(HASHTAB_H) $(RTL_H) \
|
||||
cp/operators.def $(TM_P_H) tree-inline.h diagnostic.h c-pragma.h \
|
||||
debug.h gt-cp-decl.h gtype-cp.h
|
||||
cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/lex.h cp/decl.h $(EXPR_H) \
|
||||
output.h except.h toplev.h $(GGC_H) $(RTL_H) c-common.h gt-cp-decl2.h
|
||||
output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h
|
||||
cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h output.h $(TM_P_H) \
|
||||
diagnostic.h
|
||||
cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
|
||||
diagnostic.h
|
||||
cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(TARGET_H)
|
||||
cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \
|
||||
$(GGC_H) diagnostic.h gt-cp-call.h
|
||||
diagnostic.h gt-cp-call.h
|
||||
cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h $(EXPR_H)
|
||||
cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
|
||||
$(GGC_H) except.h
|
||||
cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(GGC_H) $(RTL_H) $(EXPR_H) \
|
||||
except.h
|
||||
cp/method.o: cp/method.c $(CXX_TREE_H) $(TM_H) toplev.h $(RTL_H) $(EXPR_H) \
|
||||
$(TM_P_H) $(TARGET_H)
|
||||
cp/cvt.o: cp/cvt.c $(CXX_TREE_H) $(TM_H) cp/decl.h flags.h toplev.h convert.h
|
||||
cp/search.o: cp/search.c $(CXX_TREE_H) $(TM_H) stack.h flags.h toplev.h $(RTL_H)
|
||||
cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(GGC_H) $(RTL_H) \
|
||||
cp/tree.o: cp/tree.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \
|
||||
insn-config.h integrate.h tree-inline.h real.h gt-cp-tree.h $(TARGET_H)
|
||||
cp/ptree.o: cp/ptree.c $(CXX_TREE_H) $(TM_H)
|
||||
cp/rtti.o: cp/rtti.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h
|
||||
|
@ -246,13 +247,13 @@ cp/except.o: cp/except.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) except.h toplev.
|
|||
cp/expr.o: cp/expr.c $(CXX_TREE_H) $(TM_H) $(RTL_H) flags.h $(EXPR_H) toplev.h \
|
||||
except.h $(TM_P_H)
|
||||
cp/pt.o: cp/pt.c $(CXX_TREE_H) $(TM_H) cp/decl.h cp/lex.h \
|
||||
toplev.h $(GGC_H) $(RTL_H) except.h tree-inline.h gt-cp-pt.h
|
||||
toplev.h $(RTL_H) except.h tree-inline.h gt-cp-pt.h
|
||||
cp/error.o: cp/error.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h flags.h real.h \
|
||||
$(LANGHOOKS_DEF_H)
|
||||
cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h $(GGC_H) diagnostic.h \
|
||||
cp/repo.o: cp/repo.c $(CXX_TREE_H) $(TM_H) toplev.h diagnostic.h \
|
||||
gt-cp-repo.h
|
||||
cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h \
|
||||
flags.h $(GGC_H) debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
|
||||
flags.h debug.h output.h $(RTL_H) $(TIMEVAR_H) $(EXPR_H) \
|
||||
tree-inline.h
|
||||
cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h
|
||||
cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \
|
||||
|
|
|
@ -35,7 +35,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "rtl.h"
|
||||
#include "toplev.h"
|
||||
#include "expr.h"
|
||||
#include "ggc.h"
|
||||
#include "diagnostic.h"
|
||||
|
||||
extern int inhibit_warnings;
|
||||
|
|
133
gcc/cp/class.c
133
gcc/cp/class.c
|
@ -33,7 +33,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "rtl.h"
|
||||
#include "output.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "lex.h"
|
||||
#include "target.h"
|
||||
|
||||
|
@ -125,8 +124,10 @@ static tree modify_all_vtables PARAMS ((tree, tree));
|
|||
static void determine_primary_base PARAMS ((tree));
|
||||
static void finish_struct_methods PARAMS ((tree));
|
||||
static void maybe_warn_about_overly_private_class PARAMS ((tree));
|
||||
static int field_decl_cmp PARAMS ((const tree *, const tree *));
|
||||
static int method_name_cmp PARAMS ((const tree *, const tree *));
|
||||
static int field_decl_cmp PARAMS ((const void *, const void *));
|
||||
static int resort_field_decl_cmp PARAMS ((const void *, const void *));
|
||||
static int method_name_cmp PARAMS ((const void *, const void *));
|
||||
static int resort_method_name_cmp PARAMS ((const void *, const void *));
|
||||
static void add_implicitly_declared_members PARAMS ((tree, int, int, int));
|
||||
static tree fixed_type_or_null PARAMS ((tree, int *, int *));
|
||||
static tree resolve_address_of_overloaded_function PARAMS ((tree, tree, int,
|
||||
|
@ -1449,7 +1450,8 @@ mark_primary_virtual_base (base_binfo, type)
|
|||
base, then BINFO has no primary base in this graph. Called from
|
||||
mark_primary_bases. DATA is the most derived type. */
|
||||
|
||||
static tree dfs_unshared_virtual_bases (binfo, data)
|
||||
static tree
|
||||
dfs_unshared_virtual_bases (binfo, data)
|
||||
tree binfo;
|
||||
void *data;
|
||||
{
|
||||
|
@ -1923,9 +1925,11 @@ maybe_warn_about_overly_private_class (t)
|
|||
/* Function to help qsort sort FIELD_DECLs by name order. */
|
||||
|
||||
static int
|
||||
field_decl_cmp (x, y)
|
||||
const tree *x, *y;
|
||||
field_decl_cmp (x_p, y_p)
|
||||
const void *x_p, *y_p;
|
||||
{
|
||||
const tree *const x = x_p;
|
||||
const tree *const y = y_p;
|
||||
if (DECL_NAME (*x) == DECL_NAME (*y))
|
||||
/* A nontype is "greater" than a type. */
|
||||
return DECL_DECLARES_TYPE_P (*y) - DECL_DECLARES_TYPE_P (*x);
|
||||
|
@ -1938,12 +1942,64 @@ field_decl_cmp (x, y)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static struct {
|
||||
gt_pointer_operator new_value;
|
||||
void *cookie;
|
||||
} resort_data;
|
||||
|
||||
/* This routine compares two fields like field_decl_cmp but using the
|
||||
pointer operator in resort_data. */
|
||||
|
||||
static int
|
||||
resort_field_decl_cmp (x_p, y_p)
|
||||
const void *x_p, *y_p;
|
||||
{
|
||||
const tree *const x = x_p;
|
||||
const tree *const y = y_p;
|
||||
|
||||
if (DECL_NAME (*x) == DECL_NAME (*y))
|
||||
/* A nontype is "greater" than a type. */
|
||||
return DECL_DECLARES_TYPE_P (*y) - DECL_DECLARES_TYPE_P (*x);
|
||||
if (DECL_NAME (*x) == NULL_TREE)
|
||||
return -1;
|
||||
if (DECL_NAME (*y) == NULL_TREE)
|
||||
return 1;
|
||||
{
|
||||
tree d1 = DECL_NAME (*x);
|
||||
tree d2 = DECL_NAME (*y);
|
||||
resort_data.new_value (&d1, resort_data.cookie);
|
||||
resort_data.new_value (&d2, resort_data.cookie);
|
||||
if (d1 < d2)
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Resort DECL_SORTED_FIELDS because pointers have been reordered. */
|
||||
|
||||
void
|
||||
resort_sorted_fields (obj, orig_obj, new_value, cookie)
|
||||
void *obj;
|
||||
void *orig_obj;
|
||||
gt_pointer_operator new_value;
|
||||
void *cookie;
|
||||
{
|
||||
tree sf = obj;
|
||||
resort_data.new_value = new_value;
|
||||
resort_data.cookie = cookie;
|
||||
qsort (&TREE_VEC_ELT (sf, 0), TREE_VEC_LENGTH (sf), sizeof (tree),
|
||||
resort_field_decl_cmp);
|
||||
}
|
||||
|
||||
/* Comparison function to compare two TYPE_METHOD_VEC entries by name. */
|
||||
|
||||
static int
|
||||
method_name_cmp (m1, m2)
|
||||
const tree *m1, *m2;
|
||||
method_name_cmp (m1_p, m2_p)
|
||||
const void *m1_p, *m2_p;
|
||||
{
|
||||
const tree *const m1 = m1_p;
|
||||
const tree *const m2 = m2_p;
|
||||
|
||||
if (*m1 == NULL_TREE && *m2 == NULL_TREE)
|
||||
return 0;
|
||||
if (*m1 == NULL_TREE)
|
||||
|
@ -1955,6 +2011,63 @@ method_name_cmp (m1, m2)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* This routine compares two fields like method_name_cmp but using the
|
||||
pointer operator in resort_field_decl_data. */
|
||||
|
||||
static int
|
||||
resort_method_name_cmp (m1_p, m2_p)
|
||||
const void *m1_p, *m2_p;
|
||||
{
|
||||
const tree *const m1 = m1_p;
|
||||
const tree *const m2 = m2_p;
|
||||
if (*m1 == NULL_TREE && *m2 == NULL_TREE)
|
||||
return 0;
|
||||
if (*m1 == NULL_TREE)
|
||||
return -1;
|
||||
if (*m2 == NULL_TREE)
|
||||
return 1;
|
||||
{
|
||||
tree d1 = DECL_NAME (OVL_CURRENT (*m1));
|
||||
tree d2 = DECL_NAME (OVL_CURRENT (*m2));
|
||||
resort_data.new_value (&d1, resort_data.cookie);
|
||||
resort_data.new_value (&d2, resort_data.cookie);
|
||||
if (d1 < d2)
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Resort TYPE_METHOD_VEC because pointers have been reordered. */
|
||||
|
||||
void
|
||||
resort_type_method_vec (obj, orig_obj, new_value, cookie)
|
||||
void *obj;
|
||||
void *orig_obj;
|
||||
gt_pointer_operator new_value;
|
||||
void *cookie;
|
||||
{
|
||||
tree method_vec = obj;
|
||||
int len = TREE_VEC_LENGTH (method_vec);
|
||||
int slot;
|
||||
|
||||
/* The type conversion ops have to live at the front of the vec, so we
|
||||
can't sort them. */
|
||||
for (slot = 2; slot < len; ++slot)
|
||||
{
|
||||
tree fn = TREE_VEC_ELT (method_vec, slot);
|
||||
|
||||
if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
|
||||
break;
|
||||
}
|
||||
if (len - slot > 1)
|
||||
{
|
||||
resort_data.new_value = new_value;
|
||||
resort_data.cookie = cookie;
|
||||
qsort (&TREE_VEC_ELT (method_vec, slot), len - slot, sizeof (tree),
|
||||
resort_method_name_cmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Warn about duplicate methods in fn_fields. Also compact method
|
||||
lists so that lookup can be made faster.
|
||||
|
||||
|
@ -2025,7 +2138,7 @@ finish_struct_methods (t)
|
|||
}
|
||||
if (len - slot > 1)
|
||||
qsort (&TREE_VEC_ELT (method_vec, slot), len-slot, sizeof (tree),
|
||||
(int (*)(const void *, const void *))method_name_cmp);
|
||||
method_name_cmp);
|
||||
}
|
||||
|
||||
/* Emit error when a duplicate definition of a type is seen. Patch up. */
|
||||
|
@ -5418,7 +5531,7 @@ finish_struct_1 (t)
|
|||
tree field_vec = make_tree_vec (n_fields);
|
||||
add_fields_to_vec (TYPE_FIELDS (t), field_vec, 0);
|
||||
qsort (&TREE_VEC_ELT (field_vec, 0), n_fields, sizeof (tree),
|
||||
(int (*)(const void *, const void *))field_decl_cmp);
|
||||
field_decl_cmp);
|
||||
if (! DECL_LANG_SPECIFIC (TYPE_MAIN_DECL (t)))
|
||||
retrofit_lang_decl (TYPE_MAIN_DECL (t));
|
||||
DECL_SORTED_FIELDS (TYPE_MAIN_DECL (t)) = field_vec;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Definitions for C++ parsing and type checking.
|
||||
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2003,
|
||||
2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
|
@ -23,6 +23,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#ifndef GCC_CP_TREE_H
|
||||
#define GCC_CP_TREE_H
|
||||
|
||||
#include "ggc.h"
|
||||
#include "function.h"
|
||||
#include "hashtab.h"
|
||||
#include "splay-tree.h"
|
||||
|
@ -1182,7 +1183,7 @@ struct lang_type_class GTY(())
|
|||
tree as_base;
|
||||
tree pure_virtuals;
|
||||
tree friend_classes;
|
||||
tree methods;
|
||||
tree GTY ((reorder ("resort_type_method_vec"))) methods;
|
||||
tree key_method;
|
||||
tree decl_list;
|
||||
tree template_info;
|
||||
|
@ -1782,7 +1783,7 @@ struct lang_decl_flags GTY(())
|
|||
tree GTY ((tag ("0"))) access;
|
||||
|
||||
/* For VAR_DECL in function, this is DECL_DISCRIMINATOR. */
|
||||
int discriminator;
|
||||
int GTY ((tag ("1"))) discriminator;
|
||||
|
||||
/* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is
|
||||
THUNK_VIRTUAL_OFFSET. */
|
||||
|
@ -1790,6 +1791,9 @@ struct lang_decl_flags GTY(())
|
|||
} GTY ((desc ("%1.u2sel"))) u2;
|
||||
};
|
||||
|
||||
/* sorted_fields is sorted based on a pointer, so we need to be able
|
||||
to resort it if pointers get rearranged. */
|
||||
|
||||
struct lang_decl GTY(())
|
||||
{
|
||||
struct lang_decl_flags decl_flags;
|
||||
|
@ -1827,7 +1831,8 @@ struct lang_decl GTY(())
|
|||
|
||||
union lang_decl_u3
|
||||
{
|
||||
tree GTY ((tag ("0"))) sorted_fields;
|
||||
tree GTY ((tag ("0"), reorder ("resort_sorted_fields")))
|
||||
sorted_fields;
|
||||
struct cp_token_cache * GTY ((tag ("2"))) pending_inline_info;
|
||||
struct language_function * GTY ((tag ("1")))
|
||||
saved_language_function;
|
||||
|
@ -3555,7 +3560,7 @@ extern void init_reswords PARAMS ((void));
|
|||
opname_tab[(int) MINUS_EXPR] == "-". */
|
||||
extern const char **opname_tab, **assignop_tab;
|
||||
|
||||
typedef struct operator_name_info_t
|
||||
typedef struct operator_name_info_t GTY(())
|
||||
{
|
||||
/* The IDENTIFIER_NODE for the operator. */
|
||||
tree identifier;
|
||||
|
@ -3568,9 +3573,11 @@ typedef struct operator_name_info_t
|
|||
} operator_name_info_t;
|
||||
|
||||
/* A mapping from tree codes to operator name information. */
|
||||
extern operator_name_info_t operator_name_info[];
|
||||
extern GTY(()) operator_name_info_t operator_name_info
|
||||
[(int) LAST_CPLUS_TREE_CODE];
|
||||
/* Similar, but for assignment operators. */
|
||||
extern operator_name_info_t assignment_operator_name_info[];
|
||||
extern GTY(()) operator_name_info_t assignment_operator_name_info
|
||||
[(int) LAST_CPLUS_TREE_CODE];
|
||||
|
||||
/* in call.c */
|
||||
extern bool check_dtor_name (tree, tree);
|
||||
|
@ -3611,10 +3618,14 @@ extern tree in_charge_arg_for_name (tree);
|
|||
|
||||
/* in class.c */
|
||||
extern tree build_base_path PARAMS ((enum tree_code, tree, tree, int));
|
||||
extern tree convert_to_base (tree, tree, bool);
|
||||
extern tree convert_to_base PARAMS ((tree, tree, bool));
|
||||
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 resort_sorted_fields
|
||||
PARAMS ((void *, void *, gt_pointer_operator, void *));
|
||||
extern void resort_type_method_vec
|
||||
PARAMS ((void *, void *, gt_pointer_operator, void *));
|
||||
extern void add_method PARAMS ((tree, tree, int));
|
||||
extern int currently_open_class PARAMS ((tree));
|
||||
extern tree currently_open_derived_class PARAMS ((tree));
|
||||
|
|
|
@ -44,7 +44,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "except.h"
|
||||
#include "toplev.h"
|
||||
#include "hashtab.h"
|
||||
#include "ggc.h"
|
||||
#include "tm_p.h"
|
||||
#include "target.h"
|
||||
#include "c-common.h"
|
||||
|
@ -2731,7 +2730,7 @@ pushtag (tree name, tree type, int globalize)
|
|||
|
||||
/* Counter used to create anonymous type names. */
|
||||
|
||||
static int anon_cnt = 0;
|
||||
static GTY(()) int anon_cnt;
|
||||
|
||||
/* Return an IDENTIFIER which can be used as a name for
|
||||
anonymous structs and unions. */
|
||||
|
|
|
@ -42,7 +42,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "output.h"
|
||||
#include "except.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "timevar.h"
|
||||
#include "cpplib.h"
|
||||
#include "target.h"
|
||||
|
@ -2589,6 +2588,9 @@ finish_file ()
|
|||
if (! global_bindings_p () || current_class_type || decl_namespace_list)
|
||||
return;
|
||||
|
||||
if (pch_file)
|
||||
c_common_write_pch ();
|
||||
|
||||
/* Otherwise, GDB can get confused, because in only knows
|
||||
about source for LINENO-1 lines. */
|
||||
lineno -= 1;
|
||||
|
|
102
gcc/cp/g++spec.c
102
gcc/cp/g++spec.c
|
@ -60,14 +60,16 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
/* If nonzero, the user gave us the `-v' flag. */
|
||||
int saw_verbose_flag = 0;
|
||||
|
||||
/* This will be 0 if we encounter a situation where we should not
|
||||
link in libstdc++. */
|
||||
int library = 1;
|
||||
/* This is a tristate:
|
||||
-1 means we should not link in libstdc++
|
||||
0 means we should link in libstdc++ if it is needed
|
||||
1 means libstdc++ is needed and should be linked in. */
|
||||
int library = 0;
|
||||
|
||||
/* The number of arguments being added to what's in argv, other than
|
||||
libraries. We use this to track the number of times we've inserted
|
||||
-xc++/-xnone. */
|
||||
int added = 2;
|
||||
int added = 0;
|
||||
|
||||
/* Used to track options that take arguments, so we don't go wrapping
|
||||
those with -xc++/-xnone. */
|
||||
|
@ -131,10 +133,10 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0
|
||||
|| strcmp (argv[i], "-nodefaultlibs") == 0))
|
||||
if (strcmp (argv[i], "-nostdlib") == 0
|
||||
|| strcmp (argv[i], "-nodefaultlibs") == 0)
|
||||
{
|
||||
library = 0;
|
||||
library = -1;
|
||||
}
|
||||
else if (strcmp (argv[i], "-lm") == 0
|
||||
|| strcmp (argv[i], "-lmath") == 0
|
||||
|
@ -152,31 +154,37 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
else if (strcmp (argv[i], "-pg") == 0 || strcmp (argv[i], "-p") == 0)
|
||||
saw_profile_flag++;
|
||||
else if (strcmp (argv[i], "-v") == 0)
|
||||
{
|
||||
saw_verbose_flag = 1;
|
||||
if (argc == 2)
|
||||
{
|
||||
/* If they only gave us `-v', don't try to link
|
||||
in libg++. */
|
||||
library = 0;
|
||||
}
|
||||
}
|
||||
saw_verbose_flag = 1;
|
||||
else if (strncmp (argv[i], "-x", 2) == 0)
|
||||
saw_speclang = 1;
|
||||
{
|
||||
if (library == 0)
|
||||
{
|
||||
const char * arg;
|
||||
if (argv[i][2] != '\0')
|
||||
arg = argv[i]+2;
|
||||
else if (argv[i+1] != NULL)
|
||||
arg = argv[i+1];
|
||||
else /* Error condition, message will be printed later. */
|
||||
arg = "";
|
||||
if (strcmp (arg, "c++") == 0
|
||||
|| strcmp (arg, "c++-cpp-output") == 0)
|
||||
library = 1;
|
||||
}
|
||||
saw_speclang = 1;
|
||||
}
|
||||
else if (((argv[i][2] == '\0'
|
||||
&& (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL)
|
||||
|| strcmp (argv[i], "-Xlinker") == 0
|
||||
|| strcmp (argv[i], "-Tdata") == 0))
|
||||
quote = argv[i];
|
||||
else if (library != 0 && ((argv[i][2] == '\0'
|
||||
&& (char *) strchr ("cSEM", argv[i][1]) != NULL)
|
||||
|| strcmp (argv[i], "-MM") == 0
|
||||
|| strcmp (argv[i], "-fsyntax-only") == 0))
|
||||
else if ((argv[i][2] == '\0'
|
||||
&& (char *) strchr ("cSEM", argv[i][1]) != NULL)
|
||||
|| strcmp (argv[i], "-MM") == 0
|
||||
|| strcmp (argv[i], "-fsyntax-only") == 0)
|
||||
{
|
||||
/* Don't specify libraries if we won't link, since that would
|
||||
cause a warning. */
|
||||
library = 0;
|
||||
added -= 2;
|
||||
library = -1;
|
||||
}
|
||||
else if (strcmp (argv[i], "-static-libgcc") == 0
|
||||
|| strcmp (argv[i], "-static") == 0)
|
||||
|
@ -195,16 +203,28 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* If the filename ends in .c or .i, put options around it.
|
||||
/* If the filename ends in .[chi], put options around it.
|
||||
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;
|
||||
}
|
||||
|
||||
/* If we don't know that this is a header file, we might
|
||||
need to be linking in the libraries. */
|
||||
if (library == 0)
|
||||
{
|
||||
if ((len <= 2 || strcmp (argv[i] + (len - 2), ".H") != 0)
|
||||
&& (len <= 2 || strcmp (argv[i] + (len - 2), ".h") != 0)
|
||||
&& (len <= 3 || strcmp (argv[i] + (len - 3), ".hh") != 0))
|
||||
library = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,7 +232,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
fatal ("argument to `%s' missing\n", quote);
|
||||
|
||||
/* If we know we don't have to do anything, bail now. */
|
||||
if (! added && ! library)
|
||||
if (! added && library <= 0)
|
||||
{
|
||||
free (args);
|
||||
return;
|
||||
|
@ -225,7 +245,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
#endif
|
||||
|
||||
/* Make sure to have room for the trailing NULL argument. */
|
||||
num_args = argc + added + need_math + shared_libgcc + 1;
|
||||
num_args = argc + added + need_math + shared_libgcc + (library > 0) + 1;
|
||||
arglist = (const char **) xmalloc (num_args * sizeof (char *));
|
||||
|
||||
i = 0;
|
||||
|
@ -241,27 +261,37 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
|
||||
/* Make sure -lstdc++ is before the math library, since libstdc++
|
||||
itself uses those math routines. */
|
||||
if (!saw_math && (args[i] & MATHLIB) && library)
|
||||
if (!saw_math && (args[i] & MATHLIB) && library > 0)
|
||||
{
|
||||
--j;
|
||||
saw_math = argv[i];
|
||||
}
|
||||
|
||||
if (!saw_libc && (args[i] & WITHLIBC) && library)
|
||||
if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
|
||||
{
|
||||
--j;
|
||||
saw_libc = argv[i];
|
||||
}
|
||||
|
||||
/* Wrap foo.c and foo.i files in a language specification to
|
||||
/* Wrap foo.[chi] files in a language specification to
|
||||
force the gcc compiler driver to run cc1plus on them. */
|
||||
if (args[i] & LANGSPEC)
|
||||
{
|
||||
int len = strlen (argv[i]);
|
||||
if (argv[i][len - 1] == 'i')
|
||||
arglist[j++] = "-xc++-cpp-output";
|
||||
else
|
||||
arglist[j++] = "-xc++";
|
||||
switch (argv[i][len - 1])
|
||||
{
|
||||
case 'c':
|
||||
arglist[j++] = "-xc++";
|
||||
break;
|
||||
case 'i':
|
||||
arglist[j++] = "-xc++-cpp-output";
|
||||
break;
|
||||
case 'h':
|
||||
arglist[j++] = "-xc++-header";
|
||||
break;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
arglist[j++] = argv[i];
|
||||
arglist[j] = "-xnone";
|
||||
}
|
||||
|
@ -271,7 +301,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
}
|
||||
|
||||
/* Add `-lstdc++' if we haven't already done so. */
|
||||
if (library)
|
||||
if (library > 0)
|
||||
{
|
||||
arglist[j++] = saw_profile_flag ? LIBSTDCXX_PROFILE : LIBSTDCXX;
|
||||
added_libraries++;
|
||||
|
@ -285,7 +315,7 @@ lang_specific_driver (in_argc, in_argv, in_added_libraries)
|
|||
}
|
||||
if (saw_math)
|
||||
arglist[j++] = saw_math;
|
||||
else if (library && need_math)
|
||||
else if (library > 0 && need_math)
|
||||
{
|
||||
arglist[j++] = saw_profile_flag ? MATH_LIBRARY_PROFILE : MATH_LIBRARY;
|
||||
added_libraries++;
|
||||
|
|
|
@ -34,7 +34,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "output.h"
|
||||
#include "except.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
|
||||
static void construct_virtual_base (tree, tree);
|
||||
static void expand_aggr_init_1 PARAMS ((tree, tree, tree, tree, int));
|
||||
|
|
|
@ -33,6 +33,19 @@ Boston, MA 02111-1307, USA. */
|
|||
{".c++", "@c++", 0},
|
||||
{".C", "@c++", 0},
|
||||
{".CPP", "@c++", 0},
|
||||
{".H", "@c++-header", 0},
|
||||
{".hh", "@c++-header", 0},
|
||||
{"@c++-header",
|
||||
"%{E|M|MM:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
|
||||
%(cpp_options) %2 %(cpp_debug_options)}\
|
||||
%{!E:%{!M:%{!MM:\
|
||||
%{save-temps:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
|
||||
%(cpp_options) %2 %b.ii \n}\
|
||||
cc1plus %{save-temps:-fpreprocessed %b.ii}\
|
||||
%{!save-temps:%(cpp_unique_options) %{!no-gcc:-D__GNUG__=%v1}}\
|
||||
%(cc1_options) %2 %{+e1*}\
|
||||
-o %g.s %{!o*:--output-pch=%i.pch} %W{o*:--output-pch=%*}%V}}}",
|
||||
CPLUSPLUS_CPP_SPEC},
|
||||
{"@c++",
|
||||
"%{E|M|MM:cc1plus -E %{!no-gcc:-D__GNUG__=%v1}\
|
||||
%(cpp_options) %2 %(cpp_debug_options)}\
|
||||
|
|
|
@ -36,7 +36,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "c-pragma.h"
|
||||
#include "toplev.h"
|
||||
#include "output.h"
|
||||
#include "ggc.h"
|
||||
#include "tm_p.h"
|
||||
#include "timevar.h"
|
||||
#include "diagnostic.h"
|
||||
|
@ -380,10 +379,7 @@ init_reswords ()
|
|||
int mask = ((flag_no_asm ? D_ASM : 0)
|
||||
| (flag_no_gnu_keywords ? D_EXT : 0));
|
||||
|
||||
/* It is not necessary to register ridpointers as a GC root, because
|
||||
all the trees it points to are permanently interned in the
|
||||
get_identifier hash anyway. */
|
||||
ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree));
|
||||
ridpointers = (tree *) ggc_calloc ((int) RID_MAX, sizeof (tree));
|
||||
for (i = 0; i < ARRAY_SIZE (reswords); i++)
|
||||
{
|
||||
id = get_identifier (reswords[i].word);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Handle the hair of processing (but not expanding) inline functions.
|
||||
Also manage function and variable name overloading.
|
||||
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000 Free Software Foundation, Inc.
|
||||
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Contributed by Michael Tiemann (tiemann@cygnus.com)
|
||||
|
||||
This file is part of GCC.
|
||||
|
@ -34,7 +34,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "output.h"
|
||||
#include "flags.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "tm_p.h"
|
||||
#include "target.h"
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "integrate.h"
|
||||
#include "toplev.h"
|
||||
#include "varray.h"
|
||||
#include "ggc.h"
|
||||
#include "params.h"
|
||||
#include "hashtab.h"
|
||||
#include "debug.h"
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "decl.h"
|
||||
#include "flags.h"
|
||||
#include "diagnostic.h"
|
||||
#include "ggc.h"
|
||||
#include "toplev.h"
|
||||
#include "output.h"
|
||||
|
||||
|
@ -213,8 +212,8 @@ typedef struct cp_lexer GTY (())
|
|||
|
||||
/* Prototypes. */
|
||||
|
||||
static cp_lexer *cp_lexer_new
|
||||
PARAMS ((bool));
|
||||
static cp_lexer *cp_lexer_new_main
|
||||
PARAMS ((void));
|
||||
static cp_lexer *cp_lexer_new_from_tokens
|
||||
PARAMS ((struct cp_token_cache *));
|
||||
static int cp_lexer_saving_tokens
|
||||
|
@ -292,29 +291,37 @@ static void cp_lexer_stop_debugging
|
|||
/* The stream to which debugging output should be written. */
|
||||
static FILE *cp_lexer_debug_stream;
|
||||
|
||||
/* Create a new C++ lexer. If MAIN_LEXER_P is true the new lexer is
|
||||
the main lexer -- i.e, the lexer that gets tokens from the
|
||||
preprocessor. Otherwise, it is a lexer that uses a cache of stored
|
||||
tokens. */
|
||||
/* Create a new main C++ lexer, the lexer that gets tokens from the
|
||||
preprocessor. */
|
||||
|
||||
static cp_lexer *
|
||||
cp_lexer_new (bool main_lexer_p)
|
||||
cp_lexer_new_main (void)
|
||||
{
|
||||
cp_lexer *lexer;
|
||||
cp_token first_token;
|
||||
|
||||
/* It's possible that lexing the first token will load a PCH file,
|
||||
which is a GC collection point. So we have to grab the first
|
||||
token before allocating any memory. */
|
||||
cp_lexer_get_preprocessor_token (NULL, &first_token);
|
||||
cpp_get_callbacks (parse_in)->valid_pch = NULL;
|
||||
|
||||
/* Allocate the memory. */
|
||||
lexer = (cp_lexer *) ggc_alloc_cleared (sizeof (cp_lexer));
|
||||
|
||||
/* Create the circular buffer. */
|
||||
lexer->buffer = ((cp_token *)
|
||||
ggc_alloc (CP_TOKEN_BUFFER_SIZE * sizeof (cp_token)));
|
||||
ggc_calloc (CP_TOKEN_BUFFER_SIZE, sizeof (cp_token)));
|
||||
lexer->buffer_end = lexer->buffer + CP_TOKEN_BUFFER_SIZE;
|
||||
|
||||
/* There are no tokens in the buffer. */
|
||||
lexer->last_token = lexer->buffer;
|
||||
/* There is one token in the buffer. */
|
||||
lexer->last_token = lexer->buffer + 1;
|
||||
lexer->first_token = lexer->buffer;
|
||||
lexer->next_token = lexer->buffer;
|
||||
memcpy (lexer->buffer, &first_token, sizeof (cp_token));
|
||||
|
||||
/* This lexer obtains more tokens by calling c_lex. */
|
||||
lexer->main_lexer_p = main_lexer_p;
|
||||
lexer->main_lexer_p = true;
|
||||
|
||||
/* Create the SAVED_TOKENS stack. */
|
||||
VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
|
||||
|
@ -339,15 +346,14 @@ cp_lexer_new_from_tokens (cp_token_cache *tokens)
|
|||
cp_token_block *block;
|
||||
ptrdiff_t num_tokens;
|
||||
|
||||
/* Create the lexer. */
|
||||
lexer = cp_lexer_new (/*main_lexer_p=*/false);
|
||||
/* Allocate the memory. */
|
||||
lexer = (cp_lexer *) ggc_alloc_cleared (sizeof (cp_lexer));
|
||||
|
||||
/* Create a new buffer, appropriately sized. */
|
||||
num_tokens = 0;
|
||||
for (block = tokens->first; block != NULL; block = block->next)
|
||||
num_tokens += block->num_tokens;
|
||||
lexer->buffer = ((cp_token *)
|
||||
ggc_alloc (num_tokens * sizeof (cp_token)));
|
||||
lexer->buffer = ((cp_token *) ggc_alloc (num_tokens * sizeof (cp_token)));
|
||||
lexer->buffer_end = lexer->buffer + num_tokens;
|
||||
|
||||
/* Install the tokens. */
|
||||
|
@ -365,6 +371,18 @@ cp_lexer_new_from_tokens (cp_token_cache *tokens)
|
|||
/* The buffer is full. */
|
||||
lexer->last_token = lexer->first_token;
|
||||
|
||||
/* This lexer doesn't obtain more tokens. */
|
||||
lexer->main_lexer_p = false;
|
||||
|
||||
/* Create the SAVED_TOKENS stack. */
|
||||
VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
|
||||
|
||||
/* Create the STRINGS array. */
|
||||
VARRAY_TREE_INIT (lexer->string_tokens, 32, "strings");
|
||||
|
||||
/* Assume we are not debugging. */
|
||||
lexer->debugging_p = false;
|
||||
|
||||
return lexer;
|
||||
}
|
||||
|
||||
|
@ -610,7 +628,7 @@ cp_lexer_get_preprocessor_token (lexer, token)
|
|||
bool done;
|
||||
|
||||
/* If this not the main lexer, return a terminating CPP_EOF token. */
|
||||
if (!lexer->main_lexer_p)
|
||||
if (lexer != NULL && !lexer->main_lexer_p)
|
||||
{
|
||||
token->type = CPP_EOF;
|
||||
token->line_number = 0;
|
||||
|
@ -2472,9 +2490,14 @@ static cp_parser *
|
|||
cp_parser_new ()
|
||||
{
|
||||
cp_parser *parser;
|
||||
cp_lexer *lexer;
|
||||
|
||||
/* cp_lexer_new_main is called before calling ggc_alloc because
|
||||
cp_lexer_new_main might load a PCH file. */
|
||||
lexer = cp_lexer_new_main ();
|
||||
|
||||
parser = (cp_parser *) ggc_alloc_cleared (sizeof (cp_parser));
|
||||
parser->lexer = cp_lexer_new (/*main_lexer_p=*/true);
|
||||
parser->lexer = lexer;
|
||||
parser->context = cp_parser_context_new (NULL);
|
||||
|
||||
/* For now, we always accept GNU extensions. */
|
||||
|
@ -14422,9 +14445,7 @@ cp_parser_late_parsing_for_member (parser, member_function)
|
|||
|
||||
/* Set the current source position to be the location of the first
|
||||
token in the saved inline body. */
|
||||
cp_lexer_set_source_position_from_token
|
||||
(parser->lexer,
|
||||
cp_lexer_peek_token (parser->lexer));
|
||||
(void) cp_lexer_peek_token (parser->lexer);
|
||||
|
||||
/* Let the front end know that we going to be defining this
|
||||
function. */
|
||||
|
@ -14477,8 +14498,7 @@ cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
|
|||
|
||||
/* Set the current source position to be the location of the
|
||||
first token in the default argument. */
|
||||
cp_lexer_set_source_position_from_token
|
||||
(parser->lexer, cp_lexer_peek_token (parser->lexer));
|
||||
(void) cp_lexer_peek_token (parser->lexer);
|
||||
|
||||
/* Local variable names (and the `this' keyword) may not appear
|
||||
in a default argument. */
|
||||
|
@ -14996,6 +15016,8 @@ yyparse ()
|
|||
the_parser = cp_parser_new ();
|
||||
error_occurred = cp_parser_translation_unit (the_parser);
|
||||
the_parser = NULL;
|
||||
|
||||
finish_file ();
|
||||
|
||||
return error_occurred;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "except.h"
|
||||
#include "toplev.h"
|
||||
#include "rtl.h"
|
||||
#include "ggc.h"
|
||||
#include "timevar.h"
|
||||
|
||||
/* The type of functions taking a tree, and some additional data, and
|
||||
|
|
|
@ -35,7 +35,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "input.h"
|
||||
#include "obstack.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "diagnostic.h"
|
||||
|
||||
static tree repo_get_id (tree);
|
||||
|
|
|
@ -33,7 +33,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "flags.h"
|
||||
#include "rtl.h"
|
||||
#include "output.h"
|
||||
#include "ggc.h"
|
||||
#include "toplev.h"
|
||||
#include "stack.h"
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
building RTL. These routines are used both during actual parsing
|
||||
and during the instantiation of template functions.
|
||||
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
Written by Mark Mitchell (mmitchell@usa.net) based on code found
|
||||
formerly in parse.y and pt.c.
|
||||
|
||||
|
@ -35,7 +35,6 @@
|
|||
#include "lex.h"
|
||||
#include "toplev.h"
|
||||
#include "flags.h"
|
||||
#include "ggc.h"
|
||||
#include "rtl.h"
|
||||
#include "expr.h"
|
||||
#include "output.h"
|
||||
|
@ -1628,8 +1627,6 @@ finish_translation_unit ()
|
|||
|
||||
/* Do file scope __FUNCTION__ et al. */
|
||||
finish_fname_decls ();
|
||||
|
||||
finish_file ();
|
||||
}
|
||||
|
||||
/* Finish a template type parameter, specified as AGGR IDENTIFIER.
|
||||
|
|
|
@ -30,7 +30,6 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "real.h"
|
||||
#include "rtl.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "insn-config.h"
|
||||
#include "integrate.h"
|
||||
#include "tree-inline.h"
|
||||
|
|
115
gcc/cppfiles.c
115
gcc/cppfiles.c
|
@ -22,6 +22,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include <dirent.h>
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "cpplib.h"
|
||||
|
@ -87,6 +88,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
/* This structure is used for the table of all includes. */
|
||||
struct include_file {
|
||||
const char *name; /* actual path name of file */
|
||||
const char *header_name; /* the original header found */
|
||||
const cpp_hashnode *cmacro; /* macro, if any, preventing reinclusion. */
|
||||
const struct search_path *foundhere;
|
||||
/* location in search path where file was
|
||||
|
@ -98,6 +100,13 @@ struct include_file {
|
|||
unsigned short include_count; /* number of times file has been read */
|
||||
unsigned short refcnt; /* number of stacked buffers using this file */
|
||||
unsigned char mapped; /* file buffer is mmapped */
|
||||
unsigned char pch; /* 0: file not known to be a PCH.
|
||||
1: file is a PCH
|
||||
(on return from find_include_file).
|
||||
2: file is not and never will be a valid
|
||||
precompiled header.
|
||||
3: file is always a valid precompiled
|
||||
header. */
|
||||
};
|
||||
|
||||
/* Variable length record files on VMS will have a stat size that includes
|
||||
|
@ -118,6 +127,7 @@ struct include_file {
|
|||
((inc)->cmacro && ((inc)->cmacro == NEVER_REREAD \
|
||||
|| (inc)->cmacro->type == NT_MACRO))
|
||||
#define NO_INCLUDE_PATH ((struct include_file *) -1)
|
||||
#define INCLUDE_PCH_P(F) (((F)->pch & 1) != 0)
|
||||
|
||||
static struct file_name_map *read_name_map
|
||||
PARAMS ((cpp_reader *, const char *));
|
||||
|
@ -130,6 +140,11 @@ static struct include_file *
|
|||
find_include_file PARAMS ((cpp_reader *, const cpp_token *,
|
||||
enum include_type));
|
||||
static struct include_file *open_file PARAMS ((cpp_reader *, const char *));
|
||||
static struct include_file *validate_pch PARAMS ((cpp_reader *,
|
||||
const char *,
|
||||
const char *));
|
||||
static struct include_file *open_file_pch PARAMS ((cpp_reader *,
|
||||
const char *));
|
||||
static int read_include_file PARAMS ((cpp_reader *, struct include_file *));
|
||||
static bool stack_include_file PARAMS ((cpp_reader *, struct include_file *));
|
||||
static void purge_cache PARAMS ((struct include_file *));
|
||||
|
@ -212,6 +227,7 @@ find_or_create_entry (pfile, fname)
|
|||
{
|
||||
file = xcnew (struct include_file);
|
||||
file->name = name;
|
||||
file->header_name = name;
|
||||
file->err_no = errno;
|
||||
node = splay_tree_insert (pfile->all_include_files,
|
||||
(splay_tree_key) file->name,
|
||||
|
@ -306,6 +322,89 @@ open_file (pfile, filename)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct include_file *
|
||||
validate_pch (pfile, filename, pchname)
|
||||
cpp_reader *pfile;
|
||||
const char *filename;
|
||||
const char *pchname;
|
||||
{
|
||||
struct include_file * file;
|
||||
|
||||
file = open_file (pfile, pchname);
|
||||
if (file == NULL)
|
||||
return NULL;
|
||||
if ((file->pch & 2) == 0)
|
||||
file->pch = pfile->cb.valid_pch (pfile, pchname, file->fd);
|
||||
if (INCLUDE_PCH_P (file))
|
||||
{
|
||||
file->header_name = _cpp_simplify_pathname (xstrdup (filename));
|
||||
return file;
|
||||
}
|
||||
close (file->fd);
|
||||
file->fd = -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Like open_file, but also look for a precompiled header if (a) one exists
|
||||
and (b) it is valid. */
|
||||
static struct include_file *
|
||||
open_file_pch (pfile, filename)
|
||||
cpp_reader *pfile;
|
||||
const char *filename;
|
||||
{
|
||||
if (filename[0] != '\0'
|
||||
&& pfile->cb.valid_pch != NULL)
|
||||
{
|
||||
size_t namelen = strlen (filename);
|
||||
char *pchname = alloca (namelen + 5);
|
||||
struct include_file * file;
|
||||
splay_tree_node nd;
|
||||
|
||||
memcpy (pchname, filename, namelen);
|
||||
memcpy (pchname + namelen, ".pch", 5);
|
||||
|
||||
nd = find_or_create_entry (pfile, pchname);
|
||||
file = (struct include_file *) nd->value;
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
if (stat (file->name, &file->st) == 0 && S_ISDIR (file->st.st_mode))
|
||||
{
|
||||
DIR * thedir;
|
||||
struct dirent *d;
|
||||
size_t subname_len = namelen + 64;
|
||||
char *subname = xmalloc (subname_len);
|
||||
|
||||
thedir = opendir (pchname);
|
||||
if (thedir == NULL)
|
||||
return NULL;
|
||||
memcpy (subname, pchname, namelen + 4);
|
||||
subname[namelen+4] = '/';
|
||||
while ((d = readdir (thedir)) != NULL)
|
||||
{
|
||||
if (strlen (d->d_name) + namelen + 7 > subname_len)
|
||||
{
|
||||
subname_len = strlen (d->d_name) + namelen + 64;
|
||||
subname = xrealloc (subname, subname_len);
|
||||
}
|
||||
strcpy (subname + namelen + 5, d->d_name);
|
||||
file = validate_pch (pfile, filename, subname);
|
||||
if (file)
|
||||
break;
|
||||
}
|
||||
closedir (thedir);
|
||||
free (subname);
|
||||
}
|
||||
else
|
||||
file = validate_pch (pfile, filename, pchname);
|
||||
if (file)
|
||||
return file;
|
||||
}
|
||||
}
|
||||
return open_file (pfile, filename);
|
||||
}
|
||||
|
||||
/* Place the file referenced by INC into a new buffer on the buffer
|
||||
stack, unless there are errors, or the file is not re-included
|
||||
because of e.g. multiple-include guards. Returns true if a buffer
|
||||
|
@ -332,6 +431,15 @@ stack_include_file (pfile, inc)
|
|||
deps_add_dep (pfile->deps, inc->name);
|
||||
}
|
||||
|
||||
/* PCH files get dealt with immediately. */
|
||||
if (INCLUDE_PCH_P (inc))
|
||||
{
|
||||
pfile->cb.read_pch (pfile, inc->name, inc->fd, inc->header_name);
|
||||
close (inc->fd);
|
||||
inc->fd = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Not in cache? */
|
||||
if (! inc->buffer)
|
||||
{
|
||||
|
@ -579,7 +687,7 @@ find_include_file (pfile, header, type)
|
|||
char *name, *n;
|
||||
|
||||
if (IS_ABSOLUTE_PATHNAME (fname))
|
||||
return open_file (pfile, fname);
|
||||
return open_file_pch (pfile, fname);
|
||||
|
||||
/* For #include_next, skip in the search path past the dir in which
|
||||
the current file was found, but if it was found via an absolute
|
||||
|
@ -615,7 +723,7 @@ find_include_file (pfile, header, type)
|
|||
else
|
||||
n = name;
|
||||
|
||||
file = open_file (pfile, n);
|
||||
file = open_file_pch (pfile, n);
|
||||
if (file)
|
||||
{
|
||||
file->foundhere = path;
|
||||
|
@ -757,6 +865,9 @@ _cpp_read_file (pfile, fname)
|
|||
cpp_reader *pfile;
|
||||
const char *fname;
|
||||
{
|
||||
/* This uses open_file, because we don't allow a PCH to be used as
|
||||
the toplevel compilation (that would prevent re-compiling an
|
||||
existing PCH without deleting it first). */
|
||||
struct include_file *f = open_file (pfile, fname);
|
||||
|
||||
if (f == NULL)
|
||||
|
|
|
@ -449,6 +449,10 @@ struct cpp_reader
|
|||
/* Used to save the original line number during traditional
|
||||
preprocessing. */
|
||||
unsigned int saved_line;
|
||||
|
||||
/* A saved list of the defined macros, for dependency checking
|
||||
of precompiled headers. */
|
||||
struct cpp_savedstate *savedstate;
|
||||
};
|
||||
|
||||
/* Character classes. Based on the more primitive macros in safe-ctype.h.
|
||||
|
@ -542,6 +546,8 @@ extern void _cpp_maybe_push_include_file PARAMS ((cpp_reader *));
|
|||
extern int _cpp_test_assertion PARAMS ((cpp_reader *, unsigned int *));
|
||||
extern int _cpp_handle_directive PARAMS ((cpp_reader *, int));
|
||||
extern void _cpp_define_builtin PARAMS ((cpp_reader *, const char *));
|
||||
extern char ** _cpp_save_pragma_names PARAMS ((cpp_reader *));
|
||||
extern void _cpp_restore_pragma_names PARAMS ((cpp_reader *, char **));
|
||||
extern void _cpp_do__Pragma PARAMS ((cpp_reader *));
|
||||
extern void _cpp_init_directives PARAMS ((cpp_reader *));
|
||||
extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
|
||||
|
|
84
gcc/cpplib.c
84
gcc/cpplib.c
|
@ -121,6 +121,11 @@ static struct pragma_entry *lookup_pragma_entry
|
|||
static struct pragma_entry *insert_pragma_entry
|
||||
PARAMS ((cpp_reader *, struct pragma_entry **, const cpp_hashnode *,
|
||||
pragma_cb));
|
||||
static int count_registered_pragmas PARAMS ((struct pragma_entry *));
|
||||
static char ** save_registered_pragmas
|
||||
PARAMS ((struct pragma_entry *, char **));
|
||||
static char ** restore_registered_pragmas
|
||||
PARAMS ((cpp_reader *, struct pragma_entry *, char **));
|
||||
static void do_pragma_once PARAMS ((cpp_reader *));
|
||||
static void do_pragma_poison PARAMS ((cpp_reader *));
|
||||
static void do_pragma_system_header PARAMS ((cpp_reader *));
|
||||
|
@ -1085,6 +1090,85 @@ _cpp_init_internal_pragmas (pfile)
|
|||
cpp_register_pragma (pfile, "GCC", "dependency", do_pragma_dependency);
|
||||
}
|
||||
|
||||
/* Return the number of registered pragmas in PE. */
|
||||
|
||||
static int
|
||||
count_registered_pragmas (pe)
|
||||
struct pragma_entry *pe;
|
||||
{
|
||||
int ct = 0;
|
||||
for (; pe != NULL; pe = pe->next)
|
||||
{
|
||||
if (pe->is_nspace)
|
||||
ct += count_registered_pragmas (pe->u.space);
|
||||
ct++;
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
/* Save into SD the names of the registered pragmas referenced by PE,
|
||||
and return a pointer to the next free space in SD. */
|
||||
|
||||
static char **
|
||||
save_registered_pragmas (pe, sd)
|
||||
struct pragma_entry *pe;
|
||||
char **sd;
|
||||
{
|
||||
for (; pe != NULL; pe = pe->next)
|
||||
{
|
||||
if (pe->is_nspace)
|
||||
sd = save_registered_pragmas (pe->u.space, sd);
|
||||
*sd++ = xmemdup (HT_STR (&pe->pragma->ident),
|
||||
HT_LEN (&pe->pragma->ident),
|
||||
HT_LEN (&pe->pragma->ident) + 1);
|
||||
}
|
||||
return sd;
|
||||
}
|
||||
|
||||
/* Return a newly-allocated array which saves the names of the
|
||||
registered pragmas. */
|
||||
|
||||
char **
|
||||
_cpp_save_pragma_names (pfile)
|
||||
cpp_reader *pfile;
|
||||
{
|
||||
int ct = count_registered_pragmas (pfile->pragmas);
|
||||
char **result = xnewvec (char *, ct);
|
||||
(void) save_registered_pragmas (pfile->pragmas, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Restore from SD the names of the registered pragmas referenced by PE,
|
||||
and return a pointer to the next unused name in SD. */
|
||||
|
||||
static char **
|
||||
restore_registered_pragmas (pfile, pe, sd)
|
||||
cpp_reader *pfile;
|
||||
struct pragma_entry *pe;
|
||||
char **sd;
|
||||
{
|
||||
for (; pe != NULL; pe = pe->next)
|
||||
{
|
||||
if (pe->is_nspace)
|
||||
sd = restore_registered_pragmas (pfile, pe->u.space, sd);
|
||||
pe->pragma = cpp_lookup (pfile, U *sd, strlen (*sd));
|
||||
free (*sd);
|
||||
sd++;
|
||||
}
|
||||
return sd;
|
||||
}
|
||||
|
||||
/* Restore the names of the registered pragmas from SAVED. */
|
||||
|
||||
void
|
||||
_cpp_restore_pragma_names (pfile, saved)
|
||||
cpp_reader *pfile;
|
||||
char **saved;
|
||||
{
|
||||
(void) restore_registered_pragmas (pfile, pfile->pragmas, saved);
|
||||
free (saved);
|
||||
}
|
||||
|
||||
/* Pragmata handling. We handle some, and pass the rest on to the
|
||||
front end. C99 defines three pragmas and says that no macro
|
||||
expansion is to be performed on them; whether or not macro
|
||||
|
|
35
gcc/cpplib.h
35
gcc/cpplib.h
|
@ -400,6 +400,12 @@ struct cpp_options
|
|||
|
||||
/* Nonzero means __STDC__ should have the value 0 in system headers. */
|
||||
unsigned char stdc_0_in_system_headers;
|
||||
|
||||
/* True to warn about precompiled header files we couldn't use. */
|
||||
bool warn_invalid_pch;
|
||||
|
||||
/* True if dependencies should be restored from a precompiled header. */
|
||||
bool restore_pch_deps;
|
||||
};
|
||||
|
||||
/* Call backs. */
|
||||
|
@ -417,6 +423,8 @@ struct cpp_callbacks
|
|||
/* Called when the client has a chance to properly register
|
||||
built-ins with cpp_define() and cpp_assert(). */
|
||||
void (*register_builtins) PARAMS ((cpp_reader *));
|
||||
int (*valid_pch) PARAMS ((cpp_reader *, const char *, int));
|
||||
void (*read_pch) PARAMS ((cpp_reader *, const char *, int, const char *));
|
||||
};
|
||||
|
||||
/* Name under which this program was invoked. */
|
||||
|
@ -472,7 +480,7 @@ enum builtin_type
|
|||
/* The common part of an identifier node shared amongst all 3 C front
|
||||
ends. Also used to store CPP identifiers, which are a superset of
|
||||
identifiers in the grammatical sense. */
|
||||
struct cpp_hashnode
|
||||
struct cpp_hashnode GTY(())
|
||||
{
|
||||
struct ht_identifier ident;
|
||||
unsigned int is_directive : 1;
|
||||
|
@ -485,11 +493,15 @@ struct cpp_hashnode
|
|||
|
||||
union _cpp_hashnode_value
|
||||
{
|
||||
cpp_macro *macro; /* If a macro. */
|
||||
struct answer *answers; /* Answers to an assertion. */
|
||||
enum builtin_type builtin; /* Code for a builtin macro. */
|
||||
unsigned short arg_index; /* Macro argument index. */
|
||||
} value;
|
||||
/* If a macro. */
|
||||
cpp_macro * GTY((skip (""))) macro;
|
||||
/* Answers to an assertion. */
|
||||
struct answer * GTY ((skip (""))) answers;
|
||||
/* Code for a builtin macro. */
|
||||
enum builtin_type GTY ((tag ("1"))) builtin;
|
||||
/* Macro argument index. */
|
||||
unsigned short GTY ((tag ("0"))) arg_index;
|
||||
} GTY ((desc ("0"))) value;
|
||||
};
|
||||
|
||||
/* Call this first to get a handle to pass to other functions. */
|
||||
|
@ -722,6 +734,17 @@ extern unsigned char *cpp_quote_string PARAMS ((unsigned char *,
|
|||
extern int cpp_included PARAMS ((cpp_reader *, const char *));
|
||||
extern void cpp_make_system_header PARAMS ((cpp_reader *, int, int));
|
||||
|
||||
/* In cpppch.c */
|
||||
struct save_macro_data;
|
||||
extern int cpp_save_state PARAMS ((cpp_reader *, FILE *));
|
||||
extern int cpp_write_pch_deps PARAMS ((cpp_reader *, FILE *));
|
||||
extern int cpp_write_pch_state PARAMS ((cpp_reader *, FILE *));
|
||||
extern int cpp_valid_state PARAMS ((cpp_reader *, const char *, int));
|
||||
extern void cpp_prepare_state PARAMS ((cpp_reader *,
|
||||
struct save_macro_data **));
|
||||
extern int cpp_read_state PARAMS ((cpp_reader *, const char *, FILE *,
|
||||
struct save_macro_data *));
|
||||
|
||||
/* In cppmain.c */
|
||||
extern void cpp_preprocess_file PARAMS ((cpp_reader *, const char *, FILE *));
|
||||
|
||||
|
|
684
gcc/cpppch.c
Normal file
684
gcc/cpppch.c
Normal file
|
@ -0,0 +1,684 @@
|
|||
/* Part of CPP library. (Precompiled header reading/writing.)
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; 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 "coretypes.h"
|
||||
#include "cpplib.h"
|
||||
#include "cpphash.h"
|
||||
#include "intl.h"
|
||||
#include "hashtab.h"
|
||||
#include "mkdeps.h"
|
||||
|
||||
static int write_macdef PARAMS ((cpp_reader *, cpp_hashnode *, void *));
|
||||
static int save_idents PARAMS ((cpp_reader *, cpp_hashnode *, void *));
|
||||
static hashval_t hashmem PARAMS ((const void *, size_t));
|
||||
static hashval_t cpp_string_hash PARAMS ((const void *));
|
||||
static int cpp_string_eq PARAMS ((const void *, const void *));
|
||||
static int count_defs PARAMS ((cpp_reader *, cpp_hashnode *, void *));
|
||||
static int write_defs PARAMS ((cpp_reader *, cpp_hashnode *, void *));
|
||||
static int save_macros PARAMS ((cpp_reader *, cpp_hashnode *, void *));
|
||||
static int reset_ht PARAMS ((cpp_reader *, cpp_hashnode *, void *));
|
||||
|
||||
/* This structure represents a macro definition on disk. */
|
||||
struct macrodef_struct
|
||||
{
|
||||
unsigned int definition_length;
|
||||
unsigned short name_length;
|
||||
unsigned short flags;
|
||||
};
|
||||
|
||||
/* This is how we write out a macro definition.
|
||||
Suitable for being called by cpp_forall_identifiers. */
|
||||
|
||||
static int
|
||||
write_macdef (pfile, hn, file_p)
|
||||
cpp_reader *pfile;
|
||||
cpp_hashnode *hn;
|
||||
void *file_p;
|
||||
{
|
||||
FILE *f = (FILE *) file_p;
|
||||
switch (hn->type)
|
||||
{
|
||||
case NT_VOID:
|
||||
if (! (hn->flags & NODE_POISONED))
|
||||
return 1;
|
||||
|
||||
case NT_MACRO:
|
||||
if ((hn->flags & NODE_BUILTIN))
|
||||
return 1;
|
||||
|
||||
{
|
||||
struct macrodef_struct s;
|
||||
const unsigned char *defn;
|
||||
|
||||
s.name_length = NODE_LEN (hn);
|
||||
s.flags = hn->flags & NODE_POISONED;
|
||||
|
||||
if (hn->type == NT_MACRO)
|
||||
{
|
||||
defn = cpp_macro_definition (pfile, hn);
|
||||
s.definition_length = ustrlen (defn);
|
||||
}
|
||||
else
|
||||
{
|
||||
defn = NODE_NAME (hn);
|
||||
s.definition_length = s.name_length;
|
||||
}
|
||||
|
||||
if (fwrite (&s, sizeof (s), 1, f) != 1
|
||||
|| fwrite (defn, 1, s.definition_length, f) != s.definition_length)
|
||||
{
|
||||
cpp_errno (pfile, DL_ERROR, "while writing precompiled header");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
case NT_ASSERTION:
|
||||
/* Not currently implemented. */
|
||||
return 1;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* This structure records the names of the defined macros.
|
||||
It's also used as a callback structure for size_initial_idents
|
||||
and save_idents. */
|
||||
|
||||
struct cpp_savedstate
|
||||
{
|
||||
/* A hash table of the defined identifiers. */
|
||||
htab_t definedhash;
|
||||
/* The size of the definitions of those identifiers (the size of
|
||||
'definedstrs'). */
|
||||
size_t hashsize;
|
||||
/* Space for the next definition. Definitions are null-terminated
|
||||
strings. */
|
||||
unsigned char *definedstrs;
|
||||
};
|
||||
|
||||
/* Save this identifier into the state: put it in the hash table,
|
||||
put the definition in 'definedstrs'. */
|
||||
|
||||
static int
|
||||
save_idents (pfile, hn, ss_p)
|
||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||
cpp_hashnode *hn;
|
||||
void *ss_p;
|
||||
{
|
||||
struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
|
||||
|
||||
if (hn->type != NT_VOID)
|
||||
{
|
||||
struct cpp_string news;
|
||||
void **slot;
|
||||
|
||||
news.len = NODE_LEN (hn);
|
||||
news.text= NODE_NAME (hn);
|
||||
slot = htab_find_slot (ss->definedhash, &news, INSERT);
|
||||
if (*slot == NULL)
|
||||
{
|
||||
struct cpp_string *sp;
|
||||
unsigned char *text;
|
||||
|
||||
sp = xmalloc (sizeof (struct cpp_string));
|
||||
*slot = sp;
|
||||
|
||||
sp->len = NODE_LEN (hn);
|
||||
sp->text = text = xmalloc (NODE_LEN (hn));
|
||||
memcpy (text, NODE_NAME (hn), NODE_LEN (hn));
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Hash some memory in a generic way. */
|
||||
|
||||
static hashval_t
|
||||
hashmem (p_p, sz)
|
||||
const void *p_p;
|
||||
size_t sz;
|
||||
{
|
||||
const unsigned char *p = (const unsigned char *)p_p;
|
||||
size_t i;
|
||||
hashval_t h;
|
||||
|
||||
h = 0;
|
||||
for (i = 0; i < sz; i++)
|
||||
h = h * 67 - (*p++ - 113);
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Hash a cpp string for the hashtable machinery. */
|
||||
|
||||
static hashval_t
|
||||
cpp_string_hash (a_p)
|
||||
const void *a_p;
|
||||
{
|
||||
const struct cpp_string *a = (const struct cpp_string *) a_p;
|
||||
return hashmem (a->text, a->len);
|
||||
}
|
||||
|
||||
/* Compare two cpp strings for the hashtable machinery. */
|
||||
|
||||
static int
|
||||
cpp_string_eq (a_p, b_p)
|
||||
const void *a_p;
|
||||
const void *b_p;
|
||||
{
|
||||
const struct cpp_string *a = (const struct cpp_string *) a_p;
|
||||
const struct cpp_string *b = (const struct cpp_string *) b_p;
|
||||
return (a->len == b->len
|
||||
&& memcmp (a->text, b->text, a->len) == 0);
|
||||
}
|
||||
|
||||
/* Save the current definitions of the cpp_reader for dependency
|
||||
checking purposes. When writing a precompiled header, this should
|
||||
be called at the same point in the compilation as cpp_valid_state
|
||||
would be called when reading the precompiled header back in. */
|
||||
|
||||
int
|
||||
cpp_save_state (r, f)
|
||||
cpp_reader *r;
|
||||
FILE *f;
|
||||
{
|
||||
/* Save the list of non-void identifiers for the dependency checking. */
|
||||
r->savedstate = xmalloc (sizeof (struct cpp_savedstate));
|
||||
r->savedstate->definedhash = htab_create (100, cpp_string_hash,
|
||||
cpp_string_eq, NULL);
|
||||
cpp_forall_identifiers (r, save_idents, r->savedstate);
|
||||
|
||||
/* Write out the list of defined identifiers. */
|
||||
cpp_forall_identifiers (r, write_macdef, f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate the 'hashsize' field of the saved state. */
|
||||
|
||||
static int
|
||||
count_defs (pfile, hn, ss_p)
|
||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||
cpp_hashnode *hn;
|
||||
void *ss_p;
|
||||
{
|
||||
struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
|
||||
|
||||
switch (hn->type)
|
||||
{
|
||||
case NT_MACRO:
|
||||
if (hn->flags & NODE_BUILTIN)
|
||||
return 1;
|
||||
|
||||
/* else fall through. */
|
||||
|
||||
case NT_VOID:
|
||||
{
|
||||
struct cpp_string news;
|
||||
void **slot;
|
||||
|
||||
news.len = NODE_LEN (hn);
|
||||
news.text = NODE_NAME (hn);
|
||||
slot = htab_find (ss->definedhash, &news);
|
||||
if (slot == NULL)
|
||||
ss->hashsize += NODE_LEN (hn) + 1;
|
||||
}
|
||||
return 1;
|
||||
|
||||
case NT_ASSERTION:
|
||||
/* Not currently implemented. */
|
||||
return 1;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the identifiers into 'definedstrs' of the state. */
|
||||
|
||||
static int
|
||||
write_defs (pfile, hn, ss_p)
|
||||
cpp_reader *pfile ATTRIBUTE_UNUSED;
|
||||
cpp_hashnode *hn;
|
||||
void *ss_p;
|
||||
{
|
||||
struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
|
||||
|
||||
switch (hn->type)
|
||||
{
|
||||
case NT_MACRO:
|
||||
if (hn->flags & NODE_BUILTIN)
|
||||
return 1;
|
||||
|
||||
/* else fall through. */
|
||||
|
||||
case NT_VOID:
|
||||
{
|
||||
struct cpp_string news;
|
||||
void **slot;
|
||||
|
||||
news.len = NODE_LEN (hn);
|
||||
news.text = NODE_NAME (hn);
|
||||
slot = htab_find (ss->definedhash, &news);
|
||||
if (slot == NULL)
|
||||
{
|
||||
memcpy (ss->definedstrs, NODE_NAME (hn), NODE_LEN (hn));
|
||||
ss->definedstrs[NODE_LEN (hn)] = 0;
|
||||
ss->definedstrs += NODE_LEN (hn) + 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
||||
case NT_ASSERTION:
|
||||
/* Not currently implemented. */
|
||||
return 1;
|
||||
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
/* Write out the remainder of the dependency information. This should be
|
||||
called after the PCH is ready to be saved. */
|
||||
|
||||
int
|
||||
cpp_write_pch_deps (r, f)
|
||||
cpp_reader *r;
|
||||
FILE *f;
|
||||
{
|
||||
struct macrodef_struct z;
|
||||
struct cpp_savedstate *const ss = r->savedstate;
|
||||
unsigned char *definedstrs;
|
||||
|
||||
ss->hashsize = 0;
|
||||
|
||||
/* Write out the list of identifiers which have been seen and
|
||||
weren't defined to anything previously. */
|
||||
cpp_forall_identifiers (r, count_defs, ss);
|
||||
definedstrs = ss->definedstrs = xmalloc (ss->hashsize);
|
||||
cpp_forall_identifiers (r, write_defs, ss);
|
||||
memset (&z, 0, sizeof (z));
|
||||
z.definition_length = ss->hashsize;
|
||||
if (fwrite (&z, sizeof (z), 1, f) != 1
|
||||
|| fwrite (definedstrs, ss->hashsize, 1, f) != 1)
|
||||
{
|
||||
cpp_errno (r, DL_ERROR, "while writing precompiled header");
|
||||
return -1;
|
||||
}
|
||||
free (definedstrs);
|
||||
|
||||
/* Free the saved state. */
|
||||
free (ss);
|
||||
r->savedstate = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write out the definitions of the preprocessor, in a form suitable for
|
||||
cpp_read_state. */
|
||||
|
||||
int
|
||||
cpp_write_pch_state (r, f)
|
||||
cpp_reader *r;
|
||||
FILE *f;
|
||||
{
|
||||
struct macrodef_struct z;
|
||||
|
||||
/* Write out the list of defined identifiers. */
|
||||
cpp_forall_identifiers (r, write_macdef, f);
|
||||
memset (&z, 0, sizeof (z));
|
||||
if (fwrite (&z, sizeof (z), 1, f) != 1)
|
||||
{
|
||||
cpp_errno (r, DL_ERROR, "while writing precompiled header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!r->deps)
|
||||
r->deps = deps_init ();
|
||||
|
||||
if (deps_save (r->deps, f) != 0)
|
||||
{
|
||||
cpp_errno (r, DL_ERROR, "while writing precompiled header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return nonzero if FD is a precompiled header which is consistent
|
||||
with the preprocessor's current definitions. It will be consistent
|
||||
when:
|
||||
|
||||
- anything that was defined just before the PCH was generated
|
||||
is defined the same way now; and
|
||||
- anything that was not defined then, but is defined now, was not
|
||||
used by the PCH.
|
||||
|
||||
NAME is used to print warnings if `warn_invalid_pch' is set in the
|
||||
reader's flags.
|
||||
*/
|
||||
|
||||
int
|
||||
cpp_valid_state (r, name, fd)
|
||||
cpp_reader *r;
|
||||
const char *name;
|
||||
int fd;
|
||||
{
|
||||
struct macrodef_struct m;
|
||||
size_t namebufsz = 256;
|
||||
unsigned char *namebuf = xmalloc (namebufsz);
|
||||
unsigned char *undeftab = NULL;
|
||||
unsigned int i;
|
||||
|
||||
/* Read in the list of identifiers that must be defined
|
||||
Check that they are defined in the same way. */
|
||||
for (;;)
|
||||
{
|
||||
cpp_hashnode *h;
|
||||
const unsigned char *newdefn;
|
||||
|
||||
if (read (fd, &m, sizeof (m)) != sizeof (m))
|
||||
goto error;
|
||||
|
||||
if (m.name_length == 0)
|
||||
break;
|
||||
|
||||
if (m.definition_length > namebufsz)
|
||||
{
|
||||
free (namebuf);
|
||||
namebufsz = m.definition_length + 256;
|
||||
namebuf = xmalloc (namebufsz);
|
||||
}
|
||||
|
||||
if ((size_t)read (fd, namebuf, m.definition_length)
|
||||
!= m.definition_length)
|
||||
goto error;
|
||||
|
||||
h = cpp_lookup (r, namebuf, m.name_length);
|
||||
if (m.flags & NODE_POISONED
|
||||
|| h->type != NT_MACRO
|
||||
|| h->flags & NODE_POISONED)
|
||||
{
|
||||
if (CPP_OPTION (r, warn_invalid_pch))
|
||||
cpp_error (r, DL_WARNING,
|
||||
"%s: not used because `%.*s' not defined",
|
||||
name, m.name_length, namebuf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
newdefn = cpp_macro_definition (r, h);
|
||||
|
||||
if (m.definition_length != ustrlen (newdefn)
|
||||
|| memcmp (namebuf, newdefn, m.definition_length) != 0)
|
||||
{
|
||||
if (CPP_OPTION (r, warn_invalid_pch))
|
||||
cpp_error (r, DL_WARNING,
|
||||
"%s: not used because `%.*s' defined as `%s' not `%.*s'",
|
||||
name, m.name_length, namebuf, newdefn + m.name_length,
|
||||
m.definition_length - m.name_length,
|
||||
namebuf + m.name_length);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
free (namebuf);
|
||||
namebuf = NULL;
|
||||
|
||||
/* Read in the list of identifiers that must not be defined.
|
||||
Check that they really aren't. */
|
||||
undeftab = xmalloc (m.definition_length);
|
||||
if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length)
|
||||
goto error;
|
||||
for (i = 0; i < m.definition_length; )
|
||||
{
|
||||
int l = ustrlen (undeftab + i);
|
||||
cpp_hashnode *h;
|
||||
h = cpp_lookup (r, undeftab + i, l);
|
||||
if (h->type != NT_VOID
|
||||
|| h->flags & NODE_POISONED)
|
||||
{
|
||||
if (CPP_OPTION (r, warn_invalid_pch))
|
||||
cpp_error (r, DL_WARNING, "%s: not used because `%s' is defined",
|
||||
name, undeftab + i);
|
||||
goto fail;
|
||||
}
|
||||
i += l + 1;
|
||||
}
|
||||
free (undeftab);
|
||||
|
||||
/* We win! */
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cpp_errno (r, DL_ERROR, "while reading precompiled header");
|
||||
return -1;
|
||||
|
||||
fail:
|
||||
if (namebuf != NULL)
|
||||
free (namebuf);
|
||||
if (undeftab != NULL)
|
||||
free (undeftab);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Save all the existing macros and assertions.
|
||||
This code assumes that there might be hundreds, but not thousands of
|
||||
existing definitions. */
|
||||
|
||||
struct save_macro_item {
|
||||
struct save_macro_item *next;
|
||||
struct cpp_hashnode macs[64];
|
||||
};
|
||||
|
||||
struct save_macro_data
|
||||
{
|
||||
struct save_macro_item *macros;
|
||||
size_t count;
|
||||
char **saved_pragmas;
|
||||
};
|
||||
|
||||
/* Save the definition of a single macro, so that it will persist across
|
||||
a PCH restore. */
|
||||
|
||||
static int
|
||||
save_macros (r, h, data_p)
|
||||
cpp_reader *r ATTRIBUTE_UNUSED;
|
||||
cpp_hashnode *h;
|
||||
void *data_p;
|
||||
{
|
||||
struct save_macro_data *data = (struct save_macro_data *)data_p;
|
||||
if (h->type != NT_VOID
|
||||
&& (h->flags & NODE_BUILTIN) == 0)
|
||||
{
|
||||
cpp_hashnode *save;
|
||||
if (data->count == ARRAY_SIZE (data->macros->macs))
|
||||
{
|
||||
struct save_macro_item *d = data->macros;
|
||||
data->macros = xmalloc (sizeof (struct save_macro_item));
|
||||
data->macros->next = d;
|
||||
data->count = 0;
|
||||
}
|
||||
save = data->macros->macs + data->count;
|
||||
data->count++;
|
||||
memcpy (save, h, sizeof (struct cpp_hashnode));
|
||||
HT_STR (&save->ident) = xmemdup (HT_STR (HT_NODE (save)),
|
||||
HT_LEN (HT_NODE (save)),
|
||||
HT_LEN (HT_NODE (save)) + 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Prepare to restore the state, by saving the currently-defined
|
||||
macros in 'data'. */
|
||||
|
||||
void
|
||||
cpp_prepare_state (r, data)
|
||||
cpp_reader *r;
|
||||
struct save_macro_data **data;
|
||||
{
|
||||
struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
|
||||
|
||||
d->macros = NULL;
|
||||
d->count = ARRAY_SIZE (d->macros->macs);
|
||||
cpp_forall_identifiers (r, save_macros, d);
|
||||
d->saved_pragmas = _cpp_save_pragma_names (r);
|
||||
*data = d;
|
||||
}
|
||||
|
||||
/* Erase all the existing macros and assertions. */
|
||||
|
||||
static int
|
||||
reset_ht (r, h, unused)
|
||||
cpp_reader *r ATTRIBUTE_UNUSED;
|
||||
cpp_hashnode *h;
|
||||
void *unused ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (h->type != NT_VOID
|
||||
&& (h->flags & NODE_BUILTIN) == 0)
|
||||
{
|
||||
h->type = NT_VOID;
|
||||
memset (&h->value, 0, sizeof (h->value));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Given a precompiled header that was previously determined to be valid,
|
||||
apply all its definitions (and undefinitions) to the current state.
|
||||
DEPNAME is passed to deps_restore. */
|
||||
|
||||
int
|
||||
cpp_read_state (r, name, f, data)
|
||||
cpp_reader *r;
|
||||
const char *name;
|
||||
FILE *f;
|
||||
struct save_macro_data *data;
|
||||
{
|
||||
struct macrodef_struct m;
|
||||
size_t defnlen = 256;
|
||||
unsigned char *defn = xmalloc (defnlen);
|
||||
struct lexer_state old_state;
|
||||
struct save_macro_item *d;
|
||||
size_t i, mac_count;
|
||||
int saved_line = r->line;
|
||||
|
||||
/* Erase all the existing hashtable entries for macros. At this
|
||||
point, they're all from the PCH file, and their pointers won't be
|
||||
valid. */
|
||||
cpp_forall_identifiers (r, reset_ht, NULL);
|
||||
|
||||
/* Restore spec_nodes, which will be full of references to the old
|
||||
hashtable entries and so will now be invalid. */
|
||||
{
|
||||
struct spec_nodes *s = &r->spec_nodes;
|
||||
s->n_defined = cpp_lookup (r, DSC("defined"));
|
||||
s->n_true = cpp_lookup (r, DSC("true"));
|
||||
s->n_false = cpp_lookup (r, DSC("false"));
|
||||
s->n__VA_ARGS__ = cpp_lookup (r, DSC("__VA_ARGS__"));
|
||||
}
|
||||
|
||||
/* Run through the carefully-saved macros, insert them. */
|
||||
d = data->macros;
|
||||
mac_count = data->count;
|
||||
while (d)
|
||||
{
|
||||
struct save_macro_item *nextd;
|
||||
for (i = 0; i < mac_count; i++)
|
||||
{
|
||||
cpp_hashnode *h;
|
||||
|
||||
h = cpp_lookup (r, HT_STR (HT_NODE (&d->macs[i])),
|
||||
HT_LEN (HT_NODE (&d->macs[i])));
|
||||
h->type = d->macs[i].type;
|
||||
h->flags = d->macs[i].flags;
|
||||
h->value = d->macs[i].value;
|
||||
free ((void *)HT_STR (HT_NODE (&d->macs[i])));
|
||||
}
|
||||
nextd = d->next;
|
||||
free (d);
|
||||
d = nextd;
|
||||
mac_count = ARRAY_SIZE (d->macs);
|
||||
}
|
||||
|
||||
_cpp_restore_pragma_names (r, data->saved_pragmas);
|
||||
|
||||
free (data);
|
||||
|
||||
old_state = r->state;
|
||||
|
||||
r->state.in_directive = 1;
|
||||
r->state.prevent_expansion = 1;
|
||||
r->state.angled_headers = 0;
|
||||
|
||||
/* Read in the identifiers that must be defined. */
|
||||
for (;;)
|
||||
{
|
||||
cpp_hashnode *h;
|
||||
|
||||
if (fread (&m, sizeof (m), 1, f) != 1)
|
||||
goto error;
|
||||
|
||||
if (m.name_length == 0)
|
||||
break;
|
||||
|
||||
if (defnlen < m.definition_length + 1)
|
||||
{
|
||||
defnlen = m.definition_length + 256;
|
||||
defn = xrealloc (defn, defnlen);
|
||||
}
|
||||
|
||||
if (fread (defn, 1, m.definition_length, f) != m.definition_length)
|
||||
goto error;
|
||||
defn[m.definition_length] = '\0';
|
||||
|
||||
h = cpp_lookup (r, defn, m.name_length);
|
||||
|
||||
if (h->type == NT_MACRO)
|
||||
_cpp_free_definition (h);
|
||||
if (m.flags & NODE_POISONED)
|
||||
h->flags |= NODE_POISONED | NODE_DIAGNOSTIC;
|
||||
else if (m.name_length != m.definition_length)
|
||||
{
|
||||
if (cpp_push_buffer (r, defn + m.name_length,
|
||||
m.definition_length - m.name_length,
|
||||
true, 1) != NULL)
|
||||
{
|
||||
if (!_cpp_create_definition (r, h))
|
||||
abort ();
|
||||
_cpp_pop_buffer (r);
|
||||
}
|
||||
else
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
r->state = old_state;
|
||||
r->line = saved_line;
|
||||
free (defn);
|
||||
defn = NULL;
|
||||
|
||||
if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL)
|
||||
!= 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
cpp_errno (r, DL_ERROR, "while reading precompiled header");
|
||||
return -1;
|
||||
}
|
145
gcc/dbxout.c
145
gcc/dbxout.c
|
@ -137,6 +137,66 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#define STABS_GCC_MARKER "gcc2_compiled."
|
||||
#endif
|
||||
|
||||
/* Last source file name mentioned in a NOTE insn. */
|
||||
|
||||
static const char *lastfile;
|
||||
|
||||
/* Current working directory. */
|
||||
|
||||
static const char *cwd;
|
||||
|
||||
enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
|
||||
|
||||
/* Structure recording information about a C data type.
|
||||
The status element says whether we have yet output
|
||||
the definition of the type. TYPE_XREF says we have
|
||||
output it as a cross-reference only.
|
||||
The file_number and type_number elements are used if DBX_USE_BINCL
|
||||
is defined. */
|
||||
|
||||
struct typeinfo GTY(())
|
||||
{
|
||||
enum typestatus status;
|
||||
int file_number;
|
||||
int type_number;
|
||||
};
|
||||
|
||||
/* Vector recording information about C data types.
|
||||
When we first notice a data type (a tree node),
|
||||
we assign it a number using next_type_number.
|
||||
That is its index in this vector. */
|
||||
|
||||
static GTY ((length ("typevec_len"))) struct typeinfo *typevec;
|
||||
|
||||
/* Number of elements of space allocated in `typevec'. */
|
||||
|
||||
static GTY(()) int typevec_len;
|
||||
|
||||
/* In dbx output, each type gets a unique number.
|
||||
This is the number for the next type output.
|
||||
The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */
|
||||
|
||||
static GTY(()) int next_type_number;
|
||||
|
||||
/* When using N_BINCL in dbx output, each type number is actually a
|
||||
pair of the file number and the type number within the file.
|
||||
This is a stack of input files. */
|
||||
|
||||
struct dbx_file GTY(())
|
||||
{
|
||||
struct dbx_file *next;
|
||||
int file_number;
|
||||
int next_type_number;
|
||||
};
|
||||
|
||||
/* This is the top of the stack. */
|
||||
|
||||
static GTY(()) struct dbx_file *current_file;
|
||||
|
||||
/* This is the next file number to use. */
|
||||
|
||||
static GTY(()) int next_file_number;
|
||||
|
||||
/* Typical USG systems don't have stab.h, and they also have
|
||||
no use for DBX-format debugging info. */
|
||||
|
||||
|
@ -188,72 +248,6 @@ static int source_label_number = 1;
|
|||
|
||||
static FILE *asmfile;
|
||||
|
||||
/* Last source file name mentioned in a NOTE insn. */
|
||||
|
||||
static const char *lastfile;
|
||||
|
||||
/* Current working directory. */
|
||||
|
||||
static const char *cwd;
|
||||
|
||||
enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
|
||||
|
||||
/* Structure recording information about a C data type.
|
||||
The status element says whether we have yet output
|
||||
the definition of the type. TYPE_XREF says we have
|
||||
output it as a cross-reference only.
|
||||
The file_number and type_number elements are used if DBX_USE_BINCL
|
||||
is defined. */
|
||||
|
||||
struct typeinfo
|
||||
{
|
||||
enum typestatus status;
|
||||
#ifdef DBX_USE_BINCL
|
||||
int file_number;
|
||||
int type_number;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Vector recording information about C data types.
|
||||
When we first notice a data type (a tree node),
|
||||
we assign it a number using next_type_number.
|
||||
That is its index in this vector. */
|
||||
|
||||
struct typeinfo *typevec;
|
||||
|
||||
/* Number of elements of space allocated in `typevec'. */
|
||||
|
||||
static int typevec_len;
|
||||
|
||||
/* In dbx output, each type gets a unique number.
|
||||
This is the number for the next type output.
|
||||
The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */
|
||||
|
||||
static int next_type_number;
|
||||
|
||||
#ifdef DBX_USE_BINCL
|
||||
|
||||
/* When using N_BINCL in dbx output, each type number is actually a
|
||||
pair of the file number and the type number within the file.
|
||||
This is a stack of input files. */
|
||||
|
||||
struct dbx_file
|
||||
{
|
||||
struct dbx_file *next;
|
||||
int file_number;
|
||||
int next_type_number;
|
||||
};
|
||||
|
||||
/* This is the top of the stack. */
|
||||
|
||||
static struct dbx_file *current_file;
|
||||
|
||||
/* This is the next file number to use. */
|
||||
|
||||
static int next_file_number;
|
||||
|
||||
#endif /* DBX_USE_BINCL */
|
||||
|
||||
/* These variables are for dbxout_symbol to communicate to
|
||||
dbxout_finish_symbol.
|
||||
current_sym_code is the symbol-type-code, a symbol N_... define in stab.h.
|
||||
|
@ -425,7 +419,7 @@ dbxout_init (input_file_name)
|
|||
asmfile = asm_out_file;
|
||||
|
||||
typevec_len = 100;
|
||||
typevec = (struct typeinfo *) xcalloc (typevec_len, sizeof typevec[0]);
|
||||
typevec = (struct typeinfo *) ggc_calloc (typevec_len, sizeof typevec[0]);
|
||||
|
||||
/* Convert Ltext into the appropriate format for local labels in case
|
||||
the system doesn't insert underscores in front of user generated
|
||||
|
@ -484,7 +478,7 @@ dbxout_init (input_file_name)
|
|||
next_type_number = 1;
|
||||
|
||||
#ifdef DBX_USE_BINCL
|
||||
current_file = (struct dbx_file *) xmalloc (sizeof *current_file);
|
||||
current_file = (struct dbx_file *) ggc_alloc (sizeof *current_file);
|
||||
current_file->next = NULL;
|
||||
current_file->file_number = 0;
|
||||
current_file->next_type_number = 1;
|
||||
|
@ -541,7 +535,7 @@ dbxout_start_source_file (line, filename)
|
|||
const char *filename ATTRIBUTE_UNUSED;
|
||||
{
|
||||
#ifdef DBX_USE_BINCL
|
||||
struct dbx_file *n = (struct dbx_file *) xmalloc (sizeof *n);
|
||||
struct dbx_file *n = (struct dbx_file *) ggc_alloc (sizeof *n);
|
||||
|
||||
n->next = current_file;
|
||||
n->file_number = next_file_number++;
|
||||
|
@ -560,12 +554,8 @@ dbxout_end_source_file (line)
|
|||
unsigned int line ATTRIBUTE_UNUSED;
|
||||
{
|
||||
#ifdef DBX_USE_BINCL
|
||||
struct dbx_file *next;
|
||||
|
||||
fprintf (asmfile, "%s%d,0,0,0\n", ASM_STABN_OP, N_EINCL);
|
||||
next = current_file->next;
|
||||
free (current_file);
|
||||
current_file = next;
|
||||
current_file = current_file->next;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1149,8 +1139,9 @@ dbxout_type (type, full)
|
|||
if (next_type_number == typevec_len)
|
||||
{
|
||||
typevec
|
||||
= (struct typeinfo *) xrealloc (typevec,
|
||||
typevec_len * 2 * sizeof typevec[0]);
|
||||
= (struct typeinfo *) ggc_realloc (typevec,
|
||||
(typevec_len * 2
|
||||
* sizeof typevec[0]));
|
||||
memset ((char *) (typevec + typevec_len), 0,
|
||||
typevec_len * sizeof typevec[0]);
|
||||
typevec_len *= 2;
|
||||
|
@ -3008,3 +2999,5 @@ dbxout_begin_function (decl)
|
|||
#endif /* DBX_DEBUGGING_INFO */
|
||||
|
||||
#endif /* DBX_DEBUGGING_INFO || XCOFF_DEBUGGING_INFO */
|
||||
|
||||
#include "gt-dbxout.h"
|
||||
|
|
|
@ -301,6 +301,17 @@ a dependency output file as a side-effect of the compilation process.
|
|||
Like @option{-MD} except mention only user header files, not system
|
||||
-header files.
|
||||
|
||||
@ifclear cppmanual
|
||||
@item -fpch-deps
|
||||
@opindex fpch-deps
|
||||
When using precompiled headers (@pxref{Precompiled Headers}), this flag
|
||||
will cause the dependency-output flags to also list the files from the
|
||||
precompiled header's dependencies. If not specified only the
|
||||
precompiled header would be listed and not the files that were used to
|
||||
create it because those files are not consulted when a precompiled
|
||||
header is used.
|
||||
|
||||
@end ifclear
|
||||
@item -x c
|
||||
@itemx -x c++
|
||||
@itemx -x objective-c
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
|
||||
GCC uses some fairly sophisticated memory management techniques, which
|
||||
involve determining information about GCC's data structures from GCC's
|
||||
source code and using this information to perform garbage collection.
|
||||
source code and using this information to perform garbage collection and
|
||||
implement precompiled headers.
|
||||
|
||||
A full C parser would be too overcomplicated for this task, so a limited
|
||||
subset of C is interpreted and special markers are used to determine
|
||||
|
@ -227,6 +228,39 @@ this field is always @code{NULL}. This is used to avoid requiring
|
|||
backends to define certain optional structures. It doesn't work with
|
||||
language frontends.
|
||||
|
||||
@findex chain_next
|
||||
@findex chain_prev
|
||||
@item chain_next
|
||||
@itemx chain_prev
|
||||
|
||||
It's helpful for the type machinery to know if objects are often
|
||||
chained together in long lists; this lets it generate code that uses
|
||||
less stack space by iterating along the list instead of recursing down
|
||||
it. @code{chain_next} is an expression for the next item in the list,
|
||||
@code{chain_prev} is an expression for the previous item. The
|
||||
machinery requires that taking the next item of the previous item
|
||||
gives the original item.
|
||||
|
||||
@findex reorder
|
||||
@item reorder
|
||||
|
||||
Some data structures depend on the relative ordering of pointers. If
|
||||
the type machinery needs to change that ordering, it will call the
|
||||
function referenced by the @code{reorder} option, before changing the
|
||||
pointers in the object that's pointed to by the field the option
|
||||
applies to. The function must be of the type @code{void ()(void *,
|
||||
void *, gt_pointer_operator, void *)}. The second parameter is the
|
||||
pointed-to object; the third parameter is a routine that, given a
|
||||
pointer, can update it to its new value. The fourth parameter is a
|
||||
cookie to be passed to the third parameter. The first parameter is
|
||||
the structure that contains the object, or the object itself if it is
|
||||
a structure.
|
||||
|
||||
No data structure may depend on the absolute value of pointers. Even
|
||||
relying on relative orderings and using @code{reorder} functions can
|
||||
be expensive. It is better to depend on properties of the data, like
|
||||
an ID number or the hash of a string instead.
|
||||
|
||||
@findex special
|
||||
@item special
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ only one of these two forms, whichever one is not the default.
|
|||
* Code Gen Options:: Specifying conventions for function calls, data layout
|
||||
and register usage.
|
||||
* Environment Variables:: Env vars that affect GCC.
|
||||
* Precompiled Headers:: Compiling a header once, and using it many times.
|
||||
* Running Protoize:: Automatically adding or removing function prototypes.
|
||||
@end menu
|
||||
|
||||
|
@ -220,7 +221,7 @@ in the following sections.
|
|||
-Wimplicit -Wimplicit-int @gol
|
||||
-Wimplicit-function-declaration @gol
|
||||
-Werror-implicit-function-declaration @gol
|
||||
-Wimport -Winline -Wno-endif-labels @gol
|
||||
-Wimport -Winline -Winvalid-pch -Wno-endif-labels @gol
|
||||
-Wlarger-than-@var{len} -Wlong-long @gol
|
||||
-Wmain -Wmissing-braces @gol
|
||||
-Wmissing-format-attribute -Wmissing-noreturn @gol
|
||||
|
@ -767,7 +768,7 @@ Objective-C source code. Note that you must link with the library
|
|||
Objective-C source code which should not be preprocessed.
|
||||
|
||||
@item @var{file}.h
|
||||
C header file (not to be compiled or linked).
|
||||
C or C++ header file to be turned into a precompiled header.
|
||||
|
||||
@item @var{file}.cc
|
||||
@itemx @var{file}.cp
|
||||
|
@ -780,6 +781,10 @@ C++ source code which must be preprocessed. Note that in @samp{.cxx},
|
|||
the last two letters must both be literally @samp{x}. Likewise,
|
||||
@samp{.C} refers to a literal capital C@.
|
||||
|
||||
@item @var{file}.hh
|
||||
@itemx @var{file}.H
|
||||
C++ header file to be turned into a precompiled header.
|
||||
|
||||
@item @var{file}.f
|
||||
@itemx @var{file}.for
|
||||
@itemx @var{file}.FOR
|
||||
|
@ -843,7 +848,7 @@ name suffix). This option applies to all following input files until
|
|||
the next @option{-x} option. Possible values for @var{language} are:
|
||||
@example
|
||||
c c-header cpp-output
|
||||
c++ c++-cpp-output
|
||||
c++ c++-header c++-cpp-output
|
||||
objective-c objc-cpp-output
|
||||
assembler assembler-with-cpp
|
||||
ada
|
||||
|
@ -965,22 +970,24 @@ Display the version number and copyrights of the invoked GCC.
|
|||
@cindex suffixes for C++ source
|
||||
@cindex C++ source file suffixes
|
||||
C++ source files conventionally use one of the suffixes @samp{.C},
|
||||
@samp{.cc}, @samp{.cpp}, @samp{.CPP}, @samp{.c++}, @samp{.cp}, or @samp{.cxx};
|
||||
@samp{.cc}, @samp{.cpp}, @samp{.CPP}, @samp{.c++}, @samp{.cp}, or
|
||||
@samp{.cxx}; C++ header files often use @samp{.hh} or @samp{.H}; and
|
||||
preprocessed C++ files use the suffix @samp{.ii}. GCC recognizes
|
||||
files with these names and compiles them as C++ programs even if you
|
||||
call the compiler the same way as for compiling C programs (usually with
|
||||
the name @command{gcc}).
|
||||
call the compiler the same way as for compiling C programs (usually
|
||||
with the name @command{gcc}).
|
||||
|
||||
@findex g++
|
||||
@findex c++
|
||||
However, C++ programs often require class libraries as well as a
|
||||
compiler that understands the C++ language---and under some
|
||||
circumstances, you might want to compile programs from standard input,
|
||||
or otherwise without a suffix that flags them as C++ programs.
|
||||
@command{g++} is a program that calls GCC with the default language
|
||||
set to C++, and automatically specifies linking against the C++
|
||||
library. On many systems, @command{g++} is also
|
||||
installed with the name @command{c++}.
|
||||
circumstances, you might want to compile programs or header files from
|
||||
standard input, or otherwise without a suffix that flags them as C++
|
||||
programs. You might also like to precompile a C header file with a
|
||||
@samp{.h} extension to be used in C++ compilations. @command{g++} is a
|
||||
program that calls GCC with the default language set to C++, and
|
||||
automatically specifies linking against the C++ library. On many
|
||||
systems, @command{g++} is also installed with the name @command{c++}.
|
||||
|
||||
@cindex invoking @command{g++}
|
||||
When you compile C++ programs, you may specify many of the same
|
||||
|
@ -2800,6 +2807,11 @@ code is to provide behavior which is selectable at compile-time.
|
|||
@opindex Winline
|
||||
Warn if a function can not be inlined and it was declared as inline.
|
||||
|
||||
@item -Winvalid-pch
|
||||
@opindex Winvalid-pch
|
||||
Warn if a precompiled header (@pxref{Precompiled Headers}) is found in
|
||||
the search path but can't be used.
|
||||
|
||||
@item -Wlong-long
|
||||
@opindex Wlong-long
|
||||
@opindex Wno-long-long
|
||||
|
@ -10924,6 +10936,104 @@ preprocessor.
|
|||
|
||||
@c man end
|
||||
|
||||
@node Precompiled Headers
|
||||
@section Using Precompiled Headers
|
||||
@cindex precompiled headers
|
||||
@cindex speed of compilation
|
||||
|
||||
Often large projects have many header files that are included in every
|
||||
source file. The time the compiler takes to process these header files
|
||||
over and over again can account for nearly all of the time required to
|
||||
build the project. To make builds faster, GCC allows users to
|
||||
`precompile' a header file; then, if builds can use the precompiled
|
||||
header file they will be much faster.
|
||||
|
||||
To create a precompiled header file, simply compile it as you would any
|
||||
other file, if necessary using the @option{-x} option to make the driver
|
||||
treat it as a C or C++ header file. You will probably want to use a
|
||||
tool like @command{make} to keep the precompiled header up-to-date when
|
||||
the headers it contains change.
|
||||
|
||||
A precompiled header file will be searched for when @code{#include} is
|
||||
seen in the compilation. As it searches for the included file
|
||||
(@pxref{Search Path,,Search Path,cpp.info,The C Preprocessor}) the
|
||||
compiler looks for a precompiled header in each directory just before it
|
||||
looks for the include file in that directory. The name searched for is
|
||||
the name specified in the @code{#include} with @samp{.pch} appended. If
|
||||
the precompiled header file can't be used, it is ignored.
|
||||
|
||||
For instance, if you have @code{#include "all.h"}, and you have
|
||||
@file{all.h.pch} in the same directory as @file{all.h}, then the
|
||||
precompiled header file will be used if possible, and the original
|
||||
header will be used otherwise.
|
||||
|
||||
Alternatively, you might decide to put the precompiled header file in a
|
||||
directory and use @option{-I} to ensure that directory is searched
|
||||
before (or instead of) the directory containing the original header.
|
||||
Then, if you want to check that the precompiled header file is always
|
||||
used, you can put a file of the same name as the original header in this
|
||||
directory containing an @code{#error} command.
|
||||
|
||||
This also works with @option{-include}. So yet another way to use
|
||||
precompiled headers, good for projects not designed with precompiled
|
||||
header files in mind, is to simply take most of the header files used by
|
||||
a project, include them from another header file, precompile that header
|
||||
file, and @option{-include} the precompiled header. If the header files
|
||||
have guards against multiple inclusion, they will be skipped because
|
||||
they've already been included (in the precompiled header).
|
||||
|
||||
If you need to precompile the same header file for different
|
||||
languages, targets, or compiler options, you can instead make a
|
||||
@emph{directory} named like @file{all.h.pch}, and put each precompiled
|
||||
header in the directory. (It doesn't matter what you call the files
|
||||
in the directory, every precompiled header in the directory will be
|
||||
considered.) The first precompiled header encountered in the
|
||||
directory that is valid for this compilation will be used; they're
|
||||
searched in no particular order.
|
||||
|
||||
There are many other possibilities, limited only by your imagination,
|
||||
good sense, and the constraints of your build system.
|
||||
|
||||
A precompiled header file can be used only when these conditions apply:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Only one precompiled header can be used in a particular compilation.
|
||||
@item
|
||||
A precompiled header can't be used once the first C token is seen. You
|
||||
can have preprocessor directives before a precompiled header; you can
|
||||
even include a precompiled header from inside another header, so long as
|
||||
there are no C tokens before the @code{#include}.
|
||||
@item
|
||||
The precompiled header file must be produced for the same language as
|
||||
the current compilation. You can't use a C precompiled header for a C++
|
||||
compilation.
|
||||
@item
|
||||
The precompiled header file must be produced by the same compiler
|
||||
version and configuration as the current compilation is using.
|
||||
The easiest way to guarantee this is to use the same compiler binary
|
||||
for creating and using precompiled headers.
|
||||
@item
|
||||
Any macros defined before the precompiled header (including with
|
||||
@option{-D}) must either be defined in the same way as when the
|
||||
precompiled header was generated, or must not affect the precompiled
|
||||
header, which usually means that the they don't appear in the
|
||||
precompiled header at all.
|
||||
@item
|
||||
Certain command-line options must be defined in the same way as when the
|
||||
precompiled header was generated. At present, it's not clear which
|
||||
options are safe to change and which are not; the safest choice is to
|
||||
use exactly the same options when generating and using the precompiled
|
||||
header.
|
||||
@end itemize
|
||||
|
||||
For all of these but the last, the compiler will automatically ignore
|
||||
the precompiled header if the conditions aren't met. For the last item,
|
||||
some option changes will cause the precompiled header to be rejected,
|
||||
but not all incompatible option combinations have yet been found. If
|
||||
you find a new incompatible combination, please consider filing a bug
|
||||
report, see @ref{Bugs}.
|
||||
|
||||
@node Running Protoize
|
||||
@section Running Protoize
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
||||
@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2002,
|
||||
@c 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
@c This is part of the GCC manual.
|
||||
@c For copying conditions, see the file gcc.texi.
|
||||
|
@ -73,54 +73,22 @@ performed by cpplib, which is covered in separate documentation. In
|
|||
particular, the internals are covered in @xref{Top, ,Cpplib internals,
|
||||
cppinternals, Cpplib Internals}.
|
||||
|
||||
@c Avoiding overfull is tricky here.
|
||||
The source files to parse C are
|
||||
@file{c-convert.c},
|
||||
@file{c-decl.c},
|
||||
@file{c-errors.c},
|
||||
@file{c-lang.c},
|
||||
@file{c-objc-common.c},
|
||||
@file{c-parse.in},
|
||||
@file{c-aux-info.c},
|
||||
and
|
||||
@file{c-typeck.c},
|
||||
along with a header file
|
||||
@file{c-tree.h}
|
||||
and some files shared with Objective-C and C++.
|
||||
|
||||
The source files for parsing C++ are in @file{cp/}.
|
||||
They are @file{parse.y},
|
||||
@file{class.c},
|
||||
@file{cvt.c}, @file{decl.c}, @file{decl2.c},
|
||||
@file{except.c},
|
||||
@file{expr.c}, @file{init.c}, @file{lex.c},
|
||||
@file{method.c}, @file{ptree.c},
|
||||
@file{search.c}, @file{spew.c},
|
||||
@file{semantics.c}, @file{tree.c},
|
||||
@file{typeck2.c}, and
|
||||
@file{typeck.c}, along with header files @file{cp-tree.def},
|
||||
@file{cp-tree.h}, and @file{decl.h}.
|
||||
|
||||
The special source files for parsing Objective-C are in @file{objc/}.
|
||||
They are @file{objc-act.c}, @file{objc-tree.def}, and @file{objc-act.h}.
|
||||
Certain C-specific files are used for this as well.
|
||||
|
||||
The files
|
||||
@file{c-common.c},
|
||||
The source files to parse C are found in the toplevel directory, and
|
||||
by convention are named @file{c-*}. Some of these are also used by
|
||||
the other C-like languages: @file{c-common.c},
|
||||
@file{c-common.def},
|
||||
@file{c-format.c},
|
||||
@file{c-opts.c},
|
||||
@file{c-pragma.c},
|
||||
@file{c-semantics.c},
|
||||
and
|
||||
@file{c-lex.c},
|
||||
along with header files
|
||||
@file{c-common.h},
|
||||
@file{c-dump.h},
|
||||
and
|
||||
@file{c-pragma.h},
|
||||
are also used for all of the above languages.
|
||||
|
||||
Files specific to each language are in subdirectories named after the
|
||||
language in question, like @file{ada}, @file{objc}, @file{cp} (for C++).
|
||||
|
||||
@cindex Tree optimization
|
||||
@item
|
||||
|
|
|
@ -688,12 +688,12 @@ dw2_asm_output_delta_sleb128 VPARAMS ((const char *lab1 ATTRIBUTE_UNUSED,
|
|||
VA_CLOSE (ap);
|
||||
}
|
||||
|
||||
static int mark_indirect_pool_entry PARAMS ((splay_tree_node, void *));
|
||||
static void mark_indirect_pool PARAMS ((PTR arg));
|
||||
static rtx dw2_force_const_mem PARAMS ((rtx));
|
||||
static int dw2_output_indirect_constant_1 PARAMS ((splay_tree_node, void *));
|
||||
|
||||
static splay_tree indirect_pool;
|
||||
static GTY((param1_is (char *), param2_is (tree))) splay_tree indirect_pool;
|
||||
|
||||
static GTY(()) int dw2_const_labelno;
|
||||
|
||||
#if defined(HAVE_GAS_HIDDEN) && defined(SUPPORTS_ONE_ONLY)
|
||||
# define USE_LINKONCE_INDIRECT 1
|
||||
|
@ -701,26 +701,6 @@ static splay_tree indirect_pool;
|
|||
# define USE_LINKONCE_INDIRECT 0
|
||||
#endif
|
||||
|
||||
/* Mark all indirect constants for GC. */
|
||||
|
||||
static int
|
||||
mark_indirect_pool_entry (node, data)
|
||||
splay_tree_node node;
|
||||
void* data ATTRIBUTE_UNUSED;
|
||||
{
|
||||
ggc_mark_tree ((tree) node->value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Mark all indirect constants for GC. */
|
||||
|
||||
static void
|
||||
mark_indirect_pool (arg)
|
||||
PTR arg ATTRIBUTE_UNUSED;
|
||||
{
|
||||
splay_tree_foreach (indirect_pool, mark_indirect_pool_entry, NULL);
|
||||
}
|
||||
|
||||
/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
|
||||
memory. Differs from force_const_mem in that a single pool is used for
|
||||
the entire unit of translation, and the memory is not guaranteed to be
|
||||
|
@ -735,10 +715,7 @@ dw2_force_const_mem (x)
|
|||
tree decl;
|
||||
|
||||
if (! indirect_pool)
|
||||
{
|
||||
indirect_pool = splay_tree_new (splay_tree_compare_pointers, NULL, NULL);
|
||||
ggc_add_root (&indirect_pool, 1, sizeof indirect_pool, mark_indirect_pool);
|
||||
}
|
||||
indirect_pool = splay_tree_new_ggc (splay_tree_compare_pointers);
|
||||
|
||||
if (GET_CODE (x) != SYMBOL_REF)
|
||||
abort ();
|
||||
|
@ -765,11 +742,10 @@ dw2_force_const_mem (x)
|
|||
}
|
||||
else
|
||||
{
|
||||
extern int const_labelno;
|
||||
char label[32];
|
||||
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "LC", const_labelno);
|
||||
++const_labelno;
|
||||
ASM_GENERATE_INTERNAL_LABEL (label, "LDFCM", dw2_const_labelno);
|
||||
++dw2_const_labelno;
|
||||
id = get_identifier (label);
|
||||
decl = build_decl (VAR_DECL, id, ptr_type_node);
|
||||
DECL_ARTIFICIAL (decl) = 1;
|
||||
|
@ -906,3 +882,5 @@ dw2_asm_output_encoded_addr_rtx VPARAMS ((int encoding,
|
|||
|
||||
VA_CLOSE (ap);
|
||||
}
|
||||
|
||||
#include "gt-dwarf2asm.h"
|
||||
|
|
486
gcc/dwarf2out.c
486
gcc/dwarf2out.c
File diff suppressed because it is too large
Load diff
|
@ -5315,14 +5315,14 @@ init_emit_once (line_numbers)
|
|||
|
||||
/* Initialize the CONST_INT, CONST_DOUBLE, and memory attribute hash
|
||||
tables. */
|
||||
const_int_htab = htab_create (37, const_int_htab_hash,
|
||||
const_int_htab_eq, NULL);
|
||||
const_int_htab = htab_create_ggc (37, const_int_htab_hash,
|
||||
const_int_htab_eq, NULL);
|
||||
|
||||
const_double_htab = htab_create (37, const_double_htab_hash,
|
||||
const_double_htab_eq, NULL);
|
||||
const_double_htab = htab_create_ggc (37, const_double_htab_hash,
|
||||
const_double_htab_eq, NULL);
|
||||
|
||||
mem_attrs_htab = htab_create (37, mem_attrs_htab_hash,
|
||||
mem_attrs_htab_eq, NULL);
|
||||
mem_attrs_htab = htab_create_ggc (37, mem_attrs_htab_hash,
|
||||
mem_attrs_htab_eq, NULL);
|
||||
|
||||
no_line_numbers = ! line_numbers;
|
||||
|
||||
|
|
|
@ -1395,7 +1395,7 @@ size_int_type_wide (number, type)
|
|||
|
||||
if (size_htab == 0)
|
||||
{
|
||||
size_htab = htab_create (1024, size_htab_hash, size_htab_eq, NULL);
|
||||
size_htab = htab_create_ggc (1024, size_htab_hash, size_htab_eq, NULL);
|
||||
new_const = make_node (INTEGER_CST);
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ int current_function_uses_only_leaf_regs;
|
|||
int virtuals_instantiated;
|
||||
|
||||
/* Assign unique numbers to labels generated for profiling, debugging, etc. */
|
||||
static int funcdef_no;
|
||||
static GTY(()) int funcdef_no;
|
||||
|
||||
/* These variables hold pointers to functions to create and destroy
|
||||
target specific, per-function data structures. */
|
||||
|
|
30
gcc/gcc.c
30
gcc/gcc.c
|
@ -421,6 +421,7 @@ or with constant text in a single argument.
|
|||
%w marks the argument containing or following the %w as the
|
||||
"output file" of this compilation. This puts the argument
|
||||
into the sequence of arguments that %o will substitute later.
|
||||
%V indicates that this compilation produces no "output file".
|
||||
%W{...}
|
||||
like %{...} but mark last argument supplied within
|
||||
as a file to be deleted on failure.
|
||||
|
@ -914,9 +915,19 @@ static const struct compiler default_compilers[] =
|
|||
%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
|
||||
{".h", "@c-header", 0},
|
||||
{"@c-header",
|
||||
"%{!E:%ecompilation of header file requested} \
|
||||
%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)",
|
||||
0},
|
||||
/* cc1 has an integrated ISO C preprocessor. We should invoke the
|
||||
external preprocessor if -save-temps is given. */
|
||||
"%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
|
||||
%{!E:%{!M:%{!MM:\
|
||||
%{save-temps|traditional-cpp:%(trad_capable_cpp) \
|
||||
%(cpp_options) %b.i \n\
|
||||
cc1 -fpreprocessed %b.i %(cc1_options)\
|
||||
-o %g.s %{!o*:--output-pch=%i.pch}\
|
||||
%W{o*:--output-pch=%*}%V}\
|
||||
%{!save-temps:%{!traditional-cpp:\
|
||||
cc1 %(cpp_unique_options) %(cc1_options)\
|
||||
-o %g.s %{!o*:--output-pch=%i.pch}\
|
||||
%W{o*:--output-pch=%*}%V}}}}}", 0},
|
||||
{".i", "@cpp-output", 0},
|
||||
{"@cpp-output",
|
||||
"%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
|
||||
|
@ -4765,6 +4776,10 @@ do_spec_1 (spec, inswitch, soft_matched_part)
|
|||
this_is_library_file = 1;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
outfiles[input_file_number] = NULL;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
this_is_output_file = 1;
|
||||
break;
|
||||
|
@ -6079,6 +6094,7 @@ main (argc, argv)
|
|||
size_t i;
|
||||
int value;
|
||||
int linker_was_run = 0;
|
||||
int num_linker_inputs = 0;
|
||||
char *explicit_link_files;
|
||||
char *specs_file;
|
||||
const char *p;
|
||||
|
@ -6516,9 +6532,15 @@ main (argc, argv)
|
|||
error_count++;
|
||||
}
|
||||
|
||||
/* Determine if there are any linker input files. */
|
||||
num_linker_inputs = 0;
|
||||
for (i = 0; (int) i < n_infiles; i++)
|
||||
if (explicit_link_files[i] || outfiles[i] != NULL)
|
||||
num_linker_inputs++;
|
||||
|
||||
/* Run ld to link all the compiler output files. */
|
||||
|
||||
if (error_count == 0)
|
||||
if (num_linker_inputs > 0 && error_count == 0)
|
||||
{
|
||||
int tmp = execution_count;
|
||||
|
||||
|
|
1552
gcc/gengtype.c
1552
gcc/gengtype.c
File diff suppressed because it is too large
Load diff
559
gcc/ggc-common.c
559
gcc/ggc-common.c
|
@ -24,14 +24,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "rtl.h"
|
||||
#include "tree.h"
|
||||
#include "tm_p.h"
|
||||
#include "hashtab.h"
|
||||
#include "varray.h"
|
||||
#include "ggc.h"
|
||||
#include "langhooks.h"
|
||||
#include "toplev.h"
|
||||
|
||||
#ifdef HAVE_MMAP_FILE
|
||||
# include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_VALGRIND_CHECKING
|
||||
#include <valgrind.h>
|
||||
#else
|
||||
|
@ -42,46 +42,20 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
/* Statistics about the allocation. */
|
||||
static ggc_statistics *ggc_stats;
|
||||
|
||||
struct traversal_state;
|
||||
|
||||
static int ggc_htab_delete PARAMS ((void **, void *));
|
||||
static hashval_t saving_htab_hash PARAMS ((const PTR));
|
||||
static int saving_htab_eq PARAMS ((const PTR, const PTR));
|
||||
static int call_count PARAMS ((void **, void *));
|
||||
static int call_alloc PARAMS ((void **, void *));
|
||||
static int compare_ptr_data PARAMS ((const void *, const void *));
|
||||
static void relocate_ptrs PARAMS ((void *, void *));
|
||||
static void write_pch_globals PARAMS ((const struct ggc_root_tab * const *tab,
|
||||
struct traversal_state *state));
|
||||
|
||||
/* Maintain global roots that are preserved during GC. */
|
||||
|
||||
/* Global roots that are preserved during calls to gc. */
|
||||
|
||||
struct ggc_root
|
||||
{
|
||||
struct ggc_root *next;
|
||||
void *base;
|
||||
int nelt;
|
||||
int size;
|
||||
void (*cb) PARAMS ((void *));
|
||||
};
|
||||
|
||||
static struct ggc_root *roots;
|
||||
|
||||
/* Add BASE as a new garbage collection root. It is an array of
|
||||
length NELT with each element SIZE bytes long. CB is a
|
||||
function that will be called with a pointer to each element
|
||||
of the array; it is the intention that CB call the appropriate
|
||||
routine to mark gc-able memory for that element. */
|
||||
|
||||
void
|
||||
ggc_add_root (base, nelt, size, cb)
|
||||
void *base;
|
||||
int nelt, size;
|
||||
void (*cb) PARAMS ((void *));
|
||||
{
|
||||
struct ggc_root *x = (struct ggc_root *) xmalloc (sizeof (*x));
|
||||
|
||||
x->next = roots;
|
||||
x->base = base;
|
||||
x->nelt = nelt;
|
||||
x->size = size;
|
||||
x->cb = cb;
|
||||
|
||||
roots = x;
|
||||
}
|
||||
|
||||
/* Process a slot of an htab by deleting it if it has not been marked. */
|
||||
|
||||
static int
|
||||
|
@ -104,7 +78,6 @@ ggc_htab_delete (slot, info)
|
|||
void
|
||||
ggc_mark_roots ()
|
||||
{
|
||||
struct ggc_root *x;
|
||||
const struct ggc_root_tab *const *rt;
|
||||
const struct ggc_root_tab *rti;
|
||||
const struct ggc_cache_tab *const *ct;
|
||||
|
@ -120,23 +93,18 @@ ggc_mark_roots ()
|
|||
for (i = 0; i < rti->nelt; i++)
|
||||
(*rti->cb)(*(void **)((char *)rti->base + rti->stride * i));
|
||||
|
||||
for (x = roots; x != NULL; x = x->next)
|
||||
{
|
||||
char *elt = x->base;
|
||||
int s = x->size, n = x->nelt;
|
||||
void (*cb) PARAMS ((void *)) = x->cb;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; ++i, elt += s)
|
||||
(*cb)(elt);
|
||||
}
|
||||
ggc_mark_stringpool ();
|
||||
|
||||
/* Now scan all hash tables that have objects which are to be deleted if
|
||||
they are not already marked. */
|
||||
for (ct = gt_ggc_cache_rtab; *ct; ct++)
|
||||
for (cti = *ct; cti->base != NULL; cti++)
|
||||
if (*cti->base)
|
||||
htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti);
|
||||
{
|
||||
ggc_set_mark (*cti->base);
|
||||
htab_traverse (*cti->base, ggc_htab_delete, (PTR) cti);
|
||||
ggc_set_mark ((*cti->base)->entries);
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate a block of memory, then clear it. */
|
||||
|
@ -204,6 +172,26 @@ ggc_calloc (s1, s2)
|
|||
return ggc_alloc_cleared (s1 * s2);
|
||||
}
|
||||
|
||||
/* These are for splay_tree_new_ggc. */
|
||||
PTR
|
||||
ggc_splay_alloc (sz, nl)
|
||||
int sz;
|
||||
PTR nl;
|
||||
{
|
||||
if (nl != NULL)
|
||||
abort ();
|
||||
return ggc_alloc (sz);
|
||||
}
|
||||
|
||||
void
|
||||
ggc_splay_dont_free (x, nl)
|
||||
PTR x ATTRIBUTE_UNUSED;
|
||||
PTR nl;
|
||||
{
|
||||
if (nl != NULL)
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Print statistics that are independent of the collector in use. */
|
||||
#define SCALE(x) ((unsigned long) ((x) < 1024*10 \
|
||||
? (x) \
|
||||
|
@ -214,11 +202,9 @@ ggc_calloc (s1, s2)
|
|||
|
||||
void
|
||||
ggc_print_common_statistics (stream, stats)
|
||||
FILE *stream;
|
||||
FILE *stream ATTRIBUTE_UNUSED;
|
||||
ggc_statistics *stats;
|
||||
{
|
||||
int code;
|
||||
|
||||
/* Set the pointer so that during collection we will actually gather
|
||||
the statistics. */
|
||||
ggc_stats = stats;
|
||||
|
@ -226,58 +212,415 @@ ggc_print_common_statistics (stream, stats)
|
|||
/* Then do one collection to fill in the statistics. */
|
||||
ggc_collect ();
|
||||
|
||||
/* Total the statistics. */
|
||||
for (code = 0; code < MAX_TREE_CODES; ++code)
|
||||
{
|
||||
stats->total_num_trees += stats->num_trees[code];
|
||||
stats->total_size_trees += stats->size_trees[code];
|
||||
}
|
||||
for (code = 0; code < NUM_RTX_CODE; ++code)
|
||||
{
|
||||
stats->total_num_rtxs += stats->num_rtxs[code];
|
||||
stats->total_size_rtxs += stats->size_rtxs[code];
|
||||
}
|
||||
|
||||
/* Print the statistics for trees. */
|
||||
fprintf (stream, "\n%-17s%10s %16s %10s\n", "Tree",
|
||||
"Number", "Bytes", "% Total");
|
||||
for (code = 0; code < MAX_TREE_CODES; ++code)
|
||||
if (ggc_stats->num_trees[code])
|
||||
{
|
||||
fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
|
||||
tree_code_name[code],
|
||||
ggc_stats->num_trees[code],
|
||||
SCALE (ggc_stats->size_trees[code]),
|
||||
LABEL (ggc_stats->size_trees[code]),
|
||||
(100 * ((double) ggc_stats->size_trees[code])
|
||||
/ ggc_stats->total_size_trees));
|
||||
}
|
||||
fprintf (stream,
|
||||
"%-17s%10u%16ld%c\n", "Total",
|
||||
ggc_stats->total_num_trees,
|
||||
SCALE (ggc_stats->total_size_trees),
|
||||
LABEL (ggc_stats->total_size_trees));
|
||||
|
||||
/* Print the statistics for RTL. */
|
||||
fprintf (stream, "\n%-17s%10s %16s %10s\n", "RTX",
|
||||
"Number", "Bytes", "% Total");
|
||||
for (code = 0; code < NUM_RTX_CODE; ++code)
|
||||
if (ggc_stats->num_rtxs[code])
|
||||
{
|
||||
fprintf (stream, "%-17s%10u%16ld%c %10.3f\n",
|
||||
rtx_name[code],
|
||||
ggc_stats->num_rtxs[code],
|
||||
SCALE (ggc_stats->size_rtxs[code]),
|
||||
LABEL (ggc_stats->size_rtxs[code]),
|
||||
(100 * ((double) ggc_stats->size_rtxs[code])
|
||||
/ ggc_stats->total_size_rtxs));
|
||||
}
|
||||
fprintf (stream,
|
||||
"%-17s%10u%16ld%c\n", "Total",
|
||||
ggc_stats->total_num_rtxs,
|
||||
SCALE (ggc_stats->total_size_rtxs),
|
||||
LABEL (ggc_stats->total_size_rtxs));
|
||||
/* At present, we don't really gather any interesting statistics. */
|
||||
|
||||
/* Don't gather statistics any more. */
|
||||
ggc_stats = NULL;
|
||||
}
|
||||
|
||||
/* Functions for saving and restoring GCable memory to disk. */
|
||||
|
||||
static htab_t saving_htab;
|
||||
|
||||
struct ptr_data
|
||||
{
|
||||
void *obj;
|
||||
void *note_ptr_cookie;
|
||||
gt_note_pointers note_ptr_fn;
|
||||
gt_handle_reorder reorder_fn;
|
||||
size_t size;
|
||||
void *new_addr;
|
||||
};
|
||||
|
||||
#define POINTER_HASH(x) (hashval_t)((long)x >> 3)
|
||||
|
||||
/* Register an object in the hash table. */
|
||||
|
||||
int
|
||||
gt_pch_note_object (obj, note_ptr_cookie, note_ptr_fn)
|
||||
void *obj;
|
||||
void *note_ptr_cookie;
|
||||
gt_note_pointers note_ptr_fn;
|
||||
{
|
||||
struct ptr_data **slot;
|
||||
|
||||
if (obj == NULL || obj == (void *) 1)
|
||||
return 0;
|
||||
|
||||
slot = (struct ptr_data **)
|
||||
htab_find_slot_with_hash (saving_htab, obj, POINTER_HASH (obj),
|
||||
INSERT);
|
||||
if (*slot != NULL)
|
||||
{
|
||||
if ((*slot)->note_ptr_fn != note_ptr_fn
|
||||
|| (*slot)->note_ptr_cookie != note_ptr_cookie)
|
||||
abort ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
*slot = xcalloc (sizeof (struct ptr_data), 1);
|
||||
(*slot)->obj = obj;
|
||||
(*slot)->note_ptr_fn = note_ptr_fn;
|
||||
(*slot)->note_ptr_cookie = note_ptr_cookie;
|
||||
if (note_ptr_fn == gt_pch_p_S)
|
||||
(*slot)->size = strlen (obj) + 1;
|
||||
else
|
||||
(*slot)->size = ggc_get_size (obj);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Register an object in the hash table. */
|
||||
|
||||
void
|
||||
gt_pch_note_reorder (obj, note_ptr_cookie, reorder_fn)
|
||||
void *obj;
|
||||
void *note_ptr_cookie;
|
||||
gt_handle_reorder reorder_fn;
|
||||
{
|
||||
struct ptr_data *data;
|
||||
|
||||
if (obj == NULL || obj == (void *) 1)
|
||||
return;
|
||||
|
||||
data = htab_find_with_hash (saving_htab, obj, POINTER_HASH (obj));
|
||||
if (data == NULL
|
||||
|| data->note_ptr_cookie != note_ptr_cookie)
|
||||
abort ();
|
||||
|
||||
data->reorder_fn = reorder_fn;
|
||||
}
|
||||
|
||||
/* Hash and equality functions for saving_htab, callbacks for htab_create. */
|
||||
|
||||
static hashval_t
|
||||
saving_htab_hash (p)
|
||||
const PTR p;
|
||||
{
|
||||
return POINTER_HASH (((struct ptr_data *)p)->obj);
|
||||
}
|
||||
|
||||
static int
|
||||
saving_htab_eq (p1, p2)
|
||||
const PTR p1;
|
||||
const PTR p2;
|
||||
{
|
||||
return ((struct ptr_data *)p1)->obj == p2;
|
||||
}
|
||||
|
||||
/* Handy state for the traversal functions. */
|
||||
|
||||
struct traversal_state
|
||||
{
|
||||
FILE *f;
|
||||
struct ggc_pch_data *d;
|
||||
size_t count;
|
||||
struct ptr_data **ptrs;
|
||||
size_t ptrs_i;
|
||||
};
|
||||
|
||||
/* Callbacks for htab_traverse. */
|
||||
|
||||
static int
|
||||
call_count (slot, state_p)
|
||||
void **slot;
|
||||
void *state_p;
|
||||
{
|
||||
struct ptr_data *d = (struct ptr_data *)*slot;
|
||||
struct traversal_state *state = (struct traversal_state *)state_p;
|
||||
|
||||
ggc_pch_count_object (state->d, d->obj, d->size);
|
||||
state->count++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
call_alloc (slot, state_p)
|
||||
void **slot;
|
||||
void *state_p;
|
||||
{
|
||||
struct ptr_data *d = (struct ptr_data *)*slot;
|
||||
struct traversal_state *state = (struct traversal_state *)state_p;
|
||||
|
||||
d->new_addr = ggc_pch_alloc_object (state->d, d->obj, d->size);
|
||||
state->ptrs[state->ptrs_i++] = d;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Callback for qsort. */
|
||||
|
||||
static int
|
||||
compare_ptr_data (p1_p, p2_p)
|
||||
const void *p1_p;
|
||||
const void *p2_p;
|
||||
{
|
||||
struct ptr_data *p1 = *(struct ptr_data *const *)p1_p;
|
||||
struct ptr_data *p2 = *(struct ptr_data *const *)p2_p;
|
||||
return (((size_t)p1->new_addr > (size_t)p2->new_addr)
|
||||
- ((size_t)p1->new_addr < (size_t)p2->new_addr));
|
||||
}
|
||||
|
||||
/* Callbacks for note_ptr_fn. */
|
||||
|
||||
static void
|
||||
relocate_ptrs (ptr_p, state_p)
|
||||
void *ptr_p;
|
||||
void *state_p;
|
||||
{
|
||||
void **ptr = (void **)ptr_p;
|
||||
struct traversal_state *state ATTRIBUTE_UNUSED
|
||||
= (struct traversal_state *)state_p;
|
||||
struct ptr_data *result;
|
||||
|
||||
if (*ptr == NULL || *ptr == (void *)1)
|
||||
return;
|
||||
|
||||
result = htab_find_with_hash (saving_htab, *ptr, POINTER_HASH (*ptr));
|
||||
if (result == NULL)
|
||||
abort ();
|
||||
*ptr = result->new_addr;
|
||||
}
|
||||
|
||||
/* Write out, after relocation, the pointers in TAB. */
|
||||
static void
|
||||
write_pch_globals (tab, state)
|
||||
const struct ggc_root_tab * const *tab;
|
||||
struct traversal_state *state;
|
||||
{
|
||||
const struct ggc_root_tab *const *rt;
|
||||
const struct ggc_root_tab *rti;
|
||||
size_t i;
|
||||
|
||||
for (rt = tab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
{
|
||||
void *ptr = *(void **)((char *)rti->base + rti->stride * i);
|
||||
struct ptr_data *new_ptr;
|
||||
if (ptr == NULL || ptr == (void *)1)
|
||||
{
|
||||
if (fwrite (&ptr, sizeof (void *), 1, state->f)
|
||||
!= 1)
|
||||
fatal_io_error ("can't write PCH file");
|
||||
}
|
||||
else
|
||||
{
|
||||
new_ptr = htab_find_with_hash (saving_htab, ptr,
|
||||
POINTER_HASH (ptr));
|
||||
if (fwrite (&new_ptr->new_addr, sizeof (void *), 1, state->f)
|
||||
!= 1)
|
||||
fatal_io_error ("can't write PCH file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Hold the information we need to mmap the file back in. */
|
||||
|
||||
struct mmap_info
|
||||
{
|
||||
size_t offset;
|
||||
size_t size;
|
||||
void *preferred_base;
|
||||
};
|
||||
|
||||
/* Write out the state of the compiler to F. */
|
||||
|
||||
void
|
||||
gt_pch_save (f)
|
||||
FILE *f;
|
||||
{
|
||||
const struct ggc_root_tab *const *rt;
|
||||
const struct ggc_root_tab *rti;
|
||||
size_t i;
|
||||
struct traversal_state state;
|
||||
char *this_object = NULL;
|
||||
size_t this_object_size = 0;
|
||||
struct mmap_info mmi;
|
||||
size_t page_size = getpagesize();
|
||||
|
||||
gt_pch_save_stringpool ();
|
||||
|
||||
saving_htab = htab_create (50000, saving_htab_hash, saving_htab_eq, free);
|
||||
|
||||
for (rt = gt_ggc_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
(*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
|
||||
|
||||
for (rt = gt_pch_cache_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
(*rti->pchw)(*(void **)((char *)rti->base + rti->stride * i));
|
||||
|
||||
/* Prepare the objects for writing, determine addresses and such. */
|
||||
state.f = f;
|
||||
state.d = init_ggc_pch();
|
||||
state.count = 0;
|
||||
htab_traverse (saving_htab, call_count, &state);
|
||||
|
||||
mmi.size = ggc_pch_total_size (state.d);
|
||||
|
||||
/* Try to arrange things so that no relocation is necessary,
|
||||
but don't try very hard. On most platforms, this will always work,
|
||||
and on the rest it's a lot of work to do better. */
|
||||
#if HAVE_MMAP_FILE
|
||||
mmi.preferred_base = mmap (NULL, mmi.size,
|
||||
PROT_READ | PROT_WRITE, MAP_PRIVATE,
|
||||
fileno (state.f), 0);
|
||||
if (mmi.preferred_base == (void *)-1)
|
||||
mmi.preferred_base = NULL;
|
||||
else
|
||||
munmap (mmi.preferred_base, mmi.size);
|
||||
#else /* HAVE_MMAP_FILE */
|
||||
mmi.preferred_base = NULL;
|
||||
#endif /* HAVE_MMAP_FILE */
|
||||
|
||||
ggc_pch_this_base (state.d, mmi.preferred_base);
|
||||
|
||||
state.ptrs = xmalloc (state.count * sizeof (*state.ptrs));
|
||||
state.ptrs_i = 0;
|
||||
htab_traverse (saving_htab, call_alloc, &state);
|
||||
qsort (state.ptrs, state.count, sizeof (*state.ptrs), compare_ptr_data);
|
||||
|
||||
/* Write out all the scalar variables. */
|
||||
for (rt = gt_pch_scalar_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
if (fwrite (rti->base, rti->stride, 1, f) != 1)
|
||||
fatal_io_error ("can't write PCH file");
|
||||
|
||||
/* Write out all the global pointers, after translation. */
|
||||
write_pch_globals (gt_ggc_rtab, &state);
|
||||
write_pch_globals (gt_pch_cache_rtab, &state);
|
||||
|
||||
ggc_pch_prepare_write (state.d, state.f);
|
||||
|
||||
/* Pad the PCH file so that the mmaped area starts on a page boundary. */
|
||||
{
|
||||
off_t o;
|
||||
o = ftello (state.f) + sizeof (mmi);
|
||||
if (o == (off_t) -1)
|
||||
fatal_io_error ("can't get position in PCH file");
|
||||
mmi.offset = page_size - o % page_size;
|
||||
if (mmi.offset == page_size)
|
||||
mmi.offset = 0;
|
||||
mmi.offset += o;
|
||||
}
|
||||
if (fwrite (&mmi, sizeof (mmi), 1, state.f) != 1)
|
||||
fatal_io_error ("can't write PCH file");
|
||||
if (mmi.offset != 0
|
||||
&& fseek (state.f, mmi.offset, SEEK_SET) != 0)
|
||||
fatal_io_error ("can't write padding to PCH file");
|
||||
|
||||
/* Actually write out the objects. */
|
||||
for (i = 0; i < state.count; i++)
|
||||
{
|
||||
if (this_object_size < state.ptrs[i]->size)
|
||||
{
|
||||
this_object_size = state.ptrs[i]->size;
|
||||
this_object = xrealloc (this_object, this_object_size);
|
||||
}
|
||||
memcpy (this_object, state.ptrs[i]->obj, state.ptrs[i]->size);
|
||||
if (state.ptrs[i]->reorder_fn != NULL)
|
||||
state.ptrs[i]->reorder_fn (state.ptrs[i]->obj,
|
||||
state.ptrs[i]->note_ptr_cookie,
|
||||
relocate_ptrs, &state);
|
||||
state.ptrs[i]->note_ptr_fn (state.ptrs[i]->obj,
|
||||
state.ptrs[i]->note_ptr_cookie,
|
||||
relocate_ptrs, &state);
|
||||
ggc_pch_write_object (state.d, state.f, state.ptrs[i]->obj,
|
||||
state.ptrs[i]->new_addr, state.ptrs[i]->size);
|
||||
if (state.ptrs[i]->note_ptr_fn != gt_pch_p_S)
|
||||
memcpy (state.ptrs[i]->obj, this_object, state.ptrs[i]->size);
|
||||
}
|
||||
ggc_pch_finish (state.d, state.f);
|
||||
|
||||
free (state.ptrs);
|
||||
htab_delete (saving_htab);
|
||||
}
|
||||
|
||||
/* Read the state of the compiler back in from F. */
|
||||
|
||||
void
|
||||
gt_pch_restore (f)
|
||||
FILE *f;
|
||||
{
|
||||
const struct ggc_root_tab *const *rt;
|
||||
const struct ggc_root_tab *rti;
|
||||
size_t i;
|
||||
struct mmap_info mmi;
|
||||
void *addr;
|
||||
|
||||
/* Delete any deletable objects. This makes ggc_pch_read much
|
||||
faster, as it can be sure that no GCable objects remain other
|
||||
than the ones just read in. */
|
||||
for (rt = gt_ggc_deletable_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
memset (rti->base, 0, rti->stride);
|
||||
|
||||
/* Read in all the scalar variables. */
|
||||
for (rt = gt_pch_scalar_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
if (fread (rti->base, rti->stride, 1, f) != 1)
|
||||
fatal_io_error ("can't read PCH file");
|
||||
|
||||
/* Read in all the global pointers, in 6 easy loops. */
|
||||
for (rt = gt_ggc_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
if (fread ((char *)rti->base + rti->stride * i,
|
||||
sizeof (void *), 1, f) != 1)
|
||||
fatal_io_error ("can't read PCH file");
|
||||
|
||||
for (rt = gt_pch_cache_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
if (fread ((char *)rti->base + rti->stride * i,
|
||||
sizeof (void *), 1, f) != 1)
|
||||
fatal_io_error ("can't read PCH file");
|
||||
|
||||
if (fread (&mmi, sizeof (mmi), 1, f) != 1)
|
||||
fatal_io_error ("can't read PCH file");
|
||||
|
||||
#if HAVE_MMAP_FILE
|
||||
addr = mmap (mmi.preferred_base, mmi.size,
|
||||
PROT_READ | PROT_WRITE, MAP_PRIVATE,
|
||||
fileno (f), mmi.offset);
|
||||
#else
|
||||
addr = (void *)-1;
|
||||
#endif
|
||||
if (addr == (void *)-1)
|
||||
{
|
||||
addr = xmalloc (mmi.size);
|
||||
if (fseek (f, mmi.offset, SEEK_SET) != 0
|
||||
|| fread (&mmi, mmi.size, 1, f) != 1)
|
||||
fatal_io_error ("can't read PCH file");
|
||||
}
|
||||
else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
|
||||
fatal_io_error ("can't read PCH file");
|
||||
|
||||
ggc_pch_read (f, addr);
|
||||
|
||||
if (addr != mmi.preferred_base)
|
||||
{
|
||||
for (rt = gt_ggc_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
{
|
||||
char **ptr = (char **)((char *)rti->base + rti->stride * i);
|
||||
if (*ptr != NULL)
|
||||
*ptr += (size_t)addr - (size_t)mmi.preferred_base;
|
||||
}
|
||||
|
||||
for (rt = gt_pch_cache_rtab; *rt; rt++)
|
||||
for (rti = *rt; rti->base != NULL; rti++)
|
||||
for (i = 0; i < rti->nelt; i++)
|
||||
{
|
||||
char **ptr = (char **)((char *)rti->base + rti->stride * i);
|
||||
if (*ptr != NULL)
|
||||
*ptr += (size_t)addr - (size_t)mmi.preferred_base;
|
||||
}
|
||||
|
||||
sorry ("had to relocate PCH");
|
||||
}
|
||||
|
||||
gt_pch_restore_stringpool ();
|
||||
}
|
||||
|
|
258
gcc/ggc-page.c
258
gcc/ggc-page.c
|
@ -1,5 +1,5 @@
|
|||
/* "Bag-of-pages" garbage collector for the GNU compiler.
|
||||
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -147,6 +147,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
the indicated ORDER. */
|
||||
#define OBJECTS_PER_PAGE(ORDER) objects_per_page_table[ORDER]
|
||||
|
||||
/* The number of objects in P. */
|
||||
#define OBJECTS_IN_PAGE(P) ((P)->bytes / OBJECT_SIZE ((P)->order))
|
||||
|
||||
/* The size of an object on a page of the indicated ORDER. */
|
||||
#define OBJECT_SIZE(ORDER) object_size_table[ORDER]
|
||||
|
||||
|
@ -202,6 +205,15 @@ struct max_alignment {
|
|||
|
||||
#define MAX_ALIGNMENT (offsetof (struct max_alignment, u))
|
||||
|
||||
/* Compute the smallest nonnegative number which when added to X gives
|
||||
a multiple of F. */
|
||||
|
||||
#define ROUND_UP_VALUE(x, f) ((f) - 1 - ((f) - 1 + (x)) % (f))
|
||||
|
||||
/* Compute the smallest multiple of F that is >= X. */
|
||||
|
||||
#define ROUND_UP(x, f) (CEIL (x, f) * (f))
|
||||
|
||||
/* The Ith entry is the number of objects on a page or order I. */
|
||||
|
||||
static unsigned objects_per_page_table[NUM_ORDERS];
|
||||
|
@ -1172,7 +1184,7 @@ init_ggc ()
|
|||
|
||||
/* If S is not a multiple of the MAX_ALIGNMENT, then round it up
|
||||
so that we're sure of getting aligned memory. */
|
||||
s = CEIL (s, MAX_ALIGNMENT) * MAX_ALIGNMENT;
|
||||
s = ROUND_UP (s, MAX_ALIGNMENT);
|
||||
object_size_table[order] = s;
|
||||
}
|
||||
|
||||
|
@ -1225,7 +1237,7 @@ ggc_recalculate_in_use_p (p)
|
|||
|
||||
/* Because the past-the-end bit in in_use_p is always set, we
|
||||
pretend there is one additional object. */
|
||||
num_objects = OBJECTS_PER_PAGE (p->order) + 1;
|
||||
num_objects = OBJECTS_IN_PAGE (p) + 1;
|
||||
|
||||
/* Reset the free object count. */
|
||||
p->num_free_objects = num_objects;
|
||||
|
@ -1294,12 +1306,13 @@ clear_marks ()
|
|||
|
||||
for (order = 2; order < NUM_ORDERS; order++)
|
||||
{
|
||||
size_t num_objects = OBJECTS_PER_PAGE (order);
|
||||
size_t bitmap_size = BITMAP_SIZE (num_objects + 1);
|
||||
page_entry *p;
|
||||
|
||||
for (p = G.pages[order]; p != NULL; p = p->next)
|
||||
{
|
||||
size_t num_objects = OBJECTS_IN_PAGE (p);
|
||||
size_t bitmap_size = BITMAP_SIZE (num_objects + 1);
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
/* The data should be page-aligned. */
|
||||
if ((size_t) p->page & (G.pagesize - 1))
|
||||
|
@ -1342,7 +1355,7 @@ sweep_pages ()
|
|||
placed at the end of the list. */
|
||||
page_entry * const last = G.page_tails[order];
|
||||
|
||||
size_t num_objects = OBJECTS_PER_PAGE (order);
|
||||
size_t num_objects;
|
||||
size_t live_objects;
|
||||
page_entry *p, *previous;
|
||||
int done;
|
||||
|
@ -1358,6 +1371,8 @@ sweep_pages ()
|
|||
|
||||
/* Loop until all entries have been examined. */
|
||||
done = (p == last);
|
||||
|
||||
num_objects = OBJECTS_IN_PAGE (p);
|
||||
|
||||
/* Add all live objects on this page to the count of
|
||||
allocated memory. */
|
||||
|
@ -1445,12 +1460,12 @@ poison_pages ()
|
|||
|
||||
for (order = 2; order < NUM_ORDERS; order++)
|
||||
{
|
||||
size_t num_objects = OBJECTS_PER_PAGE (order);
|
||||
size_t size = OBJECT_SIZE (order);
|
||||
page_entry *p;
|
||||
|
||||
for (p = G.pages[order]; p != NULL; p = p->next)
|
||||
{
|
||||
size_t num_objects;
|
||||
size_t i;
|
||||
|
||||
if (p->context_depth != G.context_depth)
|
||||
|
@ -1460,6 +1475,7 @@ poison_pages ()
|
|||
contexts. */
|
||||
continue;
|
||||
|
||||
num_objects = OBJECTS_IN_PAGE (p);
|
||||
for (i = 0; i < num_objects; i++)
|
||||
{
|
||||
size_t word, bit;
|
||||
|
@ -1581,11 +1597,11 @@ ggc_print_statistics ()
|
|||
for (p = G.pages[i]; p; p = p->next)
|
||||
{
|
||||
allocated += p->bytes;
|
||||
in_use +=
|
||||
(OBJECTS_PER_PAGE (i) - p->num_free_objects) * OBJECT_SIZE (i);
|
||||
in_use +=
|
||||
(OBJECTS_IN_PAGE (p) - p->num_free_objects) * OBJECT_SIZE (i);
|
||||
|
||||
overhead += (sizeof (page_entry) - sizeof (long)
|
||||
+ BITMAP_SIZE (OBJECTS_PER_PAGE (i) + 1));
|
||||
+ BITMAP_SIZE (OBJECTS_IN_PAGE (p) + 1));
|
||||
}
|
||||
fprintf (stderr, "%-5lu %10lu%c %10lu%c %10lu%c\n",
|
||||
(unsigned long) OBJECT_SIZE (i),
|
||||
|
@ -1599,3 +1615,225 @@ ggc_print_statistics ()
|
|||
SCALE (G.allocated), LABEL(G.allocated),
|
||||
SCALE (total_overhead), LABEL (total_overhead));
|
||||
}
|
||||
|
||||
struct ggc_pch_data
|
||||
{
|
||||
struct ggc_pch_ondisk
|
||||
{
|
||||
unsigned totals[NUM_ORDERS];
|
||||
} d;
|
||||
size_t base[NUM_ORDERS];
|
||||
size_t written[NUM_ORDERS];
|
||||
};
|
||||
|
||||
struct ggc_pch_data *
|
||||
init_ggc_pch ()
|
||||
{
|
||||
return xcalloc (sizeof (struct ggc_pch_data), 1);
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_count_object (d, x, size)
|
||||
struct ggc_pch_data *d;
|
||||
void *x ATTRIBUTE_UNUSED;
|
||||
size_t size;
|
||||
{
|
||||
unsigned order;
|
||||
|
||||
if (size <= 256)
|
||||
order = size_lookup[size];
|
||||
else
|
||||
{
|
||||
order = 9;
|
||||
while (size > OBJECT_SIZE (order))
|
||||
order++;
|
||||
}
|
||||
|
||||
d->d.totals[order]++;
|
||||
}
|
||||
|
||||
size_t
|
||||
ggc_pch_total_size (d)
|
||||
struct ggc_pch_data *d;
|
||||
{
|
||||
size_t a = 0;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NUM_ORDERS; i++)
|
||||
a += ROUND_UP (d->d.totals[i] * OBJECT_SIZE (i), G.pagesize);
|
||||
return a;
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_this_base (d, base)
|
||||
struct ggc_pch_data *d;
|
||||
void *base;
|
||||
{
|
||||
size_t a = (size_t) base;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < NUM_ORDERS; i++)
|
||||
{
|
||||
d->base[i] = a;
|
||||
a += ROUND_UP (d->d.totals[i] * OBJECT_SIZE (i), G.pagesize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ggc_pch_alloc_object (d, x, size)
|
||||
struct ggc_pch_data *d;
|
||||
void *x ATTRIBUTE_UNUSED;
|
||||
size_t size;
|
||||
{
|
||||
unsigned order;
|
||||
char *result;
|
||||
|
||||
if (size <= 256)
|
||||
order = size_lookup[size];
|
||||
else
|
||||
{
|
||||
order = 9;
|
||||
while (size > OBJECT_SIZE (order))
|
||||
order++;
|
||||
}
|
||||
|
||||
result = (char *) d->base[order];
|
||||
d->base[order] += OBJECT_SIZE (order);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_prepare_write (d, f)
|
||||
struct ggc_pch_data * d ATTRIBUTE_UNUSED;
|
||||
FILE * f ATTRIBUTE_UNUSED;
|
||||
{
|
||||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_write_object (d, f, x, newx, size)
|
||||
struct ggc_pch_data * d ATTRIBUTE_UNUSED;
|
||||
FILE *f;
|
||||
void *x;
|
||||
void *newx ATTRIBUTE_UNUSED;
|
||||
size_t size;
|
||||
{
|
||||
unsigned order;
|
||||
|
||||
if (size <= 256)
|
||||
order = size_lookup[size];
|
||||
else
|
||||
{
|
||||
order = 9;
|
||||
while (size > OBJECT_SIZE (order))
|
||||
order++;
|
||||
}
|
||||
|
||||
if (fwrite (x, size, 1, f) != 1)
|
||||
fatal_io_error ("can't write PCH file");
|
||||
|
||||
/* In the current implementation, SIZE is always equal to
|
||||
OBJECT_SIZE (order) and so the fseek is never executed. */
|
||||
if (size != OBJECT_SIZE (order)
|
||||
&& fseek (f, OBJECT_SIZE (order) - size, SEEK_CUR) != 0)
|
||||
fatal_io_error ("can't write PCH file");
|
||||
|
||||
d->written[order]++;
|
||||
if (d->written[order] == d->d.totals[order]
|
||||
&& fseek (f, ROUND_UP_VALUE (d->d.totals[order] * OBJECT_SIZE (order),
|
||||
G.pagesize),
|
||||
SEEK_CUR) != 0)
|
||||
fatal_io_error ("can't write PCH file");
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_finish (d, f)
|
||||
struct ggc_pch_data * d;
|
||||
FILE *f;
|
||||
{
|
||||
if (fwrite (&d->d, sizeof (d->d), 1, f) != 1)
|
||||
fatal_io_error ("can't write PCH file");
|
||||
free (d);
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_read (f, addr)
|
||||
FILE *f;
|
||||
void *addr;
|
||||
{
|
||||
struct ggc_pch_ondisk d;
|
||||
unsigned i;
|
||||
char *offs = addr;
|
||||
|
||||
/* We've just read in a PCH file. So, every object that used to be allocated
|
||||
is now free. */
|
||||
clear_marks ();
|
||||
#ifdef GGC_POISON
|
||||
poison_pages ();
|
||||
#endif
|
||||
|
||||
/* No object read from a PCH file should ever be freed. So, set the
|
||||
context depth to 1, and set the depth of all the currently-allocated
|
||||
pages to be 1 too. PCH pages will have depth 0. */
|
||||
if (G.context_depth != 0)
|
||||
abort ();
|
||||
G.context_depth = 1;
|
||||
for (i = 0; i < NUM_ORDERS; i++)
|
||||
{
|
||||
page_entry *p;
|
||||
for (p = G.pages[i]; p != NULL; p = p->next)
|
||||
p->context_depth = G.context_depth;
|
||||
}
|
||||
|
||||
/* Allocate the appropriate page-table entries for the pages read from
|
||||
the PCH file. */
|
||||
if (fread (&d, sizeof (d), 1, f) != 1)
|
||||
fatal_io_error ("can't read PCH file");
|
||||
|
||||
for (i = 0; i < NUM_ORDERS; i++)
|
||||
{
|
||||
struct page_entry *entry;
|
||||
char *pte;
|
||||
size_t bytes;
|
||||
size_t num_objs;
|
||||
size_t j;
|
||||
|
||||
if (d.totals[i] == 0)
|
||||
continue;
|
||||
|
||||
bytes = ROUND_UP (d.totals[i] * OBJECT_SIZE (i), G.pagesize);
|
||||
num_objs = bytes / OBJECT_SIZE (i);
|
||||
entry = xcalloc (1, (sizeof (struct page_entry)
|
||||
- sizeof (long)
|
||||
+ BITMAP_SIZE (num_objs + 1)));
|
||||
entry->bytes = bytes;
|
||||
entry->page = offs;
|
||||
entry->context_depth = 0;
|
||||
offs += bytes;
|
||||
entry->num_free_objects = 0;
|
||||
entry->order = i;
|
||||
|
||||
for (j = 0;
|
||||
j + HOST_BITS_PER_LONG <= num_objs + 1;
|
||||
j += HOST_BITS_PER_LONG)
|
||||
entry->in_use_p[j / HOST_BITS_PER_LONG] = -1;
|
||||
for (; j < num_objs + 1; j++)
|
||||
entry->in_use_p[j / HOST_BITS_PER_LONG]
|
||||
|= 1L << (j % HOST_BITS_PER_LONG);
|
||||
|
||||
for (pte = entry->page;
|
||||
pte < entry->page + entry->bytes;
|
||||
pte += G.pagesize)
|
||||
set_page_table_entry (pte, entry);
|
||||
|
||||
if (G.page_tails[i] != NULL)
|
||||
G.page_tails[i]->next = entry;
|
||||
else
|
||||
G.pages[i] = entry;
|
||||
G.page_tails[i] = entry;
|
||||
}
|
||||
|
||||
/* Update the statistics. */
|
||||
G.allocated = G.allocated_last_gc = offs - (char *)addr;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Simple garbage collection for the GNU compiler.
|
||||
Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include "flags.h"
|
||||
#include "varray.h"
|
||||
#include "ggc.h"
|
||||
#include "toplev.h"
|
||||
#include "timevar.h"
|
||||
#include "params.h"
|
||||
|
||||
|
@ -490,16 +491,90 @@ ggc_print_statistics ()
|
|||
|
||||
fprintf (stderr, "\n\
|
||||
Total internal data (bytes)\t%ld%c\n\
|
||||
Number of leaves in tree\t%d\n\
|
||||
Number of leaves in tree\t%lu\n\
|
||||
Average leaf depth\t\t%.1f\n",
|
||||
SCALE(G.objects * offsetof (struct ggc_mem, u)),
|
||||
LABEL(G.objects * offsetof (struct ggc_mem, u)),
|
||||
nleaf, (double)sumdepth / (double)nleaf);
|
||||
(unsigned long)nleaf, (double)sumdepth / (double)nleaf);
|
||||
|
||||
/* Report overall memory usage. */
|
||||
fprintf (stderr, "\n\
|
||||
Total objects allocated\t\t%d\n\
|
||||
Total objects allocated\t\t%ld\n\
|
||||
Total memory in GC arena\t%ld%c\n",
|
||||
G.objects,
|
||||
(unsigned long)G.objects,
|
||||
SCALE(G.allocated), LABEL(G.allocated));
|
||||
}
|
||||
|
||||
struct ggc_pch_data *
|
||||
init_ggc_pch ()
|
||||
{
|
||||
sorry ("Generating PCH files is not supported when using ggc-simple.c");
|
||||
/* It could be supported, but the code is not yet written. */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_count_object (d, x, size)
|
||||
struct ggc_pch_data *d ATTRIBUTE_UNUSED;
|
||||
void *x ATTRIBUTE_UNUSED;
|
||||
size_t size ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
size_t
|
||||
ggc_pch_total_size (d)
|
||||
struct ggc_pch_data *d ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_this_base (d, base)
|
||||
struct ggc_pch_data *d ATTRIBUTE_UNUSED;
|
||||
void *base ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ggc_pch_alloc_object (d, x, size)
|
||||
struct ggc_pch_data *d ATTRIBUTE_UNUSED;
|
||||
void *x ATTRIBUTE_UNUSED;
|
||||
size_t size ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_prepare_write (d, f)
|
||||
struct ggc_pch_data * d ATTRIBUTE_UNUSED;
|
||||
FILE * f ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_write_object (d, f, x, newx, size)
|
||||
struct ggc_pch_data * d ATTRIBUTE_UNUSED;
|
||||
FILE *f ATTRIBUTE_UNUSED;
|
||||
void *x ATTRIBUTE_UNUSED;
|
||||
void *newx ATTRIBUTE_UNUSED;
|
||||
size_t size ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_finish (d, f)
|
||||
struct ggc_pch_data * d ATTRIBUTE_UNUSED;
|
||||
FILE *f ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ggc_pch_read (f, addr)
|
||||
FILE *f ATTRIBUTE_UNUSED;
|
||||
void *addr ATTRIBUTE_UNUSED;
|
||||
{
|
||||
/* This should be impossible, since we won't generate any valid PCH
|
||||
files for this configuration. */
|
||||
abort ();
|
||||
}
|
||||
|
|
184
gcc/ggc.h
184
gcc/ggc.h
|
@ -18,9 +18,6 @@ along with GCC; see the file COPYING. If not, write to the Free
|
|||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#include "varray.h"
|
||||
#include "gtype-desc.h"
|
||||
|
||||
/* Symbols are marked with `ggc' for `gcc gc' so as not to interfere with
|
||||
an external gc library that might be linked in. */
|
||||
|
||||
|
@ -29,10 +26,39 @@ extern const char empty_string[]; /* empty string */
|
|||
extern const char digit_vector[]; /* "0" .. "9" */
|
||||
#define digit_string(d) (digit_vector + ((d) * 2))
|
||||
|
||||
/* Manipulate global roots that are needed between calls to gc.
|
||||
THIS ROUTINE IS OBSOLETE, do not use it for new code. */
|
||||
extern void ggc_add_root PARAMS ((void *base, int nelt,
|
||||
int size, void (*)(void *)));
|
||||
/* Internal functions and data structures used by the GTY
|
||||
machinery. */
|
||||
|
||||
/* The first parameter is a pointer to a pointer, the second a cookie. */
|
||||
typedef void (*gt_pointer_operator) PARAMS ((void *, void *));
|
||||
|
||||
#include "gtype-desc.h"
|
||||
|
||||
/* One of these applies its third parameter (with cookie in the fourth
|
||||
parameter) to each pointer in the object pointed to by the first
|
||||
parameter, using the second parameter. */
|
||||
typedef void (*gt_note_pointers)
|
||||
PARAMS ((void *, void *, gt_pointer_operator, void *));
|
||||
|
||||
/* One of these is called before objects are re-ordered in memory.
|
||||
The first parameter is the original object, the second is the
|
||||
subobject that has had its pointers reordered, the third parameter
|
||||
can compute the new values of a pointer when given the cookie in
|
||||
the fourth parameter. */
|
||||
typedef void (*gt_handle_reorder)
|
||||
PARAMS ((void *, void *, gt_pointer_operator, void *));
|
||||
|
||||
/* Used by the gt_pch_n_* routines. Register an object in the hash table. */
|
||||
extern int gt_pch_note_object
|
||||
PARAMS ((void *, void *, gt_note_pointers));
|
||||
|
||||
/* Used by the gt_pch_n_* routines. Register that an object has a reorder
|
||||
function. */
|
||||
extern void gt_pch_note_reorder
|
||||
PARAMS ((void *, void *, gt_handle_reorder));
|
||||
|
||||
/* Mark the object in the first parameter and anything it points to. */
|
||||
typedef void (*gt_pointer_walker) PARAMS ((void *));
|
||||
|
||||
/* Structures for the easy way to mark roots.
|
||||
In an array, terminated by having base == NULL.*/
|
||||
|
@ -40,12 +66,15 @@ struct ggc_root_tab {
|
|||
void *base;
|
||||
size_t nelt;
|
||||
size_t stride;
|
||||
void (*cb) PARAMS ((void *));
|
||||
gt_pointer_walker cb;
|
||||
gt_pointer_walker pchw;
|
||||
};
|
||||
#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL }
|
||||
#define LAST_GGC_ROOT_TAB { NULL, 0, 0, NULL, NULL }
|
||||
/* Pointers to arrays of ggc_root_tab, terminated by NULL. */
|
||||
extern const struct ggc_root_tab * const gt_ggc_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_ggc_deletable_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_pch_cache_rtab[];
|
||||
extern const struct ggc_root_tab * const gt_pch_scalar_rtab[];
|
||||
|
||||
/* Structure for hash table cache marking. */
|
||||
struct htab;
|
||||
|
@ -53,23 +82,19 @@ struct ggc_cache_tab {
|
|||
struct htab * *base;
|
||||
size_t nelt;
|
||||
size_t stride;
|
||||
void (*cb) PARAMS ((void *));
|
||||
gt_pointer_walker cb;
|
||||
gt_pointer_walker pchw;
|
||||
int (*marked_p) PARAMS ((const void *));
|
||||
};
|
||||
#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL }
|
||||
#define LAST_GGC_CACHE_TAB { NULL, 0, 0, NULL, NULL, NULL }
|
||||
/* Pointers to arrays of ggc_cache_tab, terminated by NULL. */
|
||||
extern const struct ggc_cache_tab * const gt_ggc_cache_rtab[];
|
||||
|
||||
extern void ggc_mark_roots PARAMS ((void));
|
||||
|
||||
/* If EXPR is not NULL and previously unmarked, mark it and evaluate
|
||||
to true. Otherwise evaluate to false. */
|
||||
#define ggc_test_and_set_mark(EXPR) \
|
||||
((EXPR) != NULL && ((void *) (EXPR)) != (void *) 1 && ! ggc_set_mark (EXPR))
|
||||
|
||||
#define ggc_mark_rtx gt_ggc_m_7rtx_def
|
||||
#define ggc_mark_tree gt_ggc_m_9tree_node
|
||||
|
||||
#define ggc_mark(EXPR) \
|
||||
do { \
|
||||
const void *const a__ = (EXPR); \
|
||||
|
@ -77,11 +102,45 @@ extern void ggc_mark_roots PARAMS ((void));
|
|||
ggc_set_mark (a__); \
|
||||
} while (0)
|
||||
|
||||
/* A GC implementation must provide these functions. */
|
||||
/* Actually set the mark on a particular region of memory, but don't
|
||||
follow pointers. This function is called by ggc_mark_*. It
|
||||
returns zero if the object was not previously marked; non-zero if
|
||||
the object was already marked, or if, for any other reason,
|
||||
pointers in this data structure should not be traversed. */
|
||||
extern int ggc_set_mark PARAMS ((const void *));
|
||||
|
||||
/* Return 1 if P has been marked, zero otherwise.
|
||||
P must have been allocated by the GC allocator; it mustn't point to
|
||||
static objects, stack variables, or memory allocated with malloc. */
|
||||
extern int ggc_marked_p PARAMS ((const void *));
|
||||
|
||||
/* Mark the entries in the string pool. */
|
||||
extern void ggc_mark_stringpool PARAMS ((void));
|
||||
|
||||
/* Call ggc_set_mark on all the roots. */
|
||||
|
||||
extern void ggc_mark_roots PARAMS ((void));
|
||||
|
||||
/* Save and restore the string pool entries for PCH. */
|
||||
|
||||
extern void gt_pch_save_stringpool PARAMS ((void));
|
||||
extern void gt_pch_restore_stringpool PARAMS ((void));
|
||||
|
||||
/* PCH and GGC handling for strings, mostly trivial. */
|
||||
|
||||
extern void gt_pch_p_S PARAMS ((void *, void *,
|
||||
gt_pointer_operator, void *));
|
||||
extern void gt_pch_n_S PARAMS ((const void *));
|
||||
extern void gt_ggc_m_S PARAMS ((void *));
|
||||
|
||||
/* Initialise the string pool. */
|
||||
extern void init_stringpool PARAMS ((void));
|
||||
|
||||
/* A GC implementation must provide these functions. They are internal
|
||||
to the GC system. */
|
||||
|
||||
/* Initialize the garbage collector. */
|
||||
extern void init_ggc PARAMS ((void));
|
||||
extern void init_stringpool PARAMS ((void));
|
||||
|
||||
/* Start a new GGC context. Memory allocated in previous contexts
|
||||
will not be collected while the new context is active. */
|
||||
|
@ -91,6 +150,48 @@ extern void ggc_push_context PARAMS ((void));
|
|||
will be merged with the old context. */
|
||||
extern void ggc_pop_context PARAMS ((void));
|
||||
|
||||
struct ggc_pch_data;
|
||||
|
||||
/* Return a new ggc_pch_data structure. */
|
||||
extern struct ggc_pch_data *init_ggc_pch PARAMS ((void));
|
||||
|
||||
/* The second parameter and third parameters give the address and size
|
||||
of an object. Update the ggc_pch_data structure with as much of
|
||||
that information as is necessary. */
|
||||
extern void ggc_pch_count_object PARAMS ((struct ggc_pch_data *,
|
||||
void *, size_t));
|
||||
|
||||
/* Return the total size of the data to be written to hold all
|
||||
the objects previously passed to ggc_pch_count_object. */
|
||||
extern size_t ggc_pch_total_size PARAMS ((struct ggc_pch_data *));
|
||||
|
||||
/* The objects, when read, will most likely be at the address
|
||||
in the second parameter. */
|
||||
extern void ggc_pch_this_base PARAMS ((struct ggc_pch_data *,
|
||||
void *));
|
||||
|
||||
/* Assuming that the objects really do end up at the address
|
||||
passed to ggc_pch_this_base, return the address of this object. */
|
||||
extern char *ggc_pch_alloc_object PARAMS ((struct ggc_pch_data *,
|
||||
void *, size_t));
|
||||
|
||||
/* Write out any initial information required. */
|
||||
extern void ggc_pch_prepare_write PARAMS ((struct ggc_pch_data *,
|
||||
FILE *));
|
||||
/* Write out this object, including any padding. */
|
||||
extern void ggc_pch_write_object PARAMS ((struct ggc_pch_data *,
|
||||
FILE *, void *, void *,
|
||||
size_t));
|
||||
/* All objects have been written, write out any final information
|
||||
required. */
|
||||
extern void ggc_pch_finish PARAMS ((struct ggc_pch_data *,
|
||||
FILE *));
|
||||
|
||||
/* A PCH file has just been read in at the address specified second
|
||||
parameter. Set up the GC implementation for the new objects. */
|
||||
extern void ggc_pch_read PARAMS ((FILE *, void *));
|
||||
|
||||
|
||||
/* Allocation. */
|
||||
|
||||
/* The internal primitive. */
|
||||
|
@ -115,6 +216,13 @@ extern void *ggc_calloc PARAMS ((size_t, size_t));
|
|||
#define htab_create_ggc(SIZE, HASH, EQ, DEL) \
|
||||
htab_create_alloc (SIZE, HASH, EQ, DEL, ggc_calloc, NULL)
|
||||
|
||||
#define splay_tree_new_ggc(COMPARE) \
|
||||
splay_tree_new_with_allocator (COMPARE, NULL, NULL, \
|
||||
&ggc_splay_alloc, &ggc_splay_dont_free, \
|
||||
NULL)
|
||||
extern PTR ggc_splay_alloc PARAMS ((int, void *));
|
||||
extern void ggc_splay_dont_free PARAMS ((void *, void *));
|
||||
|
||||
/* Allocate a gc-able string, and fill it with LENGTH bytes from CONTENTS.
|
||||
If LENGTH is -1, then CONTENTS is assumed to be a
|
||||
null-terminated string and the memory sized accordingly. */
|
||||
|
@ -128,47 +236,25 @@ extern const char *ggc_alloc_string PARAMS ((const char *contents,
|
|||
function is called, not during allocations. */
|
||||
extern void ggc_collect PARAMS ((void));
|
||||
|
||||
/* Actually set the mark on a particular region of memory, but don't
|
||||
follow pointers. This function is called by ggc_mark_*. It
|
||||
returns zero if the object was not previously marked; nonzero if
|
||||
the object was already marked, or if, for any other reason,
|
||||
pointers in this data structure should not be traversed. */
|
||||
extern int ggc_set_mark PARAMS ((const void *));
|
||||
/* Return the number of bytes allocated at the indicated address. */
|
||||
extern size_t ggc_get_size PARAMS ((const void *));
|
||||
|
||||
/* Return 1 if P has been marked, zero otherwise.
|
||||
P must have been allocated by the GC allocator; it mustn't point to
|
||||
static objects, stack variables, or memory allocated with malloc. */
|
||||
extern int ggc_marked_p PARAMS ((const void *));
|
||||
/* Write out all GCed objects to F. */
|
||||
extern void gt_pch_save PARAMS ((FILE *f));
|
||||
|
||||
/* Read objects previously saved with gt_pch_save from F. */
|
||||
extern void gt_pch_restore PARAMS ((FILE *f));
|
||||
|
||||
/* Statistics. */
|
||||
|
||||
/* This structure contains the statistics common to all collectors.
|
||||
Particular collectors can extend this structure. */
|
||||
typedef struct ggc_statistics
|
||||
{
|
||||
/* The Ith element is the number of nodes allocated with code I. */
|
||||
unsigned num_trees[256];
|
||||
/* The Ith element is the number of bytes allocated by nodes with
|
||||
code I. */
|
||||
size_t size_trees[256];
|
||||
/* The Ith element is the number of nodes allocated with code I. */
|
||||
unsigned num_rtxs[256];
|
||||
/* The Ith element is the number of bytes allocated by nodes with
|
||||
code I. */
|
||||
size_t size_rtxs[256];
|
||||
/* The total size of the tree nodes allocated. */
|
||||
size_t total_size_trees;
|
||||
/* The total size of the RTL nodes allocated. */
|
||||
size_t total_size_rtxs;
|
||||
/* The total number of tree nodes allocated. */
|
||||
unsigned total_num_trees;
|
||||
/* The total number of RTL nodes allocated. */
|
||||
unsigned total_num_rtxs;
|
||||
/* At present, we don't really gather any interesting statistics. */
|
||||
int unused;
|
||||
} ggc_statistics;
|
||||
|
||||
/* Return the number of bytes allocated at the indicated address. */
|
||||
extern size_t ggc_get_size PARAMS ((const void *));
|
||||
|
||||
/* Used by the various collectors to gather and print statistics that
|
||||
do not depend on the collector in use. */
|
||||
extern void ggc_print_common_statistics PARAMS ((FILE *, ggc_statistics *));
|
||||
|
|
|
@ -1,3 +1,77 @@
|
|||
2003-01-09 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
Merge from pch-branch:
|
||||
|
||||
2002-12-02 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* Make-lang.in (java/gjavah.o): Update dependencies.
|
||||
* gjavah.c: Include ggc.h.
|
||||
|
||||
2002-08-16 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* Make-lang.in (GCJH_OBJS): Add ggc-none.o.
|
||||
(JCFDUMP_OBJS): Add ggc-none.o.
|
||||
(java/jcf-dump.o): Depend on GGC_H.
|
||||
* jcf-reader.c (jcf_parse_constant_pool): Use ggc_alloc to allocate
|
||||
CPool substructures.
|
||||
* jcf-parse.c (process_zip_dir): Use ggc_alloc to allocate JCFs.
|
||||
* jcf-dump.c: Include ggc.h.
|
||||
|
||||
2002-08-08 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* jcf.h (union cpool_entry): New.
|
||||
(struct CPool): Use gengtype to mark. Change field 'data' to be
|
||||
an array of unions.
|
||||
(struct JCF): Use gengtype to mark.
|
||||
(CPOOL_UINT): Update for new cpool_entry type.
|
||||
(CPOOL_USHORT1): Likewise.
|
||||
(CPOOL_USHORT2): Likewise.
|
||||
(CPOOL_FINISH): Use GC to free cpool subfields.
|
||||
* parse.h (struct parser_ctxt): Mark field current_jcf.
|
||||
* lex.c (java_init_lex): Use GC to allocate struct JCF.
|
||||
* jcf-parse.c (HANDLE_CONSTANT_Utf8): Update for new cpool_entry type.
|
||||
(main_jcf): Use gengtype to mark.
|
||||
(ggc_mark_jcf): Delete.
|
||||
(get_constant): Update for new cpool_entry type.
|
||||
(give_name_to_class): Likewise.
|
||||
(get_class_constant): Likewise.
|
||||
(init_outgoing_cpool): Use GGC to allocate struct CPool.
|
||||
(java_parse_file): Use GGC to allocate struct JCF.
|
||||
(init_jcf_parse): Don't call ggc_add_root.
|
||||
* jcf-reader.c (jcf_parse_constant_pool): Update for new
|
||||
cpool_entry type.
|
||||
* java-tree.h (current_jcf): Use gengtype to mark.
|
||||
(CPOOL_UTF): Update for new cpool_entry type.
|
||||
(outgoing_cpool): Use gengtype to mark.
|
||||
(struct lang_type): GC struct JCF and struct CPool.
|
||||
* config-lang.in (gtfiles): Add jcf.h.
|
||||
* constants.c (find_tree_constant): New.
|
||||
(set_constant_entry): Allocate cpool subfields using GGC. Update
|
||||
for new cpool_entry type.
|
||||
(find_constant1): Update for new cpool_entry type.
|
||||
(find_constant2): Likewise.
|
||||
(find_utf8_constant): Use find_tree_constant.
|
||||
(find_class_or_string_constant): Remove unnecessary cast to jword.
|
||||
Update for new cpool_entry type.
|
||||
(count_constant_pool_bytes): Update for new cpool_entry type.
|
||||
(write_constant_pool): Likewise.
|
||||
(alloc_name_constant): Use find_tree_constant.
|
||||
(build_constants_constructor): Update for new cpool_entry type.
|
||||
|
||||
2002-08-08 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* parse.y (mark_parser_ctxt): Delete.
|
||||
(goal): Don't use ggc_add_root.
|
||||
(create_new_parser_context): Use GC to allocate struct parser_ctxt.
|
||||
(java_pop_parser_context): Let GC free parser_ctxt.
|
||||
(java_parser_context_resume): Likewise.
|
||||
* parse.h (struct parser_ctxt): Use gengtype to mark.
|
||||
(ctxp): Likewise.
|
||||
(ctxp_for_generation): Likewise.
|
||||
* lex.h (struct java_lc_s): Mark for gengtype.
|
||||
(java_lexer): Rearrange for gengtype.
|
||||
* config-lang.in (gtfiles): Add lex.h, parse.h.
|
||||
|
||||
2003-01-09 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* All Files: Remove PARAMS macro.
|
||||
|
|
|
@ -113,12 +113,12 @@ JAVA_OBJS = java/parse.o java/class.o java/decl.o java/expr.o \
|
|||
java/jcf-path.o java/xref.o java/boehm.o java/java-tree-inline.o mkdeps.o
|
||||
|
||||
GCJH_OBJS = java/gjavah.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
|
||||
java/zextract.o version.o mkdeps.o errors.o
|
||||
java/zextract.o version.o mkdeps.o errors.o ggc-none.o
|
||||
|
||||
JVSCAN_OBJS = java/parse-scan.o java/jv-scan.o version.o
|
||||
|
||||
JCFDUMP_OBJS = java/jcf-dump.o java/jcf-io.o java/jcf-depend.o java/jcf-path.o \
|
||||
java/zextract.o errors.o version.o mkdeps.o
|
||||
java/zextract.o errors.o version.o mkdeps.o ggc-none.o
|
||||
|
||||
JVGENMAIN_OBJS = java/jvgenmain.o java/mangle_name.o errors.o
|
||||
|
||||
|
@ -267,9 +267,9 @@ java/parse.o: java/parse.c java/jcf-reader.c $(CONFIG_H) $(SYSTEM_H) \
|
|||
java/lex.h $(GGC_H) debug.h gt-java-parse.h gtype-java.h
|
||||
java/jcf-dump.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(JAVA_TREE_H) \
|
||||
java/jcf-dump.c java/jcf-reader.c java/jcf.h java/javaop.h java/javaop.def \
|
||||
version.h
|
||||
version.h $(GGC_H)
|
||||
java/gjavah.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(JAVA_TREE_H) \
|
||||
java/gjavah.c java/jcf-reader.c java/jcf.h java/javaop.h version.h
|
||||
java/gjavah.c java/jcf-reader.c java/jcf.h java/javaop.h version.h $(GGC_H)
|
||||
java/boehm.o: java/boehm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
|
||||
$(TREE_H) $(JAVA_TREE_H) java/parse.h toplev.h
|
||||
java/buffer.o: java/buffer.c $(CONFIG_H) java/buffer.h $(SYSTEM_H) coretypes.h \
|
||||
|
|
|
@ -36,7 +36,7 @@ compilers="jc1\$(exeext) jvgenmain\$(exeext)"
|
|||
|
||||
stagestuff="jc1\$(exeext) gcj\$(exeext) jvgenmain\$(exeext) gcjh\$(exeext) jv-scan\$(exeext) jcf-dump\$(exeext)"
|
||||
|
||||
gtfiles="\$(srcdir)/java/java-tree.h \$(srcdir)/java/builtins.c \$(srcdir)/java/class.c \$(srcdir)/java/constants.c \$(srcdir)/java/decl.c \$(srcdir)/java/expr.c \$(srcdir)/java/jcf-parse.c \$(srcdir)/java/jcf-write.c \$(srcdir)/java/lang.c \$(srcdir)/java/mangle.c \$(srcdir)/java/parse.y"
|
||||
gtfiles="\$(srcdir)/java/java-tree.h \$(srcdir)/java/jcf.h \$(srcdir)/java/lex.h \$(srcdir)/java/parse.h \$(srcdir)/java/builtins.c \$(srcdir)/java/class.c \$(srcdir)/java/constants.c \$(srcdir)/java/decl.c \$(srcdir)/java/expr.c \$(srcdir)/java/jcf-parse.c \$(srcdir)/java/jcf-write.c \$(srcdir)/java/lang.c \$(srcdir)/java/mangle.c \$(srcdir)/java/parse.y"
|
||||
|
||||
target_libs=${libgcj_saved}
|
||||
lang_dirs="zlib fastjar"
|
||||
|
|
|
@ -32,6 +32,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
#include "ggc.h"
|
||||
|
||||
static void set_constant_entry (CPool *, int, int, jword);
|
||||
static int find_tree_constant (CPool *, int, tree);
|
||||
static int find_class_or_string_constant (CPool *, int, tree);
|
||||
static int find_name_and_type_constant (CPool *, tree, tree);
|
||||
static tree get_tag_node (int);
|
||||
|
@ -49,8 +50,8 @@ set_constant_entry (cpool, index, tag, value)
|
|||
if (cpool->data == NULL)
|
||||
{
|
||||
cpool->capacity = 100;
|
||||
cpool->tags = xmalloc (sizeof(uint8) * cpool->capacity);
|
||||
cpool->data = xmalloc (sizeof(jword) * cpool->capacity);
|
||||
cpool->tags = ggc_alloc (sizeof(uint8) * cpool->capacity);
|
||||
cpool->data = ggc_alloc (sizeof(union cpool_entry) * cpool->capacity);
|
||||
cpool->count = 1;
|
||||
}
|
||||
if (index >= cpool->capacity)
|
||||
|
@ -58,13 +59,15 @@ set_constant_entry (cpool, index, tag, value)
|
|||
cpool->capacity *= 2;
|
||||
if (index >= cpool->capacity)
|
||||
cpool->capacity = index + 10;
|
||||
cpool->tags = xrealloc (cpool->tags, sizeof(uint8) * cpool->capacity);
|
||||
cpool->data = xrealloc (cpool->data, sizeof(jword) * cpool->capacity);
|
||||
cpool->tags = ggc_realloc (cpool->tags,
|
||||
sizeof(uint8) * cpool->capacity);
|
||||
cpool->data = ggc_realloc (cpool->data,
|
||||
sizeof(union cpool_entry) * cpool->capacity);
|
||||
}
|
||||
if (index >= cpool->count)
|
||||
cpool->count = index + 1;
|
||||
cpool->tags[index] = tag;
|
||||
cpool->data[index] = value;
|
||||
cpool->data[index].w = value;
|
||||
}
|
||||
|
||||
/* Find (or create) a constant pool entry matching TAG and VALUE. */
|
||||
|
@ -78,7 +81,7 @@ find_constant1 (cpool, tag, value)
|
|||
int i;
|
||||
for (i = cpool->count; --i > 0; )
|
||||
{
|
||||
if (cpool->tags[i] == tag && cpool->data[i] == value)
|
||||
if (cpool->tags[i] == tag && cpool->data[i].w == value)
|
||||
return i;
|
||||
}
|
||||
i = cpool->count == 0 ? 1 : cpool->count;
|
||||
|
@ -98,8 +101,8 @@ find_constant2 (cpool, tag, word1, word2)
|
|||
for (i = cpool->count - 1; --i > 0; )
|
||||
{
|
||||
if (cpool->tags[i] == tag
|
||||
&& cpool->data[i] == word1
|
||||
&& cpool->data[i+1] == word2)
|
||||
&& cpool->data[i].w == word1
|
||||
&& cpool->data[i+1].w == word2)
|
||||
return i;
|
||||
}
|
||||
i = cpool->count == 0 ? 1 : cpool->count;
|
||||
|
@ -108,6 +111,25 @@ find_constant2 (cpool, tag, word1, word2)
|
|||
return i;
|
||||
}
|
||||
|
||||
static int
|
||||
find_tree_constant (cpool, tag, value)
|
||||
CPool *cpool;
|
||||
int tag;
|
||||
tree value;
|
||||
{
|
||||
int i;
|
||||
for (i = cpool->count; --i > 0; )
|
||||
{
|
||||
if (cpool->tags[i] == tag && cpool->data[i].t == value)
|
||||
return i;
|
||||
}
|
||||
i = cpool->count == 0 ? 1 : cpool->count;
|
||||
set_constant_entry (cpool, i, tag, 0);
|
||||
cpool->data[i].t = value;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
find_utf8_constant (cpool, name)
|
||||
CPool *cpool;
|
||||
|
@ -115,7 +137,7 @@ find_utf8_constant (cpool, name)
|
|||
{
|
||||
if (name == NULL_TREE)
|
||||
return 0;
|
||||
return find_constant1 (cpool, CONSTANT_Utf8, (jword) name);
|
||||
return find_tree_constant (cpool, CONSTANT_Utf8, name);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -124,15 +146,15 @@ find_class_or_string_constant (cpool, tag, name)
|
|||
int tag;
|
||||
tree name;
|
||||
{
|
||||
int j = find_utf8_constant (cpool, name);
|
||||
jword j = find_utf8_constant (cpool, name);
|
||||
int i;
|
||||
for (i = cpool->count; --i > 0; )
|
||||
{
|
||||
if (cpool->tags[i] == tag && cpool->data[i] == (jword) j)
|
||||
if (cpool->tags[i] == tag && cpool->data[i].w == j)
|
||||
return i;
|
||||
}
|
||||
i = cpool->count;
|
||||
set_constant_entry (cpool, i, tag, (jword) j);
|
||||
set_constant_entry (cpool, i, tag, j);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -255,7 +277,7 @@ count_constant_pool_bytes (cpool)
|
|||
break;
|
||||
case CONSTANT_Utf8:
|
||||
{
|
||||
tree t = (tree) cpool->data[i];
|
||||
tree t = cpool->data[i].t;
|
||||
int len = IDENTIFIER_LENGTH (t);
|
||||
size += len + 2;
|
||||
}
|
||||
|
@ -279,7 +301,7 @@ write_constant_pool (cpool, buffer, length)
|
|||
{
|
||||
unsigned char *ptr = buffer;
|
||||
int i = 1;
|
||||
jword *datap = &cpool->data[1];
|
||||
union cpool_entry *datap = &cpool->data[1];
|
||||
PUT2 (cpool->count);
|
||||
for ( ; i < cpool->count; i++, datap++)
|
||||
{
|
||||
|
@ -293,23 +315,23 @@ write_constant_pool (cpool, buffer, length)
|
|||
case CONSTANT_InterfaceMethodref:
|
||||
case CONSTANT_Float:
|
||||
case CONSTANT_Integer:
|
||||
PUT4 (*datap);
|
||||
PUT4 (datap->w);
|
||||
break;
|
||||
case CONSTANT_Class:
|
||||
case CONSTANT_String:
|
||||
PUT2 (*datap);
|
||||
PUT2 (datap->w);
|
||||
break;
|
||||
break;
|
||||
case CONSTANT_Long:
|
||||
case CONSTANT_Double:
|
||||
PUT4(*datap);
|
||||
PUT4(datap->w);
|
||||
i++;
|
||||
datap++;
|
||||
PUT4 (*datap);
|
||||
PUT4 (datap->w);
|
||||
break;
|
||||
case CONSTANT_Utf8:
|
||||
{
|
||||
tree t = (tree) *datap;
|
||||
tree t = datap->t;
|
||||
int len = IDENTIFIER_LENGTH (t);
|
||||
PUT2 (len);
|
||||
PUTN (IDENTIFIER_POINTER (t), len);
|
||||
|
@ -347,7 +369,7 @@ alloc_name_constant (tag, name)
|
|||
int tag;
|
||||
tree name;
|
||||
{
|
||||
return find_constant1 (outgoing_cpool, tag, (jword) name);
|
||||
return find_tree_constant (outgoing_cpool, tag, name);
|
||||
}
|
||||
|
||||
/* Build an identifier for the internal name of reference type TYPE. */
|
||||
|
@ -438,7 +460,7 @@ build_constants_constructor ()
|
|||
= tree_cons (NULL_TREE, get_tag_node (outgoing_cpool->tags[i]),
|
||||
tags_list);
|
||||
data_list
|
||||
= tree_cons (NULL_TREE, build_utf8_ref ((tree)outgoing_cpool->data[i]),
|
||||
= tree_cons (NULL_TREE, build_utf8_ref (outgoing_cpool->data[i].t),
|
||||
data_list);
|
||||
}
|
||||
if (outgoing_cpool->count > 0)
|
||||
|
|
|
@ -38,6 +38,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
#include "javaop.h"
|
||||
#include "java-tree.h"
|
||||
#include "java-opcodes.h"
|
||||
#include "ggc.h"
|
||||
#include "hashtab.h"
|
||||
|
||||
#include <getopt.h>
|
||||
|
|
|
@ -229,7 +229,7 @@ extern int flag_store_check;
|
|||
extern const char *current_encoding;
|
||||
|
||||
/* The Java .class file that provides main_class; the main input file. */
|
||||
extern struct JCF *current_jcf;
|
||||
extern GTY(()) struct JCF * current_jcf;
|
||||
|
||||
typedef struct CPool constant_pool;
|
||||
|
||||
|
@ -241,7 +241,7 @@ typedef struct CPool constant_pool;
|
|||
/* The cpool->data[i] for a ResolvedClass points to a RECORD_TYPE. */
|
||||
#define CONSTANT_ResolvedClass (CONSTANT_Class+CONSTANT_ResolvedFlag)
|
||||
|
||||
#define CPOOL_UTF(CPOOL, INDEX) ((tree) (CPOOL)->data[INDEX])
|
||||
#define CPOOL_UTF(CPOOL, INDEX) ((CPOOL)->data[INDEX].t)
|
||||
|
||||
/* A NameAndType constant is represented as a TREE_LIST.
|
||||
The type is the signature string (as an IDENTIFIER_NODE). */
|
||||
|
@ -686,7 +686,7 @@ extern GTY(()) tree java_global_trees[JTI_MAX];
|
|||
#define nativecode_ptr_type_node ptr_type_node
|
||||
|
||||
/* They need to be reset before processing each class */
|
||||
extern struct CPool *outgoing_cpool;
|
||||
extern GTY(()) struct CPool *outgoing_cpool;
|
||||
|
||||
#define wfl_operator \
|
||||
java_global_trees[JTI_WFL_OPERATOR]
|
||||
|
@ -1066,8 +1066,8 @@ struct lang_decl GTY(())
|
|||
struct lang_type GTY(())
|
||||
{
|
||||
tree signature;
|
||||
struct JCF * GTY ((skip (""))) jcf;
|
||||
struct CPool * GTY ((skip (""))) cpool;
|
||||
struct JCF * jcf;
|
||||
struct CPool * cpool;
|
||||
tree cpool_data_ref; /* Cached */
|
||||
tree finit_stmt_list; /* List of statements finit$ will use */
|
||||
tree clinit_stmt_list; /* List of statements <clinit> will use */
|
||||
|
|
|
@ -53,6 +53,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
#include "system.h"
|
||||
#include "coretypes.h"
|
||||
#include "tm.h"
|
||||
#include "ggc.h"
|
||||
|
||||
#include "jcf.h"
|
||||
#include "tree.h"
|
||||
|
|
|
@ -62,7 +62,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
text = (JCF)->read_ptr; \
|
||||
save = text[LENGTH]; \
|
||||
text[LENGTH] = 0; \
|
||||
(JCF)->cpool.data[INDEX] = (jword) get_identifier (text); \
|
||||
(JCF)->cpool.data[INDEX].t = get_identifier (text); \
|
||||
text[LENGTH] = save; \
|
||||
JCF_SKIP (JCF, LENGTH); } while (0)
|
||||
|
||||
|
@ -86,7 +86,7 @@ static GTY(()) tree parse_roots[3];
|
|||
#define current_file_list parse_roots[2]
|
||||
|
||||
/* The Java archive that provides main_class; the main input file. */
|
||||
static struct JCF main_jcf[1];
|
||||
static GTY(()) struct JCF * main_jcf;
|
||||
|
||||
static struct ZipFile *localToFile;
|
||||
|
||||
|
@ -100,33 +100,9 @@ static void parse_source_file_2 (void);
|
|||
static void parse_source_file_3 (void);
|
||||
static void parse_class_file (void);
|
||||
static void set_source_filename (JCF *, int);
|
||||
static void ggc_mark_jcf (void**);
|
||||
static void jcf_parse (struct JCF*);
|
||||
static void load_inner_classes (tree);
|
||||
|
||||
/* Mark (for garbage collection) all the tree nodes that are
|
||||
referenced from JCF's constant pool table. Do that only if the JCF
|
||||
hasn't been marked finished. */
|
||||
|
||||
static void
|
||||
ggc_mark_jcf (elt)
|
||||
void **elt;
|
||||
{
|
||||
JCF *jcf = *(JCF**) elt;
|
||||
if (jcf != NULL && !jcf->finished)
|
||||
{
|
||||
CPool *cpool = &jcf->cpool;
|
||||
int size = CPOOL_COUNT(cpool);
|
||||
int index;
|
||||
for (index = 1; index < size; index++)
|
||||
{
|
||||
int tag = JPOOL_TAG (jcf, index);
|
||||
if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
|
||||
ggc_mark_tree ((tree) cpool->data[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle "SourceFile" attribute. */
|
||||
|
||||
static void
|
||||
|
@ -270,7 +246,7 @@ get_constant (jcf, index)
|
|||
goto bad;
|
||||
tag = JPOOL_TAG (jcf, index);
|
||||
if ((tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8)
|
||||
return (tree) jcf->cpool.data[index];
|
||||
return jcf->cpool.data[index].t;
|
||||
switch (tag)
|
||||
{
|
||||
case CONSTANT_Integer:
|
||||
|
@ -352,7 +328,7 @@ get_constant (jcf, index)
|
|||
goto bad;
|
||||
}
|
||||
JPOOL_TAG (jcf, index) = tag | CONSTANT_ResolvedFlag;
|
||||
jcf->cpool.data [index] = (jword) value;
|
||||
jcf->cpool.data[index].t = value;
|
||||
return value;
|
||||
bad:
|
||||
internal_error ("bad value constant type %d, index %d",
|
||||
|
@ -435,7 +411,7 @@ give_name_to_class (jcf, i)
|
|||
if (main_input_filename == NULL && jcf == main_jcf)
|
||||
main_input_filename = input_filename;
|
||||
|
||||
jcf->cpool.data[i] = (jword) this_class;
|
||||
jcf->cpool.data[i].t = this_class;
|
||||
JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
|
||||
return this_class;
|
||||
}
|
||||
|
@ -465,11 +441,11 @@ get_class_constant (JCF *jcf , int i)
|
|||
tree cname = unmangle_classname (name, nlength);
|
||||
type = lookup_class (cname);
|
||||
}
|
||||
jcf->cpool.data[i] = (jword) type;
|
||||
jcf->cpool.data[i].t = type;
|
||||
JPOOL_TAG (jcf, i) = CONSTANT_ResolvedClass;
|
||||
}
|
||||
else
|
||||
type = (tree) jcf->cpool.data[i];
|
||||
type = jcf->cpool.data[i].t;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -709,8 +685,7 @@ load_inner_classes (cur_class)
|
|||
void
|
||||
init_outgoing_cpool ()
|
||||
{
|
||||
outgoing_cpool = xmalloc (sizeof (struct CPool));
|
||||
memset (outgoing_cpool, 0, sizeof (struct CPool));
|
||||
outgoing_cpool = ggc_alloc_cleared (sizeof (struct CPool));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1074,7 +1049,7 @@ java_parse_file (set_yydebug)
|
|||
if (magic == 0xcafebabe)
|
||||
{
|
||||
CLASS_FILE_P (node) = 1;
|
||||
current_jcf = ALLOC (sizeof (JCF));
|
||||
current_jcf = ggc_alloc (sizeof (JCF));
|
||||
JCF_ZERO (current_jcf);
|
||||
current_jcf->read_state = finput;
|
||||
current_jcf->filbuf = jcf_filbuf_from_stdio;
|
||||
|
@ -1086,6 +1061,7 @@ java_parse_file (set_yydebug)
|
|||
else if (magic == (JCF_u4)ZIPMAGIC)
|
||||
{
|
||||
ZIP_FILE_P (node) = 1;
|
||||
main_jcf = ggc_alloc (sizeof (JCF));
|
||||
JCF_ZERO (main_jcf);
|
||||
main_jcf->read_state = finput;
|
||||
main_jcf->filbuf = jcf_filbuf_from_stdio;
|
||||
|
@ -1223,7 +1199,7 @@ process_zip_dir (FILE *finput)
|
|||
|
||||
class_name = ALLOC (zdir->filename_length+1-6);
|
||||
file_name = ALLOC (zdir->filename_length+1);
|
||||
jcf = ALLOC (sizeof (JCF));
|
||||
jcf = ggc_alloc (sizeof (JCF));
|
||||
JCF_ZERO (jcf);
|
||||
|
||||
strncpy (class_name, class_name_in_zip_dir, zdir->filename_length-6);
|
||||
|
@ -1255,9 +1231,6 @@ process_zip_dir (FILE *finput)
|
|||
void
|
||||
init_jcf_parse ()
|
||||
{
|
||||
/* Register roots with the garbage collector. */
|
||||
ggc_add_root (¤t_jcf, 1, sizeof (JCF), (void (*)(void *))ggc_mark_jcf);
|
||||
|
||||
init_src_parse ();
|
||||
}
|
||||
|
||||
|
|
|
@ -264,8 +264,8 @@ jcf_parse_constant_pool (JCF* jcf)
|
|||
{
|
||||
int i, n;
|
||||
JPOOL_SIZE (jcf) = (JCF_FILL (jcf, 2), JCF_readu2 (jcf));
|
||||
jcf->cpool.tags = ALLOC (JPOOL_SIZE (jcf));
|
||||
jcf->cpool.data = ALLOC (sizeof (jword) * JPOOL_SIZE (jcf));
|
||||
jcf->cpool.tags = ggc_alloc (JPOOL_SIZE (jcf));
|
||||
jcf->cpool.data = ggc_alloc (sizeof (jword) * JPOOL_SIZE (jcf));
|
||||
jcf->cpool.tags[0] = 0;
|
||||
#ifdef HANDLE_START_CONSTANT_POOL
|
||||
HANDLE_START_CONSTANT_POOL (JPOOL_SIZE (jcf));
|
||||
|
@ -285,25 +285,25 @@ jcf_parse_constant_pool (JCF* jcf)
|
|||
{
|
||||
case CONSTANT_String:
|
||||
case CONSTANT_Class:
|
||||
jcf->cpool.data[i] = JCF_readu2 (jcf);
|
||||
jcf->cpool.data[i].w = JCF_readu2 (jcf);
|
||||
break;
|
||||
case CONSTANT_Fieldref:
|
||||
case CONSTANT_Methodref:
|
||||
case CONSTANT_InterfaceMethodref:
|
||||
case CONSTANT_NameAndType:
|
||||
jcf->cpool.data[i] = JCF_readu2 (jcf);
|
||||
jcf->cpool.data[i] |= JCF_readu2 (jcf) << 16;
|
||||
jcf->cpool.data[i].w = JCF_readu2 (jcf);
|
||||
jcf->cpool.data[i].w |= JCF_readu2 (jcf) << 16;
|
||||
break;
|
||||
case CONSTANT_Integer:
|
||||
case CONSTANT_Float:
|
||||
jcf->cpool.data[i] = JCF_readu4 (jcf);
|
||||
jcf->cpool.data[i].w = JCF_readu4 (jcf);
|
||||
break;
|
||||
case CONSTANT_Long:
|
||||
case CONSTANT_Double:
|
||||
jcf->cpool.data[i] = JCF_readu4 (jcf);
|
||||
jcf->cpool.data[i].w = JCF_readu4 (jcf);
|
||||
i++; /* These take up two spots in the constant pool */
|
||||
jcf->cpool.tags[i] = 0;
|
||||
jcf->cpool.data[i] = JCF_readu4 (jcf);
|
||||
jcf->cpool.data[i].w = JCF_readu4 (jcf);
|
||||
break;
|
||||
case CONSTANT_Utf8:
|
||||
n = JCF_readu2 (jcf);
|
||||
|
@ -311,7 +311,7 @@ jcf_parse_constant_pool (JCF* jcf)
|
|||
#ifdef HANDLE_CONSTANT_Utf8
|
||||
HANDLE_CONSTANT_Utf8(jcf, i, n);
|
||||
#else
|
||||
jcf->cpool.data[i] = JCF_TELL(jcf) - 2;
|
||||
jcf->cpool.data[i].w = JCF_TELL(jcf) - 2;
|
||||
JCF_SKIP (jcf, n);
|
||||
#endif
|
||||
break;
|
||||
|
|
|
@ -55,9 +55,17 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
|||
#endif
|
||||
|
||||
struct JCF;
|
||||
typedef int (*jcf_filbuf_t) (struct JCF*, int needed);
|
||||
typedef int (*jcf_filbuf_t) PARAMS ((struct JCF*, int needed));
|
||||
|
||||
typedef struct CPool {
|
||||
union cpool_entry GTY(()) {
|
||||
jword GTY ((tag ("0"))) w;
|
||||
tree GTY ((tag ("1"))) t;
|
||||
};
|
||||
|
||||
#define cpool_entry_is_tree(tag) \
|
||||
(tag & CONSTANT_ResolvedFlag) || tag == CONSTANT_Utf8
|
||||
|
||||
typedef struct CPool GTY(()) {
|
||||
/* Available number of elements in the constants array, before it
|
||||
must be re-allocated. */
|
||||
int capacity;
|
||||
|
@ -65,29 +73,33 @@ typedef struct CPool {
|
|||
/* The constant_pool_count. */
|
||||
int count;
|
||||
|
||||
uint8* tags;
|
||||
uint8* GTY((length ("%h.count"))) tags;
|
||||
|
||||
jword* data;
|
||||
union cpool_entry * GTY((length ("%h.count"),
|
||||
desc ("cpool_entry_is_tree (%1.tags%a)"))) data;
|
||||
} CPool;
|
||||
|
||||
struct ZipDirectory;
|
||||
|
||||
/* JCF encapsulates the state of reading a Java Class File. */
|
||||
|
||||
typedef struct JCF {
|
||||
unsigned char *buffer;
|
||||
unsigned char *buffer_end;
|
||||
unsigned char *read_ptr;
|
||||
unsigned char *read_end;
|
||||
typedef struct JCF GTY(()) {
|
||||
unsigned char * GTY ((skip (""))) buffer;
|
||||
unsigned char * GTY ((skip (""))) buffer_end;
|
||||
unsigned char * GTY ((skip (""))) read_ptr;
|
||||
unsigned char * GTY ((skip (""))) read_end;
|
||||
int java_source : 1;
|
||||
int right_zip : 1;
|
||||
int finished : 1;
|
||||
jcf_filbuf_t filbuf;
|
||||
void *read_state;
|
||||
PTR GTY ((skip (""))) read_state;
|
||||
const char *filename;
|
||||
const char *classname;
|
||||
struct ZipDirectory *zipd; /* Directory entry where it was found */
|
||||
JCF_u2 access_flags, this_class, super_class;
|
||||
/* Directory entry where it was found. */
|
||||
struct ZipDirectory * GTY ((skip (""))) zipd;
|
||||
JCF_u2 access_flags;
|
||||
JCF_u2 this_class;
|
||||
JCF_u2 super_class;
|
||||
CPool cpool;
|
||||
} JCF;
|
||||
/*typedef JCF* JCF_FILE;*/
|
||||
|
@ -102,13 +114,13 @@ typedef struct JCF {
|
|||
#define JPOOL_SIZE(JCF) CPOOL_COUNT(&(JCF)->cpool)
|
||||
#define JPOOL_TAG(JCF, INDEX) ((JCF)->cpool.tags[INDEX])
|
||||
/* The INDEX'th constant pool entry as a JCF_u4. */
|
||||
#define CPOOL_UINT(CPOOL, INDEX) ((CPOOL)->data[INDEX])
|
||||
#define CPOOL_UINT(CPOOL, INDEX) ((CPOOL)->data[INDEX].w)
|
||||
#define JPOOL_UINT(JCF, INDEX) CPOOL_UINT(&(JCF)->cpool, INDEX) /*deprecated*/
|
||||
/* The first uint16 of the INDEX'th constant pool entry. */
|
||||
#define CPOOL_USHORT1(CPOOL, INDEX) ((CPOOL)->data[INDEX] & 0xFFFF)
|
||||
#define CPOOL_USHORT1(CPOOL, INDEX) ((CPOOL)->data[INDEX].w & 0xFFFF)
|
||||
#define JPOOL_USHORT1(JCF, INDEX) CPOOL_USHORT1(&(JCF)->cpool, INDEX)
|
||||
/* The second uint16 of the INDEX'th constant pool entry. */
|
||||
#define CPOOL_USHORT2(CPOOL, INDEX) ((CPOOL)->data[INDEX] >> 16)
|
||||
#define CPOOL_USHORT2(CPOOL, INDEX) ((CPOOL)->data[INDEX].w >> 16)
|
||||
#define JPOOL_USHORT2(JCF, INDEX) CPOOL_USHORT2(&(JCF)->cpool, INDEX)
|
||||
#define JPOOL_LONG(JCF, INDEX) \
|
||||
WORDS_TO_LONG (JPOOL_UINT(JCF, INDEX), JPOOL_UINT(JCF, (INDEX)+1))
|
||||
|
@ -128,9 +140,10 @@ typedef struct JCF {
|
|||
#define CPOOL_INDEX_IN_RANGE(CPOOL, INDEX) \
|
||||
((INDEX) > 0 && (INDEX) < CPOOL_COUNT(CPOOL))
|
||||
|
||||
#define CPOOL_FINISH(CPOOL) { \
|
||||
if ((CPOOL)->tags) FREE ((CPOOL)->tags); \
|
||||
if ((CPOOL)->data) FREE ((CPOOL)->data); }
|
||||
#define CPOOL_FINISH(CPOOL) { \
|
||||
(CPOOL)->tags = 0; \
|
||||
(CPOOL)->data = 0; \
|
||||
}
|
||||
|
||||
#define JCF_FINISH(JCF) { \
|
||||
CPOOL_FINISH(&(JCF)->cpool); \
|
||||
|
|
|
@ -125,7 +125,7 @@ java_init_lex (finput, encoding)
|
|||
CPC_INSTANCE_INITIALIZER_LIST (ctxp) = NULL_TREE;
|
||||
|
||||
memset (ctxp->modifier_ctx, 0, sizeof (ctxp->modifier_ctx));
|
||||
memset (current_jcf, 0, sizeof (JCF));
|
||||
current_jcf = ggc_alloc_cleared (sizeof (JCF));
|
||||
ctxp->current_parsed_class = NULL;
|
||||
ctxp->package = NULL_TREE;
|
||||
#endif
|
||||
|
|
|
@ -96,13 +96,13 @@ struct java_error {
|
|||
int error;
|
||||
};
|
||||
|
||||
typedef struct _java_lc {
|
||||
typedef struct java_lc_s GTY(()) {
|
||||
int line;
|
||||
int prev_col;
|
||||
int col;
|
||||
} java_lc;
|
||||
|
||||
typedef struct java_lexer
|
||||
struct java_lexer
|
||||
{
|
||||
/* The file from which we're reading. */
|
||||
FILE *finput;
|
||||
|
@ -155,7 +155,8 @@ typedef struct java_lexer
|
|||
int out_last;
|
||||
|
||||
#endif /* HAVE_ICONV */
|
||||
} java_lexer;
|
||||
};
|
||||
typedef struct java_lexer java_lexer;
|
||||
|
||||
/* Destroy a lexer object. */
|
||||
extern void java_destroy_lexer (java_lexer *);
|
||||
|
|
|
@ -427,9 +427,6 @@ enum {
|
|||
INVOKE_VIRTUAL
|
||||
};
|
||||
|
||||
/* We need the resolution stuff only if we compile jc1 */
|
||||
#ifndef JC1_LITE
|
||||
|
||||
/* Unresolved type identifiers handling. When we process the source
|
||||
code, we blindly accept an unknown type identifier and try to
|
||||
resolve it later. When an unknown type identifier is encountered
|
||||
|
@ -509,13 +506,12 @@ typedef struct _jdep {
|
|||
#define JDEP_RESOLVED_P(J) \
|
||||
(!(J)->solv || TREE_CODE ((J)->solv) != POINTER_TYPE)
|
||||
|
||||
typedef struct _jdeplist {
|
||||
struct jdeplist_s {
|
||||
jdep *first;
|
||||
jdep *last;
|
||||
struct _jdeplist *next;
|
||||
} jdeplist;
|
||||
|
||||
#endif /* JC1_LITE */
|
||||
struct jdeplist_s *next;
|
||||
};
|
||||
typedef struct jdeplist_s jdeplist;
|
||||
|
||||
#define CLASSD_FIRST(CD) ((CD)->first)
|
||||
#define CLASSD_LAST(CD) ((CD)->last)
|
||||
|
@ -727,14 +723,15 @@ typedef struct _jdeplist {
|
|||
#define DECL_INHERITED_SOURCE_LINE(DECL) (DECL_CHECK (DECL)->decl.u2.i)
|
||||
|
||||
/* Parser context data structure. */
|
||||
struct parser_ctxt {
|
||||
struct parser_ctxt GTY(()) {
|
||||
|
||||
const char *filename; /* Current filename */
|
||||
struct parser_ctxt *next;
|
||||
|
||||
java_lexer *lexer; /* Current lexer state */
|
||||
java_lexer * GTY((skip (""))) lexer; /* Current lexer state */
|
||||
char marker_begining; /* Marker. Should be a sub-struct */
|
||||
struct java_line *p_line, *c_line; /* Previous and current line */
|
||||
struct java_line * GTY ((skip (""))) p_line; /* Previous line */
|
||||
struct java_line * GTY ((skip (""))) c_line; /* Current line */
|
||||
java_lc elc; /* Error's line column info */
|
||||
int ccb_indent; /* Keep track of {} indent, lexer */
|
||||
int first_ccb_indent1; /* First { at ident level 1 */
|
||||
|
@ -742,7 +739,7 @@ struct parser_ctxt {
|
|||
int parser_ccb_indent; /* Keep track of {} indent, parser */
|
||||
int osb_depth; /* Current depth of [ in an expression */
|
||||
int osb_limit; /* Limit of this depth */
|
||||
int *osb_number; /* Keep track of ['s */
|
||||
int * GTY ((skip (""))) osb_number; /* Keep track of ['s */
|
||||
int lineno; /* Current lineno */
|
||||
char marker_end; /* End marker. Should be a sub-struct */
|
||||
|
||||
|
@ -761,13 +758,12 @@ struct parser_ctxt {
|
|||
/* Flag to report certain errors (fix this documentation. FIXME) */
|
||||
unsigned class_err:1;
|
||||
|
||||
/* This section is defined only if we compile jc1 */
|
||||
#ifndef JC1_LITE
|
||||
/* This section is used only if we compile jc1 */
|
||||
tree modifier_ctx [12]; /* WFL of modifiers */
|
||||
tree class_type; /* Current class */
|
||||
tree function_decl; /* Current function decl, save/restore */
|
||||
|
||||
struct JCF *current_jcf; /* CU jcf */
|
||||
struct JCF * current_jcf; /* CU jcf */
|
||||
|
||||
int prevent_ese; /* Prevent expression statement error */
|
||||
|
||||
|
@ -778,7 +774,7 @@ struct parser_ctxt {
|
|||
|
||||
/* These two lists won't survive file traversal */
|
||||
tree class_list; /* List of classes in a CU */
|
||||
jdeplist *classd_list; /* Classe dependencies in a CU */
|
||||
jdeplist * GTY((skip (""))) classd_list; /* Classe dependencies in a CU */
|
||||
|
||||
tree current_parsed_class; /* Class currently parsed */
|
||||
tree current_parsed_class_un; /* Curr. parsed class unqualified name */
|
||||
|
@ -801,7 +797,6 @@ struct parser_ctxt {
|
|||
constructor. This flag is used to trap
|
||||
illegal argument usage during an
|
||||
explicit constructor invocation. */
|
||||
#endif /* JC1_LITE */
|
||||
};
|
||||
|
||||
/* A set of macros to push/pop/access the currently parsed class. */
|
||||
|
@ -947,7 +942,7 @@ ATTRIBUTE_NORETURN
|
|||
;
|
||||
extern void java_expand_classes (void);
|
||||
|
||||
extern struct parser_ctxt *ctxp;
|
||||
extern struct parser_ctxt *ctxp_for_generation;
|
||||
extern GTY(()) struct parser_ctxt *ctxp;
|
||||
extern GTY(()) struct parser_ctxt *ctxp_for_generation;
|
||||
|
||||
#endif /* ! GCC_JAVA_PARSE_H */
|
||||
|
|
|
@ -304,13 +304,16 @@ static tree maybe_build_thisn_access_method (tree);
|
|||
|
||||
static tree build_outer_field_access (tree, tree);
|
||||
static tree build_outer_field_access_methods (tree);
|
||||
static tree build_outer_field_access_expr (int, tree, tree, tree, tree);
|
||||
static tree build_outer_field_access_expr (int, tree, tree,
|
||||
tree, tree);
|
||||
static tree build_outer_method_access_method (tree);
|
||||
static tree build_new_access_id (void);
|
||||
static tree build_outer_field_access_method (tree, tree, tree, tree, tree);
|
||||
static tree build_outer_field_access_method (tree, tree, tree,
|
||||
tree, tree);
|
||||
|
||||
static int outer_field_access_p (tree, tree);
|
||||
static int outer_field_expanded_access_p (tree, tree *, tree *, tree *);
|
||||
static int outer_field_expanded_access_p (tree, tree *,
|
||||
tree *, tree *);
|
||||
static tree outer_field_access_fix (tree, tree, tree);
|
||||
static tree build_incomplete_class_ref (int, tree);
|
||||
static tree patch_incomplete_class_ref (tree);
|
||||
|
@ -321,7 +324,6 @@ static void add_inner_class_fields (tree, tree);
|
|||
static tree build_dot_class_method (tree);
|
||||
static tree build_dot_class_method_invocation (tree);
|
||||
static void create_new_parser_context (int);
|
||||
static void mark_parser_ctxt (void *);
|
||||
static tree maybe_build_class_init_for_field (tree, tree);
|
||||
|
||||
static int attach_init_test_initialization_flags (PTR *, PTR);
|
||||
|
@ -594,18 +596,7 @@ static GTY(()) tree src_parse_roots[1];
|
|||
|
||||
%%
|
||||
/* 19.2 Production from 2.3: The Syntactic Grammar */
|
||||
goal:
|
||||
{
|
||||
/* Register static variables with the garbage
|
||||
collector. */
|
||||
ggc_add_root (&ctxp, 1,
|
||||
sizeof (struct parser_ctxt *),
|
||||
mark_parser_ctxt);
|
||||
ggc_add_root (&ctxp_for_generation, 1,
|
||||
sizeof (struct parser_ctxt *),
|
||||
mark_parser_ctxt);
|
||||
}
|
||||
compilation_unit
|
||||
goal: compilation_unit
|
||||
{}
|
||||
;
|
||||
|
||||
|
@ -2669,7 +2660,7 @@ create_new_parser_context (copy_from_previous)
|
|||
{
|
||||
struct parser_ctxt *new;
|
||||
|
||||
new = (struct parser_ctxt *)xmalloc(sizeof (struct parser_ctxt));
|
||||
new = (struct parser_ctxt *) ggc_alloc (sizeof (struct parser_ctxt));
|
||||
if (copy_from_previous)
|
||||
{
|
||||
memcpy ((PTR)new, (PTR)ctxp, sizeof (struct parser_ctxt));
|
||||
|
@ -2730,8 +2721,6 @@ java_pop_parser_context (generate)
|
|||
toFree->next = ctxp_for_generation;
|
||||
ctxp_for_generation = toFree;
|
||||
}
|
||||
else
|
||||
free (toFree);
|
||||
}
|
||||
|
||||
/* Create a parser context for the use of saving some global
|
||||
|
@ -2830,10 +2819,6 @@ java_parser_context_resume ()
|
|||
/* Re-installed the data for the parsing to carry on */
|
||||
memcpy (&ctxp->marker_begining, &old->marker_begining,
|
||||
(size_t)(&ctxp->marker_end - &ctxp->marker_begining));
|
||||
|
||||
/* Buffer context can now be discarded */
|
||||
free (saver);
|
||||
free (old);
|
||||
}
|
||||
|
||||
/* Add a new anchor node to which all statement(s) initializing static
|
||||
|
@ -6732,10 +6717,9 @@ process_imports ()
|
|||
tree to_be_found = EXPR_WFL_NODE (TREE_PURPOSE (import));
|
||||
char *original_name;
|
||||
|
||||
obstack_grow0 (&temporary_obstack,
|
||||
IDENTIFIER_POINTER (to_be_found),
|
||||
IDENTIFIER_LENGTH (to_be_found));
|
||||
original_name = obstack_finish (&temporary_obstack);
|
||||
original_name = xmemdup (IDENTIFIER_POINTER (to_be_found),
|
||||
IDENTIFIER_LENGTH (to_be_found),
|
||||
IDENTIFIER_LENGTH (to_be_found) + 1);
|
||||
|
||||
/* Don't load twice something already defined. */
|
||||
if (IDENTIFIER_CLASS_VALUE (to_be_found))
|
||||
|
@ -6771,7 +6755,7 @@ process_imports ()
|
|||
error_found = 1;
|
||||
}
|
||||
|
||||
obstack_free (&temporary_obstack, original_name);
|
||||
free (original_name);
|
||||
if (error_found)
|
||||
return 1;
|
||||
}
|
||||
|
@ -16190,42 +16174,6 @@ resolve_qualified_name (name, context)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Mark P, which is really a `struct parser_ctxt **' for GC. */
|
||||
|
||||
static void
|
||||
mark_parser_ctxt (p)
|
||||
void *p;
|
||||
{
|
||||
struct parser_ctxt *pc = *((struct parser_ctxt **) p);
|
||||
#ifndef JC1_LITE
|
||||
size_t i;
|
||||
#endif
|
||||
|
||||
if (!pc)
|
||||
return;
|
||||
|
||||
#ifndef JC1_LITE
|
||||
for (i = 0; i < ARRAY_SIZE (pc->modifier_ctx); ++i)
|
||||
ggc_mark_tree (pc->modifier_ctx[i]);
|
||||
ggc_mark_tree (pc->class_type);
|
||||
ggc_mark_tree (pc->function_decl);
|
||||
ggc_mark_tree (pc->package);
|
||||
ggc_mark_tree (pc->class_list);
|
||||
ggc_mark_tree (pc->current_parsed_class);
|
||||
ggc_mark_tree (pc->current_parsed_class_un);
|
||||
ggc_mark_tree (pc->non_static_initialized);
|
||||
ggc_mark_tree (pc->static_initialized);
|
||||
ggc_mark_tree (pc->instance_initializers);
|
||||
ggc_mark_tree (pc->import_list);
|
||||
ggc_mark_tree (pc->import_demand_list);
|
||||
ggc_mark_tree (pc->current_loop);
|
||||
ggc_mark_tree (pc->current_labeled_block);
|
||||
#endif /* JC1_LITE */
|
||||
|
||||
if (pc->next)
|
||||
mark_parser_ctxt (&pc->next);
|
||||
}
|
||||
|
||||
void
|
||||
init_src_parse ()
|
||||
{
|
||||
|
|
74
gcc/mkdeps.c
74
gcc/mkdeps.c
|
@ -291,3 +291,77 @@ deps_phony_targets (d, fp)
|
|||
putc ('\n', fp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Write out a deps buffer to a file, in a form that can be read back
|
||||
with deps_restore. Returns nonzero on error, in which case the
|
||||
error number will be in errno. */
|
||||
|
||||
int
|
||||
deps_save (deps, f)
|
||||
struct deps *deps;
|
||||
FILE *f;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
/* The cppreader structure contains makefile dependences. Write out this
|
||||
structure. */
|
||||
|
||||
/* The number of dependences. */
|
||||
if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
|
||||
return -1;
|
||||
/* The length of each dependence followed by the string. */
|
||||
for (i = 0; i < deps->ndeps; i++)
|
||||
{
|
||||
size_t num_to_write = strlen (deps->depv[i]);
|
||||
if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
|
||||
return -1;
|
||||
if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read back dependency information written with deps_save into
|
||||
the deps buffer. The third argument may be NULL, in which case
|
||||
the dependency information is just skipped, or it may be a filename,
|
||||
in which case that filename is skipped. */
|
||||
|
||||
int
|
||||
deps_restore (deps, fd, self)
|
||||
struct deps *deps;
|
||||
FILE *fd;
|
||||
const char *self;
|
||||
{
|
||||
unsigned int i, count;
|
||||
size_t num_to_read;
|
||||
size_t buf_size = 512;
|
||||
char *buf = (char *) xmalloc (buf_size);
|
||||
|
||||
/* Number of dependences. */
|
||||
if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
|
||||
return -1;
|
||||
|
||||
/* The length of each dependence string, followed by the string. */
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
/* Read in # bytes in string. */
|
||||
if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
|
||||
return -1;
|
||||
if (buf_size < num_to_read + 1)
|
||||
{
|
||||
buf_size = num_to_read + 1 + 127;
|
||||
buf = xrealloc (buf, buf_size);
|
||||
}
|
||||
if (fread (buf, 1, num_to_read, fd) != num_to_read)
|
||||
return -1;
|
||||
buf[num_to_read] = '\0';
|
||||
|
||||
/* Generate makefile dependencies from .pch if -nopch-deps. */
|
||||
if (self != NULL && strcmp (buf, self) != 0)
|
||||
deps_add_dep (deps, buf);
|
||||
}
|
||||
|
||||
free (buf);
|
||||
return 0;
|
||||
}
|
||||
|
|
11
gcc/mkdeps.h
11
gcc/mkdeps.h
|
@ -53,6 +53,17 @@ extern void deps_add_dep PARAMS ((struct deps *, const char *));
|
|||
extern void deps_write PARAMS ((const struct deps *, FILE *,
|
||||
unsigned int));
|
||||
|
||||
/* Write out a deps buffer to a file, in a form that can be read back
|
||||
with deps_restore. Returns nonzero on error, in which case the
|
||||
error number will be in errno. */
|
||||
extern int deps_save PARAMS ((struct deps *, FILE *));
|
||||
|
||||
/* Read back dependency information written with deps_save into
|
||||
the deps buffer. The third argument may be NULL, in which case
|
||||
the dependency information is just skipped, or it may be a filename,
|
||||
in which case that filename is skipped. */
|
||||
extern int deps_restore PARAMS ((struct deps *, FILE *, const char *));
|
||||
|
||||
/* For each dependency *except the first*, emit a dummy rule for that
|
||||
file, causing it to depend on nothing. This is used to work around
|
||||
the intermediate-file deletion misfeature in Make, in some
|
||||
|
|
|
@ -56,6 +56,7 @@ Boston, MA 02111-1307, USA. */
|
|||
#include "output.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "varray.h"
|
||||
#include "debug.h"
|
||||
#include "target.h"
|
||||
#include "diagnostic.h"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Definitions for code generation pass of GNU compiler.
|
||||
Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -246,7 +246,7 @@ extern enum insn_code reload_in_optab[NUM_MACHINE_MODES];
|
|||
extern enum insn_code reload_out_optab[NUM_MACHINE_MODES];
|
||||
|
||||
/* Contains the optab used for each rtx code. */
|
||||
extern optab code_to_optab[NUM_RTX_CODE + 1];
|
||||
extern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1];
|
||||
|
||||
|
||||
typedef rtx (*rtxfun) PARAMS ((rtx));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* String pool for GCC.
|
||||
Copyright (C) 2000, 2001 Free Software Foundation, Inc.
|
||||
Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
|
@ -50,7 +50,6 @@ static struct obstack string_stack;
|
|||
|
||||
static hashnode alloc_node PARAMS ((hash_table *));
|
||||
static int mark_ident PARAMS ((struct cpp_reader *, hashnode, const PTR));
|
||||
static void mark_ident_hash PARAMS ((void *));
|
||||
|
||||
/* Initialize the string pool. */
|
||||
void
|
||||
|
@ -60,7 +59,6 @@ init_stringpool ()
|
|||
ident_hash = ht_create (14);
|
||||
ident_hash->alloc_node = alloc_node;
|
||||
gcc_obstack_init (&string_stack);
|
||||
ggc_add_root (&ident_hash, 1, sizeof ident_hash, mark_ident_hash);
|
||||
}
|
||||
|
||||
/* Allocate a hash node. */
|
||||
|
@ -160,15 +158,94 @@ mark_ident (pfile, h, v)
|
|||
hashnode h;
|
||||
const PTR v ATTRIBUTE_UNUSED;
|
||||
{
|
||||
ggc_mark_tree (HT_IDENT_TO_GCC_IDENT (h));
|
||||
gt_ggc_m_9tree_node (HT_IDENT_TO_GCC_IDENT (h));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Mark all identifiers for GC. */
|
||||
/* Mark the trees hanging off the identifier node for GGC. These are
|
||||
handled specially (not using gengtype) because of the special
|
||||
treatment for strings. */
|
||||
|
||||
static void
|
||||
mark_ident_hash (arg)
|
||||
PTR arg ATTRIBUTE_UNUSED;
|
||||
void
|
||||
ggc_mark_stringpool ()
|
||||
{
|
||||
ht_forall (ident_hash, mark_ident, NULL);
|
||||
}
|
||||
|
||||
/* Strings are _not_ GCed, but this routine exists so that a separate
|
||||
roots table isn't needed for the few global variables that refer
|
||||
to strings. */
|
||||
|
||||
void
|
||||
gt_ggc_m_S (x)
|
||||
void *x ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
/* Pointer-walking routine for strings (not very interesting, since
|
||||
strings don't contain pointers). */
|
||||
|
||||
void
|
||||
gt_pch_p_S (obj, x, op, cookie)
|
||||
void *obj ATTRIBUTE_UNUSED;
|
||||
void *x ATTRIBUTE_UNUSED;
|
||||
gt_pointer_operator op ATTRIBUTE_UNUSED;
|
||||
void *cookie ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
/* PCH pointer-walking routine for strings. */
|
||||
|
||||
void
|
||||
gt_pch_n_S (x)
|
||||
const void *x;
|
||||
{
|
||||
gt_pch_note_object ((void *)x, (void *)x, >_pch_p_S);
|
||||
}
|
||||
|
||||
/* Handle saving and restoring the string pool for PCH. */
|
||||
|
||||
struct string_pool_data GTY(())
|
||||
{
|
||||
tree * GTY((length ("%h.nslots"))) entries;
|
||||
unsigned int nslots;
|
||||
unsigned int nelements;
|
||||
};
|
||||
|
||||
static GTY(()) struct string_pool_data * spd;
|
||||
|
||||
void
|
||||
gt_pch_save_stringpool ()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
spd = ggc_alloc (sizeof (*spd));
|
||||
spd->nslots = ident_hash->nslots;
|
||||
spd->nelements = ident_hash->nelements;
|
||||
spd->entries = ggc_alloc (sizeof (tree *) * spd->nslots);
|
||||
for (i = 0; i < spd->nslots; i++)
|
||||
if (ident_hash->entries[i] != NULL)
|
||||
spd->entries[i] = HT_IDENT_TO_GCC_IDENT (ident_hash->entries[i]);
|
||||
else
|
||||
spd->entries[i] = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gt_pch_restore_stringpool ()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
ident_hash->nslots = spd->nslots;
|
||||
ident_hash->nelements = spd->nelements;
|
||||
ident_hash->entries = xrealloc (ident_hash->entries,
|
||||
sizeof (hashnode) * spd->nslots);
|
||||
for (i = 0; i < spd->nslots; i++)
|
||||
if (spd->entries[i] != NULL)
|
||||
ident_hash->entries[i] = GCC_IDENT_TO_HT_IDENT (spd->entries[i]);
|
||||
else
|
||||
ident_hash->entries[i] = NULL;
|
||||
|
||||
spd = NULL;
|
||||
}
|
||||
|
||||
#include "gt-stringpool.h"
|
||||
|
|
|
@ -1,3 +1,87 @@
|
|||
2003-01-09 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
Merge from pch-branch:
|
||||
|
||||
2002-12-23 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gcc.dg/pch/cpp-1.h: New.
|
||||
* gcc.dg/pch/cpp-1.c: New.
|
||||
* gcc.dg/pch/cpp-2.h: New.
|
||||
* gcc.dg/pch/cpp-2.c: New.
|
||||
|
||||
2002-11-19 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gcc.dg/pch/except-1.h: New.
|
||||
* gcc.dg/pch/except-1.c: New.
|
||||
|
||||
2002-11-13 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gcc.dg/pch/pch.exp: Ensure that <test>.hp doesn't exist before
|
||||
running test.
|
||||
* gcc.dg/pch: Include *.hp not *.h.
|
||||
* gcc.dg/pch/system-1.h: New.
|
||||
* gcc.dg/pch/system-1.c: New.
|
||||
|
||||
2002-11-11 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gcc.dg/pch/pch.exp: Compare .s files with/without PCH,
|
||||
rather than trying to build and run a program using PCH.
|
||||
* gcc.dg/pch: Remove dg-do commands from test files.
|
||||
|
||||
2002-11-08 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gcc.dg/pch/macro-3.c: New.
|
||||
* gcc.dg/pch/macro-3.h: New.
|
||||
|
||||
2002-11-04 Geoffrey Keating <geoffk@apple.com>
|
||||
|
||||
* gcc.dg/pch/common-1.c: New.
|
||||
* gcc.dg/pch/common-1.h: New.
|
||||
* gcc.dg/pch/decl-1.c: New.
|
||||
* gcc.dg/pch/decl-1.h: New.
|
||||
* gcc.dg/pch/decl-2.c: New.
|
||||
* gcc.dg/pch/decl-2.h: New.
|
||||
* gcc.dg/pch/decl-3.c: New.
|
||||
* gcc.dg/pch/decl-3.h: New.
|
||||
* gcc.dg/pch/decl-4.c: New.
|
||||
* gcc.dg/pch/decl-4.h: New.
|
||||
* gcc.dg/pch/decl-5.c: New.
|
||||
* gcc.dg/pch/decl-5.h: New.
|
||||
* gcc.dg/pch/global-1.c: New.
|
||||
* gcc.dg/pch/global-1.h: New.
|
||||
* gcc.dg/pch/inline-1.c: New.
|
||||
* gcc.dg/pch/inline-1.h: New.
|
||||
* gcc.dg/pch/inline-2.c: New.
|
||||
* gcc.dg/pch/inline-2.h: New.
|
||||
* gcc.dg/pch/static-1.c: New.
|
||||
* gcc.dg/pch/static-1.h: New.
|
||||
* gcc.dg/pch/static-2.c: New.
|
||||
* gcc.dg/pch/static-2.h: New.
|
||||
|
||||
2002-09-01 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* g++.dg/pch/pch.exp: Better handle failing testcases.
|
||||
* gcc.dg/pch/pch.exp: Likewise.
|
||||
* gcc.dg/pch/macro-1.c: New.
|
||||
* gcc.dg/pch/macro-1.h: New.
|
||||
* gcc.dg/pch/macro-2.c: New.
|
||||
* gcc.dg/pch/macro-2.h: New.
|
||||
|
||||
2002-08-27 Geoffrey Keating <geoffk@redhat.com>
|
||||
|
||||
* g++.dg/dg.exp: Treat files in pch/ specially.
|
||||
* g++.dg/pch/pch.exp: New file.
|
||||
* g++.dg/pch/empty.H: New file.
|
||||
* g++.dg/pch/empty.C: New file.
|
||||
* lib/g++-dg.exp (g++-dg-test): Add case for when $do_what is
|
||||
"precompile".
|
||||
|
||||
* gcc.dg/pch/pch.exp: New file.
|
||||
* gcc.dg/pch/empty.h: New file.
|
||||
* gcc.dg/pch/empty.c: New file.
|
||||
* lib/gcc-dg.exp (gcc-dg-test): Add case for when $do_what is
|
||||
"precompile".
|
||||
|
||||
2003-01-09 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
|
||||
|
||||
* g++.dg/template/friend14.C: New test.
|
||||
|
|
|
@ -35,6 +35,7 @@ set tests [prune $tests $srcdir/$subdir/bprob/*]
|
|||
set tests [prune $tests $srcdir/$subdir/compat/*]
|
||||
set tests [prune $tests $srcdir/$subdir/debug/*]
|
||||
set tests [prune $tests $srcdir/$subdir/gcov/*]
|
||||
set tests [prune $tests $srcdir/$subdir/pch/*]
|
||||
set tests [prune $tests $srcdir/$subdir/special/*]
|
||||
set tests [prune $tests $srcdir/$subdir/tls/*]
|
||||
|
||||
|
|
5
gcc/testsuite/g++.dg/pch/empty.C
Normal file
5
gcc/testsuite/g++.dg/pch/empty.C
Normal file
|
@ -0,0 +1,5 @@
|
|||
#include "empty.Hp"
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
0
gcc/testsuite/g++.dg/pch/empty.H
Normal file
0
gcc/testsuite/g++.dg/pch/empty.H
Normal file
100
gcc/testsuite/g++.dg/pch/pch.exp
Normal file
100
gcc/testsuite/g++.dg/pch/pch.exp
Normal file
|
@ -0,0 +1,100 @@
|
|||
# Copyright (C) 1997, 2002 Free Software Foundation, Inc.
|
||||
|
||||
# This program 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 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
# GCC testsuite for precompiled header interaction,
|
||||
# that uses the `dg.exp' driver.
|
||||
|
||||
# Load support procs.
|
||||
load_lib "g++-dg.exp"
|
||||
|
||||
# Initialize `dg'.
|
||||
dg-init
|
||||
|
||||
set old_dg_do_what_default "${dg-do-what-default}"
|
||||
|
||||
# Main loop.
|
||||
foreach test [lsort [glob -nocomplain $srcdir/$subdir/*.C]] {
|
||||
global runtests dg-do-what-default
|
||||
|
||||
# If we're only testing specific files and this isn't one of them, skip it.
|
||||
if ![runtest_file_p $runtests $test] {
|
||||
continue
|
||||
}
|
||||
set nshort [file tail [file dirname $test]]/[file tail $test]
|
||||
set bname "[file rootname [file tail $test]]"
|
||||
|
||||
catch { file delete "$bname.Hp.pch" }
|
||||
catch { file delete "$bname.H.pch" }
|
||||
catch { file delete "$bname.s" }
|
||||
catch { file delete "$bname.s-pch" }
|
||||
catch { file delete "$bname.Hp" }
|
||||
|
||||
# We don't try to use the loop-optimizing options, since they are highly
|
||||
# unlikely to make any difference to PCH.
|
||||
foreach flags { "-g" "-O2 -g" "-O2" } {
|
||||
verbose "Testing $nshort, $flags" 1
|
||||
|
||||
# For the header files, the default is to precompile.
|
||||
set dg-do-what-default precompile
|
||||
dg-test -keep-output "[file rootname $test].H" $flags ""
|
||||
|
||||
# For the rest, the default is to compile to .s.
|
||||
set dg-do-what-default compile
|
||||
|
||||
if { [ file exists "$bname.H.pch" ] } {
|
||||
# To ensure that the PCH is used, not the original header,
|
||||
# the actual PCH file is renamed to "<foo>.Hp.pch".
|
||||
file rename "$bname.H.pch" "$bname.Hp.pch"
|
||||
if { [ is_remote host ] } {
|
||||
remote_download host "$bname.Hp.pch"
|
||||
}
|
||||
|
||||
dg-test -keep-output $test $flags "-I."
|
||||
file delete "$bname.Hp.pch"
|
||||
if { [ file exists "$bname.s" ] } {
|
||||
file rename "$bname.s" "$bname.s-pch"
|
||||
if { [ is_remote host ] } {
|
||||
remote_upload host "[file rootname $test].H" "$bname.Hp"
|
||||
} else {
|
||||
file copy "[file rootname $test].H" "$bname.Hp"
|
||||
}
|
||||
dg-test -keep-output $test $flags "-I."
|
||||
remote_file host delete "$bname.Hp"
|
||||
set tmp [ diff "$bname.s" "$bname.s-pch" ]
|
||||
if { $tmp == 0 } {
|
||||
untested "$nshort $flags assembly comparison"
|
||||
} elseif { $tmp == 1 } {
|
||||
pass "$nshort $flags assembly comparison"
|
||||
} else {
|
||||
fail "$nshort $flags assembly comparison"
|
||||
}
|
||||
file delete "$bname.s"
|
||||
file delete "$bname.s-pch"
|
||||
} else {
|
||||
untested "$nshort $flags assembly comparison"
|
||||
}
|
||||
|
||||
} else {
|
||||
untested $nshort
|
||||
untested "$nshort $flags assembly comparison"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set dg-do-what-default "$old_dg_do_what_default"
|
||||
|
||||
# All done.
|
||||
dg-finish
|
7
gcc/testsuite/g++.dg/pch/system-1.C
Normal file
7
gcc/testsuite/g++.dg/pch/system-1.C
Normal file
|
@ -0,0 +1,7 @@
|
|||
#include "system-1.Hp"
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout << "hello world!" << '\n';
|
||||
return 0;
|
||||
}
|
1
gcc/testsuite/g++.dg/pch/system-1.H
Normal file
1
gcc/testsuite/g++.dg/pch/system-1.H
Normal file
|
@ -0,0 +1 @@
|
|||
#include <iostream>
|
3
gcc/testsuite/gcc.dg/pch/common-1.c
Normal file
3
gcc/testsuite/gcc.dg/pch/common-1.c
Normal file
|
@ -0,0 +1,3 @@
|
|||
#include "common-1.hp"
|
||||
int foo2 = 3;
|
||||
int zz = 2;
|
3
gcc/testsuite/gcc.dg/pch/common-1.h
Normal file
3
gcc/testsuite/gcc.dg/pch/common-1.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
static int foo1 = 9;
|
||||
int foo2;
|
||||
extern int zz;
|
4
gcc/testsuite/gcc.dg/pch/cpp-1.c
Normal file
4
gcc/testsuite/gcc.dg/pch/cpp-1.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
#include "cpp-1.hp"
|
||||
#if !defined(__GNUC__)
|
||||
panic! panic!
|
||||
#endif
|
1
gcc/testsuite/gcc.dg/pch/cpp-1.h
Normal file
1
gcc/testsuite/gcc.dg/pch/cpp-1.h
Normal file
|
@ -0,0 +1 @@
|
|||
/* Empty. */
|
4
gcc/testsuite/gcc.dg/pch/cpp-2.c
Normal file
4
gcc/testsuite/gcc.dg/pch/cpp-2.c
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* { dg-options "-Wunknown-pragmas -I." } */
|
||||
#include "cpp-2.hp"
|
||||
#pragma GCC poison not_used
|
||||
|
1
gcc/testsuite/gcc.dg/pch/cpp-2.h
Normal file
1
gcc/testsuite/gcc.dg/pch/cpp-2.h
Normal file
|
@ -0,0 +1 @@
|
|||
/* Empty. */
|
2
gcc/testsuite/gcc.dg/pch/decl-1.c
Normal file
2
gcc/testsuite/gcc.dg/pch/decl-1.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "decl-1.hp"
|
||||
int main(void) { return foo; }
|
1
gcc/testsuite/gcc.dg/pch/decl-1.h
Normal file
1
gcc/testsuite/gcc.dg/pch/decl-1.h
Normal file
|
@ -0,0 +1 @@
|
|||
extern int foo;
|
2
gcc/testsuite/gcc.dg/pch/decl-2.c
Normal file
2
gcc/testsuite/gcc.dg/pch/decl-2.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "decl-2.hp"
|
||||
int main(void) { return fun (1, 2); }
|
3
gcc/testsuite/gcc.dg/pch/decl-2.h
Normal file
3
gcc/testsuite/gcc.dg/pch/decl-2.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
extern int fun (int a, int b);
|
||||
|
||||
|
11
gcc/testsuite/gcc.dg/pch/decl-3.c
Normal file
11
gcc/testsuite/gcc.dg/pch/decl-3.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include "decl-3.hp"
|
||||
|
||||
foo_p bar (void)
|
||||
{
|
||||
return foop;
|
||||
}
|
||||
|
||||
struct foo *bar2 (void)
|
||||
{
|
||||
return foop;
|
||||
}
|
3
gcc/testsuite/gcc.dg/pch/decl-3.h
Normal file
3
gcc/testsuite/gcc.dg/pch/decl-3.h
Normal file
|
@ -0,0 +1,3 @@
|
|||
struct foo;
|
||||
typedef struct foo *foo_p;
|
||||
extern foo_p foop;
|
9
gcc/testsuite/gcc.dg/pch/decl-4.c
Normal file
9
gcc/testsuite/gcc.dg/pch/decl-4.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "decl-4.hp"
|
||||
|
||||
int bar (foo_p f)
|
||||
{
|
||||
if (f->a + foop->a)
|
||||
return f->c->b + foop->b;
|
||||
else
|
||||
return foop->c->b + f->a;
|
||||
}
|
7
gcc/testsuite/gcc.dg/pch/decl-4.h
Normal file
7
gcc/testsuite/gcc.dg/pch/decl-4.h
Normal file
|
@ -0,0 +1,7 @@
|
|||
typedef struct foo {
|
||||
int a;
|
||||
char b;
|
||||
struct foo *c;
|
||||
} foo_s;
|
||||
typedef struct foo *foo_p;
|
||||
extern foo_p foop;
|
2
gcc/testsuite/gcc.dg/pch/decl-5.c
Normal file
2
gcc/testsuite/gcc.dg/pch/decl-5.c
Normal file
|
@ -0,0 +1,2 @@
|
|||
#include "decl-5.hp"
|
||||
static int (*t)(void) = foo;
|
1
gcc/testsuite/gcc.dg/pch/decl-5.h
Normal file
1
gcc/testsuite/gcc.dg/pch/decl-5.h
Normal file
|
@ -0,0 +1 @@
|
|||
extern int foo(void);
|
8
gcc/testsuite/gcc.dg/pch/empty.c
Normal file
8
gcc/testsuite/gcc.dg/pch/empty.c
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* Yes, it's called "empty" because it has no contents at all.
|
||||
Even this comment goes here, rather than in empty.h. */
|
||||
#include "empty.hp"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue