Index: ChangeLog

2003-07-10  Geoffrey Keating  <geoffk@apple.com>

	* c-decl.c (finish_decl): Handle 'used' here...
	* cgraphunit.c (cgraph_finalize_function): ... and here ...
	* c-common.c: (handle_used_attribute): ... not here.

	* configure.in (onstep): Support --enable-intermodule.
	* Makefile.in (OBJS-common): New.
	(OBJS-md): New.
	(OBJS-archive): New.
	(OBJS): Build from OBJS-common, OBJS-md, OBJS-archive.
	(OBJS-onestep): New.
	(libbackend.a): Support @onestep@.
	(libbackend.o): New.
	* configure: Regenerate.

	* c-common.h (c_reset_state): New prototype.
	(c_parse_file): New prototype.
	(finish_file): Move prototype from c-tree.h.
	* c-decl.c: Include <hashtab.h>.
	(builtin_decls): New.
	(current_file_decl): New.
	(duplicate_decls): Add extra parameter. Change all callers.  Don't
	output duplicate common symbols.
	(link_hash_hash): New.
	(link_hash_eq): New.
	(poplevel): Handle popping of the top level.
	(warn_if_shadowing): Handle TRANSLATION_UNIT_DECL.
	(pushdecl): Set DECL_CONTEXT to TRANSLATION_UNIT_DECL if appropriate.
	(pushdecl_top_level): Likewise.
	(redeclaration_error_message): Handle TRANSLATION_UNIT_DECL.
	(c_init_decl_processing): Create TRANSLATION_UNIT_DECL.
	(finish_decl): Handle TRANSLATION_UNIT_DECL.
	(merge_translation_unit_decls): New.
	(c_write_global_declarations): New.
	(c_reset_state): New.
	(implicitly_declare): Handle TRANSLATION_UNIT_DECL.
	* c-lang.c (LANG_HOOKS_WRITE_GLOBALS): New.
	* c-objc-common.c (c_cannot_inline_tree_fn): Handle
	TRANSLATION_UNIT_DECL.
	(c_objc_common_finish_file): Call merge_translation_unit_decls.
	* c-opts.c (in_fnames): Rename from in_fname.
	(c_common_decode_option): Handle multiple input filenames.
	(c_common_post_options): Likewise.
	(c_common_parse_file): Likewise; also, call c_parse_file rather than
	yyparse.
	* c-parse.in: Move cleanup code to c_parse_file.
	(free_parser_stacks): Move contents to c_parse_file.
	(c_parse_file): New.
	* c-tree.h (union lang_tree_node): Chain along TYPE_NEXT_VARIANT
	for integer types.
	(C_DECL_FILE_SCOPE): New.
	(finish_file): Move prototype to c-common.h.
	(merge_translation_unit_decls): New prototype.
	(comptypes): Add extra parameter to prototype.
	(c_write_global_declarations): New prototype.
	* c-typeck.c (tagged_types_tu_compatible_p): New.
	(function_types_compatible_p): Add extra parameter, change all callers.
	(type_lists_compatible_p): Likewise.
	(comptypes): Likewise.
	(struct tagged_tu_seen): New.
	(tagged_tu_seen_base): New.
	(build_unary_op): Handle TRANSLATION_UNIT_DECL.
	(c_mark_addressable): Remove #if 0 code.
	* calls.c (special_function_p): Handle TRANSLATION_UNIT_DECL, add
	comment explaining why it shouldn't have to.
	* cgraph.h (struct cgraph_node): Add chain_next and chain_prev GTY
	options.
	* cppinit.c (cpp_read_next_file): New.
	(cpp_read_main_file): Use it.
	* cpplib.c (undefine_macros): New.
	(cpp_undef_all): New.
	* cpplib.h (cpp_read_next_file): Prototype.
	(cpp_undef_all): Prototype.
	* langhooks-def.h (write_global_declarations): Remove prototype.
	* toplev.h (write_global_declarations): Add prototype.
	* tree.c (decl_type_context): Use switch statement, handle
	TRANSLATION_UNIT_DECL.
	* tree.def: Update documentation for TRANSLATION_UNIT_DECL.
	(TRANSLATION_UNIT_DECL): New kind of tree.
	* tree.h: Update documentation for TRANSLATION_UNIT_DECL.
	* Makefile.in (c-decl.o): Add $(HASHTAB_H) to dependencies.
	* doc/invoke.texi: Make attempt to document new functionality.

	2003-05-19  Per Bothner <bothner@apple.com>

	* gcc.c (combine_inputs): New.
	(process_command): Set combine_inputs.
	(do_spec_1): Handle combine_inputs.
	(main): Likewise.

Index: cp/ChangeLog
2003-07-10  Geoffrey Keating  <geoffk@apple.com>

	* decl.c (cp_finish_decl): Handle 'used' attribute.

	* cp-lang.c (c_reset_state): New dummy routine.
	* cp-tree.h (finish_file): Move prototype to c-common.h.
	* parser.c (c_parse_file): Rename from yyparse; don't call finish_file.

From-SVN: r69224
This commit is contained in:
Geoffrey Keating 2003-07-11 08:33:21 +00:00 committed by Geoffrey Keating
parent 6eeba0cc43
commit d1bd0ded61
32 changed files with 1150 additions and 448 deletions

View File

@ -1,3 +1,94 @@
2003-07-11 Geoffrey Keating <geoffk@apple.com>
* c-decl.c (finish_decl): Handle 'used' here...
* cgraphunit.c (cgraph_finalize_function): ... and here ...
* c-common.c: (handle_used_attribute): ... not here.
* configure.in (onstep): Support --enable-intermodule.
* Makefile.in (OBJS-common): New.
(OBJS-md): New.
(OBJS-archive): New.
(OBJS): Build from OBJS-common, OBJS-md, OBJS-archive.
(OBJS-onestep): New.
(libbackend.a): Support @onestep@.
(libbackend.o): New.
* configure: Regenerate.
* c-common.h (c_reset_state): New prototype.
(c_parse_file): New prototype.
(finish_file): Move prototype from c-tree.h.
* c-decl.c: Include <hashtab.h>.
(builtin_decls): New.
(current_file_decl): New.
(duplicate_decls): Add extra parameter. Change all callers. Don't
output duplicate common symbols.
(link_hash_hash): New.
(link_hash_eq): New.
(poplevel): Handle popping of the top level.
(warn_if_shadowing): Handle TRANSLATION_UNIT_DECL.
(pushdecl): Set DECL_CONTEXT to TRANSLATION_UNIT_DECL if appropriate.
(pushdecl_top_level): Likewise.
(redeclaration_error_message): Handle TRANSLATION_UNIT_DECL.
(c_init_decl_processing): Create TRANSLATION_UNIT_DECL.
(finish_decl): Handle TRANSLATION_UNIT_DECL.
(merge_translation_unit_decls): New.
(c_write_global_declarations): New.
(c_reset_state): New.
(implicitly_declare): Handle TRANSLATION_UNIT_DECL.
* c-lang.c (LANG_HOOKS_WRITE_GLOBALS): New.
* c-objc-common.c (c_cannot_inline_tree_fn): Handle
TRANSLATION_UNIT_DECL.
(c_objc_common_finish_file): Call merge_translation_unit_decls.
* c-opts.c (in_fnames): Rename from in_fname.
(c_common_decode_option): Handle multiple input filenames.
(c_common_post_options): Likewise.
(c_common_parse_file): Likewise; also, call c_parse_file rather than
yyparse.
* c-parse.in: Move cleanup code to c_parse_file.
(free_parser_stacks): Move contents to c_parse_file.
(c_parse_file): New.
* c-tree.h (union lang_tree_node): Chain along TYPE_NEXT_VARIANT
for integer types.
(C_DECL_FILE_SCOPE): New.
(finish_file): Move prototype to c-common.h.
(merge_translation_unit_decls): New prototype.
(comptypes): Add extra parameter to prototype.
(c_write_global_declarations): New prototype.
* c-typeck.c (tagged_types_tu_compatible_p): New.
(function_types_compatible_p): Add extra parameter, change all callers.
(type_lists_compatible_p): Likewise.
(comptypes): Likewise.
(struct tagged_tu_seen): New.
(tagged_tu_seen_base): New.
(build_unary_op): Handle TRANSLATION_UNIT_DECL.
(c_mark_addressable): Remove #if 0 code.
* calls.c (special_function_p): Handle TRANSLATION_UNIT_DECL, add
comment explaining why it shouldn't have to.
* cgraph.h (struct cgraph_node): Add chain_next and chain_prev GTY
options.
* cppinit.c (cpp_read_next_file): New.
(cpp_read_main_file): Use it.
* cpplib.c (undefine_macros): New.
(cpp_undef_all): New.
* cpplib.h (cpp_read_next_file): Prototype.
(cpp_undef_all): Prototype.
* langhooks-def.h (write_global_declarations): Remove prototype.
* toplev.h (write_global_declarations): Add prototype.
* tree.c (decl_type_context): Use switch statement, handle
TRANSLATION_UNIT_DECL.
* tree.def: Update documentation for TRANSLATION_UNIT_DECL.
(TRANSLATION_UNIT_DECL): New kind of tree.
* tree.h: Update documentation for TRANSLATION_UNIT_DECL.
* Makefile.in (c-decl.o): Add $(HASHTAB_H) to dependencies.
* doc/invoke.texi: Make attempt to document new functionality.
2003-05-19 Per Bothner <bothner@apple.com>
* gcc.c (combine_inputs): New.
(process_command): Set combine_inputs.
(do_spec_1): Handle combine_inputs.
(main): Likewise.
2003-07-10 James E Wilson <wilson@tuliptree.org>
PR optimization/9745

