attributes weak and alias
authorJason Merrill <merrill@gnu.org>
Sun, 16 Apr 1995 06:14:00 +0000 (06:14 +0000)
committerJason Merrill <merrill@gnu.org>
Sun, 16 Apr 1995 06:14:00 +0000 (06:14 +0000)
From-SVN: r9391

gcc/c-common.c
gcc/config/aoutos.h
gcc/config/sparc/sunos4.h
gcc/toplev.c
gcc/varasm.c

index 1c1a5da57e314b7ab79ef77bbc177807b02aa642..18d6265b7106a43676db40212862b21d1e364b45 100644 (file)
@@ -30,7 +30,7 @@ extern struct obstack permanent_obstack;
 
 enum attrs {A_PACKED, A_NOCOMMON, A_NORETURN, A_CONST, A_T_UNION,
            A_CONSTRUCTOR, A_DESTRUCTOR, A_MODE, A_SECTION, A_ALIGNED,
-           A_FORMAT};
+           A_FORMAT, A_WEAK, A_ALIAS};
 
 static void declare_hidden_char_array  PROTO((char *, char *));
 static void add_attribute              PROTO((enum attrs, char *,
@@ -258,6 +258,8 @@ init_attributes ()
   add_attribute (A_SECTION, "section", 1, 1, 1);
   add_attribute (A_ALIGNED, "aligned", 0, 1, 0);
   add_attribute (A_FORMAT, "format", 3, 3, 1);
+  add_attribute (A_WEAK, "weak", 0, 0, 1);
+  add_attribute (A_ALIAS, "alias", 1, 1, 1);
 }
 \f
 /* Process the attributes listed in ATTRIBUTES and PREFIX_ATTRIBUTES
@@ -606,6 +608,29 @@ decl_attributes (node, attributes, prefix_attributes)
                                    is_scan, format_num, first_arg_num);
            break;
          }
+
+       case A_WEAK:
+         declare_weak (decl);
+         break;
+
+       case A_ALIAS:
+         if ((TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
+             || TREE_CODE (decl) != FUNCTION_DECL && ! DECL_EXTERNAL (decl))
+           error_with_decl (decl,
+                            "`%s' defined both normally and as an alias");
+         else if (decl_function_context (decl) == 0)
+           {
+             tree id = get_identifier (TREE_STRING_POINTER
+                                       (TREE_VALUE (args)));
+             if (TREE_CODE (decl) == FUNCTION_DECL)
+               DECL_INITIAL (decl) = error_mark_node;
+             else
+               DECL_EXTERNAL (decl) = 0;
+             assemble_alias (decl, id);
+           }
+         else
+           warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
+         break;
        }
     }
 }
index b398965e7adb835d34e005ce04c3d9518a749434..f7bfc905982b510e0b16cf28813eacbb15596618 100644 (file)
@@ -85,3 +85,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        fputc ('\n', FILE);                                             \
       }                                                                        \
   } while (0)
+
+/* If we're using GNU as and ld, we support weak symbols.  */
+
+#define HANDLE_PRAGMA_WEAK flag_gnu_linker
+#define WEAK_ASM_OP    ".weak"
+#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)                             \
+ do { if (flag_gnu_linker)                                             \
+       {                                                               \
+         fprintf ((FILE), "\t%s\t", ".set");                           \
+         assemble_name (FILE, LABEL1);                                 \
+         fprintf (FILE, ",");                                          \
+         assemble_name (FILE, LABEL2);                                 \
+         fprintf (FILE, "\n");                                         \
+       }                                                               \
+  } while (0)
index c7bcaad12c414c5a958a0ad99101bea34d0ba6c6..fd108e85db868047213f2da6b2a0eeb015f8ddcd 100644 (file)
@@ -20,3 +20,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define SUNOS4_SHARED_LIBRARIES 1
 
 #include "sparc/sparc.h"
+
+/* If we're using GNU as and ld, we support weak symbols.  */
+
+#define HANDLE_PRAGMA_WEAK flag_gnu_linker
+#define WEAK_ASM_OP    ".weak"
+#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)                             \
+ do { if (flag_gnu_linker)                                             \
+       {                                                               \
+         fprintf ((FILE), "\t%s\t", ".set");                           \
+         assemble_name (FILE, LABEL1);                                 \
+         fprintf (FILE, ",");                                          \
+         assemble_name (FILE, LABEL2);                                 \
+         fprintf (FILE, "\n");                                         \
+       }                                                               \
+  } while (0)
index 988e2c670e45615bda17a35ac73dc29fc86d9530..b6afc47f30c6f2a1440c6db21d3effa3ffe50ea8 100644 (file)
@@ -2574,6 +2574,10 @@ compile_file (name)
       }
   }
 
