/* Process declarations and variables for C compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+ 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "input.h"
#include "tm.h"
#include "intl.h"
#include "tree.h"
/* Pop off the file scope and close this translation unit. */
pop_scope ();
file_scope = 0;
+
+ maybe_apply_pending_pragma_weaks ();
cgraph_finalize_compilation_unit ();
}
tree newtype, oldtype;
bool pedwarned = false;
bool warned = false;
+ bool retval = true;
/* If we have error_mark_node for either decl or type, just discard
the previous decl - we're in an error cascade already. */
if (DECL_INITIAL (newdecl))
{
- if (DECL_INITIAL (olddecl)
- && !(DECL_DECLARED_INLINE_P (olddecl)
- && DECL_EXTERNAL (olddecl)
- && !(DECL_DECLARED_INLINE_P (newdecl)
- && DECL_EXTERNAL (newdecl)
- && same_translation_unit_p (olddecl, newdecl))))
+ if (DECL_INITIAL (olddecl))
{
- error ("%Jredefinition of %qD", newdecl, newdecl);
- locate_old_decl (olddecl, error);
- return false;
- }
+ /* If both decls have extern inline and are in the same TU,
+ reject the new decl. */
+ if (DECL_DECLARED_INLINE_P (olddecl)
+ && DECL_EXTERNAL (olddecl)
+ && DECL_DECLARED_INLINE_P (newdecl)
+ && DECL_EXTERNAL (newdecl)
+ && same_translation_unit_p (newdecl, olddecl))
+ {
+ error ("%Jredefinition of %qD", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+ /* If both decls have not extern inline, reject the new decl. */
+ if (!DECL_DECLARED_INLINE_P (olddecl)
+ && !DECL_EXTERNAL (olddecl)
+ && !DECL_DECLARED_INLINE_P (newdecl)
+ && !DECL_EXTERNAL (newdecl))
+ {
+ error ("%Jredefinition of %qD", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+ /* If the new decl is declared as extern inline, error if they are
+ in the same TU, otherwise retain the old decl. */
+ if (!DECL_DECLARED_INLINE_P (olddecl)
+ && !DECL_EXTERNAL (olddecl)
+ && DECL_DECLARED_INLINE_P (newdecl)
+ && DECL_EXTERNAL (newdecl))
+ {
+ if (same_translation_unit_p (newdecl, olddecl))
+ {
+ error ("%Jredefinition of %qD", newdecl, newdecl);
+ locate_old_decl (olddecl, error);
+ return false;
+ }
+ else
+ retval = false;
+ }
+ }
}
/* If we have a prototype after an old-style function definition,
the argument types must be checked specially. */
if (warned || pedwarned)
locate_old_decl (olddecl, pedwarned ? pedwarn : warning);
- return true;
+ return retval;
}
/* Subroutine of duplicate_decls. NEWDECL has been found to be
}
}
}
- /* 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 %qD", 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);
decl = grokdeclarator (declarator, declspecs,
NORMAL, initialized, NULL);
+ if (!decl)
+ return 0;
deprecated_state = DEPRECATED_NORMAL;
if (TREE_CODE (decl) == FUNCTION_DECL && asmspec)
{
if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
- {
- tree builtin = built_in_decls [DECL_FUNCTION_CODE (decl)];
- set_user_assembler_name (builtin, asmspec);
- if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMCPY)
- init_block_move_fn (asmspec);
- else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_MEMSET)
- init_block_clear_fn (asmspec);
- }
+ set_builtin_user_assembler_name (decl, asmspec);
set_user_assembler_name (decl, asmspec);
}
DECL_DEFER_OUTPUT (decl) = 1;
DECL_COMDAT (decl) = 1;
DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
pushdecl (decl);
rest_of_decl_compilation (decl, 1, 0);
}
}
else if (TREE_CODE (type) == FUNCTION_TYPE)
{
- decl = build_decl (FUNCTION_DECL, declarator->u.id, type);
- decl = build_decl_attribute_variant (decl, decl_attr);
-
if (storage_class == csc_register || threadp)
{
error ("invalid storage class for function %qs", name);
- if (DECL_INITIAL (decl) != NULL_TREE)
- DECL_INITIAL (decl) = error_mark_node;
}
else if (current_scope != file_scope)
{
if (pedantic)
pedwarn ("invalid storage class for function %qs", name);
}
- if (storage_class == csc_static)
+ else if (storage_class == csc_static)
{
error ("invalid storage class for function %qs", name);
- if (DECL_INITIAL (decl) != NULL_TREE)
- DECL_INITIAL (decl) = error_mark_node;
+ if (funcdef_flag)
+ storage_class = declspecs->storage_class = csc_none;
+ else
+ return 0;
}
}
+ decl = build_decl (FUNCTION_DECL, declarator->u.id, type);
+ decl = build_decl_attribute_variant (decl, decl_attr);
+
DECL_LANG_SPECIFIC (decl) = GGC_CNEW (struct lang_decl);
if (pedantic && type_quals && !DECL_IN_SYSTEM_HEADER (decl))
DECL_SAVED_TREE (fndecl) = push_stmt_list ();
/* ??? Insert the contents of the pending sizes list into the function
- to be evaluated. This just changes mis-behavior until assign_parms
- phase ordering problems are resolved. */
+ to be evaluated. The only reason left to have this is
+ void foo(int n, int array[n++])
+ because we throw away the array type in favor of a pointer type, and
+ thus won't naturally see the SAVE_EXPR containing the increment. All
+ other pending sizes would be handled by gimplify_parameters. */
{
tree t;
for (t = nreverse (get_pending_sizes ()); t ; t = TREE_CHAIN (t))
else
{
if (flag_isoc99)
- c_finish_return (integer_zero_node);
+ {
+ tree stmt = c_finish_return (integer_zero_node);
+ /* Hack. We don't want the middle-end to warn that this
+ return is unreachable, so put the statement on the
+ special line 0. */
+ annotate_with_file_line (stmt, input_filename, 0);
+ }
}
}