aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1994-05-02 13:48:11 -0700
committerJim Wilson <wilson@gcc.gnu.org>1994-05-02 13:48:11 -0700
commite32fe22499cfa3b6713e89130074167f56070b3f (patch)
treeecd5b59984b94602999d943ff27e93555d11c1a5
parent53dd962232403cec65fa3d06b94835bf9353549d (diff)
downloadgcc-e32fe22499cfa3b6713e89130074167f56070b3f.zip
gcc-e32fe22499cfa3b6713e89130074167f56070b3f.tar.gz
gcc-e32fe22499cfa3b6713e89130074167f56070b3f.tar.bz2
(pushdecl): Use lookup_name_current_level_global instead of lookup_name for extern references.
(pushdecl): Use lookup_name_current_level_global instead of lookup_name for extern references. Don't return duplicate decl if it came from the global binding level, and there exists a conflicting decl in an intervening block. (lookup_name_current_level_global); New function. From-SVN: r7189
-rw-r--r--gcc/c-decl.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index a6cfe78..a844d6a 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -1828,7 +1828,7 @@ pushdecl (x)
int line;
if (DECL_EXTERNAL (x) && TREE_PUBLIC (x))
- t = lookup_name (name);
+ t = lookup_name_current_level_global (name);
else
t = lookup_name_current_level (name);
if (t != 0 && t == error_mark_node)
@@ -1869,7 +1869,12 @@ pushdecl (x)
IDENTIFIER_POINTER (name));
}
- return t;
+ /* If this is a global decl, and there exists a conflicting local
+ decl in a parent block, then we can't return as yet, because we
+ need to register this decl in the current binding block. */
+ if (! DECL_EXTERNAL (x) || ! TREE_PUBLIC (x)
+ || lookup_name (name) == t)
+ return t;
}
/* If we are processing a typedef statement, generate a whole new
@@ -2609,6 +2614,29 @@ lookup_name_current_level (name)
return t;
}
+
+/* Similar to `lookup_name_current_level' but also look at the global binding
+ level. */
+
+tree
+lookup_name_current_level_global (name)
+ tree name;
+{
+ register tree t = 0;
+
+ if (current_binding_level == global_binding_level)
+ return IDENTIFIER_GLOBAL_VALUE (name);
+
+ if (IDENTIFIER_LOCAL_VALUE (name) != 0)
+ for (t = current_binding_level->names; t; t = TREE_CHAIN (t))
+ if (DECL_NAME (t) == name)
+ break;
+
+ if (t == 0)
+ t = IDENTIFIER_GLOBAL_VALUE (name);
+
+ return t;
+}
/* Create the predefined scalar types of C,
and some nodes representing standard constants (0, 1, (void *)0).