diff options
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r-- | gcc/c-decl.c | 117 |
1 files changed, 72 insertions, 45 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 5471f6b..fb1d8e8 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -45,6 +45,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "target.h" #include "debug.h" #include "timevar.h" +#include "c-common.h" /* In grokdeclarator, distinguish syntactic contexts of declarators. */ enum decl_context @@ -280,6 +281,7 @@ static tree grokparms PARAMS ((tree, int)); static void layout_array_type PARAMS ((tree)); static tree c_make_fname_decl PARAMS ((tree, int)); static void c_expand_body PARAMS ((tree, int, int)); +static void warn_if_shadowing PARAMS ((tree, tree)); /* C-specific option variables. */ @@ -2047,6 +2049,66 @@ duplicate_decls (newdecl, olddecl, different_binding_level) return 1; } +/* Check whether decl-node X shadows an existing declaration. + OLDLOCAL is the old IDENTIFIER_LOCAL_VALUE of the DECL_NAME of X, + which might be a NULL_TREE. */ +static void +warn_if_shadowing (x, oldlocal) + tree x, oldlocal; +{ + tree name; + + if (DECL_EXTERNAL (x)) + return; + + name = DECL_NAME (x); + + /* Warn if shadowing an argument at the top level of the body. */ + if (oldlocal != 0 + /* This warning doesn't apply to the parms of a nested fcn. */ + && ! current_binding_level->parm_flag + /* Check that this is one level down from the parms. */ + && current_binding_level->level_chain->parm_flag + /* Check that the decl being shadowed + comes from the parm level, one level up. */ + && chain_member (oldlocal, current_binding_level->level_chain->names)) + { + if (TREE_CODE (oldlocal) == PARM_DECL) + pedwarn ("declaration of `%s' shadows a parameter", + IDENTIFIER_POINTER (name)); + else + pedwarn ("declaration of `%s' shadows a symbol from the parameter list", + IDENTIFIER_POINTER (name)); + } + /* Maybe warn if shadowing something else. */ + else if (warn_shadow + /* No shadow warnings for internally generated vars. */ + && DECL_SOURCE_LINE (x) != 0 + /* No shadow warnings for vars made for inlining. */ + && ! DECL_FROM_INLINE (x)) + { + if (TREE_CODE (x) == PARM_DECL + && current_binding_level->level_chain->parm_flag) + /* Don't warn about the parm names in function declarator + within a function declarator. + It would be nice to avoid warning in any function + declarator in a declaration, as opposed to a definition, + but there is no way to tell it's not a definition. */ + ; + else if (oldlocal) + { + if (TREE_CODE (oldlocal) == PARM_DECL) + shadow_warning ("a parameter", name, oldlocal); + else + shadow_warning ("a previous local", name, oldlocal); + } + else if (IDENTIFIER_GLOBAL_VALUE (name) != 0 + && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node) + shadow_warning ("a global declaration", name, + IDENTIFIER_GLOBAL_VALUE (name)); + } +} + /* Record a decl-node X as belonging to the current lexical scope. Check for errors (such as an incompatible declaration for the same name already seen in the same scope). @@ -2431,49 +2493,7 @@ pushdecl (x) IDENTIFIER_LIMBO_VALUE (name) = x; } - /* Warn if shadowing an argument at the top level of the body. */ - if (oldlocal != 0 && !DECL_EXTERNAL (x) - /* This warning doesn't apply to the parms of a nested fcn. */ - && ! current_binding_level->parm_flag - /* Check that this is one level down from the parms. */ - && current_binding_level->level_chain->parm_flag - /* Check that the decl being shadowed - comes from the parm level, one level up. */ - && chain_member (oldlocal, current_binding_level->level_chain->names)) - { - if (TREE_CODE (oldlocal) == PARM_DECL) - pedwarn ("declaration of `%s' shadows a parameter", - IDENTIFIER_POINTER (name)); - else - pedwarn ("declaration of `%s' shadows a symbol from the parameter list", - IDENTIFIER_POINTER (name)); - } - - /* Maybe warn if shadowing something else. */ - else if (warn_shadow && !DECL_EXTERNAL (x) - /* No shadow warnings for internally generated vars. */ - && DECL_SOURCE_LINE (x) != 0 - /* No shadow warnings for vars made for inlining. */ - && ! DECL_FROM_INLINE (x)) - { - const char *id = IDENTIFIER_POINTER (name); - - if (TREE_CODE (x) == PARM_DECL - && current_binding_level->level_chain->parm_flag) - /* Don't warn about the parm names in function declarator - within a function declarator. - It would be nice to avoid warning in any function - declarator in a declaration, as opposed to a definition, - but there is no way to tell it's not a definition. */ - ; - else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL) - warning ("declaration of `%s' shadows a parameter", id); - else if (oldlocal != 0) - warning ("declaration of `%s' shadows previous local", id); - else if (IDENTIFIER_GLOBAL_VALUE (name) != 0 - && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node) - warning ("declaration of `%s' shadows global declaration", id); - } + warn_if_shadowing (x, oldlocal); /* If storing a local value, there may already be one (inherited). If so, record it for restoration when this binding level ends. */ @@ -6354,11 +6374,16 @@ store_parm_decls () then CONST_DECLs for foo and bar are put here. */ tree nonparms = 0; + /* The function containing FNDECL, if any. */ + tree context = decl_function_context (fndecl); + /* Nonzero if this definition is written with a prototype. */ int prototype = 0; - /* The function containing FNDECL, if any. */ - tree context = decl_function_context (fndecl); + int saved_warn_shadow = warn_shadow; + + /* Don't re-emit shadow warnings. */ + warn_shadow = 0; if (specparms != 0 && TREE_CODE (specparms) != TREE_LIST) { @@ -6758,6 +6783,8 @@ store_parm_decls () not safe to try to expand expressions involving them. */ immediate_size_expand = 0; cfun->x_dont_save_pending_sizes_p = 1; + + warn_shadow = saved_warn_shadow; } /* Finish up a function declaration and compile that function |