View File

@ -801,7 +801,8 @@ C_OBJS = c-parse.o c-lang.o c-pretty-print.o $(C_AND_OBJC_OBJS)
# Language-independent object files.
OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
OBJS-common = \
alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o \
cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o \
cfgrtl.o combine.o conflict.o convert.o coverage.o cse.o cselib.o \
@ -809,7 +810,7 @@ OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
dwarf2asm.o dwarf2out.o dwarfout.o emit-rtl.o except.o explow.o \
expmed.o expr.o final.o flow.o fold-const.o function.o gcse.o \
genrtl.o ggc-common.o global.o graph.o gtype-desc.o \
haifa-sched.o hashtable.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o \
haifa-sched.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o \
insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o \
integrate.o intl.o jump.o langhooks.o lcm.o lists.o local-alloc.o \
loop.o optabs.o options.o opts.o params.o postreload.o predict.o \
@ -820,9 +821,16 @@ OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o \
sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o \
sibcall.o simplify-rtx.o sreal.o ssa.o ssa-ccp.o ssa-dce.o stmt.o \
stor-layout.o stringpool.o timevar.o toplev.o tracer.o tree.o tree-dump.o \
tree-inline.o unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
alloc-pool.o et-forest.o cgraph.o cgraphunit.o cfghooks.o bt-load.o \
$(GGC) $(out_object_file) $(EXTRA_OBJS) $(host_hook_obj)
unroll.o varasm.o varray.o version.o vmsdbgout.o xcoffout.o \
alloc-pool.o et-forest.o cfghooks.o bt-load.o $(GGC)
OBJS-md = $(out_object_file)
OBJS-archive = $(EXTRA_OBJS) $(host_hook_obj) hashtable.o tree-inline.o \
cgraph.o cgraphunit.o
OBJS = $(OBJS-common) $(out_object_file) $(OBJS-archive)
OBJS-onestep = libbackend.o $(OBJS-archive)
BACKEND = main.o libbackend.a
@ -1026,9 +1034,9 @@ rest.cross: $(LIBGCC) specs
compilations: $(BACKEND)
# Like libcpp.a, this archive is strictly for the host.
libbackend.a: $(OBJS)
libbackend.a: $(OBJS@onestep@)
-rm -rf libbackend.a
$(AR) $(AR_FLAGS) libbackend.a $(OBJS)
$(AR) $(AR_FLAGS) libbackend.a $(OBJS@onestep@)
-$(RANLIB) libbackend.a
# We call this executable `xgcc' rather than `gcc'
@ -1817,6 +1825,15 @@ mips-tdump: mips-tdump.o version.o $(LIBDEPS)
mips-tdump.o : mips-tdump.c $(CONFIG_H) $(RTL_H) $(SYSTEM_H) coretypes.h $(TM_H) version.h
# FIXME: writing proper dependencies for this is a *LOT* of work.
libbackend.o : $(OBJS-common:.o=.c) $(out_file) \
insn-config.h insn-flags.h insn-codes.h insn-constants.h \
insn-attr.h options_.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-DTARGET_NAME=\"$(target_alias)\" \
-DLOCALEDIR=\"$(localedir)\" \
-c $(filter %.c,$^) -o $@
#
# Generate header and source files from the machine description,
# and compile them.

View File

