This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

(IMA repairs) Disallow combinations of declarations with internaland external linkage which provoke undefined behavior; restructurehandling of invisible declarations


As you may have guessed from the subject line, this patch is
complicated, although small.

When I redid declaration handling in C, I misunderstood a subtlety of
the C standard.  I thought

  extern int foo;
  static int foo;

was valid.  It isn't; it provokes undefined behavior (6.2.2p3-5,7).
We discussed this a few weeks ago and came to the conclusion that it
would be OK to make it a hard error.  This patch does that.

While testing that change, I encountered another problem:

void A(void) { static void B(void); B(); }
void B(void) { }

This is invalid (6.7.1p5) but has long been supported as an extension,
which I do not currently propose to remove.  Unlike the previous
example, it is possible to handle this correctly in IMA - but to do
so, c-decl.c needs to be able to track invisible declarations at file
scope, not just external scope.  The easiest way to do that was a
cleanup that I'd been meaning to do anyway, viz. represent
invisibility with a bit on the binding structure instead of assigning
special significance to certain values of the ->contour pointer.  In
fact, I was able to get rid of ->contour entirely, which should be a
minuscule speedup owing to not chasing quite so many pointers.  (The
structure, unfortunately, does not get any smaller.)  A nice side
effect is that the silly C_DECL_IN_EXTERNAL_SCOPE bit goes away.

Bootstrapped i686-linux.

z "feeling a bit like Achilles chasing the tortoise" w

        * c-decl.c (struct c_binding): Remove contour field; add
        depth, invisible, nested fields.
        (B_IN_SCOPE, B_IN_CURRENT_SCOPE, B_IN_FILE_SCOPE)
        (B_IN_EXTERNAL_SCOPE): New convenience macros.
        (bind): Add invisible and nested arguments. Initialize
        new fields of struct c_binding; adjust loop scanning for
        insertion point.
        (free_binding_and_advance): Clear structure with memset.
        (pop_scope): Adjust to match.  Set DECL_CONTEXT on everything
        in file scope, even if it's in external scope too.
        (pushdecl): Adjust to match.  Create invisible file-scope
        declarations for block-scope forward declarations of static functions.
        (pushtag, warn_if_shadowing, pushdecl_top_level, implicitly_declare)
        (undeclared_variable, lookup_label, declare_label, define_label)
        (lookup_tag, lookup_name, lookup_name_in_scope, builtin_function)
        (c_make_fname_decl, store_parm_decls_newstyle, identifier_global_value)
        (store_parm_decls_oldstyle): Adjust to match.
        (diagnose_mismatched_decls): Correct handling of linkage clashes.
        (merge_decls): No need to copy C_DECL_IN_EXTERNAL_SCOPE.

        * c-tree.h (C_DECL_IN_EXTERNAL_SCOPE): Delete.
        (C_DECL_DECLARED_BUILTIN, C_DECL_REGISTER): Slide down one.

===================================================================
Index: c-decl.c
--- c-decl.c	3 Jul 2004 00:15:35 -0000	1.524
+++ c-decl.c	3 Jul 2004 02:25:35 -0000
@@ -155,16 +155,23 @@ bool c_override_global_bindings_to_false
    chained together by the ->prev field, which (as the name implies)
    runs in reverse order.  All the decls in a given namespace bound to
    a given identifier are chained by the ->shadowed field, which runs
-   from inner to outer scopes.  Finally, the ->contour field points
-   back to the relevant scope structure; this is mainly used to make
-   decls in the externals scope invisible (see below).
+   from inner to outer scopes.
 
    The ->decl field usually points to a DECL node, but there are two
    exceptions.  In the namespace of type tags, the bound entity is a
    RECORD_TYPE, UNION_TYPE, or ENUMERAL_TYPE node.  If an undeclared
    identifier is encountered, it is bound to error_mark_node to
    suppress further errors about that identifier in the current
