#include "rtl.h"
#include "tree.h"
#include "flags.h"
+#include "except.h"
#include "function.h"
#include "expr.h"
#include "output.h"
/* Tell the assembler to switch to the bss section. */
void
-bss_section (decl, name)
+bss_section ()
{
if (in_section != in_bss)
{
#endif
}
}
+
+/* Tell assembler to switch to the section for the exception handling
+ table. */
+
+void
+exception_section ()
+{
+#ifdef ASM_OUTPUT_SECTION_NAME
+ named_section (NULL_TREE, ".gcc_except_table");
+#else
+ if (flag_pic)
+ data_section ();
+ else
+#if defined (EXCEPTION_SECTION)
+ EXCEPTION_SECTION ();
+#else
+ readonly_data_section ();
+#endif
+#endif
+}
\f
/* Create the rtl to represent a function, for a function definition.
DECL is a FUNCTION_DECL node which describes which function.
globalize_reg (reg_number + --nregs);
}
}
- /* Specifying a section attribute on an uninitialized variable does not
- (and cannot) cause it to be put in the given section. The linker
- can only put initialized objects in specific sections, everything
- else goes in bss for the linker to sort out later (otherwise the
- linker would give a duplicate definition error for each compilation
- unit that behaved thusly). So warn the user. */
+ /* Specifying a section attribute on a variable forces it into a
+ non-.bss section, and thus it cannot be common. */
else if (TREE_CODE (decl) == VAR_DECL
&& DECL_SECTION_NAME (decl) != NULL_TREE
&& DECL_INITIAL (decl) == NULL_TREE
&& DECL_COMMON (decl))
- {
- warning_with_decl (decl,
- "section attribute ignored for uninitialized variable `%s'");
- /* Remove the section name so subsequent declarations won't see it.
- We are ignoring it, remember. */
- DECL_SECTION_NAME (decl) = NULL_TREE;
- }
+ DECL_COMMON (decl) = 0;
/* Now handle ordinary static variables and functions (in memory).
Also handle vars declared register invalidly. */
if (TREE_PUBLIC (decl))
{
- if (!first_global_object_name)
+ if (!first_global_object_name && ! DECL_WEAK (decl)
+ && ! DECL_ONE_ONLY (decl))
{
char *p;
name = XSTR (XEXP (DECL_RTL (decl), 0), 0);
+ if (TREE_PUBLIC (decl) && DECL_NAME (decl)
+ && ! first_global_object_name
+ && ! (DECL_COMMON (decl) && (DECL_INITIAL (decl) == 0
+ || DECL_INITIAL (decl) == error_mark_node))
+ && ! DECL_WEAK (decl)
+ && ! DECL_ONE_ONLY (decl))
+ {
+ char *p;
+
+ STRIP_NAME_ENCODING (p, name);
+ first_global_object_name = permalloc (strlen (p) + 1);
+ strcpy (first_global_object_name, p);
+ }
+
/* Handle uninitialized definitions. */
if ((DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node)
/* First make the assembler name(s) global if appropriate. */
if (TREE_PUBLIC (decl) && DECL_NAME (decl))
{
- if (!first_global_object_name)
- {
- char *p;
-
- STRIP_NAME_ENCODING (p, name);
- first_global_object_name = permalloc (strlen (p) + 1);
- strcpy (first_global_object_name, p);
- }
-
#ifdef ASM_WEAKEN_LABEL
if (DECL_WEAK (decl))
ASM_WEAKEN_LABEL (asm_out_file, name);
char *name;
{
char *real_name;
- int save_warn_id_clash = warn_id_clash;
+ tree id;
STRIP_NAME_ENCODING (real_name, name);
- /* Don't warn about an identifier name length clash on this name, since
- it can be a user symbol suffixed by a number. */
- warn_id_clash = 0;
- TREE_SYMBOL_REFERENCED (get_identifier (real_name)) = 1;
- warn_id_clash = save_warn_id_clash;
+ id = maybe_get_identifier (real_name);
+ if (id)
+ TREE_SYMBOL_REFERENCED (id) = 1;
if (name[0] == '*')
{
case STRING_CST:
case COMPLEX_CST:
case CONSTRUCTOR:
+ case INTEGER_CST:
x = TREE_CST_RTL (target);
break;
return copy_node (exp);
case COMPLEX_CST:
- return build_complex (copy_constant (TREE_REALPART (exp)),
+ return build_complex (TREE_TYPE (exp),
+ copy_constant (TREE_REALPART (exp)),
copy_constant (TREE_IMAGPART (exp)));
case PLUS_EXPR:
int reloc;
register rtx def;
- if (TREE_CODE (exp) == INTEGER_CST)
- abort (); /* No TREE_CST_RTL slot in these. */
-
if (TREE_CST_RTL (exp))
return TREE_CST_RTL (exp);
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);
+#ifdef ASM_OUTPUT_DEF
/* Make name accessible from other files, if appropriate. */
if (TREE_PUBLIC (decl))
ASM_OUTPUT_DEF (asm_out_file, name, IDENTIFIER_POINTER (target));
TREE_ASM_WRITTEN (decl) = 1;
#else
- warning ("alias definitions not supported in this configuration");
+#ifdef ASM_OUTPUT_WEAK_ALIAS
+ if (! DECL_WEAK (decl))
+ warning ("only weak aliases are supported in this configuration");
+
+ ASM_OUTPUT_WEAK_ALIAS (asm_out_file, name, IDENTIFIER_POINTER (target));
+ TREE_ASM_WRITTEN (decl) = 1;
+#else
+ warning ("alias definitions not supported in this configuration; ignored");
+#endif
+#endif
+}
+
+/* This determines whether or not we support link-once semantics. */
+#ifndef SUPPORTS_ONE_ONLY
+#ifdef MAKE_DECL_ONE_ONLY
+#define SUPPORTS_ONE_ONLY 1
+#else
+#define SUPPORTS_ONE_ONLY 0
#endif
+#endif
+
+/* Returns 1 if the target configuration supports defining public symbols
+ so that one of them will be chosen at link time instead of generating a
+ multiply-defined symbol error, whether through the use of weak symbols or
+ a target-specific mechanism for having duplicates discarded. */
+
+int
+supports_one_only ()
+{
+ if (SUPPORTS_ONE_ONLY)
+ return 1;
+ return SUPPORTS_WEAK;
+}
+
+/* Set up DECL as a public symbol that can be defined in multiple
+ translation units without generating a linker error. */
+
+void
+make_decl_one_only (decl)
+ tree decl;
+{
+ if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
+ abort ();
+
+ TREE_PUBLIC (decl) = 1;
+
+ if (TREE_CODE (decl) == VAR_DECL
+ && (DECL_INITIAL (decl) == 0 || DECL_INITIAL (decl) == error_mark_node))
+ DECL_COMMON (decl) = 1;
+ else if (SUPPORTS_ONE_ONLY)
+ {
+#ifdef MAKE_DECL_ONE_ONLY
+ MAKE_DECL_ONE_ONLY (decl);
+#endif
+ DECL_ONE_ONLY (decl) = 1;
+ }
+ else if (SUPPORTS_WEAK)
+ DECL_WEAK (decl) = 1;
+ else
+ abort ();
}