aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2004-07-09 21:30:35 +0000
committerZack Weinberg <zack@gcc.gnu.org>2004-07-09 21:30:35 +0000
commit9affb2c7e47fd5abfa4ee62ee4121d5329076a23 (patch)
tree58b85f972de94f99b74cfcf79c3da6dcde633962 /gcc/c-decl.c
parent4077d207437b94a2d07d76c93b6583d5920bf7a8 (diff)
downloadgcc-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.c63
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;