@ -4680,7 +4680,6 @@ handle_used_attribute (tree *pnode, tree name, tree args ATTRIBUTE_UNUSED,
if (TREE_CODE (node) == FUNCTION_DECL
|| (TREE_CODE (node) == VAR_DECL && TREE_STATIC (node)))
{
mark_referenced (DECL_ASSEMBLER_NAME (node));
TREE_USED (node) = 1;
}
else

View File

@ -963,6 +963,14 @@ extern bool c_promoting_integer_type_p (tree);
extern int self_promoting_args_p (tree);
extern tree strip_array_types (tree);
/* This function resets the parsers' state in preparation for parsing
a new file. */
extern void c_reset_state (void);
/* This is the basic parsing function. */
extern void c_parse_file (void);
/* This is misnamed, it actually performs end-of-compilation processing. */
extern void finish_file (void);
/* These macros provide convenient access to the various _STMT nodes. */
/* Nonzero if this statement should be considered a full-expression,

View File

@ -127,6 +127,14 @@ static GTY(()) tree shadowed_labels;
some other global meaning for that identifier. */
static GTY(()) tree truly_local_externals;
/* A list of the builtin file-scope DECLs. */
static GTY(()) tree builtin_decls;
/* A DECL for the current file-scope context. */
static GTY(()) tree current_file_decl;
/* Set to 0 at beginning of a function definition, set to 1 if
a return statement that specifies a return value is seen. */
@ -265,7 +273,7 @@ tree static_ctors, static_dtors;
static struct binding_level *make_binding_level (void);
static void pop_binding_level (struct binding_level **);
static int duplicate_decls (tree, tree, int);
static int duplicate_decls (tree, tree, int, int);
static int redeclaration_error_message (tree, tree);
static void implicit_decl_warning (tree);
static void storedecls (tree);
@ -282,6 +290,8 @@ static void record_external_decl (tree);
static void warn_if_shadowing (tree, tree);
static void clone_underlying_type (tree);
static bool flexible_array_type_p (tree);
static hashval_t link_hash_hash (const void *);
static int link_hash_eq (const void *, const void *);
/* States indicating how grokdeclarator() should handle declspecs marked
with __attribute__((deprecated)). An object declared as
@ -482,8 +492,12 @@ poplevel (int keep, int reverse, int functionbody)
/* We used to warn about unused variables in expand_end_bindings,
i.e. while generating RTL. But in function-at-a-time mode we may
choose to never expand a function at all (e.g. auto inlining), so
we do this explicitly now. */
warn_about_unused_variables (decls);
we do this explicitly now.
No warnings when the global scope is popped because the global
scope isn't popped for the last translation unit, so the warnings
are done in c_write_global_declaration. */
if (current_binding_level != global_binding_level)
warn_about_unused_variables (decls);
/* Clear out the name-meanings declared on this level.
Propagate TREE_ADDRESSABLE from nested functions to their
@ -492,7 +506,8 @@ poplevel (int keep, int reverse, int functionbody)
{
if (DECL_NAME (link) != 0)
{
if (DECL_EXTERNAL (link))
if (DECL_EXTERNAL (link)
&& current_binding_level != global_binding_level)
/* External decls stay in the symbol-value slot but are
inaccessible. */
C_DECL_INVISIBLE (link) = 1;
@ -626,7 +641,7 @@ poplevel (int keep, int reverse, int functionbody)
/* Dispose of the block that we just made inside some higher level. */
if (functionbody)
DECL_INITIAL (current_function_decl) = block;
else if (block)
else if (block && current_binding_level)
current_binding_level->blocks
= chainon (current_binding_level->blocks, block);
/* If we did not make a block for the level just exited,
@ -634,7 +649,7 @@ poplevel (int keep, int reverse, int functionbody)
(since they cannot be recorded as subblocks in that level)
must be carried forward so they will later become subblocks
of something else. */
else if (subblocks)
else if (! block && subblocks)
current_binding_level->blocks
= chainon (current_binding_level->blocks, subblocks);
@ -784,9 +799,13 @@ pushtag (tree name, tree type)
and OLDDECL is in an outer binding level and should thus not be changed. */
static int
duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
duplicate_decls (tree newdecl, tree olddecl, int different_binding_level,
int different_tu)
{
int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
int comptype_flags = (different_tu ? COMPARE_DIFFERENT_TU
: COMPARE_STRICT);
int types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl),
comptype_flags);
int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL
&& DECL_INITIAL (newdecl) != 0);
tree oldtype = TREE_TYPE (olddecl);
@ -908,7 +927,7 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
trytype = build_type_attribute_variant (trytype,
TYPE_ATTRIBUTES (oldtype));
types_match = comptypes (newtype, trytype);
types_match = comptypes (newtype, trytype, comptype_flags);
if (types_match)
oldtype = trytype;
}
@ -931,7 +950,7 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
trytype = build_type_attribute_variant (trytype,
TYPE_ATTRIBUTES (oldtype));
types_match = comptypes (newtype, trytype);
types_match = comptypes (newtype, trytype, comptype_flags);
if (types_match)
oldtype = trytype;
}
@ -1030,7 +1049,7 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
&& ! pedantic
/* Return types must still match. */
&& comptypes (TREE_TYPE (oldtype),
TREE_TYPE (newtype))
TREE_TYPE (newtype), comptype_flags)
&& TYPE_ARG_TYPES (newtype) == 0))
{
error_with_decl (newdecl, "conflicting types for `%s'");
@ -1038,7 +1057,7 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
involving an empty arglist vs a nonempty one. */
if (TREE_CODE (olddecl) == FUNCTION_DECL
&& comptypes (TREE_TYPE (oldtype),
TREE_TYPE (newtype))
TREE_TYPE (newtype), comptype_flags)
&& ((TYPE_ARG_TYPES (oldtype) == 0
&& DECL_INITIAL (olddecl) == 0)
||
@ -1166,7 +1185,8 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
}
/* Type for passing arg must be consistent
with that declared for the arg. */
if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type)))
if (! comptypes (TREE_VALUE (parm), TREE_VALUE (type),
comptype_flags))
{
error_with_decl (newdecl,
"prototype for `%s' follows and argument %d doesn't match",
@ -1393,7 +1413,7 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
}
if (DECL_EXTERNAL (newdecl))
{
if (! different_binding_level)
if (! different_binding_level || different_tu)
{
/* Don't mess with these flags on local externs; they remain
external even if there's a declaration at file scope which
@ -1404,7 +1424,13 @@ duplicate_decls (tree newdecl, tree olddecl, int different_binding_level)
/* An extern decl does not override previous storage class. */
TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
if (! DECL_EXTERNAL (newdecl))
DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
{
DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
/* If we have two non-EXTERNAL file-scope decls that are
the same, only one of them should be written out. */
if (different_tu)
TREE_ASM_WRITTEN (newdecl) = 1;
}
}
else
{
@ -1586,7 +1612,7 @@ warn_if_shadowing (tree x, tree old)
if (TREE_CODE (old) == PARM_DECL)
shadow_warning (SW_PARAM, name, old);
else if (DECL_CONTEXT (old) == 0)
else if (C_DECL_FILE_SCOPE (old))
shadow_warning (SW_GLOBAL, name, old);
else
shadow_warning (SW_LOCAL, name, old);
@ -1685,12 +1711,13 @@ pushdecl (tree x)
/* A local extern declaration for a function doesn't constitute nesting.
A local auto declaration does, since it's a forward decl
for a nested function coming later. */
if ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
&& DECL_INITIAL (x) == 0 && DECL_EXTERNAL (x))
DECL_CONTEXT (x) = 0;
if (current_function_decl == NULL
|| ((TREE_CODE (x) == FUNCTION_DECL || TREE_CODE (x) == VAR_DECL)
&& DECL_INITIAL (x) == 0 && DECL_EXTERNAL (x)))
DECL_CONTEXT (x) = current_file_decl;
else
DECL_CONTEXT (x) = current_function_decl;
if (name)
{
tree old;
@ -1703,7 +1730,7 @@ pushdecl (tree x)
IDENTIFIER_POINTER (name));
old = lookup_name_current_level (name);
if (old && duplicate_decls (x, old, 0))
if (old && duplicate_decls (x, old, 0, false))
return old;
if (DECL_EXTERNAL (x) || scope == global_binding_level)
{
@ -1714,7 +1741,8 @@ pushdecl (tree x)
tree ext = any_external_decl (name);
if (ext)
{
if (duplicate_decls (x, ext, scope != global_binding_level))
if (duplicate_decls (x, ext, scope != global_binding_level,
false))
x = copy_node (ext);
}
else
@ -1788,13 +1816,13 @@ pushdecl_top_level (tree x)
if (DECL_CONTEXT (old))
abort ();
if (!duplicate_decls (x, old, 0))
if (!duplicate_decls (x, old, 0, false))
abort ();
return old;
}
DECL_CONTEXT (x) = 0;
DECL_CONTEXT (x) = current_file_decl;
IDENTIFIER_SYMBOL_VALUE (name) = x;
TREE_CHAIN (x) = global_binding_level->names;
global_binding_level->names = x;
@ -1855,7 +1883,7 @@ implicitly_declare (tree functionid)
if (!C_DECL_IMPLICIT (decl))
{
implicit_decl_warning (DECL_NAME (decl));
if (DECL_CONTEXT (decl))
if (! C_DECL_FILE_SCOPE (decl))
warning_with_decl (decl, "previous declaration of `%s'");
C_DECL_IMPLICIT (decl) = 1;
}
@ -1935,7 +1963,7 @@ redeclaration_error_message (tree newdecl, tree olddecl)
return 1;
return 0;
}
else if (DECL_CONTEXT (newdecl) == NULL_TREE)
else if (C_DECL_FILE_SCOPE (newdecl))
{
/* Objects declared at top level: */
/* If at least one is a reference, it's ok. */
@ -2245,6 +2273,9 @@ c_init_decl_processing (void)
input_location.file = "<internal>";
input_location.line = 0;
/* Make the DECL for the toplevel file scope. */
current_file_decl = build_decl (TRANSLATION_UNIT_DECL, NULL, NULL);
build_common_tree_nodes (flag_signed_char);
c_common_nodes_and_builtins ();
@ -2277,6 +2308,8 @@ c_init_decl_processing (void)
make_fname_decl = c_make_fname_decl;
start_fname_decls ();
builtin_decls = global_binding_level->names;
}
/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give the
@ -2692,7 +2725,7 @@ start_decl (tree declarator, tree declspecs, int initialized, tree attributes)
and we preserved the rtl from the previous one
(which may or may not happen). */
&& !DECL_RTL_SET_P (tem)
&& !DECL_CONTEXT (tem))
&& C_DECL_FILE_SCOPE (tem))
{
if (TREE_TYPE (tem) != error_mark_node
&& COMPLETE_TYPE_P (TREE_TYPE (tem)))
@ -2795,7 +2828,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
Otherwise, let it through, but if it is not `extern'
then it may cause an error message later. */
(DECL_INITIAL (decl) != 0
|| DECL_CONTEXT (decl) != 0)
|| !C_DECL_FILE_SCOPE (decl))
:
/* An automatic variable with an incomplete type
is an error. */
@ -2860,7 +2893,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
if (c_dialect_objc ())
objc_check_decl (decl);
if (!DECL_CONTEXT (decl))
if (C_DECL_FILE_SCOPE (decl))
{
if (DECL_INITIAL (decl) == NULL_TREE
|| DECL_INITIAL (decl) == error_mark_node)
@ -2868,9 +2901,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
when a tentative file-scope definition is seen.
But at end of compilation, do output code for them. */
DECL_DEFER_OUTPUT (decl) = 1;
rest_of_decl_compilation (decl, asmspec,
(DECL_CONTEXT (decl) == 0
|| TREE_ASM_WRITTEN (decl)), 0);
rest_of_decl_compilation (decl, asmspec, true, 0);
}
else
{
@ -2902,7 +2933,7 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
add_decl_stmt (decl);
}
if (DECL_CONTEXT (decl) != 0)
if (!C_DECL_FILE_SCOPE (decl))
{
/* Recompute the RTL of a local array now
if it used to be an incomplete type. */
@ -2918,12 +2949,16 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
}
}
/* If this was marked 'used', be sure it will be output. */
if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
mark_referenced (DECL_ASSEMBLER_NAME (decl));
if (TREE_CODE (decl) == TYPE_DECL)
{
/* This is a no-op in c-lang.c or something real in objc-act.c. */
if (c_dialect_objc ())
objc_check_decl (decl);
rest_of_decl_compilation (decl, NULL, DECL_CONTEXT (decl) == 0, 0);
rest_of_decl_compilation (decl, NULL, C_DECL_FILE_SCOPE (decl), 0);
}
/* At the end of a declaration, throw away any variable type sizes
@ -5970,7 +6005,8 @@ store_parm_decls (void)
declared for the arg. ISO C says we take the unqualified
type for parameters declared with qualified type. */
if (! comptypes (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm)),
TYPE_MAIN_VARIANT (TREE_VALUE (type))))
TYPE_MAIN_VARIANT (TREE_VALUE (type)),
COMPARE_STRICT))
{
if (TYPE_MAIN_VARIANT (TREE_TYPE (parm))
== TYPE_MAIN_VARIANT (TREE_VALUE (type)))
@ -6697,7 +6733,7 @@ tree
identifier_global_value (tree t)
{
tree decl = IDENTIFIER_SYMBOL_VALUE (t);
if (decl == 0 || DECL_CONTEXT (decl) == 0)
if (decl == 0 || C_DECL_FILE_SCOPE (decl))
return decl;
/* Shadowed by something else; find the true global value. */
@ -6751,4 +6787,176 @@ make_pointer_declarator (tree type_quals_attrs, tree target)
return build1 (INDIRECT_REF, quals, itarget);
}
/* Hash and equality functions for link_hash_table: key off
DECL_ASSEMBLER_NAME. */
static hashval_t
link_hash_hash (const void *x_p)
{
tree x = (tree)x_p;
return (hashval_t) DECL_ASSEMBLER_NAME (x);
}
static int
link_hash_eq (const void *x1_p, const void *x2_p)
{
tree x1 = (tree)x1_p;
tree x2 = (tree)x2_p;
return DECL_ASSEMBLER_NAME (x1) == DECL_ASSEMBLER_NAME (x2);
}
/* Propagate information between definitions and uses between multiple
translation units in TU_LIST based on linkage rules. */
void
merge_translation_unit_decls (void)
{
const tree tu_list = current_file_decl;
tree tu;
tree decl;
htab_t link_hash_table;
tree block;
/* Create the BLOCK that poplevel would have created, but don't
actually call poplevel since that's expensive. */
block = make_node (BLOCK);
BLOCK_VARS (block) = current_binding_level->names;
TREE_USED (block) = 1;
DECL_INITIAL (current_file_decl) = block;
/* If only one translation unit seen, no copying necessary. */
if (TREE_CHAIN (tu_list) == NULL_TREE)
return;
link_hash_table = htab_create (1021, link_hash_hash, link_hash_eq, NULL);
/* Enter any actual definitions into the hash table. */
for (tu = tu_list; tu; tu = TREE_CHAIN (tu))
for (decl = BLOCK_VARS (DECL_INITIAL (tu)); decl; decl = TREE_CHAIN (decl))
if (TREE_PUBLIC (decl) && ! DECL_EXTERNAL (decl))
{
PTR *slot;
slot = htab_find_slot (link_hash_table, decl, INSERT);
/* If we've already got a definition, work out which one is
the real one, put it into the hash table, and make the
other one DECL_EXTERNAL. This is important to avoid
putting out two definitions of the same symbol in the
assembly output. */
if (*slot != NULL)
{
tree old_decl = (tree) *slot;
/* If this is weak or common or whatever, suppress it
in favour of the other definition. */
if (DECL_WEAK (decl))
DECL_EXTERNAL (decl) = 1;
else if (DECL_WEAK (old_decl) && ! DECL_WEAK (decl))
DECL_EXTERNAL (old_decl) = 1;
else if (DECL_COMMON (decl) || DECL_ONE_ONLY (decl))
DECL_EXTERNAL (decl) = 1;
else if (DECL_COMMON (old_decl) || DECL_ONE_ONLY (old_decl))
DECL_EXTERNAL (old_decl) = 1;
if (DECL_EXTERNAL (decl))
{
DECL_INITIAL (decl) = NULL_TREE;
DECL_COMMON (decl) = 0;
DECL_ONE_ONLY (decl) = 0;
DECL_WEAK (decl) = 0;
}
else if (DECL_EXTERNAL (old_decl))
{
DECL_INITIAL (old_decl) = NULL_TREE;
DECL_COMMON (old_decl) = 0;
DECL_ONE_ONLY (old_decl) = 0;
DECL_WEAK (old_decl) = 0;
*slot = decl;
}
else
{
error_with_decl (decl, "redefinition of global `%s'");
error_with_decl (old_decl, "`%s' previously defined here");
}
}
else
*slot = decl;
}
/* Now insert the desired information from all the definitions
into any plain declarations. */
for (tu = tu_list; tu; tu = TREE_CHAIN (tu))
for (decl = BLOCK_VARS (DECL_INITIAL (tu)); decl; decl = TREE_CHAIN (decl))
if (TREE_PUBLIC (decl) && DECL_EXTERNAL (decl))
{
tree global_decl;
global_decl = (tree) htab_find (link_hash_table, decl);
if (! global_decl)
continue;
/* Print any appropriate error messages, and partially merge
the decls. */
(void) duplicate_decls (decl, global_decl, true, true);
}
htab_delete (link_hash_table);
}
/* Perform final processing on file-scope data. */
void
c_write_global_declarations(void)
{
tree link;
for (link = current_file_decl; link; link = TREE_CHAIN (link))
{
tree globals = BLOCK_VARS (DECL_INITIAL (link));
int len = list_length (globals);
tree *vec = (tree *) xmalloc (sizeof (tree) * len);
int i;
tree decl;
/* Process the decls in reverse order--earliest first.
Put them into VEC from back to front, then take out from front. */
for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
vec[len - i - 1] = decl;
wrapup_global_declarations (vec, len);
check_global_declarations (vec, len);
/* Clean up. */
free (vec);
}
}
/* Reset the parser's state in preparation for a new file. */
void
c_reset_state (void)
{
tree link;
tree file_scope_decl;
/* Pop the global binding level. */
if (current_binding_level != global_binding_level)
current_binding_level = global_binding_level;
file_scope_decl = current_file_decl;
DECL_INITIAL (file_scope_decl) = poplevel (1, 0, 0);
truly_local_externals = NULL_TREE;
/* Start a new global binding level. */
pushlevel (0);
global_binding_level = current_binding_level;
current_file_decl = build_decl (TRANSLATION_UNIT_DECL, NULL, NULL);
TREE_CHAIN (current_file_decl) = file_scope_decl;
/* Reintroduce the global declarations. */
for (link = builtin_decls; link; link = TREE_CHAIN (link))
pushdecl (copy_node (link));
}
#include "gt-c-decl.h"