+  /* Write out any pending weak symbol declarations.  */
+
+  weak_finish ();
+
   /* Do dbx symbols */
 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
   if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
index a54c5dfdf4c1cf3a91bcc636b37d5468fffac9d0..c4249a9c5d2972aab8b2eb0cfbda59dea4a75b6c 100644 (file)
@@ -97,8 +97,13 @@ int size_directive_output;
 tree last_assemble_variable_decl;
 
 /* Nonzero if at least one function definition has been seen.  */
+
 static int function_defined;
 
+/* Any weak symbol declarations waiting to be emitted.  */
+
+static tree weak_decls;
+
 struct addr_const;
 struct constant_descriptor;
 struct rtx_const;
@@ -3911,12 +3916,13 @@ output_constructor (exp, size)
     assemble_zeros (size - total_bytes);
 }
 
-
-#ifdef HANDLE_SYSV_PRAGMA
-
 /* Support #pragma weak by default if WEAK_ASM_OP and ASM_OUTPUT_DEF
    are defined.  */
-#if defined (WEAK_ASM_OP) && defined (ASM_OUTPUT_DEF)
+#if !defined (HANDLE_PRAGMA_WEAK) && defined (WEAK_ASM_OP) && defined (ASM_OUTPUT_DEF)
+#define HANDLE_PRAGMA_WEAK 1
+#endif
+
+#if defined (HANDLE_SYSV_PRAGMA) && defined (HANDLE_PRAGMA_WEAK)
 
 /* See c-pragma.c for an identical definition.  */
 enum pragma_state
@@ -3943,21 +3949,77 @@ handle_pragma_weak (what, asm_out_file, name, value)
 {
   if (what == ps_name || what == ps_value)
     {
-      fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
-
-      if (output_bytecode)
-       BC_OUTPUT_LABELREF (asm_out_file, name);
-      else
-       ASM_OUTPUT_LABELREF (asm_out_file, name);
-
-      fputc ('\n', asm_out_file);
-      if (what == ps_value)
-       ASM_OUTPUT_DEF (asm_out_file, name, value);
+      weak_decls = perm_tree_cons (what == ps_value ? value : NULL_TREE,
+                                  name, weak_decls);
     }
   else if (! (what == ps_done || what == ps_start))
     warning ("malformed `#pragma weak'");
 }
 
-#endif /* HANDLE_PRAGMA_WEAK or (WEAK_ASM_OP and SET_ASM_OP) */
+#endif /* HANDLE_SYSV_PRAGMA && HANDLE_PRAGMA_WEAK */
+
+/* Declare DECL to be a weak symbol.  */
+
+void
+declare_weak (decl)
+     tree decl;
+{
+  if (! TREE_PUBLIC (decl))
+    error_with_decl (decl, "weak declaration of `%s' must be public");
+  else
+    weak_decls = perm_tree_cons (NULL_TREE, DECL_ASSEMBLER_NAME (decl),
+                                weak_decls);
+}
+
+/* Emit any pending weak declarations.  */
+
+void
+weak_finish ()
+{
+#ifdef HANDLE_PRAGMA_WEAK
+  if (HANDLE_PRAGMA_WEAK)
+    {
+      tree t;
+      for (t = weak_decls; t; t = TREE_CHAIN (t))
+       {
+         tree decl = TREE_VALUE (t);
+         char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
 
-#endif /* WEAK_ASM_OP && ASM_OUTPUT_DEF */
+         fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
+
+         if (output_bytecode)
+           BC_OUTPUT_LABELREF (asm_out_file, name);
+         else
+           ASM_OUTPUT_LABELREF (asm_out_file, name);
+
+         fputc ('\n', asm_out_file);
+       }
+    }
+#endif
+}
+
+void
+assemble_alias (decl, target)
+     tree decl, target;
+{
+#ifdef ASM_OUTPUT_DEF
+  char *name;
+
+  make_decl_rtl (decl, (char*)0, 1);
+  name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+
+  /* Make name accessible from other files, if appropriate.  */
+
+  if (TREE_PUBLIC (decl))
+    {
+      if (output_bytecode)
+       BC_GLOBALIZE_LABEL (asm_out_file, name);
+      else
+       ASM_GLOBALIZE_LABEL (asm_out_file, name);
+    }
+
+  ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
+#else
+  warning ("alias definitions not supported in this configuration");
+#endif
+}