/* Functions for generic Darwin as target machine for GNU C compiler.
Copyright (C) 1989, 1990, 1991, 1992, 1993, 2000, 2001, 2002, 2003, 2004,
- 2005
+ 2005, 2006, 2007
Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
#include "tm_p.h"
#include "toplev.h"
#include "hashtab.h"
+#include "df.h"
/* Darwin supports a feature called fix-and-continue, which is used
for rapid turn around debugging. When code is compiled with the
/* Section names. */
section * darwin_sections[NUM_DARWIN_SECTIONS];
+/* True if we're setting __attribute__ ((ms_struct)). */
+int darwin_ms_struct = false;
+
/* A get_unnamed_section callback used to switch to an ObjC section.
DIRECTIVE is as for output_section_asm_op. */
int lprefix;
const char *name;
- /* If we aren't generating fix-and-continue code, don't do anything special. */
+ /* If we aren't generating fix-and-continue code, don't do anything
+ special. */
if (TARGET_FIX_AND_CONTINUE == 0)
return 0;
{
#if defined (TARGET_TOC)
/* Create a new register for CSE opportunities. */
- rtx hi_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
+ rtx hi_reg = (!can_create_pseudo_p () ? reg : gen_reg_rtx (Pmode));
emit_insn (gen_macho_high (hi_reg, orig));
emit_insn (gen_macho_low (reg, hi_reg, orig));
#else
#endif
#if defined (TARGET_TOC) /* i.e., PowerPC */
- rtx hi_sum_reg = (no_new_pseudos ? reg : gen_reg_rtx (Pmode));
+ rtx hi_sum_reg = (!can_create_pseudo_p ()
+ ? reg
+ : gen_reg_rtx (Pmode));
gcc_assert (reg);
|| GET_CODE (XEXP (orig, 0)) == LABEL_REF))
{
#if defined (TARGET_TOC) /* ppc */
- rtx temp_reg = (no_new_pseudos) ? reg : gen_reg_rtx (Pmode);
+ rtx temp_reg = (!can_create_pseudo_p ()
+ ? reg :
+ gen_reg_rtx (Pmode));
rtx asym = XEXP (orig, 0);
rtx mem;
gen_rtx_LO_SUM (Pmode, temp_reg, asym));
emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
#else
- /* Some other CPU -- WriteMe! but right now there are no other platform that can use dynamic-no-pic */
+ /* Some other CPU -- WriteMe! but right now there are no other
+ platforms that can use dynamic-no-pic */
gcc_unreachable ();
#endif
pic_ref = reg;
#if defined (TARGET_TOC) /* i.e., PowerPC */
/* Generating a new reg may expose opportunities for
common subexpression elimination. */
- rtx hi_sum_reg = no_new_pseudos ? reg : gen_reg_rtx (Pmode);
+ rtx hi_sum_reg = (!can_create_pseudo_p ()
+ ? reg
+ : gen_reg_rtx (Pmode));
rtx mem;
rtx insn;
rtx sum;
gen_rtx_LO_SUM (Pmode,
hi_sum_reg, offset));
insn = emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
- REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, pic_ref,
- REG_NOTES (insn));
+ set_unique_reg_note (insn, REG_EQUAL, pic_ref);
pic_ref = reg;
#else
#endif
if (reload_in_progress)
- regs_ever_live[REGNO (pic)] = 1;
+ df_set_regs_ever_live (REGNO (pic), true);
pic_ref = gen_rtx_PLUS (Pmode, pic,
gen_pic_offset (XEXP (orig, 0),
pic_base));
pic_offset_table_rtx));
#endif
if (reload_in_progress)
- regs_ever_live[REGNO (pic)] = 1;
+ df_set_regs_ever_live (REGNO (pic), true);
pic_ref = gen_rtx_PLUS (Pmode,
pic,
gen_pic_offset (orig, pic_base));
fputc ('\n', asm_out_file);
}
-section *
-machopic_select_section (tree exp, int reloc,
- unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
+static section *
+darwin_text_section (int reloc, int weak)
{
- section *base_section;
- bool weak_p = (DECL_P (exp) && DECL_WEAK (exp)
- && (lookup_attribute ("weak", DECL_ATTRIBUTES (exp))
- || ! lookup_attribute ("weak_import",
- DECL_ATTRIBUTES (exp))));
-
- if (TREE_CODE (exp) == FUNCTION_DECL)
- {
- if (reloc == 1)
- base_section = (weak_p
- ? darwin_sections[text_unlikely_coal_section]
- : unlikely_text_section ());
- else
- base_section = weak_p ? darwin_sections[text_coal_section] : text_section;
- }
- else if (decl_readonly_section_1 (exp, reloc, MACHOPIC_INDIRECT))
- base_section = weak_p ? darwin_sections[const_coal_section] : darwin_sections[const_section];
- else if (TREE_READONLY (exp) || TREE_CONSTANT (exp))
- base_section = weak_p ? darwin_sections[const_data_coal_section] : darwin_sections[const_data_section];
+ if (reloc)
+ return (weak
+ ? darwin_sections[text_unlikely_coal_section]
+ : unlikely_text_section ());
else
- base_section = weak_p ? darwin_sections[data_coal_section] : data_section;
+ return (weak
+ ? darwin_sections[text_coal_section]
+ : text_section);
+}
- if (TREE_CODE (exp) == STRING_CST
+static section *
+darwin_rodata_section (int weak)
+{
+ return (weak
+ ? darwin_sections[const_coal_section]
+ : darwin_sections[const_section]);
+}
+
+static section *
+darwin_mergeable_string_section (tree exp,
+ unsigned HOST_WIDE_INT align)
+{
+ if (flag_merge_constants
+ && TREE_CODE (exp) == STRING_CST
+ && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
+ && align <= 256
&& ((size_t) TREE_STRING_LENGTH (exp)
== strlen (TREE_STRING_POINTER (exp)) + 1))
return darwin_sections[cstring_section];
- else if ((TREE_CODE (exp) == INTEGER_CST || TREE_CODE (exp) == REAL_CST)
- && flag_merge_constants)
+
+ return readonly_data_section;
+}
+
+#ifndef HAVE_GAS_LITERAL16
+#define HAVE_GAS_LITERAL16 0
+#endif
+
+static section *
+darwin_mergeable_constant_section (tree exp,
+ unsigned HOST_WIDE_INT align)
+{
+ enum machine_mode mode = DECL_MODE (exp);
+ unsigned int modesize = GET_MODE_BITSIZE (mode);
+
+ if (flag_merge_constants
+ && mode != VOIDmode
+ && mode != BLKmode
+ && modesize <= align
+ && align >= 8
+ && align <= 256
+ && (align & (align -1)) == 0)
{
tree size = TYPE_SIZE_UNIT (TREE_TYPE (exp));
- if (TREE_CODE (size) == INTEGER_CST &&
- TREE_INT_CST_LOW (size) == 4 &&
- TREE_INT_CST_HIGH (size) == 0)
- return darwin_sections[literal4_section];
- else if (TREE_CODE (size) == INTEGER_CST &&
- TREE_INT_CST_LOW (size) == 8 &&
- TREE_INT_CST_HIGH (size) == 0)
- return darwin_sections[literal8_section];
+ if (TREE_CODE (size) == INTEGER_CST
+ && TREE_INT_CST_LOW (size) == 4
+ && TREE_INT_CST_HIGH (size) == 0)
+ return darwin_sections[literal4_section];
+ else if (TREE_CODE (size) == INTEGER_CST
+ && TREE_INT_CST_LOW (size) == 8
+ && TREE_INT_CST_HIGH (size) == 0)
+ return darwin_sections[literal8_section];
+ else if (HAVE_GAS_LITERAL16
+ && TARGET_64BIT
+ && TREE_CODE (size) == INTEGER_CST
+ && TREE_INT_CST_LOW (size) == 16
+ && TREE_INT_CST_HIGH (size) == 0)
+ return darwin_sections[literal16_section];
else
- return base_section;
+ return readonly_data_section;
}
- else if (TREE_CODE (exp) == CONSTRUCTOR
- && TREE_TYPE (exp)
- && TREE_CODE (TREE_TYPE (exp)) == RECORD_TYPE
- && TYPE_NAME (TREE_TYPE (exp)))
+
+ return readonly_data_section;
+}
+
+int
+machopic_reloc_rw_mask (void)
+{
+ return MACHOPIC_INDIRECT ? 3 : 0;
+}
+
+section *
+machopic_select_section (tree decl,
+ int reloc,
+ unsigned HOST_WIDE_INT align)
+{
+ bool weak = (DECL_P (decl)
+ && DECL_WEAK (decl)
+ && (lookup_attribute ("weak", DECL_ATTRIBUTES (decl))
+ || ! lookup_attribute ("weak_import",
+ DECL_ATTRIBUTES (decl))));
+ section *base_section;
+
+ switch (categorize_decl_for_section (decl, reloc))
{
- tree name = TYPE_NAME (TREE_TYPE (exp));
+ case SECCAT_TEXT:
+ base_section = darwin_text_section (reloc, weak);
+ break;
+
+ case SECCAT_RODATA:
+ case SECCAT_SRODATA:
+ base_section = darwin_rodata_section (weak);
+ break;
+
+ case SECCAT_RODATA_MERGE_STR:
+ base_section = darwin_mergeable_string_section (decl, align);
+ break;
+
+ case SECCAT_RODATA_MERGE_STR_INIT:
+ base_section = darwin_mergeable_string_section (DECL_INITIAL (decl), align);
+ break;
+
+ case SECCAT_RODATA_MERGE_CONST:
+ base_section = darwin_mergeable_constant_section (decl, align);
+ break;
+
+ case SECCAT_DATA:
+ case SECCAT_DATA_REL:
+ case SECCAT_DATA_REL_LOCAL:
+ case SECCAT_DATA_REL_RO:
+ case SECCAT_DATA_REL_RO_LOCAL:
+ case SECCAT_SDATA:
+ case SECCAT_TDATA:
+ case SECCAT_BSS:
+ case SECCAT_SBSS:
+ case SECCAT_TBSS:
+ if (TREE_READONLY (decl) || TREE_CONSTANT (decl))
+ base_section = weak ? darwin_sections[const_data_coal_section]
+ : darwin_sections[const_data_section];
+ else
+ base_section = weak ? darwin_sections[data_coal_section] : data_section;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Darwin weird special cases. */
+ if (TREE_CODE (decl) == CONSTRUCTOR
+ && TREE_TYPE (decl)
+ && TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE
+ && TYPE_NAME (TREE_TYPE (decl)))
+ {
+ tree name = TYPE_NAME (TREE_TYPE (decl));
if (TREE_CODE (name) == TYPE_DECL)
- name = DECL_NAME (name);
+ name = DECL_NAME (name);
if (!strcmp (IDENTIFIER_POINTER (name), "__builtin_ObjCString"))
- {
- if (flag_next_runtime)
- return darwin_sections[objc_constant_string_object_section];
- else
- return darwin_sections[objc_string_object_section];
- }
+ {
+ if (flag_next_runtime)
+ return darwin_sections[objc_constant_string_object_section];
+ else
+ return darwin_sections[objc_string_object_section];
+ }
else
- return base_section;
+ return base_section;
}
- else if (TREE_CODE (exp) == VAR_DECL &&
- DECL_NAME (exp) &&
- TREE_CODE (DECL_NAME (exp)) == IDENTIFIER_NODE &&
- IDENTIFIER_POINTER (DECL_NAME (exp)) &&
- !strncmp (IDENTIFIER_POINTER (DECL_NAME (exp)), "_OBJC_", 6))
+ else if (TREE_CODE (decl) == VAR_DECL
+ && DECL_NAME (decl)
+ && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE
+ && IDENTIFIER_POINTER (DECL_NAME (decl))
+ && !strncmp (IDENTIFIER_POINTER (DECL_NAME (decl)), "_OBJC_", 6))
{
- const char *name = IDENTIFIER_POINTER (DECL_NAME (exp));
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
if (!strncmp (name, "_OBJC_CLASS_METHODS_", 20))
- return darwin_sections[objc_cls_meth_section];
+ return darwin_sections[objc_cls_meth_section];
else if (!strncmp (name, "_OBJC_INSTANCE_METHODS_", 23))
- return darwin_sections[objc_inst_meth_section];
+ return darwin_sections[objc_inst_meth_section];
else if (!strncmp (name, "_OBJC_CATEGORY_CLASS_METHODS_", 20))
- return darwin_sections[objc_cat_cls_meth_section];
+ return darwin_sections[objc_cat_cls_meth_section];
else if (!strncmp (name, "_OBJC_CATEGORY_INSTANCE_METHODS_", 23))
- return darwin_sections[objc_cat_inst_meth_section];
+ return darwin_sections[objc_cat_inst_meth_section];
else if (!strncmp (name, "_OBJC_CLASS_VARIABLES_", 22))
- return darwin_sections[objc_class_vars_section];
+ return darwin_sections[objc_class_vars_section];
else if (!strncmp (name, "_OBJC_INSTANCE_VARIABLES_", 25))
- return darwin_sections[objc_instance_vars_section];
+ return darwin_sections[objc_instance_vars_section];
else if (!strncmp (name, "_OBJC_CLASS_PROTOCOLS_", 22))
- return darwin_sections[objc_cat_cls_meth_section];
+ return darwin_sections[objc_cat_cls_meth_section];
else if (!strncmp (name, "_OBJC_CLASS_NAME_", 17))
- return darwin_sections[objc_class_names_section];
+ return darwin_sections[objc_class_names_section];
else if (!strncmp (name, "_OBJC_METH_VAR_NAME_", 20))
- return darwin_sections[objc_meth_var_names_section];
+ return darwin_sections[objc_meth_var_names_section];
else if (!strncmp (name, "_OBJC_METH_VAR_TYPE_", 20))
- return darwin_sections[objc_meth_var_types_section];
+ return darwin_sections[objc_meth_var_types_section];
else if (!strncmp (name, "_OBJC_CLASS_REFERENCES", 22))
- return darwin_sections[objc_cls_refs_section];
+ return darwin_sections[objc_cls_refs_section];
else if (!strncmp (name, "_OBJC_CLASS_", 12))
- return darwin_sections[objc_class_section];
+ return darwin_sections[objc_class_section];
else if (!strncmp (name, "_OBJC_METACLASS_", 16))
- return darwin_sections[objc_meta_class_section];
+ return darwin_sections[objc_meta_class_section];
else if (!strncmp (name, "_OBJC_CATEGORY_", 15))
- return darwin_sections[objc_category_section];
+ return darwin_sections[objc_category_section];
else if (!strncmp (name, "_OBJC_SELECTOR_REFERENCES", 25))
- return darwin_sections[objc_selector_refs_section];
+ return darwin_sections[objc_selector_refs_section];
else if (!strncmp (name, "_OBJC_SELECTOR_FIXUP", 20))
- return darwin_sections[objc_selector_fixup_section];
+ return darwin_sections[objc_selector_fixup_section];
else if (!strncmp (name, "_OBJC_SYMBOLS", 13))
- return darwin_sections[objc_symbols_section];
+ return darwin_sections[objc_symbols_section];
else if (!strncmp (name, "_OBJC_MODULES", 13))
- return darwin_sections[objc_module_info_section];
+ return darwin_sections[objc_module_info_section];
else if (!strncmp (name, "_OBJC_IMAGE_INFO", 16))
- return darwin_sections[objc_image_info_section];
+ return darwin_sections[objc_image_info_section];
else if (!strncmp (name, "_OBJC_PROTOCOL_INSTANCE_METHODS_", 32))
- return darwin_sections[objc_cat_inst_meth_section];
+ return darwin_sections[objc_cat_inst_meth_section];
else if (!strncmp (name, "_OBJC_PROTOCOL_CLASS_METHODS_", 29))
- return darwin_sections[objc_cat_cls_meth_section];
+ return darwin_sections[objc_cat_cls_meth_section];
else if (!strncmp (name, "_OBJC_PROTOCOL_REFS_", 20))
- return darwin_sections[objc_cat_cls_meth_section];
+ return darwin_sections[objc_cat_cls_meth_section];
else if (!strncmp (name, "_OBJC_PROTOCOL_", 15))
- return darwin_sections[objc_protocol_section];
+ return darwin_sections[objc_protocol_section];
else
- return base_section;
+ return base_section;
}
- else
- return base_section;
+
+ return base_section;
}
/* This can be called with address expressions as "rtx".
&& (GET_CODE (x) == CONST_INT
|| GET_CODE (x) == CONST_DOUBLE))
return darwin_sections[literal4_section];
+ else if (HAVE_GAS_LITERAL16
+ && TARGET_64BIT
+ && GET_MODE_SIZE (mode) == 16
+ && (GET_CODE (x) == CONST_INT
+ || GET_CODE (x) == CONST_DOUBLE
+ || GET_CODE (x) == CONST_VECTOR))
+ return darwin_sections[literal16_section];
else if (MACHOPIC_INDIRECT
&& (GET_CODE (x) == SYMBOL_REF
|| GET_CODE (x) == CONST
/* Darwin does not use unique sections. */
}
+/* Handle __attribute__ ((apple_kext_compatibility)).
+ This only applies to darwin kexts for 2.95 compatibility -- it shrinks the
+ vtable for classes with this attribute (and their descendants) by not
+ outputting the new 3.0 nondeleting destructor. This means that such
+ objects CANNOT be allocated on the stack or as globals UNLESS they have
+ a completely empty `operator delete'.
+ Luckily, this fits in with the Darwin kext model.
+
+ This attribute also disables gcc3's potential overlaying of derived
+ class data members on the padding at the end of the base class. */
+
+tree
+darwin_handle_kext_attribute (tree *node, tree name,
+ tree args ATTRIBUTE_UNUSED,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
+{
+ /* APPLE KEXT stuff -- only applies with pure static C++ code. */
+ if (! TARGET_KEXTABI)
+ {
+ warning (0, "%<%s%> 2.95 vtable-compatibility attribute applies "
+ "only when compiling a kext", IDENTIFIER_POINTER (name));
+
+ *no_add_attrs = true;
+ }
+ else if (TREE_CODE (*node) != RECORD_TYPE)
+ {
+ warning (0, "%<%s%> 2.95 vtable-compatibility attribute applies "
+ "only to C++ classes", IDENTIFIER_POINTER (name));
+
+ *no_add_attrs = true;
+ }
+
+ return NULL_TREE;
+}
+
/* Handle a "weak_import" attribute; arguments as in
struct attribute_spec.handler. */
void
darwin_emit_unwind_label (FILE *file, tree decl, int for_eh, int empty)
{
- tree id = DECL_ASSEMBLER_NAME (decl)
- ? DECL_ASSEMBLER_NAME (decl)
- : DECL_NAME (decl);
-
- const char *prefix = user_label_prefix;
+ const char *base;
+ char *lab;
+ bool need_quotes;
- const char *base = IDENTIFIER_POINTER (id);
- unsigned int base_len = IDENTIFIER_LENGTH (id);
+ if (DECL_ASSEMBLER_NAME_SET_P (decl))
+ base = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+ else
+ base = IDENTIFIER_POINTER (DECL_NAME (decl));
- const char *suffix = ".eh";
-
- int need_quotes = name_needs_quotes (base);
- int quotes_len = need_quotes ? 2 : 0;
- char *lab;
+ base = targetm.strip_name_encoding (base);
+ need_quotes = name_needs_quotes (base);
if (! for_eh)
- suffix = ".eh1";
-
- lab = XNEWVEC (char, strlen (prefix)
- + base_len + strlen (suffix) + quotes_len + 1);
- lab[0] = '\0';
+ return;
- if (need_quotes)
- strcat(lab, "\"");
- strcat(lab, prefix);
- strcat(lab, base);
- strcat(lab, suffix);
- if (need_quotes)
- strcat(lab, "\"");
+ lab = concat (need_quotes ? "\"" : "", user_label_prefix, base, ".eh",
+ need_quotes ? "\"" : "", NULL);
if (TREE_PUBLIC (decl))
fprintf (file, "\t%s %s\n",
fprintf (file, "\n\t%s L$set$%d", directive, darwin_dwarf_label_counter++);
}
+/* Output labels for the start of the DWARF sections if necessary. */
+void
+darwin_file_start (void)
+{
+ if (write_symbols == DWARF2_DEBUG)
+ {
+ static const char * const debugnames[] =
+ {
+ DEBUG_FRAME_SECTION,
+ DEBUG_INFO_SECTION,
+ DEBUG_ABBREV_SECTION,
+ DEBUG_ARANGES_SECTION,
+ DEBUG_MACINFO_SECTION,
+ DEBUG_LINE_SECTION,
+ DEBUG_LOC_SECTION,
+ DEBUG_PUBNAMES_SECTION,
+ DEBUG_PUBTYPES_SECTION,
+ DEBUG_STR_SECTION,
+ DEBUG_RANGES_SECTION
+ };
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE (debugnames); i++)
+ {
+ int namelen;
+
+ switch_to_section (get_section (debugnames[i], SECTION_DEBUG, NULL));
+
+ gcc_assert (strncmp (debugnames[i], "__DWARF,", 8) == 0);
+ gcc_assert (strchr (debugnames[i] + 8, ','));
+
+ namelen = strchr (debugnames[i] + 8, ',') - (debugnames[i] + 8);
+ fprintf (asm_out_file, "Lsection%.*s:\n", namelen, debugnames[i] + 8);
+ }
+ }
+}
+
+/* Output an offset in a DWARF section on Darwin. On Darwin, DWARF section
+ offsets are not represented using relocs in .o files; either the
+ section never leaves the .o file, or the linker or other tool is
+ responsible for parsing the DWARF and updating the offsets. */
+
+void
+darwin_asm_output_dwarf_offset (FILE *file, int size, const char * lab,
+ section *base)
+{
+ char sname[64];
+ int namelen;
+
+ gcc_assert (base->common.flags & SECTION_NAMED);
+ gcc_assert (strncmp (base->named.name, "__DWARF,", 8) == 0);
+ gcc_assert (strchr (base->named.name + 8, ','));
+
+ namelen = strchr (base->named.name + 8, ',') - (base->named.name + 8);
+ sprintf (sname, "*Lsection%.*s", namelen, base->named.name + 8);
+ darwin_asm_output_dwarf_delta (file, size, lab, sname);
+}
+
void
darwin_file_end (void)
{
fprintf (asm_out_file, "\t.subsections_via_symbols\n");
}
+/* TODO: Add a language hook for identifying if a decl is a vtable. */
+#define DARWIN_VTABLE_P(DECL) 0
+
/* Cross-module name binding. Darwin does not support overriding
- functions at dynamic-link time. */
+ functions at dynamic-link time, except for vtables in kexts. */
bool
darwin_binds_local_p (tree decl)
{
- return default_binds_local_p_1 (decl, 0);
+ return default_binds_local_p_1 (decl,
+ TARGET_KEXTABI && DARWIN_VTABLE_P (decl));
+}
+
+#if 0
+/* See TARGET_ASM_OUTPUT_ANCHOR for why we can't do this yet. */
+/* The Darwin's implementation of TARGET_ASM_OUTPUT_ANCHOR. Define the
+ anchor relative to ".", the current section position. We cannot use
+ the default one because ASM_OUTPUT_DEF is wrong for Darwin. */
+
+void
+darwin_asm_output_anchor (rtx symbol)
+{
+ fprintf (asm_out_file, "\t.set\t");
+ assemble_name (asm_out_file, XSTR (symbol, 0));
+ fprintf (asm_out_file, ", . + " HOST_WIDE_INT_PRINT_DEC "\n",
+ SYMBOL_REF_BLOCK_OFFSET (symbol));
+}
+#endif
+
+/* Set the darwin specific attributes on TYPE. */
+void
+darwin_set_default_type_attributes (tree type)
+{
+ if (darwin_ms_struct
+ && TREE_CODE (type) == RECORD_TYPE)
+ TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("ms_struct"),
+ NULL_TREE,
+ TYPE_ATTRIBUTES (type));
+}
+
+/* True, iff we're generating code for loadable kernel extensions. */
+
+bool
+darwin_kextabi_p (void) {
+ return flag_apple_kext;
+}
+
+void
+darwin_override_options (void)
+{
+ if (flag_mkernel || flag_apple_kext)
+ {
+ /* -mkernel implies -fapple-kext for C++ */
+ if (strcmp (lang_hooks.name, "GNU C++") == 0)
+ flag_apple_kext = 1;
+
+ flag_no_common = 1;
+
+ /* No EH in kexts. */
+ flag_exceptions = 0;
+ /* No -fnon-call-exceptions data in kexts. */
+ flag_non_call_exceptions = 0;
+ }
+ if (flag_var_tracking
+ && strverscmp (darwin_macosx_version_min, "10.5") >= 0)
+ flag_var_tracking_uninit = 1;
}
#include "gt-darwin.h"