View File

@ -125,6 +125,9 @@ enum c_language_kind c_language = clk_c;
#undef LANG_HOOKS_TYPE_PROMOTES_TO
#define LANG_HOOKS_TYPE_PROMOTES_TO c_type_promotes_to
#undef LANG_HOOKS_WRITE_GLOBALS
#define LANG_HOOKS_WRITE_GLOBALS c_write_global_declarations
/* ### When changing hooks, consider if ObjC needs changing too!! ### */
/* Each front end provides its own. */

View File

@ -127,7 +127,7 @@ inline_forbidden_p (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
/* We cannot inline a nested function that jumps to a nonlocal
label. */
if (TREE_CODE (t) == LABEL_DECL
&& DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
&& !C_DECL_FILE_SCOPE (t) && DECL_CONTEXT (t) != fn)
return node;
break;
@ -184,7 +184,7 @@ c_cannot_inline_tree_fn (tree *fnp)
goto cannot_inline;
}
if (DECL_CONTEXT (fn))
if (! C_DECL_FILE_SCOPE (fn))
{
/* If a nested function has pending sizes, we may have already
saved them. */
@ -357,6 +357,10 @@ c_objc_common_finish_file (void)
if (pch_file)
c_common_write_pch ();
/* If multiple translation units were built, copy information between
them based on linkage rules. */
merge_translation_unit_decls ();
if (flag_unit_at_a_time)
{
cgraph_finalize_compilation_unit ();

View File

@ -52,7 +52,8 @@ static int saved_lineno;
static cpp_options *cpp_opts;
/* Input filename. */
static const char *in_fname;
static const char **in_fnames;
static unsigned num_in_fnames;
/* Filename and stream for preprocessed output. */
static const char *out_fname;
@ -1039,12 +1040,9 @@ c_common_handle_option (size_t scode, const char *arg, int value)
void
c_common_handle_filename (const char *filename)
{
if (!in_fname)
in_fname = filename;
else if (!out_fname)
out_fname = filename;
else
error ("output filename specified twice");
num_in_fnames++;
in_fnames = xrealloc (in_fnames, num_in_fnames * sizeof (in_fnames[0]));
in_fnames[num_in_fnames - 1] = filename;
}
/* Post-switch processing. */
@ -1052,8 +1050,13 @@ bool
c_common_post_options (const char **pfilename)
{
/* Canonicalize the input and output filenames. */
if (in_fname == NULL || !strcmp (in_fname, "-"))
in_fname = "";
if (in_fnames == NULL)
{
in_fnames = xmalloc (sizeof (in_fnames[0]));
in_fnames[0] = "";
}
else if (strcmp (in_fnames[0], "-") == 0)
in_fnames[0] = "";
if (out_fname == NULL || !strcmp (out_fname, "-"))
out_fname = "";
@ -1119,6 +1122,10 @@ c_common_post_options (const char **pfilename)
return false;
}
if (num_in_fnames > 1)
error ("too many filenames given. Type %s --help for usage",
progname);
init_pp_output (out_stream);
}
else
@ -1132,7 +1139,7 @@ c_common_post_options (const char **pfilename)
cpp_get_callbacks (parse_in)->file_change = cb_file_change;
/* NOTE: we use in_fname here, not the one supplied. */
*pfilename = cpp_read_main_file (parse_in, in_fname);
*pfilename = cpp_read_main_file (parse_in, in_fnames[0]);
saved_lineno = input_line;
input_line = 0;
@ -1176,23 +1183,43 @@ c_common_init (void)
return true;
}
/* A thin wrapper around the real parser that initializes the
integrated preprocessor after debug output has been initialized.
Also, make sure the start_source_file debug hook gets called for
the primary source file. */
/* Initialize the integrated preprocessor after debug output has been
initialized; loop over each input file. */
void
c_common_parse_file (int set_yydebug ATTRIBUTE_UNUSED)
{
unsigned file_index;
#if YYDEBUG != 0
yydebug = set_yydebug;
#else
warning ("YYDEBUG not defined");
#endif
finish_options();
pch_init();
yyparse ();
file_index = 0;
do
{
if (file_index > 0)
{
/* Reset the state of the parser. */
c_reset_state();
/* Reset cpplib's macros and start a new file. */
cpp_undef_all (parse_in);
cpp_read_next_file (parse_in, in_fnames[file_index]);
}
finish_options();
if (file_index == 0)
pch_init();
c_parse_file ();
file_index++;
} while (file_index < num_in_fnames);
free_parser_stacks ();
finish_file ();
}
/* Common finish hook for the C, ObjC and C++ front ends. */

View File

@ -352,20 +352,8 @@ c_parse_init (void)
program: /* empty */
{ if (pedantic)
pedwarn ("ISO C forbids an empty source file");
finish_file ();
}
| extdefs
{
/* In case there were missing closebraces,
get us back to the global binding level. */
while (! global_bindings_p ())
poplevel (0, 0, 0);
/* __FUNCTION__ is defined at file scope (""). This
call may not be necessary as my tests indicate it
still works without it. */
finish_fname_decls ();
finish_file ();
}
;
/* the reason for the strange actions in this rule
@ -718,7 +706,7 @@ primary:
e1 = TYPE_MAIN_VARIANT (groktypename ($3));
e2 = TYPE_MAIN_VARIANT (groktypename ($5));
$$ = comptypes (e1, e2)
$$ = comptypes (e1, e2, COMPARE_STRICT)
? build_int_2 (1, 0) : build_int_2 (0, 0);
}
| primary '[' expr ']' %prec '.'
@ -3795,10 +3783,27 @@ yyprint (FILE *file, int yychar, YYSTYPE yyl)
void
free_parser_stacks (void)
{
}
/* Parse the file. */
void
c_parse_file (void)
{
yyparse ();
/* In case there were missing closebraces, get us back to the global
binding level. */
while (! global_bindings_p ())
poplevel (0, 0, 0);
/* __FUNCTION__ is defined at file scope (""). This
call may not be necessary as my tests indicate it
still works without it. */
finish_fname_decls ();
if (malloced_yyss)
{
free (malloced_yyss);
free (malloced_yyvs);
malloced_yyss = 0;
}
}

