diff options
author | Zack Weinberg <zack@gcc.gnu.org> | 2004-07-09 21:30:35 +0000 |
---|---|---|
committer | Zack Weinberg <zack@gcc.gnu.org> | 2004-07-09 21:30:35 +0000 |
commit | 9affb2c7e47fd5abfa4ee62ee4121d5329076a23 (patch) | |
tree | 58b85f972de94f99b74cfcf79c3da6dcde633962 /gcc/c-decl.c | |
parent | 4077d207437b94a2d07d76c93b6583d5920bf7a8 (diff) | |
download | gcc-9affb2c7e47fd5abfa4ee62ee4121d5329076a23.zip gcc-9affb2c7e47fd5abfa4ee62ee4121d5329076a23.tar.gz gcc-9affb2c7e47fd5abfa4ee62ee4121d5329076a23.tar.bz2 |
c-opts.c (c_common_post_options): Force unit-at-a-time mode on when we have more than one input file.
2004-07-09 Zack Weinberg <zack@codesourcery.com>
Andrew Pinski <apinski@apple.com>
* c-opts.c (c_common_post_options): Force unit-at-a-time mode
on when we have more than one input file.
(c_common_parse_file): Restore loop over all input files.
Clarify diagnostic for -dy when YYDEBUG wasn't defined.
* c-decl.c (set_type_context): New function.
(pop_scope): Use it to set context of types. When we
encounter a TYPE_DECL, set the context of the attached type too.
(pop_file_scope): Don't call cpp_undef_all here.
(diagnose_mismatched_decls): Do not complain about a second
definition of an 'extern inline' function if it's not in the
same translation unit. Do not complain about inline
declaration after use if the use was in a different
translation unit.
(merge_decls): Don't clobber olddecl's DECL_CONTEXT.
(pushdecl): Do not put DECL_EXTERNAL, !TREE_PUBLIC decls in
the external scope.
(pushdecl_top_level): Likewise.
(grokdeclarator): Clarify what is going on with setting
DECL_EXTERNAL on function types, a little.
(c_write_global_declarations): Don't do anything if
-fsyntax-only or errors have been encountered.
testsuite:
* gcc.dg/noncompile/init-4.c: Remove bogus dg-error marker.
From-SVN: r84402
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 63 |
1 files changed, 43 insertions, 20 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 8346c8a..6ff2dff 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -622,6 +622,16 @@ push_scope (void) } } +/* Set the TYPE_CONTEXT of all of TYPE's variants to CONTEXT. */ + +static void +set_type_context (tree type, tree context) +{ + for (type = TYPE_MAIN_VARIANT (type); type; + type = TYPE_NEXT_VARIANT (type)) + TYPE_CONTEXT (type) = context; +} + /* Exit a scope. Restore the state of the identifier-decl mappings that were in effect when this scope was entered. Return a BLOCK node containing all the DECLs in this scope that are of interest @@ -711,7 +721,7 @@ pop_scope (void) case ENUMERAL_TYPE: case UNION_TYPE: case RECORD_TYPE: - TYPE_CONTEXT (p) = context; + set_type_context (p, context); /* Types may not have tag-names, in which case the type appears in the bindings list with b->id NULL. */ @@ -767,7 +777,11 @@ pop_scope (void) This makes same_translation_unit_p work, and causes static declarations to be given disambiguating suffixes. */ if (scope == file_scope && num_in_fnames > 1) - DECL_CONTEXT (p) = context; + { + DECL_CONTEXT (p) = context; + if (TREE_CODE (p) == TYPE_DECL) + set_type_context (TREE_TYPE (p), context); + } /* Fall through. */ /* Parameters go in DECL_ARGUMENTS, not BLOCK_VARS, and have @@ -865,7 +879,6 @@ pop_file_scope (void) /* Pop off the file scope and close this translation unit. */ pop_scope (); file_scope = 0; - cpp_undef_all (parse_in); cgraph_finalize_compilation_unit (); } @@ -1215,7 +1228,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, && !(DECL_DECLARED_INLINE_P (olddecl) && DECL_EXTERNAL (olddecl) && !(DECL_DECLARED_INLINE_P (newdecl) - && DECL_EXTERNAL (newdecl)))) + && DECL_EXTERNAL (newdecl) + && same_translation_unit_p (olddecl, newdecl)))) { error ("%Jredefinition of '%D'", newdecl, newdecl); locate_old_decl (olddecl, error); @@ -1385,8 +1399,11 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl, /* Inline declaration after use or definition. ??? Should we still warn about this now we have unit-at-a-time - mode and can get it right? */ - if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl)) + mode and can get it right? + Definitely don't complain if the decls are in different translation + units. */ + if (DECL_DECLARED_INLINE_P (newdecl) && !DECL_DECLARED_INLINE_P (olddecl) + && same_translation_unit_p (olddecl, newdecl)) { if (TREE_USED (olddecl)) { @@ -1669,14 +1686,16 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) } /* Copy most of the decl-specific fields of NEWDECL into OLDDECL. - But preserve OLDDECL's DECL_UID. */ + But preserve OLDDECL's DECL_UID and DECL_CONTEXT. */ { unsigned olddecl_uid = DECL_UID (olddecl); + tree olddecl_context = DECL_CONTEXT (olddecl); memcpy ((char *) olddecl + sizeof (struct tree_common), (char *) newdecl + sizeof (struct tree_common), sizeof (struct tree_decl) - sizeof (struct tree_common)); DECL_UID (olddecl) = olddecl_uid; + DECL_CONTEXT (olddecl) = olddecl_context; } /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl @@ -1897,14 +1916,13 @@ pushdecl (tree x) they are in different translation units. In any case, the static does not go in the externals scope. */ if (b - && (DECL_EXTERNAL (x) || TREE_PUBLIC (x) - || same_translation_unit_p (x, b->decl)) + && (TREE_PUBLIC (x) || same_translation_unit_p (x, b->decl)) && duplicate_decls (x, b->decl)) { bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true); return b->decl; } - else if (DECL_EXTERNAL (x) || TREE_PUBLIC (x)) + else if (TREE_PUBLIC (x)) { bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false); nested = true; @@ -1991,7 +2009,7 @@ pushdecl_top_level (tree x) if (I_SYMBOL_BINDING (name)) abort (); - if (DECL_EXTERNAL (x) || TREE_PUBLIC (x)) + if (TREE_PUBLIC (x)) { bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false); nested = true; @@ -4459,14 +4477,6 @@ grokdeclarator (tree declarator, tree declspecs, } else if (TREE_CODE (type) == FUNCTION_TYPE) { - /* Every function declaration is "external" - except for those which are inside a function body - in which `auto' is used. - That is a case not specified by ANSI C, - and we use it for forward declarations for nested functions. */ - int extern_ref = (!(specbits & (1 << (int) RID_AUTO)) - || current_scope == file_scope); - if (specbits & (1 << (int) RID_AUTO) && (pedantic || current_scope == file_scope)) pedwarn ("invalid storage class for function `%s'", name); @@ -4497,8 +4507,16 @@ grokdeclarator (tree declarator, tree declspecs, && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))) warning ("`noreturn' function returns non-void value"); - if (extern_ref) + /* Every function declaration is an external reference + (DECL_EXTERNAL) except for those which are not at file + scope and are explicitly declared "auto". This is + forbidden by standard C (C99 6.7.1p5) and is interpreted by + GCC to signify a forward declaration of a nested function. */ + if ((specbits & (1 << RID_AUTO)) && current_scope != file_scope) + DECL_EXTERNAL (decl) = 0; + else DECL_EXTERNAL (decl) = 1; + /* Record absence of global scope for `static' or `auto'. */ TREE_PUBLIC (decl) = !(specbits & ((1 << (int) RID_STATIC) | (1 << (int) RID_AUTO))); @@ -6630,6 +6648,11 @@ c_write_global_declarations (void) if (pch_file) return; + /* Don't waste time on further processing if -fsyntax-only or we've + encountered errors. */ + if (flag_syntax_only || errorcount || sorrycount || cpp_errors (parse_in)) + return; + /* Close the external scope. */ ext_block = pop_scope (); external_scope = 0; |