aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-pragma.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2002-03-14 23:11:14 -0800
committerRichard Henderson <rth@gcc.gnu.org>2002-03-14 23:11:14 -0800
commitecb0eecefbd769b20dc9842fb0881db7492ec225 (patch)
treea4832f691fe7468c7db7811469b930a129616f84 /gcc/c-pragma.c
parent98d2b17e0c941e8e60055d10b36e2ceef522be92 (diff)
downloadgcc-ecb0eecefbd769b20dc9842fb0881db7492ec225.zip
gcc-ecb0eecefbd769b20dc9842fb0881db7492ec225.tar.gz
gcc-ecb0eecefbd769b20dc9842fb0881db7492ec225.tar.bz2
c-decl.c: Include c-pragma.h.
* c-decl.c: Include c-pragma.h. (start_decl, start_function): Invoke maybe_apply_pragma_weak. (finish_function): Tidy. * c-pragma.c: Include c-common.h. (pending_weaks, apply_pragma_weak, maybe_apply_pragma_weak): New. (handle_pragma_weak): Use them. (init_pragma): Register pending_weaks. * c-pragma.h (maybe_apply_pragma_weak): Declare. * print-tree.c (print_node): Print DECL_WEAK. * varasm.c (mark_weak_decls): Remove. (remove_from_pending_weak_list): Remove. (add_weak): Remove. (asm_emit_uninitialised): Call globalize_decl for weak commons. (weak_decls): Make a tree_list. (declare_weak): Cons weak_decls directly. (globalize_decl): Remove weak_decls elements directly. (weak_finish): Simplify weak_decls walk. Don't weaken unused symbols. Don't pretend to handle aliases. (init_varasm_once): Update weak_decls registry. * Makefile.in: Update dependencies. * cp/decl.c: Include c-pragma.h. (start_decl, start_function): Invoke maybe_apply_pragma_weak. * cp/Make-lang.in: Update dependencies. * gcc.dg/weak-1.c: New. From-SVN: r50797
Diffstat (limited to 'gcc/c-pragma.c')
-rw-r--r--gcc/c-pragma.c63
1 files changed, 56 insertions, 7 deletions
diff --git a/gcc/c-pragma.c b/gcc/c-pragma.c
index 26bf277..1a17e67 100644
--- a/gcc/c-pragma.c
+++ b/gcc/c-pragma.c
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "toplev.h"
#include "ggc.h"
#include "c-lex.h"
+#include "c-common.h"
#include "output.h"
#include "tm_p.h"
@@ -55,9 +56,9 @@ static struct align_stack * alignment_stack = NULL;
maximum_field_alignment in effect. When the final pop_alignment()
happens, we restore the value to this, not to a value of 0 for
maximum_field_alignment. Value is in bits. */
-static int default_alignment;
+static int default_alignment;
#define SET_GLOBAL_ALIGNMENT(ALIGN) \
-(default_alignment = maximum_field_alignment = (ALIGN))
+ (default_alignment = maximum_field_alignment = (ALIGN))
static void push_alignment PARAMS ((int, tree));
static void pop_alignment PARAMS ((tree));
@@ -69,7 +70,6 @@ push_alignment (alignment, id)
int alignment;
tree id;
{
-
if (alignment_stack == NULL
|| alignment_stack->alignment != alignment
|| id != NULL_TREE)
@@ -274,14 +274,53 @@ handle_pragma_pack (dummy)
#endif /* HANDLE_PRAGMA_PACK */
#ifdef HANDLE_PRAGMA_WEAK
+static void apply_pragma_weak PARAMS ((tree, tree));
static void handle_pragma_weak PARAMS ((cpp_reader *));
+static tree pending_weaks;
+
+static void
+apply_pragma_weak (decl, value)
+ tree decl, value;
+{
+ if (value)
+ decl_attributes (&decl, build_tree_list (get_identifier ("alias"),
+ build_tree_list (NULL, value)),
+ 0);
+ declare_weak (decl);
+}
+
+void
+maybe_apply_pragma_weak (decl)
+ tree decl;
+{
+ tree *p, t, id;
+
+ /* Copied from the check in set_decl_assembler_name. */
+ if (TREE_CODE (decl) == FUNCTION_DECL
+ || (TREE_CODE (decl) == VAR_DECL
+ && (TREE_STATIC (decl)
+ || DECL_EXTERNAL (decl)
+ || TREE_PUBLIC (decl))))
+ id = DECL_ASSEMBLER_NAME (decl);
+ else
+ return;
+
+ for (p = &pending_weaks; (t = *p) ; p = &TREE_CHAIN (t))
+ if (id == TREE_PURPOSE (t))
+ {
+ apply_pragma_weak (decl, TREE_VALUE (t));
+ *p = TREE_CHAIN (t);
+ break;
+ }
+}
+
/* #pragma weak name [= value] */
static void
handle_pragma_weak (dummy)
cpp_reader *dummy ATTRIBUTE_UNUSED;
{
- tree name, value, x;
+ tree name, value, x, decl;
enum cpp_ttype t;
value = 0;
@@ -298,10 +337,19 @@ handle_pragma_weak (dummy)
if (t != CPP_EOF)
warning ("junk at end of #pragma weak");
- add_weak (NULL_TREE, IDENTIFIER_POINTER (name),
- value ? IDENTIFIER_POINTER (value) : NULL);
+ decl = identifier_global_value (name);
+ if (decl && TREE_CODE_CLASS (TREE_CODE (decl)) == 'd')
+ apply_pragma_weak (decl, value);
+ else
+ pending_weaks = tree_cons (name, value, pending_weaks);
}
-#endif
+#else
+void
+maybe_apply_pragma_weak (decl)
+ tree decl ATTRIBUTE_UNUSED;
+{
+}
+#endif /* HANDLE_PRAGMA_WEAK */
void
init_pragma ()
@@ -311,6 +359,7 @@ init_pragma ()
#endif
#ifdef HANDLE_PRAGMA_WEAK
cpp_register_pragma (parse_in, 0, "weak", handle_pragma_weak);
+ ggc_add_tree_root (&pending_weaks, 1);
#endif
#ifdef REGISTER_TARGET_PRAGMAS
REGISTER_TARGET_PRAGMAS (parse_in);