View File

@ -46,7 +46,7 @@ struct lang_identifier GTY(())
union lang_tree_node
GTY((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
chain_next ("(union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
chain_next ("TREE_CODE (&%h.generic) == INTEGER_TYPE ? (union lang_tree_node *)TYPE_NEXT_VARIANT (&%h.generic) : (union lang_tree_node *)TREE_CHAIN (&%h.generic)")))
{
union tree_node GTY ((tag ("0"),
desc ("tree_node_structure (&%h)")))
@ -146,6 +146,11 @@ struct lang_type GTY(())
|| (TYPE_ARG_TYPES (TREE_TYPE (EXP)) == 0 \
&& !DECL_BUILT_IN (EXP)))
/* Nonzero for a decl which is at file scope. */
#define C_DECL_FILE_SCOPE(EXP) \
(! DECL_CONTEXT (EXP) \
|| TREE_CODE (DECL_CONTEXT (EXP)) == TRANSLATION_UNIT_DECL)
/* For FUNCTION_TYPE, a hidden list of types of arguments. The same as
TYPE_ARG_TYPES for functions with prototypes, but created for functions
without prototypes. */
@ -157,7 +162,6 @@ extern tree lookup_interface (tree);
extern tree is_class_name (tree);
extern tree objc_is_id (tree);
extern void objc_check_decl (tree);
extern void finish_file (void);
extern int objc_comptypes (tree, tree, int);
extern tree objc_message_selector (void);
extern tree lookup_objc_ivar (tree);
@ -226,6 +230,7 @@ extern tree c_begin_compound_stmt (void);
extern void c_expand_deferred_function (tree);
extern void c_expand_decl_stmt (tree);
extern tree make_pointer_declarator (tree, tree);
extern void merge_translation_unit_decls (void);
/* in c-objc-common.c */
extern int c_disregard_inline_limits (tree);
@ -242,9 +247,17 @@ extern bool c_warn_unused_global_decl (tree);
((VOLATILE_P) ? TYPE_QUAL_VOLATILE : 0))
#define c_sizeof_nowarn(T) c_sizeof_or_alignof_type (T, SIZEOF_EXPR, 0)
/* in c-typeck.c */
/* For use with comptypes. */
enum {
COMPARE_STRICT = 0,
COMPARE_DIFFERENT_TU = 1
};
extern tree require_complete_type (tree);
extern int comptypes (tree, tree);
extern int comptypes (tree, tree, int);
extern tree c_size_in_bytes (tree);
extern bool c_mark_addressable (tree);
extern void c_incomplete_type_error (tree, tree);
@ -301,6 +314,7 @@ extern int system_header_p;
/* In c-decl.c */
extern void c_finish_incomplete_decl (tree);
extern void c_write_global_declarations (void);
extern GTY(()) tree static_ctors;
extern GTY(()) tree static_dtors;

View File

