Merge from pch-branch.

From-SVN: r61136
This commit is contained in:
Geoffrey Keating 2003-01-10 02:22:34 +00:00
parent 5f7c78d8a4
commit 17211ab553
130 changed files with 5541 additions and 1594 deletions

View File

@ -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>

View File

@ -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

View File

@ -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,

View File

@ -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)")))

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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 ();
}

View File

@ -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)

View File

@ -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;

View File

@ -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
View 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);
}

View File

@ -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);

View File

@ -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 ()

View File

@ -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"

View File

@ -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

View File

@ -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.

View File

@ -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 \

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -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. */

View File

@ -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;

View File

@ -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++;

View File

@ -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));

View File

@ -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)}\

View File

@ -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);

View File

@ -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"

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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"

View File

@ -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.

View File

@ -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"

View File

@ -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)

View File

@ -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 *));

View File

@ -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

View File

@ -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
View 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;
}

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

File diff suppressed because it is too large Load Diff

View File

@ -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;

View File

@ -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);
}

View File

@ -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. */

View File

@ -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;

File diff suppressed because it is too large Load Diff

View File

@ -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 ();
}

View File

@ -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;
}

View File

@ -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
View File

@ -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 *));

View File

@ -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.

View File

@ -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 \

View File

@ -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"

View File

@ -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)

View File

@ -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>

View File

@ -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 */

View File

@ -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"

View File

@ -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 (&current_jcf, 1, sizeof (JCF), (void (*)(void *))ggc_mark_jcf);
init_src_parse ();
}

View File

@ -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;

View File

@ -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); \

View File

@ -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

View File

@ -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 *);

View File

@ -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 */

View File

@ -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 ()
{

View File

@ -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;
}

View File

@ -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

View File

@ -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"

View File

@ -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));

View File

@ -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, &gt_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"

View File

@ -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.

View File

@ -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/*]

View File

@ -0,0 +1,5 @@
#include "empty.Hp"
int main()
{
return 0;
}

View File

View 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

View File

@ -0,0 +1,7 @@
#include "system-1.Hp"
int main()
{
std::cout << "hello world!" << '\n';
return 0;
}

View File

@ -0,0 +1 @@
#include <iostream>

View File

@ -0,0 +1,3 @@
#include "common-1.hp"
int foo2 = 3;
int zz = 2;

View File

@ -0,0 +1,3 @@
static int foo1 = 9;
int foo2;
extern int zz;

View File

@ -0,0 +1,4 @@
#include "cpp-1.hp"
#if !defined(__GNUC__)
panic! panic!
#endif

View File

@ -0,0 +1 @@
/* Empty. */

View File

@ -0,0 +1,4 @@
/* { dg-options "-Wunknown-pragmas -I." } */
#include "cpp-2.hp"
#pragma GCC poison not_used

View File

@ -0,0 +1 @@
/* Empty. */

View File

@ -0,0 +1,2 @@
#include "decl-1.hp"
int main(void) { return foo; }

View File

@ -0,0 +1 @@
extern int foo;

View File

@ -0,0 +1,2 @@
#include "decl-2.hp"
int main(void) { return fun (1, 2); }

View File

@ -0,0 +1,3 @@
extern int fun (int a, int b);

View File

@ -0,0 +1,11 @@
#include "decl-3.hp"
foo_p bar (void)
{
return foop;
}
struct foo *bar2 (void)
{
return foop;
}

View File

@ -0,0 +1,3 @@
struct foo;
typedef struct foo *foo_p;
extern foo_p foop;

View 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;
}

View 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;

View File

@ -0,0 +1,2 @@
#include "decl-5.hp"
static int (*t)(void) = foo;

View File

@ -0,0 +1 @@
extern int foo(void);

View 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