#include "target.h"
#include "debug.h"
#include "timevar.h"
+#include "c-common.h"
/* In grokdeclarator, distinguish syntactic contexts of declarators. */
enum decl_context
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));
\f
/* C-specific option variables. */
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).
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. */
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)
{
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;
}
\f
/* Finish up a function declaration and compile that function
#include "ggc.h"
#include "tm_p.h"
#include "target.h"
+#include "c-common.h"
extern const struct attribute_spec *lang_attribute_table;
static tree build_cp_library_fn PARAMS ((tree, enum tree_code, tree));
static void store_parm_decls PARAMS ((tree));
static int cp_missing_noreturn_ok_p PARAMS ((tree));
-static void shadow_warning PARAMS ((const char *, tree, tree));
#if defined (DEBUG_CP_BINDING_LEVELS)
static void indent PARAMS ((void));
return 1;
}
-/* Output a -Wshadow warning MSGID, if non-NULL, and give the location
- of the previous declaration. */
-static void
-shadow_warning (msgid, name, decl)
- const char *msgid;
- tree name, decl;
-{
- warning ("declaration of `%s' shadows %s", IDENTIFIER_POINTER (name), msgid);
- warning_with_file_and_line (DECL_SOURCE_FILE (decl),
- DECL_SOURCE_LINE (decl),
- "shadowed declaration is here");
-}
-
-
/* 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).