@ -53,9 +53,10 @@ static int missing_braces_mentioned;
static int undeclared_variable_notice;
static tree qualify_type (tree, tree);
static int tagged_types_tu_compatible_p (tree, tree, int);
static int comp_target_types (tree, tree, int);
static int function_types_compatible_p (tree, tree);
static int type_lists_compatible_p (tree, tree);
static int function_types_compatible_p (tree, tree, int);
static int type_lists_compatible_p (tree, tree, int);
static tree decl_constant_value_for_broken_optimization (tree);
static tree default_function_array_conversion (tree);
static tree lookup_field (tree, tree);
@ -409,7 +410,8 @@ common_type (tree t1, tree t2)
tree memb;
for (memb = TYPE_FIELDS (TREE_VALUE (p1));
memb; memb = TREE_CHAIN (memb))
if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2),
COMPARE_STRICT))
{
TREE_VALUE (n) = TREE_VALUE (p2);
if (pedantic)
@ -423,7 +425,8 @@ common_type (tree t1, tree t2)
tree memb;
for (memb = TYPE_FIELDS (TREE_VALUE (p2));
memb; memb = TREE_CHAIN (memb))
if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1),
COMPARE_STRICT))
{
TREE_VALUE (n) = TREE_VALUE (p1);
if (pedantic)
@ -452,7 +455,7 @@ common_type (tree t1, tree t2)
but a warning may be needed if you use them together. */
int
comptypes (tree type1, tree type2)
comptypes (tree type1, tree type2, int flags)
{
tree t1 = type1;
tree t2 = type2;
@ -512,11 +515,11 @@ comptypes (tree type1, tree type2)
{
case POINTER_TYPE:
val = (TREE_TYPE (t1) == TREE_TYPE (t2)
? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2), flags));
break;
case FUNCTION_TYPE:
val = function_types_compatible_p (t1, t2);
val = function_types_compatible_p (t1, t2, flags);
break;
case ARRAY_TYPE:
@ -529,7 +532,8 @@ comptypes (tree type1, tree type2)
/* Target types must match incl. qualifiers. */
if (TREE_TYPE (t1) != TREE_TYPE (t2)
&& 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2))))
&& 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2),
flags)))
return 0;
/* Sizes must match unless one is missing or variable. */
@ -561,6 +565,11 @@ comptypes (tree type1, tree type2)
case RECORD_TYPE:
if (c_dialect_objc () && objc_comptypes (t1, t2, 0) == 1)
val = 1;
case ENUMERAL_TYPE:
case UNION_TYPE:
if (val != 1 && (flags & COMPARE_DIFFERENT_TU))
val = tagged_types_tu_compatible_p (t1, t2, flags);
break;
case VECTOR_TYPE:
@ -592,7 +601,7 @@ comp_target_types (tree ttl, tree ttr, int reflexive)
return val;
val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
TYPE_MAIN_VARIANT (TREE_TYPE (ttr)), COMPARE_STRICT);
if (val == 2 && pedantic)
pedwarn ("types are not quite compatible");
@ -601,6 +610,159 @@ comp_target_types (tree ttl, tree ttr, int reflexive)
/* Subroutines of `comptypes'. */
/* The C standard says that two structures in different translation
units are compatible with each other only if the types of their
fields are compatible (among other things). So, consider two copies
of this structure: */
struct tagged_tu_seen {
const struct tagged_tu_seen * next;
tree t1;
tree t2;
};
/* Can they be compatible with each other? We choose to break the
recursion by allowing those types to be compatible. */
static const struct tagged_tu_seen * tagged_tu_seen_base;
/* Return 1 if two 'struct', 'union', or 'enum' types T1 and T2 are
compatible. If the two types are not the same (which has been
checked earlier), this can only happen when multiple translation
units are being compiled. See C99 6.2.7 paragraph 1 for the exact
rules. */
static int
tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
{
tree s1, s2;
bool needs_warning = false;
/* We have to verify that the tags of the types are the same. This
is harder than it looks because this may be a typedef, so we have
to go look at the original type. It may even be a typedef of a
typedef... */
while (TYPE_NAME (t1) && TREE_CODE (TYPE_NAME (t1)) == TYPE_DECL)
t1 = DECL_ORIGINAL_TYPE (TYPE_NAME (t1));
while (TYPE_NAME (t2) && TREE_CODE (TYPE_NAME (t2)) == TYPE_DECL)
t2 = DECL_ORIGINAL_TYPE (TYPE_NAME (t2));
/* C90 didn't have the requirement that the two tags be the same. */
if (flag_isoc99 && TYPE_NAME (t1) != TYPE_NAME (t2))
return 0;
/* C90 didn't say what happened if one or both of the types were
incomplete; we choose to follow C99 rules here, which is that they
are compatible. */
if (TYPE_SIZE (t1) == NULL
|| TYPE_SIZE (t2) == NULL)
return 1;
{
const struct tagged_tu_seen * tts_i;
for (tts_i = tagged_tu_seen_base; tts_i != NULL; tts_i = tts_i->next)
if (tts_i->t1 == t1 && tts_i->t2 == t2)
return 1;
}
switch (TREE_CODE (t1))
{
case ENUMERAL_TYPE:
{
if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2)))
return 0;
for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1))
{
s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2));
if (s2 == NULL
|| simple_cst_equal (TREE_VALUE (s1), TREE_VALUE (s2)) != 1)
return 0;
}
return 1;
}
case UNION_TYPE:
{
if (list_length (TYPE_FIELDS (t1)) != list_length (TYPE_FIELDS (t2)))
return 0;
for (s1 = TYPE_FIELDS (t1); s1; s1 = TREE_CHAIN (s1))
{
bool ok = false;
struct tagged_tu_seen tts;
tts.next = tagged_tu_seen_base;
tts.t1 = t1;
tts.t2 = t2;
tagged_tu_seen_base = &tts;
if (DECL_NAME (s1) != NULL)
for (s2 = TYPE_VALUES (t2); s2; s2 = TREE_CHAIN (s2))
if (DECL_NAME (s1) == DECL_NAME (s2))
{
int result;
result = comptypes (TREE_TYPE (s1), TREE_TYPE (s2), flags);
if (result == 0)
break;
if (result == 2)
needs_warning = true;
if (TREE_CODE (s1) == FIELD_DECL
&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
DECL_FIELD_BIT_OFFSET (s2)) != 1)
break;
ok = true;
break;
}
tagged_tu_seen_base = tts.next;
if (! ok)
return 0;
}
return needs_warning ? 2 : 1;
}
case RECORD_TYPE:
{
struct tagged_tu_seen tts;
tts.next = tagged_tu_seen_base;
tts.t1 = t1;
tts.t2 = t2;
tagged_tu_seen_base = &tts;
for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2);
s1 && s2;
s1 = TREE_CHAIN (s1), s2 = TREE_CHAIN (s2))
{
int result;
if (TREE_CODE (s1) != TREE_CODE (s2)
|| DECL_NAME (s1) != DECL_NAME (s2))
break;
result = comptypes (TREE_TYPE (s1), TREE_TYPE (s2), flags);
if (result == 0)
break;
if (result == 2)
needs_warning = true;
if (TREE_CODE (s1) == FIELD_DECL
&& simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
DECL_FIELD_BIT_OFFSET (s2)) != 1)
break;
}
tagged_tu_seen_base = tts.next;
if (s1 && s2)
return 0;
return needs_warning ? 2 : 1;
}
default:
abort ();
}
}
/* Return 1 if two function types F1 and F2 are compatible.
If either type specifies no argument types,
the other must specify a fixed number of self-promoting arg types.
@ -609,7 +771,7 @@ comp_target_types (tree ttl, tree ttr, int reflexive)
Otherwise, the argument types must match. */
static int
function_types_compatible_p (tree f1, tree f2)
function_types_compatible_p (tree f1, tree f2, int flags)
{
tree args1, args2;
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
@ -630,7 +792,7 @@ function_types_compatible_p (tree f1, tree f2)
if (TYPE_VOLATILE (ret2))
ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
val = comptypes (ret1, ret2);
val = comptypes (ret1, ret2, flags);
if (val == 0)
return 0;
@ -648,7 +810,8 @@ function_types_compatible_p (tree f1, tree f2)
compare that with the other type's arglist.
If they don't match, ask for a warning (but no error). */
if (TYPE_ACTUAL_ARG_TYPES (f1)
&& 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))
&& 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1),
flags))
val = 2;
return val;
}
@ -657,13 +820,14 @@ function_types_compatible_p (tree f1, tree f2)
if (!self_promoting_args_p (args1))
return 0;
if (TYPE_ACTUAL_ARG_TYPES (f2)
&& 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))
&& 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2),
flags))
val = 2;
return val;
}
/* Both types have argument lists: compare them and propagate results. */
val1 = type_lists_compatible_p (args1, args2);
val1 = type_lists_compatible_p (args1, args2, flags);
return val1 != 1 ? val1 : val;
}
@ -672,7 +836,7 @@ function_types_compatible_p (tree f1, tree f2)
or 2 for compatible with warning. */
static int
type_lists_compatible_p (tree args1, tree args2)
type_lists_compatible_p (tree args1, tree args2, int flags)
{
/* 1 if no need for warning yet, 2 if warning cause has been seen. */
int val = 1;
@ -701,7 +865,8 @@ type_lists_compatible_p (tree args1, tree args2)
return 0;
}
else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)),
TYPE_MAIN_VARIANT (TREE_VALUE (args2)))))
TYPE_MAIN_VARIANT (TREE_VALUE (args2)),
flags)))
{
/* Allow wait (union {union wait *u; int *i} *)
and wait (union wait *) to be compatible. */
@ -715,7 +880,8 @@ type_lists_compatible_p (tree args1, tree args2)
tree memb;
for (memb = TYPE_FIELDS (TREE_VALUE (args1));
memb; memb = TREE_CHAIN (memb))
if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2),
flags))
break;
if (memb == 0)
return 0;
@ -730,7 +896,8 @@ type_lists_compatible_p (tree args1, tree args2)
tree memb;
for (memb = TYPE_FIELDS (TREE_VALUE (args2));
memb; memb = TREE_CHAIN (memb))
if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1),
flags))
break;
if (memb == 0)
return 0;
@ -1409,7 +1576,7 @@ build_external_ref (tree id, int fun)
/* Properly declared variable or function reference. */
if (!objc_ivar)
ref = decl;
else if (decl != objc_ivar && DECL_CONTEXT (decl) != 0)
else if (decl != objc_ivar && !C_DECL_FILE_SCOPE (decl))
{
warning ("local declaration of `%s' hides instance variable",
IDENTIFIER_POINTER (id));
@ -1449,7 +1616,7 @@ build_external_ref (tree id, int fun)
TREE_CONSTANT (ref) = 1;
}
else if (current_function_decl != 0
&& DECL_CONTEXT (current_function_decl) != 0
&& !C_DECL_FILE_SCOPE (current_function_decl)
&& (TREE_CODE (ref) == VAR_DECL
|| TREE_CODE (ref) == PARM_DECL
|| TREE_CODE (ref) == FUNCTION_DECL))
@ -3031,7 +3198,7 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
file-scope function counts as a constant. */
if (staticp (arg)
&& ! (TREE_CODE (arg) == FUNCTION_DECL
&& DECL_CONTEXT (arg) != 0))
&& !C_DECL_FILE_SCOPE (arg)))
TREE_CONSTANT (addr) = 1;
return addr;
}
@ -3258,6 +3425,7 @@ c_mark_addressable (tree exp)
/* drops in */
case FUNCTION_DECL:
TREE_ADDRESSABLE (x) = 1;
/* drops out */
default:
return true;
}
@ -3523,7 +3691,7 @@ build_c_cast (tree type, tree expr)
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
TYPE_MAIN_VARIANT (TREE_TYPE (value))))
TYPE_MAIN_VARIANT (TREE_TYPE (value)), COMPARE_STRICT))
break;
if (field)
@ -3917,7 +4085,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
This code doesn't fully support references, it's just for the
special case of va_start and va_copy. */
if (codel == REFERENCE_TYPE
&& comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
&& comptypes (TREE_TYPE (type), TREE_TYPE (rhs), COMPARE_STRICT) == 1)
{
if (!lvalue_p (rhs))
{
@ -3966,7 +4134,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
tree memb_type = TREE_TYPE (memb_types);
if (comptypes (TYPE_MAIN_VARIANT (memb_type),
TYPE_MAIN_VARIANT (rhstype)))
TYPE_MAIN_VARIANT (rhstype), COMPARE_STRICT))
break;
if (TREE_CODE (memb_type) != POINTER_TYPE)
@ -4543,7 +4711,7 @@ digest_init (tree type, tree init, int require_constant)
&& ((inside_init && TREE_CODE (inside_init) == STRING_CST)))
{
if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
TYPE_MAIN_VARIANT (type)))
TYPE_MAIN_VARIANT (type), COMPARE_STRICT))
return inside_init;
if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
@ -4585,12 +4753,13 @@ digest_init (tree type, tree init, int require_constant)
vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
below and handle as a constructor. */
if (code == VECTOR_TYPE
&& comptypes (TREE_TYPE (inside_init), type)
&& comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT)
&& TREE_CONSTANT (inside_init))
{
if (TREE_CODE (inside_init) == VECTOR_CST
&& comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
TYPE_MAIN_VARIANT (type)))
TYPE_MAIN_VARIANT (type),
COMPARE_STRICT))
return inside_init;
else
return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
@ -4601,16 +4770,16 @@ digest_init (tree type, tree init, int require_constant)
if (inside_init && TREE_TYPE (inside_init) != 0
&& (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
TYPE_MAIN_VARIANT (type))
TYPE_MAIN_VARIANT (type), COMPARE_STRICT)
|| (code == ARRAY_TYPE
&& comptypes (TREE_TYPE (inside_init), type))
&& comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT))
|| (code == VECTOR_TYPE
&& comptypes (TREE_TYPE (inside_init), type))
&& comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT))
|| (code == POINTER_TYPE
&& (TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE)
&& comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
TREE_TYPE (type)))))
TREE_TYPE (type), COMPARE_STRICT))))
{
if (code == POINTER_TYPE)
inside_init = default_function_array_conversion (inside_init);
@ -6039,7 +6208,7 @@ output_init_element (tree value, tree type, tree field, int pending)
&& TREE_CODE (type) == ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
&& !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
TYPE_MAIN_VARIANT (type))))
TYPE_MAIN_VARIANT (type), COMPARE_STRICT)))
value = default_conversion (value);
if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR

View File