-   function.  */
+   function.
+
+   The depth field is copied from the scope structure that holds this
+   decl.  It is used to preserve the proper ordering of the ->shadowed
+   field (see bind()) and also for a handful of special-case checks.
+   Finally, the invisible bit is true for a decl which should be
+   ignored for purposes of normal name lookup, and the nested bit is
+   true for a decl that's been bound a second time in an inner scope;
+   in all such cases, the binding in the outer scope will have its
+   invisible bit true.  */
 
 struct c_binding GTY((chain_next ("%h.prev")))
 {
@@ -172,8 +179,15 @@ struct c_binding GTY((chain_next ("%h.pr
   tree id;			/* the identifier it's bound to */
   struct c_binding *prev;	/* the previous decl in this scope */
   struct c_binding *shadowed;	/* the innermost decl shadowed by this one */
-  struct c_scope *contour;	/* the scope in which this decl is bound */
+  unsigned int depth : 28;      /* depth of this scope */
+  BOOL_BITFIELD invisible : 1;  /* normal lookup should ignore this binding */
+  BOOL_BITFIELD nested : 1;     /* do not set DECL_CONTEXT when popping */
+  /* two free bits */
 };
+#define B_IN_SCOPE(b1, b2) ((b1)->depth == (b2)->depth)
+#define B_IN_CURRENT_SCOPE(b) ((b)->depth == current_scope->depth)
+#define B_IN_FILE_SCOPE(b) ((b)->depth == 1 /*file_scope->depth*/)
+#define B_IN_EXTERNAL_SCOPE(b) ((b)->depth == 0 /*external_scope->depth*/)
 
 #define I_SYMBOL_BINDING(node) \
   (((struct lang_identifier *)IDENTIFIER_NODE_CHECK(node))->symbol_binding)
@@ -403,7 +417,7 @@ c_print_identifier (FILE *file, tree nod
    which may be any of several kinds of DECL or TYPE or error_mark_node,
    in the scope SCOPE.  */
 static void
-bind (tree name, tree decl, struct c_scope *scope)
+bind (tree name, tree decl, struct c_scope *scope, bool invisible, bool nested)
 {
   struct c_binding *b, **here;
 
@@ -418,7 +432,9 @@ bind (tree name, tree decl, struct c_sco
   b->shadowed = 0;
   b->decl = decl;
   b->id = name;
-  b->contour = scope;
+  b->depth = scope->depth;
+  b->invisible = invisible;
+  b->nested = nested;
 
   b->prev = scope->bindings;
   scope->bindings = b;
@@ -446,7 +462,7 @@ bind (tree name, tree decl, struct c_sco
   /* Locate the appropriate place in the chain of shadowed decls
      to insert this binding.  Normally, scope == current_scope and
      this does nothing.  */
-  while (*here && (*here)->contour->depth > scope->depth)
+  while (*here && (*here)->depth > scope->depth)
     here = &(*here)->shadowed;
 
   b->shadowed = *here;
@@ -462,10 +478,7 @@ free_binding_and_advance (struct c_bindi
 {
   struct c_binding *prev = b->prev;
 
-  b->id = 0;
-  b->decl = 0;
-  b->contour = 0;
-  b->shadowed = 0;
+  memset (b, 0, sizeof (struct c_binding));
   b->prev = binding_freelist;
   binding_freelist = b;
 
@@ -742,13 +755,15 @@ pop_scope (void)
 	common_symbol:
 	  /* All of these go in BLOCK_VARS, but only if this is the
 	     binding in the home scope.  */
-	  if (!C_DECL_IN_EXTERNAL_SCOPE (p) || scope == external_scope)
+	  if (!b->nested)
 	    {
 	      TREE_CHAIN (p) = BLOCK_VARS (block);
 	      BLOCK_VARS (block) = p;
 	    }
-	  /* If this is the file scope, must set DECL_CONTEXT on these.  */
-	  if (!C_DECL_IN_EXTERNAL_SCOPE (p) && scope == file_scope)
+	  /* If this is the file scope, must set DECL_CONTEXT on
+	     these.  Do so even for externals, so that
+	     same_translation_unit_p works.  */
+	  if (scope == file_scope)
 	    DECL_CONTEXT (p) = context;
 
 	  /* Fall through.  */
@@ -819,7 +834,8 @@ push_file_scope (void)
   start_fname_decls ();
 
   for (decl = visible_builtins; decl; decl = TREE_CHAIN (decl))
-    bind (DECL_NAME (decl), decl, file_scope);
+    bind (DECL_NAME (decl), decl, file_scope,
+	  /*invisible=*/false, /*nested=*/true);
 }
 
 void
@@ -872,7 +888,7 @@ pushtag (tree name, tree type)
   /* Record the identifier as the type's name if it has none.  */
   if (name && !TYPE_NAME (type))
     TYPE_NAME (type) = name;
-  bind (name, type, current_scope);
+  bind (name, type, current_scope, /*invisible=*/false, /*nested=*/false);
 
   /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE will be the
      tagged type we just added to the current scope.  This fake
@@ -1211,33 +1227,47 @@ diagnose_mismatched_decls (tree newdecl,
 	  locate_old_decl (olddecl, error);
 	  return false;
 	}
-      /* Mismatched non-static and static is considered poor style.
-         We only diagnose static then non-static if -Wtraditional,
-	 because it is the most convenient way to get some effects
-	 (see e.g.  what unwind-dw2-fde-glibc.c does to the definition
-	 of _Unwind_Find_FDE in unwind-dw2-fde.c).  Revisit?  */
+      /* A non-static declaration (even an "extern") followed by a
+	 static declaration is undefined behavior per C99 6.2.2p3-5,7.
+	 The same is true for a static forward declaration at block
+	 scope followed by a non-static declaration/definition at file
+	 scope.  Static followed by non-static at the same scope is
+	 not undefined behavior, and is the most convenient way to get
+	 some effects (see e.g.  what unwind-dw2-fde-glibc.c does to
+	 the definition of _Unwind_Find_FDE in unwind-dw2-fde.c), but
+	 we do diagnose it if -Wtraditional. */
       if (TREE_PUBLIC (olddecl) && !TREE_PUBLIC (newdecl))
 	{
-	  /* A static function declaration for a predeclared function
-	     that isn't actually built in, silently overrides the
-	     default.  Objective C uses these.  See also above.
-	     FIXME: Make Objective C use normal builtins.  */
-	  if (TREE_CODE (olddecl) == FUNCTION_DECL
-	      && DECL_IS_BUILTIN (olddecl))
-	    return false;
-	  else
+	  /* Two exceptions to the rule.  If olddecl is an extern
+	     inline, or a predeclared function that isn't actually
+	     built in, newdecl silently overrides olddecl.  The latter
+	     occur only in Objective C; see also above.  (FIXME: Make
+	     Objective C use normal builtins.)  */
+	  if (!DECL_IS_BUILTIN (olddecl)
+	      && !(DECL_EXTERNAL (olddecl)
+		   && DECL_DECLARED_INLINE_P (olddecl)))
 	    {
-	      warning ("%Jstatic declaration of '%D' follows "
-		       "non-static declaration", newdecl, newdecl);
-	      warned = true;
+	      error ("%Jstatic declaration of '%D' follows "
+		     "non-static declaration", newdecl, newdecl);
+	      locate_old_decl (olddecl, error);
 	    }
+	  return false;
 	}
-      else if (TREE_PUBLIC (newdecl) && !TREE_PUBLIC (olddecl)
-	       && warn_traditional)
+      else if (TREE_PUBLIC (newdecl) && !TREE_PUBLIC (olddecl))
 	{
-	  warning ("%Jnon-static declaration of '%D' follows "
-		   "static declaration", newdecl, newdecl);
-	  warned = true;
+	  if (DECL_CONTEXT (olddecl))
+	    {
+	      error ("%Jnon-static declaration of '%D' follows "
+		     "static declaration", newdecl, newdecl);
+	      locate_old_decl (olddecl, error);
+	      return false;
+	    }
+	  else if (warn_traditional)
+	    {
+	      warning ("%Jnon-static declaration of '%D' follows "
+		       "static declaration", newdecl, newdecl);
+	      warned = true;
+	    }
 	}
     }
   else if (TREE_CODE (newdecl) == VAR_DECL)
@@ -1265,13 +1295,27 @@ diagnose_mismatched_decls (tree newdecl,
 	  return false;
 	}
 
-      /* Objects declared at file scope: if at least one is 'extern',
-	 it's fine (6.2.2p4); otherwise the linkage must agree (6.2.2p7).  */
-      if (DECL_FILE_SCOPE_P (newdecl))
-	{
-	  if (!DECL_EXTERNAL (newdecl)
-	      && !DECL_EXTERNAL (olddecl)
-	      && TREE_PUBLIC (newdecl) != TREE_PUBLIC (olddecl))
+      /* Objects declared at file scope: if the first declaration had
+	 external linkage (even if it was an external reference) the
+	 second must have external linkage as well, or the behavior is
+	 undefined.  If the first declaration had internal linkage, then
+	 the second must too, or else be an external reference (in which
+	 case the composite declaration still has internal linkage).
+	 As for function declarations, we warn about the static-then-
+	 extern case only for -Wtraditional.  See generally 6.2.2p3-5,7.  */
+      if (DECL_FILE_SCOPE_P (newdecl)
+	  && TREE_PUBLIC (newdecl) != TREE_PUBLIC (olddecl))
+	{
+	  if (DECL_EXTERNAL (newdecl))
+	    {
+	      if (warn_traditional)
+		{
+		  warning ("%Jnon-static declaration of '%D' follows "
+			   "static declaration", newdecl, newdecl);
+		  warned = true;
+		}
+	    }
+	  else
 	    {
 	      if (TREE_PUBLIC (newdecl))
 		error ("%Jnon-static declaration of '%D' follows "
@@ -1286,7 +1330,8 @@ diagnose_mismatched_decls (tree newdecl,
 	}
       /* Two objects with the same name declared at the same block
 	 scope must both be external references (6.7p3).  */
-      else if (DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl)
+      else if (!DECL_FILE_SCOPE_P (newdecl)
+	       && DECL_CONTEXT (newdecl) == DECL_CONTEXT (olddecl)
 	       && (!DECL_EXTERNAL (newdecl) || !DECL_EXTERNAL (olddecl)))
 	{
 	  if (DECL_EXTERNAL (newdecl))
@@ -1618,9 +1663,6 @@ merge_decls (tree newdecl, tree olddecl,
 	}
     }
 
-  /* This bit must not get wiped out.  */
-  C_DECL_IN_EXTERNAL_SCOPE (newdecl) |= C_DECL_IN_EXTERNAL_SCOPE (olddecl);
-
   /* Copy most of the decl-specific fields of NEWDECL into OLDDECL.
      But preserve OLDDECL's DECL_UID.  */
   {
@@ -1682,10 +1724,9 @@ warn_if_shadowing (tree new)
       || (TREE_CODE (new) == PARM_DECL && current_scope->outer->parm_flag))
     return;
 
-  /* Is anything being shadowed?  Do not be confused by a second binding
-     to the same decl in the externals scope.  */
+  /* Is anything being shadowed?  Invisible decls do not count.  */
   for (b = I_SYMBOL_BINDING (DECL_NAME (new)); b; b = b->shadowed)
-    if (b->decl && b->decl != new && b->contour != external_scope)
+    if (b->decl && b->decl != new && !b->invisible)
       {
 	tree old = b->decl;
 
@@ -1786,6 +1827,7 @@ pushdecl (tree x)
   tree name = DECL_NAME (x);
   struct c_scope *scope = current_scope;
   struct c_binding *b;
+  bool nested = false;
 
   /* Functions need the lang_decl data.  */
   if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_LANG_SPECIFIC (x))
@@ -1802,7 +1844,7 @@ pushdecl (tree x)
   /* Anonymous decls are just inserted in the scope.  */
   if (!name)
     {
-      bind (name, x, scope);
+      bind (name, x, scope, /*invisible=*/false, /*nested=*/false);
       return x;
     }
 
@@ -1814,7 +1856,7 @@ pushdecl (tree x)
      diagnostics).  In particular, we should not consider possible
      duplicates in the external scope, or shadowing.  */
   b = I_SYMBOL_BINDING (name);
-  if (b && b->contour == scope)
+  if (b && B_IN_SCOPE (b, scope))
     {
       if (duplicate_decls (x, b->decl))
 	return b->decl;
@@ -1839,10 +1881,9 @@ pushdecl (tree x)
       if (warn_nested_externs
 	  && scope != file_scope
 	  && !DECL_IN_SYSTEM_HEADER (x))
-	warning ("nested extern declaration of `%s'",
-		 IDENTIFIER_POINTER (name));
+	warning ("nested extern declaration of '%D'", x);
 
-      while (b && b->contour != external_scope)
+      while (b && !B_IN_EXTERNAL_SCOPE (b))
 	b = b->shadowed;
 
       /* The point of the same_translation_unit_p check here is,
@@ -1855,15 +1896,39 @@ pushdecl (tree x)
 	      || same_translation_unit_p (x, b->decl))
 	  && duplicate_decls (x, b->decl))
 	{
-	  bind (name, b->decl, scope);
+	  bind (name, b->decl, scope, /*invisible=*/false, /*nested=*/true);
 	  return b->decl;
 	}
       else if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
 	{
-	  C_DECL_IN_EXTERNAL_SCOPE (x) = 1;
-	  bind (name, x, external_scope);
+	  bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false);
+	  nested = true;
 	}
     }
+  /* Similarly, a declaration of a function with static linkage at
+     block scope must be checked against any existing declaration
+     of that function at file scope.  */
+  else if (TREE_CODE (x) == FUNCTION_DECL && scope != file_scope
+	   && !TREE_PUBLIC (x) && !DECL_INITIAL (x))
+    {
+      if (warn_nested_externs && !DECL_IN_SYSTEM_HEADER (x))
+	warning ("nested static declaration of '%D'", x);
+
+      while (b && !B_IN_FILE_SCOPE (b))
+	b = b->shadowed;
+
+      if (b && 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
+	{
+	  bind (name, x, file_scope, /*invisible=*/true, /*nested=*/false);
+	  nested = true;
+	}
+    }      
 
   warn_if_shadowing (x);
 
@@ -1871,7 +1936,7 @@ pushdecl (tree x)
   if (TREE_CODE (x) == TYPE_DECL)
     clone_underlying_type (x);
 
-  bind (name, x, scope);
+  bind (name, x, scope, /*invisible=*/false, nested);
 
   /* If x's type is incomplete because it's based on a
      structure or union which has not yet been fully declared,
@@ -1911,6 +1976,7 @@ tree
 pushdecl_top_level (tree x)
 {
   tree name;
+  bool nested = false;
 
   if (TREE_CODE (x) != VAR_DECL)
     abort ();
@@ -1922,11 +1988,11 @@ pushdecl_top_level (tree x)
 
   if (DECL_EXTERNAL (x) || TREE_PUBLIC (x))
     {
-      C_DECL_IN_EXTERNAL_SCOPE (x) = 1;
-      bind (name, x, external_scope);
+      bind (name, x, external_scope, /*invisible=*/true, /*nested=*/false);
+      nested = true;
     }
   if (file_scope)
-    bind (name, x, file_scope);
+    bind (name, x, file_scope, /*invisible=*/false, nested);
 
   return x;
 }
@@ -1965,7 +2031,8 @@ implicitly_declare (tree functionid)
 	 file scope.  */
       if (!DECL_BUILT_IN (decl) && DECL_IS_BUILTIN (decl))
 	{
-	  bind (functionid, decl, file_scope);
+	  bind (functionid, decl, file_scope,
+		/*invisible=*/false, /*nested=*/true);
 	  return decl;
 	}
       else
@@ -1979,7 +2046,8 @@ implicitly_declare (tree functionid)
 	      implicit_decl_warning (functionid, decl);
 	      C_DECL_IMPLICIT (decl) = 1;
 	    }
-	  bind (functionid, decl, current_scope);
+	  bind (functionid, decl, current_scope,
+		/*invisible=*/false, /*nested=*/true);
 	  return decl;
 	}
     }
@@ -2039,7 +2107,7 @@ undeclared_variable (tree id)
          will be nonnull but current_function_scope will be null.  */
       scope = current_function_scope ? current_function_scope : current_scope;
     }
-  bind (id, error_mark_node, scope);
+  bind (id, error_mark_node, scope, /*invisible=*/false, /*nested=*/false);
 }
 
 /* Subroutine of lookup_label, declare_label, define_label: construct a
@@ -2093,7 +2161,8 @@ lookup_label (tree name)
   label = make_label (name, input_location);
 
   /* Ordinary labels go in the current function scope.  */
