diff options
author | Geoffrey Keating <geoffk@apple.com> | 2003-07-11 08:33:21 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@gcc.gnu.org> | 2003-07-11 08:33:21 +0000 |
commit | d1bd0ded61f9444ff6350fc7db89d04e72ca1108 (patch) | |
tree | 9b4a93a8c6ef46d7812bac262156dcddbbcf0593 /gcc/c-decl.c | |
parent | 6eeba0cc4337f356d68974b8341e84879ec6cd93 (diff) | |
download | gcc-d1bd0ded61f9444ff6350fc7db89d04e72ca1108.zip gcc-d1bd0ded61f9444ff6350fc7db89d04e72ca1108.tar.gz gcc-d1bd0ded61f9444ff6350fc7db89d04e72ca1108.tar.bz2 |
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
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 280 |
1 files changed, 244 insertions, 36 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index fbe0b02..24f4637 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -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" |