@ -600,8 +600,14 @@ special_function_p (tree fndecl, int flags)
&& IDENTIFIER_LENGTH (DECL_NAME (fndecl)) <= 17
/* Exclude functions not at the file scope, or not `extern',
since they are not the magic functions we would otherwise
think they are. */
&& DECL_CONTEXT (fndecl) == NULL_TREE && TREE_PUBLIC (fndecl))
think they are.
FIXME: this should be handled with attributes, not with this
hacky imitation of DECL_ASSEMBLER_NAME. It's (also) wrong
because you can declare fork() inside a function if you
wish. */
&& (DECL_CONTEXT (fndecl) == NULL_TREE
|| TREE_CODE (DECL_CONTEXT (fndecl)) == TRANSLATION_UNIT_DECL)
&& TREE_PUBLIC (fndecl))
{
const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
const char *tname = name;

View File

@ -62,7 +62,7 @@ struct cgraph_rtl_info GTY(())
/* The cgraph data strutcture.
Each function decl has assigned cgraph_node listing callees and callers. */
struct cgraph_node GTY(())
struct cgraph_node GTY((chain_next ("%h.next"), chain_prev ("%h.previous")))
{
tree decl;
struct cgraph_edge *callees;

View File

@ -71,7 +71,8 @@ cgraph_finalize_function (decl, body)
It is possible to assemble the name later after finalizing the function
and the fact is noticed in assemble_name then. */
|| (DECL_ASSEMBLER_NAME_SET_P (decl)
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
&& TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
|| lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
{
cgraph_mark_needed_node (node, 1);
}

548
gcc/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -569,6 +569,16 @@ AC_SUBST(TARGET_SYSTEM_ROOT)
AC_SUBST(TARGET_SYSTEM_ROOT_DEFINE)
AC_SUBST(CROSS_SYSTEM_HEADER_DIR)
# Build with intermodule optimisations
local_prefix=
AC_ARG_ENABLE(intermodule,
[ --enable-intermodule build the compiler in one step],
[case "${enable_intermodule}" in
yes) onestep=-onestep : ;;
*) onestep= : ;;
esac])
AC_SUBST(onestep)
# -------------------------
# Checks for other programs
# -------------------------

View File

@ -1,3 +1,11 @@
2003-07-11 Geoffrey Keating <geoffk@apple.com>
* decl.c (cp_finish_decl): Handle 'used' attribute.
* cp-lang.c (c_reset_state): New dummy routine.
* cp-tree.h (finish_file): Move prototype to c-common.h.
* parser.c (c_parse_file): Rename from yyparse; don't call finish_file.
2003-07-11 Mark Mitchell <mark@codesourcery.com>
PR c++/8327

View File

@ -372,3 +372,9 @@ cp_var_mod_type_p (tree type)
return false;
}
/* Stub routine to tell people that this doesn't work yet. */
void
c_reset_state (void)
{
sorry ("inter-module optimisations not implemented yet");
}

View File

@ -3773,7 +3773,6 @@ extern void comdat_linkage (tree);
extern void import_export_vtable (tree, tree, int);
extern void import_export_decl (tree);
extern void import_export_tinfo (tree, tree, bool);
extern void finish_file (void);
extern tree build_cleanup (tree);
extern tree build_offset_ref_call_from_tree (tree, tree);
extern void set_decl_namespace (tree, tree, bool);

View File

@ -8259,6 +8259,10 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
if (was_readonly)
TREE_READONLY (decl) = 1;
/* If this was marked 'used', be sure it will be output. */
if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
mark_referenced (DECL_ASSEMBLER_NAME (decl));
}
/* This is here for a midend callback from c-common.c */

View File

@ -14617,10 +14617,10 @@ static GTY (()) cp_parser *the_parser;
/* External interface. */
/* Parse the entire translation unit. */
/* Parse one entire translation unit. */
int
yyparse (void)
void
c_parse_file (void)
{
bool error_occurred;
@ -14629,10 +14629,6 @@ yyparse (void)
? dk_no_deferred : dk_no_check);
error_occurred = cp_parser_translation_unit (the_parser);
the_parser = NULL;
finish_file ();
return error_occurred;
}
/* Clean up after parsing the entire translation unit. */

View File

@ -427,6 +427,15 @@ cpp_add_dependency_target (cpp_reader *pfile, const char *target, int quote)
deps_add_target (pfile->deps, target, quote);
}
/* This sets up for processing input from the file FNAME.
It returns false on error. */
bool
cpp_read_next_file (cpp_reader *pfile, const char *fname)
{
/* Open the main input file. */
return _cpp_read_file (pfile, fname);
}
/* This is called after options have been parsed, and partially
processed. Setup for processing input from the file named FNAME,
or stdin if it is the empty string. Return the original filename
@ -451,9 +460,8 @@ cpp_read_main_file (cpp_reader *pfile, const char *fname)
deps_add_default_target (pfile->deps, fname);
}
/* Open the main input file. */
pfile->line = 1;
if (!_cpp_read_file (pfile, fname))
if (!cpp_read_next_file (pfile, fname))
return NULL;
/* Set this here so the client can change the option if it wishes,

View File

@ -109,6 +109,7 @@ static unsigned int read_flag (cpp_reader *, unsigned int);
static int strtoul_for_line (const uchar *, unsigned int, unsigned long *);
static void do_diagnostic (cpp_reader *, int, int);
static cpp_hashnode *lex_macro_node (cpp_reader *);
static int undefine_macros (cpp_reader *, cpp_hashnode *, void *);
static void do_include_common (cpp_reader *, enum include_type);
static struct pragma_entry *lookup_pragma_entry (struct pragma_entry *,
const cpp_hashnode *);
@ -540,6 +541,45 @@ do_undef (cpp_reader *pfile)
check_eol (pfile);
}
/* Undefine a single macro/assertion/whatever. */
static int
undefine_macros (cpp_reader *pfile, cpp_hashnode *h,
void *data_p ATTRIBUTE_UNUSED)
{
switch (h->type)
{
case NT_VOID:
break;
case NT_MACRO:
if (pfile->cb.undef)
(*pfile->cb.undef) (pfile, pfile->directive_line, h);
if (CPP_OPTION (pfile, warn_unused_macros))
_cpp_warn_if_unused_macro (pfile, h, NULL);
/* and fall through... */
case NT_ASSERTION:
_cpp_free_definition (h);
break;
default:
abort ();
}
h->flags &= ~NODE_POISONED;
return 1;
}
/* Undefine all macros and assertions. */
void
cpp_undef_all (cpp_reader *pfile)
{
cpp_forall_identifiers (pfile, undefine_macros, NULL);
}
/* Helper routine used by parse_include. Reinterpret the current line
as an h-char-sequence (< ... >); we are looking at the first token
after the <. Returns a malloced filename. */

View File

@ -535,6 +535,10 @@ extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
too. If there was an error opening the file, it returns NULL. */
extern const char *cpp_read_main_file (cpp_reader *, const char *);
/* This continues processing to a new file. It will return false if
there was an error opening the file. */
extern bool cpp_read_next_file (cpp_reader *, const char *);
/* Set up built-ins like __FILE__. */
extern void cpp_init_builtins (cpp_reader *, int);
@ -584,6 +588,9 @@ extern void cpp_assert (cpp_reader *, const char *);
extern void cpp_undef (cpp_reader *, const char *);
extern void cpp_unassert (cpp_reader *, const char *);
/* Undefine all macros and assertions. */
extern void cpp_undef_all (cpp_reader *);
extern cpp_buffer *cpp_push_buffer (cpp_reader *, const unsigned char *,
size_t, int, int);
extern int cpp_defined (cpp_reader *, const unsigned char *, int);

View File

@ -710,10 +710,12 @@ in the following sections.
@section Options Controlling the Kind of Output
Compilation can involve up to four stages: preprocessing, compilation
proper, assembly and linking, always in that order. The first three
stages apply to an individual source file, and end by producing an
object file; linking combines all the object files (those newly
compiled, and those specified as input) into an executable file.
proper, assembly and linking, always in that order. GCC is capable of
preprocessing and compiling several files either into several
assembler input files, or into one assembler input file; then each
assembler input file produces an object file, and linking combines all
the object files (those newly compiled, and those specified as input)
into an executable file.
@cindex file name suffix
For any given input file, the file name suffix determines what kind of
@ -885,9 +887,9 @@ Place output in file @var{file}. This applies regardless to whatever
sort of output is being produced, whether it be an executable file,
an object file, an assembler file or preprocessed C code.
Since only one output file can be specified, it does not make sense to
use @option{-o} when compiling more than one input file, unless you are
producing an executable file as output.
If you specify @option{-o} when compiling more than one input file, or
you are producing an executable file as output, all the source files
on the command line will be compiled at once.
If @option{-o} is not specified, the default is to put an executable file
in @file{a.out}, the object file for @file{@var{source}.@var{suffix}} in
@ -3471,6 +3473,14 @@ Turning on optimization flags makes the compiler attempt to improve
the performance and/or code size at the expense of compilation time
and possibly the ability to debug the program.
The compiler performs optimisation based on the knowledge it has of
the program. Using the @option{-funit-at-a-time} flag will allow the
compiler to consider information gained from later functions in the
file when compiling a function. Compiling multiple files at once to a
single output file (and using @option{-funit-at-a-time}) will allow
the compiler to use information gained from all of the files when
compiling each of them.
Not all optimizations are controlled directly by a flag. Only
optimizations that have a flag are listed.
@ -4362,8 +4372,9 @@ better job.
@item -funit-at-a-time
@opindex funit-at-a-time
Parse the whole compilation unit before starting to produce code. This allows some
extra optimizations to take place but consumes more memory.
Parse the whole compilation unit before starting to produce code.
This allows some extra optimizations to take place but consumes more
memory.
@item -funroll-loops
@opindex funroll-loops

View File