-  bind (name, label, current_function_scope);
+  bind (name, label, current_function_scope,
+	/*invisible=*/false, /*nested=*/false);
   return label;
 }
 
@@ -2109,7 +2178,7 @@ declare_label (tree name)
 
   /* Check to make sure that the label hasn't already been declared
      at this scope */
-  if (b && b->contour == current_scope)
+  if (b && B_IN_CURRENT_SCOPE (b))
     {
       error ("duplicate label declaration `%s'", IDENTIFIER_POINTER (name));
       locate_old_decl (b->decl, error);
@@ -2122,7 +2191,8 @@ declare_label (tree name)
   C_DECLARED_LABEL_FLAG (label) = 1;
 
   /* Declared labels go in the current scope.  */
-  bind (name, label, current_scope);
+  bind (name, label, current_scope,
+	/*invisible=*/false, /*nested=*/false);
   return label;
 }
 
@@ -2162,7 +2232,8 @@ define_label (location_t location, tree 
       label = make_label (name, location);
 
       /* Ordinary labels go in the current function scope.  */
-      bind (name, label, current_function_scope);
+      bind (name, label, current_function_scope,
+	    /*invisible=*/false, /*nested=*/false);
     }
 
   if (warn_traditional && !in_system_header && lookup_name (name))
@@ -2199,8 +2270,8 @@ lookup_tag (enum tree_code code, tree na
 	 a tag in the file scope.  (Primarily relevant to Objective-C
 	 and its builtin structure tags, which get pushed before the
 	 file scope is created.)  */
-      if (b->contour == current_scope
-	  || (current_scope == file_scope && b->contour == external_scope))
+      if (B_IN_CURRENT_SCOPE (b)
+	  || (current_scope == file_scope && B_IN_EXTERNAL_SCOPE (b)))
 	thislevel = 1;
     }
 
@@ -2248,7 +2319,7 @@ tree
 lookup_name (tree name)
 {
   struct c_binding *b = I_SYMBOL_BINDING (name);
-  if (b && (b->contour != external_scope || TREE_CODE (b->decl) == TYPE_DECL))
+  if (b && !b->invisible)
     return b->decl;
   return 0;
 }
@@ -2261,7 +2332,7 @@ lookup_name_in_scope (tree name, struct 
   struct c_binding *b;
 
   for (b = I_SYMBOL_BINDING (name); b; b = b->shadowed)
-    if (b->contour == scope)
+    if (B_IN_SCOPE (b, scope))
       return b->decl;
   return 0;
 }
@@ -2358,7 +2429,8 @@ c_make_fname_decl (tree id, int type_dep
   if (current_function_decl)
     {
       DECL_CONTEXT (decl) = current_function_decl;
-      bind (id, decl, current_function_scope);
+      bind (id, decl, current_function_scope,
+	    /*invisible=*/false, /*nested=*/false);
     }
 
   finish_decl (decl, init, NULL_TREE);
@@ -2394,8 +2466,7 @@ builtin_function (const char *name, tree
   if (I_SYMBOL_BINDING (id))
     abort ();
 
-  C_DECL_IN_EXTERNAL_SCOPE (decl) = 1;
-  bind (id, decl, external_scope);
+  bind (id, decl, external_scope, /*invisible=*/true, /*nested=*/false);
 
   /* Builtins in the implementation namespace are made visible without
      needing to be explicitly declared.  See push_file_scope.  */
@@ -5807,7 +5878,8 @@ store_parm_decls_newstyle (tree fndecl, 
     {
       DECL_CONTEXT (decl) = current_function_decl;
       if (DECL_NAME (decl))
-	bind (DECL_NAME (decl), decl, current_scope);
+	bind (DECL_NAME (decl), decl, current_scope,
+	      /*invisible=*/false, /*nested=*/false);
       else
 	error ("%Jparameter name omitted", decl);
     }
@@ -5820,13 +5892,15 @@ store_parm_decls_newstyle (tree fndecl, 
     {
       DECL_CONTEXT (decl) = current_function_decl;
       if (DECL_NAME (decl))
-	bind (DECL_NAME (decl), decl, current_scope);
+	bind (DECL_NAME (decl), decl, current_scope,
+	      /*invisible=*/false, /*nested=*/false);
     }
 
   /* And all the tag declarations.  */
   for (decl = tags; decl; decl = TREE_CHAIN (decl))
     if (TREE_PURPOSE (decl))
-      bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope);
+      bind (TREE_PURPOSE (decl), TREE_VALUE (decl), current_scope,
+	    /*invisible=*/false, /*nested=*/false);
 }
 
 /* Subroutine of store_parm_decls which handles old-style function
@@ -5862,7 +5936,7 @@ store_parm_decls_oldstyle (tree fndecl, 
 	}
 
       b = I_SYMBOL_BINDING (TREE_VALUE (parm));
-      if (b && b->contour == current_scope)
+      if (b && B_IN_CURRENT_SCOPE (b))
 	{
 	  decl = b->decl;
 	  /* If we got something other than a PARM_DECL it is an error.  */
@@ -6454,7 +6528,7 @@ identifier_global_value	(tree t)
   struct c_binding *b;
 
   for (b = I_SYMBOL_BINDING (t); b; b = b->shadowed)
-    if (b->contour == file_scope || b->contour == external_scope)
+    if (B_IN_FILE_SCOPE (b) || B_IN_EXTERNAL_SCOPE (b))
       return b->decl;
 
   return 0;
===================================================================
Index: c-tree.h
--- c-tree.h	1 Jul 2004 08:52:26 -0000	1.158
+++ c-tree.h	3 Jul 2004 02:25:35 -0000
@@ -94,18 +94,14 @@ struct lang_type GTY(())
 /* For a FUNCTION_DECL, nonzero if it was an implicit declaration.  */
 #define C_DECL_IMPLICIT(EXP) DECL_LANG_FLAG_2 (EXP)
 
-/* For any decl, nonzero if it is bound in the externals scope and
-   pop_scope mustn't chain it into any higher block.  */
-#define C_DECL_IN_EXTERNAL_SCOPE(EXP) DECL_LANG_FLAG_3 (EXP)
-
 /* For FUNCTION_DECLs, evaluates true if the decl is built-in but has
    been declared.  */
-#define C_DECL_DECLARED_BUILTIN(EXP) DECL_LANG_FLAG_4 (EXP)
+#define C_DECL_DECLARED_BUILTIN(EXP) DECL_LANG_FLAG_3 (EXP)
 
 /* Record whether a decl was declared register.  This is strictly a
    front-end flag, whereas DECL_REGISTER is used for code generation;
    they may differ for structures with volatile fields.  */
-#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_5 (EXP)
+#define C_DECL_REGISTER(EXP) DECL_LANG_FLAG_4 (EXP)
 
 /* Nonzero for a decl which either doesn't exist or isn't a prototype.
    N.B. Could be simplified if all built-in decls had complete prototypes


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]