@ -2891,6 +2891,11 @@ static struct infile *infiles;
int n_infiles;
/* True if multiple input files are being compiled to a single
assembly file. */
static bool combine_inputs;
/* This counts the number of libraries added by lang_specific_driver, so that
we can tell if there were any user supplied any files or libraries. */
@ -3715,8 +3720,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
}
}
if (have_c && have_o && lang_n_infiles > 1)
fatal ("cannot specify -o with -c or -S and multiple compilations");
combine_inputs = (have_c && have_o && lang_n_infiles > 1);
if ((save_temps_flag || report_times) && use_pipes)
{
@ -4760,8 +4764,16 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
break;
case 'i':
obstack_grow (&obstack, input_filename, input_filename_length);
arg_going = 1;
if (combine_inputs)
{
for (i = 0; (int) i < n_infiles; i++)
store_arg (infiles[i].name, 0, 0);
}
else
{
obstack_grow (&obstack, input_filename, input_filename_length);
arg_going = 1;
}
break;
case 'I':
@ -6291,7 +6303,28 @@ main (int argc, const char *const *argv)
explicit_link_files = xcalloc (1, n_infiles);
for (i = 0; (int) i < n_infiles; i++)
if (combine_inputs)
{
int lang_n_infiles = 0;
for (i = 0; (int) i < n_infiles; i++)
{
const char *name = infiles[i].name;
struct compiler *compiler
= lookup_compiler (name, strlen (name), infiles[i].language);
if (compiler == NULL)
error ("%s: linker input file unused because linking not done",
name);
else if (lang_n_infiles > 0 && compiler != input_file_compiler)
fatal ("cannot specify -o with -c or -S and multiple languages");
else
{
lang_n_infiles++;
input_file_compiler = compiler;
}
}
}
for (i = 0; (int) i < (combine_inputs ? 1 : n_infiles); i++)
{
int this_file_error = 0;
@ -6306,9 +6339,10 @@ main (int argc, const char *const *argv)
/* Figure out which compiler from the file's suffix. */
input_file_compiler
= lookup_compiler (infiles[i].name, input_filename_length,
infiles[i].language);
if (! combine_inputs)
input_file_compiler
= lookup_compiler (infiles[i].name, input_filename_length,
infiles[i].language);
if (input_file_compiler)
{

View File

@ -80,8 +80,6 @@ extern int lhd_tree_inlining_start_inlining (tree);
extern void lhd_tree_inlining_end_inlining (tree);
extern tree lhd_tree_inlining_convert_parm_for_inlining (tree, tree, tree);
extern void write_global_declarations (void);
#define LANG_HOOKS_NAME "GNU unknown"
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
#define LANG_HOOKS_INIT hook_bool_void_false

View File

@ -3521,7 +3521,7 @@ check_ivars (inter, imp)
t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
if (!comptypes (t1, t2))
if (!comptypes (t1, t2, false))
{
if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
{
@ -4905,7 +4905,7 @@ finish_message_expr (receiver, sel_name, method_params)
;
else if (! IS_ID (rtype)
/* Allow any type that matches objc_class_type. */
&& ! comptypes (rtype, objc_class_type))
&& ! comptypes (rtype, objc_class_type, false))
{
warning ("invalid receiver type `%s'",
gen_declaration (rtype, errbuf));
@ -7064,7 +7064,8 @@ comp_method_with_proto (method, proto)
/* install return type */
TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto));
return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template);
return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function1_template,
false);
}
/* Return 1 if PROTO1 is consistent with PROTO2. */
@ -7087,7 +7088,7 @@ comp_proto_with_proto (proto0, proto1)
TREE_TYPE (function1_template) = groktypename (TREE_TYPE (proto0));
TREE_TYPE (function2_template) = groktypename (TREE_TYPE (proto1));
return comptypes (function1_template, function2_template);
return comptypes (function1_template, function2_template, false);
}
/* - Generate an identifier for the function. the format is "_n_cls",

View File

@ -91,6 +91,7 @@ extern void fnotice (FILE *, const char *, ...)
extern int wrapup_global_declarations (tree *, int);
extern void check_global_declarations (tree *, int);
extern void write_global_declarations (void);
/* A unique local time stamp, might be zero if none is available. */
extern unsigned local_tick;

View File

@ -4370,26 +4370,30 @@ decl_type_context (tree decl)
tree context = DECL_CONTEXT (decl);
while (context)
{
if (TREE_CODE (context) == NAMESPACE_DECL)
switch (TREE_CODE (context))
{
case NAMESPACE_DECL:
case TRANSLATION_UNIT_DECL:
return NULL_TREE;
if (TREE_CODE (context) == RECORD_TYPE
|| TREE_CODE (context) == UNION_TYPE
|| TREE_CODE (context) == QUAL_UNION_TYPE)
case RECORD_TYPE:
case UNION_TYPE:
case QUAL_UNION_TYPE:
return context;
if (TREE_CODE (context) == TYPE_DECL
|| TREE_CODE (context) == FUNCTION_DECL)
case TYPE_DECL:
case FUNCTION_DECL:
context = DECL_CONTEXT (context);
else if (TREE_CODE (context) == BLOCK)
break;
case BLOCK:
context = BLOCK_SUPERCONTEXT (context);
else
/* Unhandled CONTEXT!? */
break;
default:
abort ();
}
}
return NULL_TREE;
}

View File

@ -277,17 +277,18 @@ DEFTREECODE (VECTOR_CST, "vector_cst", 'c', 0)
/* Contents are TREE_STRING_LENGTH and TREE_STRING_POINTER fields. */
DEFTREECODE (STRING_CST, "string_cst", 'c', 0)
/* Declarations. All references to names are represented as ..._DECL nodes.
The decls in one binding context are chained through the TREE_CHAIN field.
Each DECL has a DECL_NAME field which contains an IDENTIFIER_NODE.
(Some decls, most often labels, may have zero as the DECL_NAME).
DECL_CONTEXT points to the node representing the context in which
this declaration has its scope. For FIELD_DECLs, this is the
RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field
is a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL,
and CONST_DECL nodes, this points to either the FUNCTION_DECL for the
containing function, the RECORD_TYPE or UNION_TYPE for the containing
type, or NULL_TREE if the given decl has "file scope".
/* Declarations. All references to names are represented as ..._DECL
nodes. The decls in one binding context are chained through the
TREE_CHAIN field. Each DECL has a DECL_NAME field which contains
an IDENTIFIER_NODE. (Some decls, most often labels, may have zero
as the DECL_NAME). DECL_CONTEXT points to the node representing
the context in which this declaration has its scope. For
FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL,
PARM_DECL, FUNCTION_DECL, LABEL_DECL, and CONST_DECL nodes, this
points to either the FUNCTION_DECL for the containing function, the
RECORD_TYPE or UNION_TYPE for the containing type, or NULL_TREE or
a TRANSLATION_UNIT_DECL if the given decl has "file scope".
DECL_ABSTRACT_ORIGIN, if non-NULL, points to the original (abstract)
..._DECL node of which this decl is an (inlined or template expanded)
instance.
@ -298,9 +299,9 @@ DEFTREECODE (STRING_CST, "string_cst", 'c', 0)
and DECL_MODE fields exist in decl nodes just as in type nodes.
They are unused in LABEL_DECL, TYPE_DECL and CONST_DECL nodes.
DECL_OFFSET holds an integer number of bits offset for the location.
DECL_VOFFSET holds an expression for a variable offset; it is
to be multiplied by DECL_VOFFSET_UNIT (an integer).
DECL_FIELD_BIT_OFFSET holds an integer number of bits offset for
the location. DECL_VOFFSET holds an expression for a variable
offset; it is to be multiplied by DECL_VOFFSET_UNIT (an integer).
These fields are relevant only in FIELD_DECLs and PARM_DECLs.
DECL_INITIAL holds the value to initialize a variable to,
@ -346,6 +347,10 @@ DEFTREECODE (FIELD_DECL, "field_decl", 'd', 0)
/* A namespace declaration. Namespaces appear in DECL_CONTEXT of other
_DECLs, providing a hierarchy of names. */
DEFTREECODE (NAMESPACE_DECL, "namespace_decl", 'd', 0)
/* A translation unit. This is not technically a declaration, since it
can't be looked up, but it's close enough. */
DEFTREECODE (TRANSLATION_UNIT_DECL, "translation_unit_decl", 'd', 0)
/* References to storage. */

View File

@ -1253,12 +1253,13 @@ struct tree_type GTY(())
the name from decl_attributes to make_function_rtl and make_decl_rtl. */
#define DECL_SECTION_NAME(NODE) (DECL_CHECK (NODE)->decl.section_name)
/* For FIELD_DECLs, this is the
RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node that the field is
a member of. For VAR_DECL, PARM_DECL, FUNCTION_DECL, LABEL_DECL,
and CONST_DECL nodes, this points to either the FUNCTION_DECL for the
containing function, the RECORD_TYPE or UNION_TYPE for the containing
type, or NULL_TREE if the given decl has "file scope". */
/* For FIELD_DECLs, this is the RECORD_TYPE, UNION_TYPE, or
QUAL_UNION_TYPE node that the field is a member of. For VAR_DECL,
PARM_DECL, FUNCTION_DECL, LABEL_DECL, and CONST_DECL nodes, this
points to either the FUNCTION_DECL for the containing function,
the RECORD_TYPE or UNION_TYPE for the containing type, or
NULL_TREE or a TRANSLATION_UNIT_DECL if the given decl has "file
scope". */
#define DECL_CONTEXT(NODE) (DECL_CHECK (NODE)->decl.context)
#define DECL_FIELD_CONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->decl.context)
/* In a DECL this is the field where attributes are stored. */
@ -1287,6 +1288,7 @@ struct tree_type GTY(())
/* In PARM_DECL, holds the type as written (perhaps a function or array). */
#define DECL_ARG_TYPE_AS_WRITTEN(NODE) (PARM_DECL_CHECK (NODE)->decl.result)
/* For a FUNCTION_DECL, holds the tree of BINDINGs.
For a TRANSLATION_UNIT_DECL, holds the namespace's BLOCK.
For a VAR_DECL, holds the initial value.
For a PARM_DECL, not used--default
values for parameters are encoded in the type of the function,